Branch '389-ds-base-1.3.0' - 3 commits - ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/chainingdb/cb_config.c | 4 +--
ldap/servers/plugins/chainingdb/cb_instance.c | 4 +--
ldap/servers/plugins/chainingdb/cb_modify.c | 2 -
ldap/servers/plugins/replication/cl5_config.c | 2 -
ldap/servers/plugins/replication/legacy_consumer.c | 2 -
ldap/servers/plugins/replication/repl5_agmt.c | 2 -
ldap/servers/plugins/replication/repl5_replica_config.c | 4 +--
ldap/servers/plugins/uiduniq/7bit.c | 2 -
ldap/servers/plugins/uiduniq/uid.c | 2 -
ldap/servers/slapd/auditlog.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 4 +--
ldap/servers/slapd/back-ldif/modify.c | 2 -
ldap/servers/slapd/bind.c | 6 +++-
ldap/servers/slapd/configdse.c | 4 +--
ldap/servers/slapd/mapping_tree.c | 2 -
ldap/servers/slapd/modify.c | 21 +++++++++-------
ldap/servers/slapd/schema.c | 2 -
ldap/servers/slapd/search.c | 6 +++-
ldap/servers/slapd/task.c | 2 -
ldap/servers/slapd/test-plugins/testpostop.c | 2 -
23 files changed, 47 insertions(+), 36 deletions(-)
New commits:
commit 1a39cf36137d522f81bc003d07c21da53371a69d
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:43:37 2014 -0600
Ticket #47772 empty modify returns LDAP_INVALID_DN_SYNTAX
https://fedorahosted.org/389/ticket/47772
Reviewed by: mreynolds (Thanks!)
Branch: 389-ds-base-1.3.0
Fix Description: Do not call normalize_mods2bvals if mods is NULL - just allow
the empty modify op to proceed. Since normalize_mods2bvals only cares about
DN syntax attributes, it is appropriate to return LDAP_INVALID_DN_SYNTAX if
normalize_mods2bvals returns NULL.
Since this fix allows NULL mods to proceed throughout the code, I checked for
all places that SLAPI_MODIFY_MODS was used, to make sure we don't try to
dereference NULL mods, and to make sure the NULL mods were handled correctly
otherwise.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry-picked with conflicts from f5730129dfbc4ef3808735051b12cbfda518f4fb)
(cherry picked from commit 469c9b9c68806e46b14595da5aec49517af60028)
(cherry picked from commit 60c36f1c6aea1913bd7f719b9efb892092317917)
diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c
index 7cbd7ba..25f466d 100644
--- a/ldap/servers/plugins/chainingdb/cb_config.c
+++ b/ldap/servers/plugins/chainingdb/cb_config.c
@@ -380,7 +380,7 @@ cb_config_modify_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slap
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
@@ -413,7 +413,7 @@ cb_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index db0cf37..c7394e1 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -305,7 +305,7 @@ int cb_instance_modify_config_check_callback(Slapi_PBlock *pb, Slapi_Entry* entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
/* First pass to validate input */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
@@ -378,7 +378,7 @@ int cb_instance_modify_config_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
/* input checked in the preop modify callback */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
diff --git a/ldap/servers/plugins/chainingdb/cb_modify.c b/ldap/servers/plugins/chainingdb/cb_modify.c
index 06e6b82..65acb58 100644
--- a/ldap/servers/plugins/chainingdb/cb_modify.c
+++ b/ldap/servers/plugins/chainingdb/cb_modify.c
@@ -291,7 +291,7 @@ cb_remove_illegal_mods(cb_backend_instance *inst, LDAPMod **mods)
slapi_rwlock_wrlock(inst->rwl_config_lock);
for (j=0; inst->illegal_attributes[j]; j++) {
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; mods && mods[i] != NULL; i++ ) {
if (slapi_attr_types_equivalent(inst->illegal_attributes[j],mods[i]->mod_type)) {
tmp = mods[i];
for ( j = i; mods[j] != NULL; j++ ) {
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
index 980cb7f..900cfc0 100644
--- a/ldap/servers/plugins/replication/cl5_config.c
+++ b/ldap/servers/plugins/replication/cl5_config.c
@@ -340,7 +340,7 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
config.maxAge = slapi_ch_strdup(CL5_STR_IGNORE);
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] != NULL; i++)
+ for (i = 0; mods && mods[i] != NULL; i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/legacy_consumer.c b/ldap/servers/plugins/replication/legacy_consumer.c
index aa5a9b5..8eb928b 100644
--- a/ldap/servers/plugins/replication/legacy_consumer.c
+++ b/ldap/servers/plugins/replication/legacy_consumer.c
@@ -321,7 +321,7 @@ legacy_consumer_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
slapi_rwlock_wrlock (legacy_consumer_config_lock);
- for (i = 0; (mods[i] && (!not_allowed)); i++)
+ for (i = 0; mods && (mods[i] && (!not_allowed)); i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 7049656..1d6b782 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -1838,7 +1838,7 @@ agmt_notify_change(Repl_Agmt *agmt, Slapi_PBlock *pb)
int i, j;
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- for (i = 0; !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
+ for (i = 0; mods && !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
{
for (j = 0; !affects_non_fractional_attribute && NULL != mods[j]; j++)
{
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 0b82c3b..0fd5121 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -349,7 +349,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
@@ -600,7 +600,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
diff --git a/ldap/servers/plugins/uiduniq/7bit.c b/ldap/servers/plugins/uiduniq/7bit.c
index 0459bb5..f690b4e 100644
--- a/ldap/servers/plugins/uiduniq/7bit.c
+++ b/ldap/servers/plugins/uiduniq/7bit.c
@@ -455,7 +455,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(mods=firstMods;*mods;mods++)
+ for(mods=firstMods;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attr_name, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
index 984b93e..d4f0c84 100644
--- a/ldap/servers/plugins/uiduniq/uid.c
+++ b/ldap/servers/plugins/uiduniq/uid.c
@@ -761,7 +761,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(;*mods;mods++)
+ for(;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attrName, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index f6afd10..fabe21e 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -154,7 +154,7 @@ write_audit_file(
addlenstr( l, attr_changetype );
addlenstr( l, ": modify\n" );
mods = change;
- for ( j = 0; mods[j] != NULL; j++ )
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ )
{
int operationtype= mods[j]->mod_op & ~LDAP_MOD_BVALUES;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
index 0b7deaa..86479c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
@@ -287,7 +287,7 @@ ldbm_instance_attrcrypt_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
char *config_attr = (char *)mods[i]->mod_type;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index b713f73..b35004a 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -2006,7 +2006,7 @@ int ldbm_config_modify_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* There are some attributes that we don't care about, like modifiersname. */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index 34d9bf5..6839240 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -767,7 +767,7 @@ ldbm_instance_modify_config_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryB
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
if (strcasecmp(attr_name, CONFIG_INSTANCE_SUFFIX) == 0) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index b5bdb41..79b3722 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -253,7 +253,7 @@ modify_apply_check_expand(
* If the objectClass attribute type was modified in any way, expand
* the objectClass values to reflect the inheritance hierarchy.
*/
- for ( i = 0; mods[i] != NULL && !repl_op; ++i ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL) && !repl_op; ++i ) {
if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
slapi_schema_expand_objectclasses( ec->ep_entry );
break;
@@ -895,7 +895,7 @@ remove_illegal_mods(LDAPMod **mods)
LDAPMod *tmp;
/* remove any attempts by the user to modify these attrs */
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL); i++ ) {
if ( strcasecmp( mods[i]->mod_type, numsubordinates ) == 0
|| strcasecmp( mods[i]->mod_type, hassubordinates ) == 0 )
{
diff --git a/ldap/servers/slapd/back-ldif/modify.c b/ldap/servers/slapd/back-ldif/modify.c
index 7fff067..9a92b17 100644
--- a/ldap/servers/slapd/back-ldif/modify.c
+++ b/ldap/servers/slapd/back-ldif/modify.c
@@ -560,7 +560,7 @@ apply_mods( Slapi_Entry *e, LDAPMod **mods )
LDAPDebug( LDAP_DEBUG_TRACE, "=> apply_mods\n", 0, 0, 0 );
err = LDAP_SUCCESS;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n",
diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c
index bd1566e..d61d62b 100644
--- a/ldap/servers/slapd/configdse.c
+++ b/ldap/servers/slapd/configdse.c
@@ -395,7 +395,7 @@ modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, in
*/
for ( apply_mods = 0; apply_mods <= 1; apply_mods++ ) {
int i = 0;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++) {
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++) {
/* send all aci modifications to the backend */
config_attr = (char *)mods[i]->mod_type;
if (ignore_attr_type(config_attr))
@@ -498,7 +498,7 @@ postop_modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
returntext[0] = '\0';
- for (i = 0; mods[i]; i++) {
+ for (i = 0; mods && mods[i]; i++) {
if (mods[i]->mod_op & LDAP_MOD_REPLACE ) {
/* Check if the server needs to be restarted */
for (j = 0; j < num_requires_restart; j++)
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 8dc4272..83aa88e 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -1074,7 +1074,7 @@ int mapping_tree_entry_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
if ( (strcasecmp(mods[i]->mod_type, "cn") == 0) ||
(strcasecmp(mods[i]->mod_type,
MAPPING_TREE_PARENT_ATTRIBUTE) == 0) )
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 5d1fa19..d26ade1 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -391,14 +391,17 @@ do_modify( Slapi_PBlock *pb )
mods = slapi_mods_get_ldapmods_passout (&smods);
/* normalize the mods */
- normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
- ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
- if (normalized_mods == NULL) {
- op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
- "mod includes invalid dn format");
- send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
- "mod includes invalid dn format", 0, NULL);
- goto free_and_return;
+ if (mods) {
+ normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
+ ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
+ if (normalized_mods == NULL) {
+ /* NOTE: normalize_mods2bvals only handles DN syntax currently */
+ op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
+ "mod includes invalid dn format");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "mod includes invalid dn format", 0, NULL);
+ goto free_and_return;
+ }
}
slapi_pblock_set(pb, SLAPI_MODIFY_MODS, normalized_mods);
@@ -1426,7 +1429,7 @@ hash_rootpw (LDAPMod **mods)
return 0;
}
- for (i=0; mods[i] != NULL; i++) {
+ for (i=0; (mods != NULL) && (mods[i] != NULL); i++) {
LDAPMod *mod = mods[i];
if (strcasecmp (mod->mod_type, CONFIG_ROOTPW_ATTRIBUTE) != 0)
continue;
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index 603ac08..f7190df 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -1672,7 +1672,7 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr
* True for DS 4.x as well, although it tried to keep going even after
* an error was detected (which was very wrong).
*/
- for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods[i]; i++) {
+ for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods && mods[i]; i++) {
schema_dse_attr_name = (char *) mods[i]->mod_type;
num_mods++; /* incr the number of mods */
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 5fc0b08..2fe1de7 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -774,7 +774,7 @@ static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e,
/* ignore eAfter, just scan the mods for anything unacceptable */
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
/* for some reason, "modifiersName" and "modifyTimestamp" are
* stuck in by the server */
if ((strcasecmp(mods[i]->mod_type, "ttl") != 0) &&
diff --git a/ldap/servers/slapd/test-plugins/testpostop.c b/ldap/servers/slapd/test-plugins/testpostop.c
index f18f4ab..d91ddd4 100644
--- a/ldap/servers/slapd/test-plugins/testpostop.c
+++ b/ldap/servers/slapd/test-plugins/testpostop.c
@@ -355,7 +355,7 @@ write_changelog(
that has been added, replaced, or deleted. */
fprintf( fp, "changetype: modify\n" );
mods = (LDAPMod **)change;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
fprintf( fp, "add: %s\n", mods[j]->mod_type );
commit 33bf4d42727804f5c10ce30834a2340c99cad459
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:24:26 2014 -0600
Ticket #47774 mem leak in do_search - rawbase not freed upon certain errors
https://fedorahosted.org/389/ticket/47774
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.0
Fix Description: Free the local rawbase variable if it was not set in the
pblock.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 1d5c6d6ca300a45305dba631a334ae9a1857d4cb)
(cherry picked from commit b065515935daa8fffe7a8eef3a66621cc8702018)
(cherry picked from commit 97f58ff4787ecb87780fde7245e354ec75e73125)
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index 9f165a1..1f0050c 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -69,6 +69,7 @@ do_search( Slapi_PBlock *pb )
int i, err, attrsonly;
ber_int_t scope, deref, sizelimit, timelimit;
char *rawbase = NULL;
+ int rawbase_set_in_pb = 0; /* was rawbase set in pb? */
char *base = NULL, *fstr = NULL;
struct slapi_filter *filter = NULL;
char **attrs = NULL;
@@ -339,6 +340,7 @@ do_search( Slapi_PBlock *pb )
}
slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET_DN, rawbase );
+ rawbase_set_in_pb = 1; /* rawbase is now owned by pb */
slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, &scope );
slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, &deref );
slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, filter );
@@ -375,7 +377,9 @@ free_and_return:;
operation->o_flags &= ~OP_FLAG_PS;
}
/* we strdup'd this above - need to free */
- slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ if (rawbase_set_in_pb) {
+ slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ }
slapi_ch_free_string(&rawbase);
}
}
commit 0911134c2c6d97243a7f6652a9a861bf7e28d91b
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:19:08 2014 -0600
Ticket #47773 - mem leak in do_bind when there is an error
https://fedorahosted.org/389/ticket/47773
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.0
Fix Description: Do not get the SLAPI_BIND_TARGET_SDN from the pblock and
free it in the clean up code if it was never set in the pblock - just free
the local variable sdn in this case.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 2a57b521b86b24c0f0a8ddfbea4169c71ee4e896)
(cherry picked from commit c0606d45b91e87e4d0d90dec0812d20a0b23f545)
(cherry picked from commit 39eab765d9c6552c246bed13903807eca4c96887)
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index ec874cc..6dcf544 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -131,6 +131,7 @@ do_bind( Slapi_PBlock *pb )
ber_tag_t ber_rc;
int rc = 0;
Slapi_DN *sdn = NULL;
+ int bind_sdn_in_pb = 0; /* is sdn set in the pb? */
Slapi_Entry *referral;
char errorbuf[BUFSIZ];
char **supported, **pmech;
@@ -369,6 +370,7 @@ do_bind( Slapi_PBlock *pb )
isroot = slapi_dn_isroot( slapi_sdn_get_ndn(sdn) );
slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_set( pb, SLAPI_BIND_TARGET_SDN, (void*)sdn );
+ bind_sdn_in_pb = 1; /* pb now owns sdn */
slapi_pblock_set( pb, SLAPI_BIND_METHOD, &method );
slapi_pblock_set( pb, SLAPI_BIND_SASLMECHANISM, saslmech );
slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, &cred );
@@ -840,7 +842,9 @@ do_bind( Slapi_PBlock *pb )
free_and_return:;
if (be)
slapi_be_Unlock(be);
- slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ if (bind_sdn_in_pb) {
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ }
slapi_sdn_free(&sdn);
slapi_ch_free_string( &saslmech );
slapi_ch_free( (void **)&cred.bv_val );
9 years, 11 months
3 commits - ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/chainingdb/cb_config.c | 4 +--
ldap/servers/plugins/chainingdb/cb_instance.c | 4 +--
ldap/servers/plugins/chainingdb/cb_modify.c | 2 -
ldap/servers/plugins/replication/cl5_config.c | 2 -
ldap/servers/plugins/replication/legacy_consumer.c | 2 -
ldap/servers/plugins/replication/repl5_agmt.c | 2 -
ldap/servers/plugins/replication/repl5_replica_config.c | 4 +--
ldap/servers/plugins/uiduniq/7bit.c | 2 -
ldap/servers/plugins/uiduniq/uid.c | 2 -
ldap/servers/slapd/auditlog.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 4 +--
ldap/servers/slapd/back-ldif/modify.c | 2 -
ldap/servers/slapd/bind.c | 6 +++-
ldap/servers/slapd/configdse.c | 4 +--
ldap/servers/slapd/mapping_tree.c | 2 -
ldap/servers/slapd/modify.c | 21 +++++++++-------
ldap/servers/slapd/schema.c | 2 -
ldap/servers/slapd/search.c | 6 +++-
ldap/servers/slapd/task.c | 2 -
ldap/servers/slapd/test-plugins/testpostop.c | 2 -
23 files changed, 47 insertions(+), 36 deletions(-)
New commits:
commit f5730129dfbc4ef3808735051b12cbfda518f4fb
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:43:37 2014 -0600
Ticket #47772 empty modify returns LDAP_INVALID_DN_SYNTAX
https://fedorahosted.org/389/ticket/47772
Reviewed by: mreynolds (Thanks!)
Branch: master
Fix Description: Do not call normalize_mods2bvals if mods is NULL - just allow
the empty modify op to proceed. Since normalize_mods2bvals only cares about
DN syntax attributes, it is appropriate to return LDAP_INVALID_DN_SYNTAX if
normalize_mods2bvals returns NULL.
Since this fix allows NULL mods to proceed throughout the code, I checked for
all places that SLAPI_MODIFY_MODS was used, to make sure we don't try to
dereference NULL mods, and to make sure the NULL mods were handled correctly
otherwise.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c
index 7cbd7ba..25f466d 100644
--- a/ldap/servers/plugins/chainingdb/cb_config.c
+++ b/ldap/servers/plugins/chainingdb/cb_config.c
@@ -380,7 +380,7 @@ cb_config_modify_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slap
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
@@ -413,7 +413,7 @@ cb_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index 10958d7..fa9c441 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -306,7 +306,7 @@ int cb_instance_modify_config_check_callback(Slapi_PBlock *pb, Slapi_Entry* entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
/* First pass to validate input */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
@@ -379,7 +379,7 @@ int cb_instance_modify_config_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
/* input checked in the preop modify callback */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
diff --git a/ldap/servers/plugins/chainingdb/cb_modify.c b/ldap/servers/plugins/chainingdb/cb_modify.c
index 06e6b82..65acb58 100644
--- a/ldap/servers/plugins/chainingdb/cb_modify.c
+++ b/ldap/servers/plugins/chainingdb/cb_modify.c
@@ -291,7 +291,7 @@ cb_remove_illegal_mods(cb_backend_instance *inst, LDAPMod **mods)
slapi_rwlock_wrlock(inst->rwl_config_lock);
for (j=0; inst->illegal_attributes[j]; j++) {
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; mods && mods[i] != NULL; i++ ) {
if (slapi_attr_types_equivalent(inst->illegal_attributes[j],mods[i]->mod_type)) {
tmp = mods[i];
for ( j = i; mods[j] != NULL; j++ ) {
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
index e168bbd..55727c2 100644
--- a/ldap/servers/plugins/replication/cl5_config.c
+++ b/ldap/servers/plugins/replication/cl5_config.c
@@ -342,7 +342,7 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
config.trimInterval = CL5_NUM_IGNORE;
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] != NULL; i++)
+ for (i = 0; mods && mods[i] != NULL; i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/legacy_consumer.c b/ldap/servers/plugins/replication/legacy_consumer.c
index aa5a9b5..8eb928b 100644
--- a/ldap/servers/plugins/replication/legacy_consumer.c
+++ b/ldap/servers/plugins/replication/legacy_consumer.c
@@ -321,7 +321,7 @@ legacy_consumer_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
slapi_rwlock_wrlock (legacy_consumer_config_lock);
- for (i = 0; (mods[i] && (!not_allowed)); i++)
+ for (i = 0; mods && (mods[i] && (!not_allowed)); i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 8fb5a02..139c8a3 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -1920,7 +1920,7 @@ agmt_notify_change(Repl_Agmt *agmt, Slapi_PBlock *pb)
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
slapi_rwlock_rdlock(agmt->attr_lock);
- for (i = 0; !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
+ for (i = 0; mods && !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
{
for (j = 0; !affects_non_fractional_attribute && NULL != mods[j]; j++)
{
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index a8c72c1..f433fc9 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -351,7 +351,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
@@ -699,7 +699,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
diff --git a/ldap/servers/plugins/uiduniq/7bit.c b/ldap/servers/plugins/uiduniq/7bit.c
index 3474bf9..c84c79c 100644
--- a/ldap/servers/plugins/uiduniq/7bit.c
+++ b/ldap/servers/plugins/uiduniq/7bit.c
@@ -472,7 +472,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(mods=firstMods;*mods;mods++)
+ for(mods=firstMods;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attr_name, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
index 984b93e..d4f0c84 100644
--- a/ldap/servers/plugins/uiduniq/uid.c
+++ b/ldap/servers/plugins/uiduniq/uid.c
@@ -761,7 +761,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(;*mods;mods++)
+ for(;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attrName, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index f6afd10..fabe21e 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -154,7 +154,7 @@ write_audit_file(
addlenstr( l, attr_changetype );
addlenstr( l, ": modify\n" );
mods = change;
- for ( j = 0; mods[j] != NULL; j++ )
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ )
{
int operationtype= mods[j]->mod_op & ~LDAP_MOD_BVALUES;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
index 0b7deaa..86479c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
@@ -287,7 +287,7 @@ ldbm_instance_attrcrypt_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
char *config_attr = (char *)mods[i]->mod_type;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index ef5cdce..0f8cc76 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -2124,7 +2124,7 @@ int ldbm_config_modify_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* There are some attributes that we don't care about, like modifiersname. */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index 565e9ad..9b93f9a 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -781,7 +781,7 @@ ldbm_instance_modify_config_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryB
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
if (strcasecmp(attr_name, CONFIG_INSTANCE_SUFFIX) == 0) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 92692f0..8bbeae0 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -253,7 +253,7 @@ modify_apply_check_expand(
* If the objectClass attribute type was modified in any way, expand
* the objectClass values to reflect the inheritance hierarchy.
*/
- for ( i = 0; mods[i] != NULL && !repl_op; ++i ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL) && !repl_op; ++i ) {
if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
slapi_schema_expand_objectclasses( ec->ep_entry );
break;
@@ -938,7 +938,7 @@ remove_illegal_mods(LDAPMod **mods)
LDAPMod *tmp;
/* remove any attempts by the user to modify these attrs */
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL); i++ ) {
if ( strcasecmp( mods[i]->mod_type, numsubordinates ) == 0
|| strcasecmp( mods[i]->mod_type, hassubordinates ) == 0 )
{
diff --git a/ldap/servers/slapd/back-ldif/modify.c b/ldap/servers/slapd/back-ldif/modify.c
index 7fff067..9a92b17 100644
--- a/ldap/servers/slapd/back-ldif/modify.c
+++ b/ldap/servers/slapd/back-ldif/modify.c
@@ -560,7 +560,7 @@ apply_mods( Slapi_Entry *e, LDAPMod **mods )
LDAPDebug( LDAP_DEBUG_TRACE, "=> apply_mods\n", 0, 0, 0 );
err = LDAP_SUCCESS;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n",
diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c
index 2cea73a..339be42 100644
--- a/ldap/servers/slapd/configdse.c
+++ b/ldap/servers/slapd/configdse.c
@@ -394,7 +394,7 @@ modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, in
*/
for ( apply_mods = 0; apply_mods <= 1; apply_mods++ ) {
int i = 0;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++) {
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++) {
/* send all aci modifications to the backend */
config_attr = (char *)mods[i]->mod_type;
if (ignore_attr_type(config_attr))
@@ -497,7 +497,7 @@ postop_modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
returntext[0] = '\0';
- for (i = 0; mods[i]; i++) {
+ for (i = 0; mods && mods[i]; i++) {
if (mods[i]->mod_op & LDAP_MOD_REPLACE ) {
/* Check if the server needs to be restarted */
for (j = 0; j < num_requires_restart; j++)
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index d01b285..338fffe 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -1096,7 +1096,7 @@ int mapping_tree_entry_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
if ( (strcasecmp(mods[i]->mod_type, "cn") == 0) ||
(strcasecmp(mods[i]->mod_type,
MAPPING_TREE_PARENT_ATTRIBUTE) == 0) )
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 79e7c7c..7763700 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -402,14 +402,17 @@ do_modify( Slapi_PBlock *pb )
mods = slapi_mods_get_ldapmods_passout (&smods);
/* normalize the mods */
- normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
- ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
- if (normalized_mods == NULL) {
- op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
- "mod includes invalid dn format");
- send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
- "mod includes invalid dn format", 0, NULL);
- goto free_and_return;
+ if (mods) {
+ normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
+ ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
+ if (normalized_mods == NULL) {
+ /* NOTE: normalize_mods2bvals only handles DN syntax currently */
+ op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
+ "mod includes invalid dn format");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "mod includes invalid dn format", 0, NULL);
+ goto free_and_return;
+ }
}
slapi_pblock_set(pb, SLAPI_MODIFY_MODS, normalized_mods);
@@ -1445,7 +1448,7 @@ hash_rootpw (LDAPMod **mods)
return 0;
}
- for (i=0; mods[i] != NULL; i++) {
+ for (i=0; (mods != NULL) && (mods[i] != NULL); i++) {
LDAPMod *mod = mods[i];
if (strcasecmp (mod->mod_type, CONFIG_ROOTPW_ATTRIBUTE) != 0)
continue;
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index 24febad..d6aae58 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -2082,7 +2082,7 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr
* True for DS 4.x as well, although it tried to keep going even after
* an error was detected (which was very wrong).
*/
- for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods[i]; i++) {
+ for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods && mods[i]; i++) {
schema_dse_attr_name = (char *) mods[i]->mod_type;
num_mods++; /* incr the number of mods */
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 5e03bc2..6340db8 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -792,7 +792,7 @@ static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e,
/* ignore eAfter, just scan the mods for anything unacceptable */
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
/* for some reason, "modifiersName" and "modifyTimestamp" are
* stuck in by the server */
if ((strcasecmp(mods[i]->mod_type, "ttl") != 0) &&
diff --git a/ldap/servers/slapd/test-plugins/testpostop.c b/ldap/servers/slapd/test-plugins/testpostop.c
index f18f4ab..d91ddd4 100644
--- a/ldap/servers/slapd/test-plugins/testpostop.c
+++ b/ldap/servers/slapd/test-plugins/testpostop.c
@@ -355,7 +355,7 @@ write_changelog(
that has been added, replaced, or deleted. */
fprintf( fp, "changetype: modify\n" );
mods = (LDAPMod **)change;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
fprintf( fp, "add: %s\n", mods[j]->mod_type );
commit 1d5c6d6ca300a45305dba631a334ae9a1857d4cb
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:24:26 2014 -0600
Ticket #47774 mem leak in do_search - rawbase not freed upon certain errors
https://fedorahosted.org/389/ticket/47774
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Free the local rawbase variable if it was not set in the
pblock.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index d68ba7b..5cdef9c 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -69,6 +69,7 @@ do_search( Slapi_PBlock *pb )
int i, err, attrsonly;
ber_int_t scope, deref, sizelimit, timelimit;
char *rawbase = NULL;
+ int rawbase_set_in_pb = 0; /* was rawbase set in pb? */
char *base = NULL, *fstr = NULL;
struct slapi_filter *filter = NULL;
char **attrs = NULL;
@@ -360,6 +361,7 @@ do_search( Slapi_PBlock *pb )
}
slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET_DN, rawbase );
+ rawbase_set_in_pb = 1; /* rawbase is now owned by pb */
slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, &scope );
slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, &deref );
slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, filter );
@@ -397,7 +399,9 @@ free_and_return:;
operation->o_flags &= ~OP_FLAG_PS;
}
/* we strdup'd this above - need to free */
- slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ if (rawbase_set_in_pb) {
+ slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ }
slapi_ch_free_string(&rawbase);
}
}
commit 2a57b521b86b24c0f0a8ddfbea4169c71ee4e896
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:19:08 2014 -0600
Ticket #47773 - mem leak in do_bind when there is an error
https://fedorahosted.org/389/ticket/47773
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Do not get the SLAPI_BIND_TARGET_SDN from the pblock and
free it in the clean up code if it was never set in the pblock - just free
the local variable sdn in this case.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index 2a9d8b7..58a4e13 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -131,6 +131,7 @@ do_bind( Slapi_PBlock *pb )
ber_tag_t ber_rc;
int rc = 0;
Slapi_DN *sdn = NULL;
+ int bind_sdn_in_pb = 0; /* is sdn set in the pb? */
Slapi_Entry *referral;
char errorbuf[BUFSIZ];
char **supported, **pmech;
@@ -369,6 +370,7 @@ do_bind( Slapi_PBlock *pb )
isroot = slapi_dn_isroot( slapi_sdn_get_ndn(sdn) );
slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_set( pb, SLAPI_BIND_TARGET_SDN, (void*)sdn );
+ bind_sdn_in_pb = 1; /* pb now owns sdn */
slapi_pblock_set( pb, SLAPI_BIND_METHOD, &method );
slapi_pblock_set( pb, SLAPI_BIND_SASLMECHANISM, saslmech );
slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, &cred );
@@ -861,7 +863,9 @@ account_locked:
free_and_return:;
if (be)
slapi_be_Unlock(be);
- slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ if (bind_sdn_in_pb) {
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ }
slapi_sdn_free(&sdn);
slapi_ch_free_string( &saslmech );
slapi_ch_free( (void **)&cred.bv_val );
9 years, 11 months
Branch '389-ds-base-1.3.2' - 3 commits - ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/chainingdb/cb_config.c | 4 +--
ldap/servers/plugins/chainingdb/cb_instance.c | 4 +--
ldap/servers/plugins/chainingdb/cb_modify.c | 2 -
ldap/servers/plugins/replication/cl5_config.c | 2 -
ldap/servers/plugins/replication/legacy_consumer.c | 2 -
ldap/servers/plugins/replication/repl5_agmt.c | 2 -
ldap/servers/plugins/replication/repl5_replica_config.c | 4 +--
ldap/servers/plugins/uiduniq/7bit.c | 2 -
ldap/servers/plugins/uiduniq/uid.c | 2 -
ldap/servers/slapd/auditlog.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 4 +--
ldap/servers/slapd/back-ldif/modify.c | 2 -
ldap/servers/slapd/bind.c | 6 +++-
ldap/servers/slapd/configdse.c | 4 +--
ldap/servers/slapd/mapping_tree.c | 2 -
ldap/servers/slapd/modify.c | 21 +++++++++-------
ldap/servers/slapd/schema.c | 2 -
ldap/servers/slapd/search.c | 6 +++-
ldap/servers/slapd/task.c | 2 -
ldap/servers/slapd/test-plugins/testpostop.c | 2 -
23 files changed, 47 insertions(+), 36 deletions(-)
New commits:
commit 469c9b9c68806e46b14595da5aec49517af60028
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:43:37 2014 -0600
Ticket #47772 empty modify returns LDAP_INVALID_DN_SYNTAX
https://fedorahosted.org/389/ticket/47772
Reviewed by: mreynolds (Thanks!)
Branch: 389-ds-base-1.3.2
Fix Description: Do not call normalize_mods2bvals if mods is NULL - just allow
the empty modify op to proceed. Since normalize_mods2bvals only cares about
DN syntax attributes, it is appropriate to return LDAP_INVALID_DN_SYNTAX if
normalize_mods2bvals returns NULL.
Since this fix allows NULL mods to proceed throughout the code, I checked for
all places that SLAPI_MODIFY_MODS was used, to make sure we don't try to
dereference NULL mods, and to make sure the NULL mods were handled correctly
otherwise.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry-picked with conflicts from f5730129dfbc4ef3808735051b12cbfda518f4fb)
diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c
index 7cbd7ba..25f466d 100644
--- a/ldap/servers/plugins/chainingdb/cb_config.c
+++ b/ldap/servers/plugins/chainingdb/cb_config.c
@@ -380,7 +380,7 @@ cb_config_modify_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slap
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
@@ -413,7 +413,7 @@ cb_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index db0cf37..c7394e1 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -305,7 +305,7 @@ int cb_instance_modify_config_check_callback(Slapi_PBlock *pb, Slapi_Entry* entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
/* First pass to validate input */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
@@ -378,7 +378,7 @@ int cb_instance_modify_config_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
/* input checked in the preop modify callback */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
diff --git a/ldap/servers/plugins/chainingdb/cb_modify.c b/ldap/servers/plugins/chainingdb/cb_modify.c
index 06e6b82..65acb58 100644
--- a/ldap/servers/plugins/chainingdb/cb_modify.c
+++ b/ldap/servers/plugins/chainingdb/cb_modify.c
@@ -291,7 +291,7 @@ cb_remove_illegal_mods(cb_backend_instance *inst, LDAPMod **mods)
slapi_rwlock_wrlock(inst->rwl_config_lock);
for (j=0; inst->illegal_attributes[j]; j++) {
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; mods && mods[i] != NULL; i++ ) {
if (slapi_attr_types_equivalent(inst->illegal_attributes[j],mods[i]->mod_type)) {
tmp = mods[i];
for ( j = i; mods[j] != NULL; j++ ) {
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
index e168bbd..55727c2 100644
--- a/ldap/servers/plugins/replication/cl5_config.c
+++ b/ldap/servers/plugins/replication/cl5_config.c
@@ -342,7 +342,7 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
config.trimInterval = CL5_NUM_IGNORE;
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] != NULL; i++)
+ for (i = 0; mods && mods[i] != NULL; i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/legacy_consumer.c b/ldap/servers/plugins/replication/legacy_consumer.c
index aa5a9b5..8eb928b 100644
--- a/ldap/servers/plugins/replication/legacy_consumer.c
+++ b/ldap/servers/plugins/replication/legacy_consumer.c
@@ -321,7 +321,7 @@ legacy_consumer_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
slapi_rwlock_wrlock (legacy_consumer_config_lock);
- for (i = 0; (mods[i] && (!not_allowed)); i++)
+ for (i = 0; mods && (mods[i] && (!not_allowed)); i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 80b87de..d5c6439 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -1866,7 +1866,7 @@ agmt_notify_change(Repl_Agmt *agmt, Slapi_PBlock *pb)
int i, j;
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- for (i = 0; !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
+ for (i = 0; mods && !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
{
for (j = 0; !affects_non_fractional_attribute && NULL != mods[j]; j++)
{
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 130dfab..e6c495c 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -350,7 +350,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
@@ -682,7 +682,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
diff --git a/ldap/servers/plugins/uiduniq/7bit.c b/ldap/servers/plugins/uiduniq/7bit.c
index 3474bf9..c84c79c 100644
--- a/ldap/servers/plugins/uiduniq/7bit.c
+++ b/ldap/servers/plugins/uiduniq/7bit.c
@@ -472,7 +472,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(mods=firstMods;*mods;mods++)
+ for(mods=firstMods;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attr_name, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
index 984b93e..d4f0c84 100644
--- a/ldap/servers/plugins/uiduniq/uid.c
+++ b/ldap/servers/plugins/uiduniq/uid.c
@@ -761,7 +761,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(;*mods;mods++)
+ for(;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attrName, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index f6afd10..fabe21e 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -154,7 +154,7 @@ write_audit_file(
addlenstr( l, attr_changetype );
addlenstr( l, ": modify\n" );
mods = change;
- for ( j = 0; mods[j] != NULL; j++ )
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ )
{
int operationtype= mods[j]->mod_op & ~LDAP_MOD_BVALUES;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
index 0b7deaa..86479c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
@@ -287,7 +287,7 @@ ldbm_instance_attrcrypt_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
char *config_attr = (char *)mods[i]->mod_type;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index d53e9b3..4faf235 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -2100,7 +2100,7 @@ int ldbm_config_modify_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* There are some attributes that we don't care about, like modifiersname. */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index 34d9bf5..6839240 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -767,7 +767,7 @@ ldbm_instance_modify_config_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryB
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
if (strcasecmp(attr_name, CONFIG_INSTANCE_SUFFIX) == 0) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 92692f0..8bbeae0 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -253,7 +253,7 @@ modify_apply_check_expand(
* If the objectClass attribute type was modified in any way, expand
* the objectClass values to reflect the inheritance hierarchy.
*/
- for ( i = 0; mods[i] != NULL && !repl_op; ++i ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL) && !repl_op; ++i ) {
if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
slapi_schema_expand_objectclasses( ec->ep_entry );
break;
@@ -938,7 +938,7 @@ remove_illegal_mods(LDAPMod **mods)
LDAPMod *tmp;
/* remove any attempts by the user to modify these attrs */
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL); i++ ) {
if ( strcasecmp( mods[i]->mod_type, numsubordinates ) == 0
|| strcasecmp( mods[i]->mod_type, hassubordinates ) == 0 )
{
diff --git a/ldap/servers/slapd/back-ldif/modify.c b/ldap/servers/slapd/back-ldif/modify.c
index 7fff067..9a92b17 100644
--- a/ldap/servers/slapd/back-ldif/modify.c
+++ b/ldap/servers/slapd/back-ldif/modify.c
@@ -560,7 +560,7 @@ apply_mods( Slapi_Entry *e, LDAPMod **mods )
LDAPDebug( LDAP_DEBUG_TRACE, "=> apply_mods\n", 0, 0, 0 );
err = LDAP_SUCCESS;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n",
diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c
index b54062d..14e8a5e 100644
--- a/ldap/servers/slapd/configdse.c
+++ b/ldap/servers/slapd/configdse.c
@@ -394,7 +394,7 @@ modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, in
*/
for ( apply_mods = 0; apply_mods <= 1; apply_mods++ ) {
int i = 0;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++) {
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++) {
/* send all aci modifications to the backend */
config_attr = (char *)mods[i]->mod_type;
if (ignore_attr_type(config_attr))
@@ -497,7 +497,7 @@ postop_modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
returntext[0] = '\0';
- for (i = 0; mods[i]; i++) {
+ for (i = 0; mods && mods[i]; i++) {
if (mods[i]->mod_op & LDAP_MOD_REPLACE ) {
/* Check if the server needs to be restarted */
for (j = 0; j < num_requires_restart; j++)
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index d01b285..338fffe 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -1096,7 +1096,7 @@ int mapping_tree_entry_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
if ( (strcasecmp(mods[i]->mod_type, "cn") == 0) ||
(strcasecmp(mods[i]->mod_type,
MAPPING_TREE_PARENT_ATTRIBUTE) == 0) )
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 79e7c7c..7763700 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -402,14 +402,17 @@ do_modify( Slapi_PBlock *pb )
mods = slapi_mods_get_ldapmods_passout (&smods);
/* normalize the mods */
- normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
- ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
- if (normalized_mods == NULL) {
- op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
- "mod includes invalid dn format");
- send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
- "mod includes invalid dn format", 0, NULL);
- goto free_and_return;
+ if (mods) {
+ normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
+ ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
+ if (normalized_mods == NULL) {
+ /* NOTE: normalize_mods2bvals only handles DN syntax currently */
+ op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
+ "mod includes invalid dn format");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "mod includes invalid dn format", 0, NULL);
+ goto free_and_return;
+ }
}
slapi_pblock_set(pb, SLAPI_MODIFY_MODS, normalized_mods);
@@ -1445,7 +1448,7 @@ hash_rootpw (LDAPMod **mods)
return 0;
}
- for (i=0; mods[i] != NULL; i++) {
+ for (i=0; (mods != NULL) && (mods[i] != NULL); i++) {
LDAPMod *mod = mods[i];
if (strcasecmp (mod->mod_type, CONFIG_ROOTPW_ATTRIBUTE) != 0)
continue;
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index ff0f3d8..2145b83 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -1829,7 +1829,7 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr
* True for DS 4.x as well, although it tried to keep going even after
* an error was detected (which was very wrong).
*/
- for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods[i]; i++) {
+ for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods && mods[i]; i++) {
schema_dse_attr_name = (char *) mods[i]->mod_type;
num_mods++; /* incr the number of mods */
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 3ffd799..d7a3fda 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -774,7 +774,7 @@ static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e,
/* ignore eAfter, just scan the mods for anything unacceptable */
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
/* for some reason, "modifiersName" and "modifyTimestamp" are
* stuck in by the server */
if ((strcasecmp(mods[i]->mod_type, "ttl") != 0) &&
diff --git a/ldap/servers/slapd/test-plugins/testpostop.c b/ldap/servers/slapd/test-plugins/testpostop.c
index f18f4ab..d91ddd4 100644
--- a/ldap/servers/slapd/test-plugins/testpostop.c
+++ b/ldap/servers/slapd/test-plugins/testpostop.c
@@ -355,7 +355,7 @@ write_changelog(
that has been added, replaced, or deleted. */
fprintf( fp, "changetype: modify\n" );
mods = (LDAPMod **)change;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
fprintf( fp, "add: %s\n", mods[j]->mod_type );
commit b065515935daa8fffe7a8eef3a66621cc8702018
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:24:26 2014 -0600
Ticket #47774 mem leak in do_search - rawbase not freed upon certain errors
https://fedorahosted.org/389/ticket/47774
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.2
Fix Description: Free the local rawbase variable if it was not set in the
pblock.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 1d5c6d6ca300a45305dba631a334ae9a1857d4cb)
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index d68ba7b..5cdef9c 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -69,6 +69,7 @@ do_search( Slapi_PBlock *pb )
int i, err, attrsonly;
ber_int_t scope, deref, sizelimit, timelimit;
char *rawbase = NULL;
+ int rawbase_set_in_pb = 0; /* was rawbase set in pb? */
char *base = NULL, *fstr = NULL;
struct slapi_filter *filter = NULL;
char **attrs = NULL;
@@ -360,6 +361,7 @@ do_search( Slapi_PBlock *pb )
}
slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET_DN, rawbase );
+ rawbase_set_in_pb = 1; /* rawbase is now owned by pb */
slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, &scope );
slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, &deref );
slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, filter );
@@ -397,7 +399,9 @@ free_and_return:;
operation->o_flags &= ~OP_FLAG_PS;
}
/* we strdup'd this above - need to free */
- slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ if (rawbase_set_in_pb) {
+ slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ }
slapi_ch_free_string(&rawbase);
}
}
commit c0606d45b91e87e4d0d90dec0812d20a0b23f545
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:19:08 2014 -0600
Ticket #47773 - mem leak in do_bind when there is an error
https://fedorahosted.org/389/ticket/47773
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.2
Fix Description: Do not get the SLAPI_BIND_TARGET_SDN from the pblock and
free it in the clean up code if it was never set in the pblock - just free
the local variable sdn in this case.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 2a57b521b86b24c0f0a8ddfbea4169c71ee4e896)
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index 2a9d8b7..58a4e13 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -131,6 +131,7 @@ do_bind( Slapi_PBlock *pb )
ber_tag_t ber_rc;
int rc = 0;
Slapi_DN *sdn = NULL;
+ int bind_sdn_in_pb = 0; /* is sdn set in the pb? */
Slapi_Entry *referral;
char errorbuf[BUFSIZ];
char **supported, **pmech;
@@ -369,6 +370,7 @@ do_bind( Slapi_PBlock *pb )
isroot = slapi_dn_isroot( slapi_sdn_get_ndn(sdn) );
slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_set( pb, SLAPI_BIND_TARGET_SDN, (void*)sdn );
+ bind_sdn_in_pb = 1; /* pb now owns sdn */
slapi_pblock_set( pb, SLAPI_BIND_METHOD, &method );
slapi_pblock_set( pb, SLAPI_BIND_SASLMECHANISM, saslmech );
slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, &cred );
@@ -861,7 +863,9 @@ account_locked:
free_and_return:;
if (be)
slapi_be_Unlock(be);
- slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ if (bind_sdn_in_pb) {
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ }
slapi_sdn_free(&sdn);
slapi_ch_free_string( &saslmech );
slapi_ch_free( (void **)&cred.bv_val );
9 years, 11 months
Branch '389-ds-base-1.3.1' - 3 commits - ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/chainingdb/cb_config.c | 4 +--
ldap/servers/plugins/chainingdb/cb_instance.c | 4 +--
ldap/servers/plugins/chainingdb/cb_modify.c | 2 -
ldap/servers/plugins/replication/cl5_config.c | 2 -
ldap/servers/plugins/replication/legacy_consumer.c | 2 -
ldap/servers/plugins/replication/repl5_agmt.c | 2 -
ldap/servers/plugins/replication/repl5_replica_config.c | 4 +--
ldap/servers/plugins/uiduniq/7bit.c | 2 -
ldap/servers/plugins/uiduniq/uid.c | 2 -
ldap/servers/slapd/auditlog.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 2 -
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 4 +--
ldap/servers/slapd/back-ldif/modify.c | 2 -
ldap/servers/slapd/bind.c | 6 +++-
ldap/servers/slapd/configdse.c | 4 +--
ldap/servers/slapd/mapping_tree.c | 2 -
ldap/servers/slapd/modify.c | 21 +++++++++-------
ldap/servers/slapd/schema.c | 2 -
ldap/servers/slapd/search.c | 6 +++-
ldap/servers/slapd/task.c | 2 -
ldap/servers/slapd/test-plugins/testpostop.c | 2 -
23 files changed, 47 insertions(+), 36 deletions(-)
New commits:
commit 60c36f1c6aea1913bd7f719b9efb892092317917
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:43:37 2014 -0600
Ticket #47772 empty modify returns LDAP_INVALID_DN_SYNTAX
https://fedorahosted.org/389/ticket/47772
Reviewed by: mreynolds (Thanks!)
Branch: 389-ds-base-1.3.1
Fix Description: Do not call normalize_mods2bvals if mods is NULL - just allow
the empty modify op to proceed. Since normalize_mods2bvals only cares about
DN syntax attributes, it is appropriate to return LDAP_INVALID_DN_SYNTAX if
normalize_mods2bvals returns NULL.
Since this fix allows NULL mods to proceed throughout the code, I checked for
all places that SLAPI_MODIFY_MODS was used, to make sure we don't try to
dereference NULL mods, and to make sure the NULL mods were handled correctly
otherwise.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry-picked with conflicts from f5730129dfbc4ef3808735051b12cbfda518f4fb)
(cherry picked from commit 469c9b9c68806e46b14595da5aec49517af60028)
diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c
index 7cbd7ba..25f466d 100644
--- a/ldap/servers/plugins/chainingdb/cb_config.c
+++ b/ldap/servers/plugins/chainingdb/cb_config.c
@@ -380,7 +380,7 @@ cb_config_modify_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slap
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
@@ -413,7 +413,7 @@ cb_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] ; i++) {
+ for (i = 0; mods && mods[i] ; i++) {
attr_name = mods[i]->mod_type;
if ( !strcasecmp ( attr_name, CB_CONFIG_GLOBAL_FORWARD_CTRLS )) {
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index db0cf37..c7394e1 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -305,7 +305,7 @@ int cb_instance_modify_config_check_callback(Slapi_PBlock *pb, Slapi_Entry* entr
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
/* First pass to validate input */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
@@ -378,7 +378,7 @@ int cb_instance_modify_config_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
/* input checked in the preop modify callback */
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* specific processing for multi-valued attributes */
diff --git a/ldap/servers/plugins/chainingdb/cb_modify.c b/ldap/servers/plugins/chainingdb/cb_modify.c
index 06e6b82..65acb58 100644
--- a/ldap/servers/plugins/chainingdb/cb_modify.c
+++ b/ldap/servers/plugins/chainingdb/cb_modify.c
@@ -291,7 +291,7 @@ cb_remove_illegal_mods(cb_backend_instance *inst, LDAPMod **mods)
slapi_rwlock_wrlock(inst->rwl_config_lock);
for (j=0; inst->illegal_attributes[j]; j++) {
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; mods && mods[i] != NULL; i++ ) {
if (slapi_attr_types_equivalent(inst->illegal_attributes[j],mods[i]->mod_type)) {
tmp = mods[i];
for ( j = i; mods[j] != NULL; j++ ) {
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
index 980cb7f..900cfc0 100644
--- a/ldap/servers/plugins/replication/cl5_config.c
+++ b/ldap/servers/plugins/replication/cl5_config.c
@@ -340,7 +340,7 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
config.maxAge = slapi_ch_strdup(CL5_STR_IGNORE);
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
- for (i = 0; mods[i] != NULL; i++)
+ for (i = 0; mods && mods[i] != NULL; i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/legacy_consumer.c b/ldap/servers/plugins/replication/legacy_consumer.c
index aa5a9b5..8eb928b 100644
--- a/ldap/servers/plugins/replication/legacy_consumer.c
+++ b/ldap/servers/plugins/replication/legacy_consumer.c
@@ -321,7 +321,7 @@ legacy_consumer_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
slapi_rwlock_wrlock (legacy_consumer_config_lock);
- for (i = 0; (mods[i] && (!not_allowed)); i++)
+ for (i = 0; mods && (mods[i] && (!not_allowed)); i++)
{
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 14c2fb4..093aa8a 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -1866,7 +1866,7 @@ agmt_notify_change(Repl_Agmt *agmt, Slapi_PBlock *pb)
int i, j;
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- for (i = 0; !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
+ for (i = 0; mods && !affects_non_fractional_attribute && NULL != agmt->frac_attrs[i]; i++)
{
for (j = 0; !affects_non_fractional_attribute && NULL != mods[j]; j++)
{
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index bc5014a..91f5c32 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -349,7 +349,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
@@ -683,7 +683,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
if (*returncode != LDAP_SUCCESS)
break;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++)
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++)
{
if (*returncode != LDAP_SUCCESS)
break;
diff --git a/ldap/servers/plugins/uiduniq/7bit.c b/ldap/servers/plugins/uiduniq/7bit.c
index 0459bb5..f690b4e 100644
--- a/ldap/servers/plugins/uiduniq/7bit.c
+++ b/ldap/servers/plugins/uiduniq/7bit.c
@@ -455,7 +455,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(mods=firstMods;*mods;mods++)
+ for(mods=firstMods;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attr_name, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
index 984b93e..d4f0c84 100644
--- a/ldap/servers/plugins/uiduniq/uid.c
+++ b/ldap/servers/plugins/uiduniq/uid.c
@@ -761,7 +761,7 @@ preop_modify(Slapi_PBlock *pb)
which are add or replace ops and are bvalue encoded
*/
/* find out how many mods meet this criteria */
- for(;*mods;mods++)
+ for(;mods && *mods;mods++)
{
mod = *mods;
if ((slapi_attr_type_cmp(mod->mod_type, attrName, 1) == 0) && /* mod contains target attr */
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index f6afd10..fabe21e 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -154,7 +154,7 @@ write_audit_file(
addlenstr( l, attr_changetype );
addlenstr( l, ": modify\n" );
mods = change;
- for ( j = 0; mods[j] != NULL; j++ )
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ )
{
int operationtype= mods[j]->mod_op & ~LDAP_MOD_BVALUES;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
index 0b7deaa..86479c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c
@@ -287,7 +287,7 @@ ldbm_instance_attrcrypt_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
char *config_attr = (char *)mods[i]->mod_type;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index cd74b5a..08f3490 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -2006,7 +2006,7 @@ int ldbm_config_modify_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
/* There are some attributes that we don't care about, like modifiersname. */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index 34d9bf5..6839240 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -767,7 +767,7 @@ ldbm_instance_modify_config_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryB
* 2nd pass: set apply mods to 1 to apply changes to internal storage
*/
for ( apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++ ) {
- for (i = 0; mods[i] && LDAP_SUCCESS == rc; i++) {
+ for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
attr_name = mods[i]->mod_type;
if (strcasecmp(attr_name, CONFIG_INSTANCE_SUFFIX) == 0) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index f3b099d..de5dd17 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -253,7 +253,7 @@ modify_apply_check_expand(
* If the objectClass attribute type was modified in any way, expand
* the objectClass values to reflect the inheritance hierarchy.
*/
- for ( i = 0; mods[i] != NULL && !repl_op; ++i ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL) && !repl_op; ++i ) {
if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
slapi_schema_expand_objectclasses( ec->ep_entry );
break;
@@ -897,7 +897,7 @@ remove_illegal_mods(LDAPMod **mods)
LDAPMod *tmp;
/* remove any attempts by the user to modify these attrs */
- for ( i = 0; mods[i] != NULL; i++ ) {
+ for ( i = 0; (mods != NULL) && (mods[i] != NULL); i++ ) {
if ( strcasecmp( mods[i]->mod_type, numsubordinates ) == 0
|| strcasecmp( mods[i]->mod_type, hassubordinates ) == 0 )
{
diff --git a/ldap/servers/slapd/back-ldif/modify.c b/ldap/servers/slapd/back-ldif/modify.c
index 7fff067..9a92b17 100644
--- a/ldap/servers/slapd/back-ldif/modify.c
+++ b/ldap/servers/slapd/back-ldif/modify.c
@@ -560,7 +560,7 @@ apply_mods( Slapi_Entry *e, LDAPMod **mods )
LDAPDebug( LDAP_DEBUG_TRACE, "=> apply_mods\n", 0, 0, 0 );
err = LDAP_SUCCESS;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n",
diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c
index b54062d..14e8a5e 100644
--- a/ldap/servers/slapd/configdse.c
+++ b/ldap/servers/slapd/configdse.c
@@ -394,7 +394,7 @@ modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, in
*/
for ( apply_mods = 0; apply_mods <= 1; apply_mods++ ) {
int i = 0;
- for (i = 0; (mods[i] && (LDAP_SUCCESS == rc)); i++) {
+ for (i = 0; mods && (mods[i] && (LDAP_SUCCESS == rc)); i++) {
/* send all aci modifications to the backend */
config_attr = (char *)mods[i]->mod_type;
if (ignore_attr_type(config_attr))
@@ -497,7 +497,7 @@ postop_modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
returntext[0] = '\0';
- for (i = 0; mods[i]; i++) {
+ for (i = 0; mods && mods[i]; i++) {
if (mods[i]->mod_op & LDAP_MOD_REPLACE ) {
/* Check if the server needs to be restarted */
for (j = 0; j < num_requires_restart; j++)
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 8dc4272..83aa88e 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -1074,7 +1074,7 @@ int mapping_tree_entry_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
return SLAPI_DSE_CALLBACK_ERROR;
}
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
if ( (strcasecmp(mods[i]->mod_type, "cn") == 0) ||
(strcasecmp(mods[i]->mod_type,
MAPPING_TREE_PARENT_ATTRIBUTE) == 0) )
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 2e78cbf..51d4194 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -401,14 +401,17 @@ do_modify( Slapi_PBlock *pb )
mods = slapi_mods_get_ldapmods_passout (&smods);
/* normalize the mods */
- normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
- ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
- if (normalized_mods == NULL) {
- op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
- "mod includes invalid dn format");
- send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
- "mod includes invalid dn format", 0, NULL);
- goto free_and_return;
+ if (mods) {
+ normalized_mods = normalize_mods2bvals((const LDAPMod**)mods);
+ ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
+ if (normalized_mods == NULL) {
+ /* NOTE: normalize_mods2bvals only handles DN syntax currently */
+ op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
+ "mod includes invalid dn format");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "mod includes invalid dn format", 0, NULL);
+ goto free_and_return;
+ }
}
slapi_pblock_set(pb, SLAPI_MODIFY_MODS, normalized_mods);
@@ -1439,7 +1442,7 @@ hash_rootpw (LDAPMod **mods)
return 0;
}
- for (i=0; mods[i] != NULL; i++) {
+ for (i=0; (mods != NULL) && (mods[i] != NULL); i++) {
LDAPMod *mod = mods[i];
if (strcasecmp (mod->mod_type, CONFIG_ROOTPW_ATTRIBUTE) != 0)
continue;
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index 0c781b1..98d5e17 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -1672,7 +1672,7 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr
* True for DS 4.x as well, although it tried to keep going even after
* an error was detected (which was very wrong).
*/
- for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods[i]; i++) {
+ for (i = 0; rc == SLAPI_DSE_CALLBACK_OK && mods && mods[i]; i++) {
schema_dse_attr_name = (char *) mods[i]->mod_type;
num_mods++; /* incr the number of mods */
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 5fc0b08..2fe1de7 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -774,7 +774,7 @@ static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e,
/* ignore eAfter, just scan the mods for anything unacceptable */
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- for (i = 0; mods[i] != NULL; i++) {
+ for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
/* for some reason, "modifiersName" and "modifyTimestamp" are
* stuck in by the server */
if ((strcasecmp(mods[i]->mod_type, "ttl") != 0) &&
diff --git a/ldap/servers/slapd/test-plugins/testpostop.c b/ldap/servers/slapd/test-plugins/testpostop.c
index f18f4ab..d91ddd4 100644
--- a/ldap/servers/slapd/test-plugins/testpostop.c
+++ b/ldap/servers/slapd/test-plugins/testpostop.c
@@ -355,7 +355,7 @@ write_changelog(
that has been added, replaced, or deleted. */
fprintf( fp, "changetype: modify\n" );
mods = (LDAPMod **)change;
- for ( j = 0; mods[j] != NULL; j++ ) {
+ for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ ) {
switch ( mods[j]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
fprintf( fp, "add: %s\n", mods[j]->mod_type );
commit 97f58ff4787ecb87780fde7245e354ec75e73125
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:24:26 2014 -0600
Ticket #47774 mem leak in do_search - rawbase not freed upon certain errors
https://fedorahosted.org/389/ticket/47774
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.1
Fix Description: Free the local rawbase variable if it was not set in the
pblock.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 1d5c6d6ca300a45305dba631a334ae9a1857d4cb)
(cherry picked from commit b065515935daa8fffe7a8eef3a66621cc8702018)
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index 59c4afb..0928fa1 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -69,6 +69,7 @@ do_search( Slapi_PBlock *pb )
int i, err, attrsonly;
ber_int_t scope, deref, sizelimit, timelimit;
char *rawbase = NULL;
+ int rawbase_set_in_pb = 0; /* was rawbase set in pb? */
char *base = NULL, *fstr = NULL;
struct slapi_filter *filter = NULL;
char **attrs = NULL;
@@ -350,6 +351,7 @@ do_search( Slapi_PBlock *pb )
}
slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET_DN, rawbase );
+ rawbase_set_in_pb = 1; /* rawbase is now owned by pb */
slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, &scope );
slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, &deref );
slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, filter );
@@ -386,7 +388,9 @@ free_and_return:;
operation->o_flags &= ~OP_FLAG_PS;
}
/* we strdup'd this above - need to free */
- slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ if (rawbase_set_in_pb) {
+ slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &rawbase);
+ }
slapi_ch_free_string(&rawbase);
}
}
commit 39eab765d9c6552c246bed13903807eca4c96887
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Apr 9 13:19:08 2014 -0600
Ticket #47773 - mem leak in do_bind when there is an error
https://fedorahosted.org/389/ticket/47773
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.1
Fix Description: Do not get the SLAPI_BIND_TARGET_SDN from the pblock and
free it in the clean up code if it was never set in the pblock - just free
the local variable sdn in this case.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 2a57b521b86b24c0f0a8ddfbea4169c71ee4e896)
(cherry picked from commit c0606d45b91e87e4d0d90dec0812d20a0b23f545)
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index 2a9d8b7..58a4e13 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -131,6 +131,7 @@ do_bind( Slapi_PBlock *pb )
ber_tag_t ber_rc;
int rc = 0;
Slapi_DN *sdn = NULL;
+ int bind_sdn_in_pb = 0; /* is sdn set in the pb? */
Slapi_Entry *referral;
char errorbuf[BUFSIZ];
char **supported, **pmech;
@@ -369,6 +370,7 @@ do_bind( Slapi_PBlock *pb )
isroot = slapi_dn_isroot( slapi_sdn_get_ndn(sdn) );
slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_set( pb, SLAPI_BIND_TARGET_SDN, (void*)sdn );
+ bind_sdn_in_pb = 1; /* pb now owns sdn */
slapi_pblock_set( pb, SLAPI_BIND_METHOD, &method );
slapi_pblock_set( pb, SLAPI_BIND_SASLMECHANISM, saslmech );
slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, &cred );
@@ -861,7 +863,9 @@ account_locked:
free_and_return:;
if (be)
slapi_be_Unlock(be);
- slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ if (bind_sdn_in_pb) {
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ }
slapi_sdn_free(&sdn);
slapi_ch_free_string( &saslmech );
slapi_ch_free( (void **)&cred.bv_val );
9 years, 11 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/back-ldbm/back-ldbm.h | 1
ldap/servers/slapd/back-ldbm/cache.c | 6 +++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 38 +++++++++++++++++++++++------
3 files changed, 36 insertions(+), 9 deletions(-)
New commits:
commit c5f22dd6c278f670fc36af8029d5c28a89051cfa
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Apr 8 14:39:47 2014 -0400
Ticket 47771 - Performing deletes during tombstone purging results in operation errors
Bug Description: An operations error can occur when deleting entry while
tombstone purging is happening. The error occurs when it
tries the lock the parent entry, but the parent entry was
replaced in the cache before it could be locked.
Fix Description: Return a special error code when cache_lock_entry fails because
the entry was marked as deleted. Then try to grab the entry
again and lock it.
https://fedorahosted.org/389/ticket/47771
Reviewed by: rmeggins & nhosoi(Thanks!!)
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index 7e5a261..8ad3c20 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -215,6 +215,7 @@ typedef unsigned short u_int16_t;
#define DEFAULT_IMPORT_INDEX_BUFFER_SIZE 0
#define SUBLEN 3
#define LDBM_CACHE_RETRY_COUNT 1000 /* Number of times we re-try a cache operation */
+#define RETRY_CACHE_LOCK 2 /* error code to signal a retry of the cache lock */
#define IDL_FETCH_RETRY_COUNT 5 /* Number of times we re-try idl_fetch if it returns deadlock */
#define IMPORT_SUBCOUNT_HASHTABLE_SIZE 500 /* Number of buckets in hash used to accumulate subcount for broody parents */
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index d97644f..865f1ef 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1471,7 +1471,9 @@ void cache_unlock(struct cache *cache)
/* locks an entry so that it can be modified (you should have gotten the
* entry via cache_find_*).
- * returns 0 on success, 1 if the entry is scheduled for deletion.
+ * returns 0 on success,
+ * returns 1 if the entry lock could not be created
+ * returns 2 (RETRY_CACHE_LOCK) if the entry is scheduled for deletion.
*/
int cache_lock_entry(struct cache *cache, struct backentry *e)
{
@@ -1503,7 +1505,7 @@ int cache_lock_entry(struct cache *cache, struct backentry *e)
PR_Unlock(cache->c_mutex);
PR_ExitMonitor(e->ep_mutexp);
LOG("<= cache_lock_entry (DELETED)\n", 0, 0, 0);
- return 1;
+ return RETRY_CACHE_LOCK;
}
PR_Unlock(cache->c_mutex);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index a4b8d8e..7c036df 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -335,14 +335,37 @@ ldbm_back_delete( Slapi_PBlock *pb )
* (find_entry2modify_only_ext), a wrong parent could be found,
* and numsubordinate count could get confused.
*/
- ID pid = (ID)strtol(pid_str, (char **)NULL, 10);
+ ID pid;
+ int cache_retry_count = 0;
+ int cache_retry = 0;
+
+ pid = (ID)strtol(pid_str, (char **)NULL, 10);
slapi_ch_free_string(&pid_str);
- parent = id2entry(be, pid ,NULL, &retval);
- if (parent && cache_lock_entry(&inst->inst_cache, parent)) {
- /* Failed to obtain parent entry's entry lock */
- CACHE_RETURN(&(inst->inst_cache), &parent);
- retval = -1;
- goto error_return;
+
+ /*
+ * Its possible that the parent entry retrieved from the cache in id2entry
+ * could be removed before we lock it, because tombstone purging updated/replaced
+ * the parent. If we fail to lock the entry, just try again.
+ */
+ while(1){
+ parent = id2entry(be, pid ,NULL, &retval);
+ if (parent && (cache_retry = cache_lock_entry(&inst->inst_cache, parent))) {
+ /* Failed to obtain parent entry's entry lock */
+ if(cache_retry == RETRY_CACHE_LOCK &&
+ cache_retry_count < LDBM_CACHE_RETRY_COUNT)
+ {
+ /* try again */
+ DS_Sleep(PR_MillisecondsToInterval(100));
+ cache_retry_count++;
+ continue;
+ }
+ retval = -1;
+ CACHE_RETURN(&(inst->inst_cache), &parent);
+ goto error_return;
+ } else {
+ /* entry locked, move on */
+ break;
+ }
}
}
if (NULL == parent) {
@@ -1224,6 +1247,7 @@ diskfull_return:
slapi_ch_free((void**)&errbuf);
slapi_sdn_done(&nscpEntrySDN);
slapi_ch_free_string(&e_uniqueid);
+ slapi_sdn_done(&parentsdn);
if (pb->pb_conn)
{
slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" NSPRIu64 " op=%d\n", pb->pb_conn->c_connid, operation->o_opid);
9 years, 11 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/back-ldbm/back-ldbm.h | 1
ldap/servers/slapd/back-ldbm/cache.c | 6 ++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 46 ++++++++++++++++++++---------
3 files changed, 37 insertions(+), 16 deletions(-)
New commits:
commit 44ecbbec4490b012e4ea5d02dfe9d77ec5526acf
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Apr 8 14:39:47 2014 -0400
Ticket 47771 - Performing deletes during tombstone purging results in operation errors
Bug Description: An operations error can occur when deleting entry while
tombstone purging is happening. The error occurs when it
tries the lock the parent entry, but the parent entry was
replaced in the cache before it could be locked.
Fix Description: Return a special error code when cache_lock_entry fails because
the entry was marked as deleted. Then try to grab the entry
again and lock it.
https://fedorahosted.org/389/ticket/47771
Reviewed by: rmeggins & nhosoi(Thanks!!)
(cherry picked from commit 844d09d0700fca7aa64a2453d99e7c274a76e784)
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index 5f8a05a..d633243 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -216,6 +216,7 @@ typedef unsigned short u_int16_t;
#define DEFAULT_IMPORT_INDEX_BUFFER_SIZE 0
#define SUBLEN 3
#define LDBM_CACHE_RETRY_COUNT 1000 /* Number of times we re-try a cache operation */
+#define RETRY_CACHE_LOCK 2 /* error code to signal a retry of the cache lock */
#define IDL_FETCH_RETRY_COUNT 5 /* Number of times we re-try idl_fetch if it returns deadlock */
#define IMPORT_SUBCOUNT_HASHTABLE_SIZE 500 /* Number of buckets in hash used to accumulate subcount for broody parents */
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index a73ae6a..7f3f025 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1483,7 +1483,9 @@ void cache_unlock(struct cache *cache)
/* locks an entry so that it can be modified (you should have gotten the
* entry via cache_find_*).
- * returns 0 on success, 1 if the entry is scheduled for deletion.
+ * returns 0 on success,
+ * returns 1 if the entry lock could not be created
+ * returns 2 (RETRY_CACHE_LOCK) if the entry is scheduled for deletion.
*/
int cache_lock_entry(struct cache *cache, struct backentry *e)
{
@@ -1515,7 +1517,7 @@ int cache_lock_entry(struct cache *cache, struct backentry *e)
PR_Unlock(cache->c_mutex);
PR_ExitMonitor(e->ep_mutexp);
LOG("<= cache_lock_entry (DELETED)\n", 0, 0, 0);
- return 1;
+ return RETRY_CACHE_LOCK;
}
PR_Unlock(cache->c_mutex);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 51dc83f..31249c7 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -98,7 +98,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
int opreturn = 0;
int free_delete_existing_entry = 0;
int not_an_error = 0;
- int updated_num = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -459,14 +458,37 @@ ldbm_back_delete( Slapi_PBlock *pb )
* (find_entry2modify_only_ext), a wrong parent could be found,
* and numsubordinate count could get confused.
*/
- ID pid = (ID)strtol(pid_str, (char **)NULL, 10);
+ ID pid;
+ int cache_retry_count = 0;
+ int cache_retry = 0;
+
+ pid = (ID)strtol(pid_str, (char **)NULL, 10);
slapi_ch_free_string(&pid_str);
- parent = id2entry(be, pid ,NULL, &retval);
- if (parent && cache_lock_entry(&inst->inst_cache, parent)) {
- /* Failed to obtain parent entry's entry lock */
- CACHE_RETURN(&(inst->inst_cache), &parent);
- retval = -1;
- goto error_return;
+
+ /*
+ * Its possible that the parent entry retrieved from the cache in id2entry
+ * could be removed before we lock it, because tombstone purging updated/replaced
+ * the parent. If we fail to lock the entry, just try again.
+ */
+ while(1){
+ parent = id2entry(be, pid ,NULL, &retval);
+ if (parent && (cache_retry = cache_lock_entry(&inst->inst_cache, parent))) {
+ /* Failed to obtain parent entry's entry lock */
+ if(cache_retry == RETRY_CACHE_LOCK &&
+ cache_retry_count < LDBM_CACHE_RETRY_COUNT)
+ {
+ /* try again */
+ DS_Sleep(PR_MillisecondsToInterval(100));
+ cache_retry_count++;
+ continue;
+ }
+ retval = -1;
+ CACHE_RETURN(&(inst->inst_cache), &parent);
+ goto error_return;
+ } else {
+ /* entry locked, move on */
+ break;
+ }
}
}
if (NULL == parent) {
@@ -502,8 +524,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
- /* MARK */
- updated_num = 1;
+
/*
* Replication urp_post_delete will delete the parent entry
* if it is a glue entry without any more children.
@@ -519,7 +540,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
}
}
}
- slapi_sdn_done(&parentsdn);
if(create_tombstone_entry)
{
@@ -1291,14 +1311,12 @@ diskfull_return:
slapi_ch_free((void**)&errbuf);
slapi_sdn_done(&nscpEntrySDN);
slapi_ch_free_string(&e_uniqueid);
+ slapi_sdn_done(&parentsdn);
if (pb->pb_conn)
{
slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" NSPRIu64 " op=%d\n",
(long long unsigned int)pb->pb_conn->c_connid, operation->o_opid);
}
- if(!updated_num && ldap_result_code != 32){
- slapi_log_error (SLAPI_LOG_FATAL,"MARK", "Failed to update numsubordinates\n");
- }
return rc;
}
9 years, 11 months
Branch '389-ds-base-1.3.2' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/back-ldbm/back-ldbm.h | 1
ldap/servers/slapd/back-ldbm/cache.c | 6 ++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 46 ++++++++++++++++++++---------
3 files changed, 37 insertions(+), 16 deletions(-)
New commits:
commit 48844b23f26f298cf248c5b760dc3f3d09ca6833
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Apr 8 14:39:47 2014 -0400
Ticket 47771 - Performing deletes during tombstone purging results in operation errors
Bug Description: An operations error can occur when deleting entry while
tombstone purging is happening. The error occurs when it
tries the lock the parent entry, but the parent entry was
replaced in the cache before it could be locked.
Fix Description: Return a special error code when cache_lock_entry fails because
the entry was marked as deleted. Then try to grab the entry
again and lock it.
https://fedorahosted.org/389/ticket/47771
Reviewed by: rmeggins & nhosoi(Thanks!!)
(cherry picked from commit 844d09d0700fca7aa64a2453d99e7c274a76e784)
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index 26e081c..0834a1c 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -216,6 +216,7 @@ typedef unsigned short u_int16_t;
#define DEFAULT_IMPORT_INDEX_BUFFER_SIZE 0
#define SUBLEN 3
#define LDBM_CACHE_RETRY_COUNT 1000 /* Number of times we re-try a cache operation */
+#define RETRY_CACHE_LOCK 2 /* error code to signal a retry of the cache lock */
#define IDL_FETCH_RETRY_COUNT 5 /* Number of times we re-try idl_fetch if it returns deadlock */
#define IMPORT_SUBCOUNT_HASHTABLE_SIZE 500 /* Number of buckets in hash used to accumulate subcount for broody parents */
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index a73ae6a..7f3f025 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1483,7 +1483,9 @@ void cache_unlock(struct cache *cache)
/* locks an entry so that it can be modified (you should have gotten the
* entry via cache_find_*).
- * returns 0 on success, 1 if the entry is scheduled for deletion.
+ * returns 0 on success,
+ * returns 1 if the entry lock could not be created
+ * returns 2 (RETRY_CACHE_LOCK) if the entry is scheduled for deletion.
*/
int cache_lock_entry(struct cache *cache, struct backentry *e)
{
@@ -1515,7 +1517,7 @@ int cache_lock_entry(struct cache *cache, struct backentry *e)
PR_Unlock(cache->c_mutex);
PR_ExitMonitor(e->ep_mutexp);
LOG("<= cache_lock_entry (DELETED)\n", 0, 0, 0);
- return 1;
+ return RETRY_CACHE_LOCK;
}
PR_Unlock(cache->c_mutex);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 2b349f6..a858fa0 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -98,7 +98,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
int opreturn = 0;
int free_delete_existing_entry = 0;
int not_an_error = 0;
- int updated_num = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -459,14 +458,37 @@ ldbm_back_delete( Slapi_PBlock *pb )
* (find_entry2modify_only_ext), a wrong parent could be found,
* and numsubordinate count could get confused.
*/
- ID pid = (ID)strtol(pid_str, (char **)NULL, 10);
+ ID pid;
+ int cache_retry_count = 0;
+ int cache_retry = 0;
+
+ pid = (ID)strtol(pid_str, (char **)NULL, 10);
slapi_ch_free_string(&pid_str);
- parent = id2entry(be, pid ,NULL, &retval);
- if (parent && cache_lock_entry(&inst->inst_cache, parent)) {
- /* Failed to obtain parent entry's entry lock */
- CACHE_RETURN(&(inst->inst_cache), &parent);
- retval = -1;
- goto error_return;
+
+ /*
+ * Its possible that the parent entry retrieved from the cache in id2entry
+ * could be removed before we lock it, because tombstone purging updated/replaced
+ * the parent. If we fail to lock the entry, just try again.
+ */
+ while(1){
+ parent = id2entry(be, pid ,NULL, &retval);
+ if (parent && (cache_retry = cache_lock_entry(&inst->inst_cache, parent))) {
+ /* Failed to obtain parent entry's entry lock */
+ if(cache_retry == RETRY_CACHE_LOCK &&
+ cache_retry_count < LDBM_CACHE_RETRY_COUNT)
+ {
+ /* try again */
+ DS_Sleep(PR_MillisecondsToInterval(100));
+ cache_retry_count++;
+ continue;
+ }
+ retval = -1;
+ CACHE_RETURN(&(inst->inst_cache), &parent);
+ goto error_return;
+ } else {
+ /* entry locked, move on */
+ break;
+ }
}
}
if (NULL == parent) {
@@ -502,8 +524,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
- /* MARK */
- updated_num = 1;
+
/*
* Replication urp_post_delete will delete the parent entry
* if it is a glue entry without any more children.
@@ -519,7 +540,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
}
}
}
- slapi_sdn_done(&parentsdn);
if(create_tombstone_entry)
{
@@ -1291,14 +1311,12 @@ diskfull_return:
slapi_ch_free((void**)&errbuf);
slapi_sdn_done(&nscpEntrySDN);
slapi_ch_free_string(&e_uniqueid);
+ slapi_sdn_done(&parentsdn);
if (pb->pb_conn)
{
slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" NSPRIu64 " op=%d\n",
(long long unsigned int)pb->pb_conn->c_connid, operation->o_opid);
}
- if(!updated_num && ldap_result_code != 32){
- slapi_log_error (SLAPI_LOG_FATAL,"MARK", "Failed to update numsubordinates\n");
- }
return rc;
}
9 years, 11 months
ldap/servers
by Mark Reynolds
ldap/servers/slapd/back-ldbm/back-ldbm.h | 1
ldap/servers/slapd/back-ldbm/cache.c | 6 ++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 46 ++++++++++++++++++++---------
3 files changed, 37 insertions(+), 16 deletions(-)
New commits:
commit 844d09d0700fca7aa64a2453d99e7c274a76e784
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Apr 8 14:39:47 2014 -0400
Ticket 47771 - Performing deletes during tombstone purging results in operation errors
Bug Description: An operations error can occur when deleting entry while
tombstone purging is happening. The error occurs when it
tries the lock the parent entry, but the parent entry was
replaced in the cache before it could be locked.
Fix Description: Return a special error code when cache_lock_entry fails because
the entry was marked as deleted. Then try to grab the entry
again and lock it.
https://fedorahosted.org/389/ticket/47771
Reviewed by: rmeggins & nhosoi(Thanks!!)
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index 26e081c..0834a1c 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -216,6 +216,7 @@ typedef unsigned short u_int16_t;
#define DEFAULT_IMPORT_INDEX_BUFFER_SIZE 0
#define SUBLEN 3
#define LDBM_CACHE_RETRY_COUNT 1000 /* Number of times we re-try a cache operation */
+#define RETRY_CACHE_LOCK 2 /* error code to signal a retry of the cache lock */
#define IDL_FETCH_RETRY_COUNT 5 /* Number of times we re-try idl_fetch if it returns deadlock */
#define IMPORT_SUBCOUNT_HASHTABLE_SIZE 500 /* Number of buckets in hash used to accumulate subcount for broody parents */
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index a73ae6a..7f3f025 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1483,7 +1483,9 @@ void cache_unlock(struct cache *cache)
/* locks an entry so that it can be modified (you should have gotten the
* entry via cache_find_*).
- * returns 0 on success, 1 if the entry is scheduled for deletion.
+ * returns 0 on success,
+ * returns 1 if the entry lock could not be created
+ * returns 2 (RETRY_CACHE_LOCK) if the entry is scheduled for deletion.
*/
int cache_lock_entry(struct cache *cache, struct backentry *e)
{
@@ -1515,7 +1517,7 @@ int cache_lock_entry(struct cache *cache, struct backentry *e)
PR_Unlock(cache->c_mutex);
PR_ExitMonitor(e->ep_mutexp);
LOG("<= cache_lock_entry (DELETED)\n", 0, 0, 0);
- return 1;
+ return RETRY_CACHE_LOCK;
}
PR_Unlock(cache->c_mutex);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 2b349f6..a858fa0 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -98,7 +98,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
int opreturn = 0;
int free_delete_existing_entry = 0;
int not_an_error = 0;
- int updated_num = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -459,14 +458,37 @@ ldbm_back_delete( Slapi_PBlock *pb )
* (find_entry2modify_only_ext), a wrong parent could be found,
* and numsubordinate count could get confused.
*/
- ID pid = (ID)strtol(pid_str, (char **)NULL, 10);
+ ID pid;
+ int cache_retry_count = 0;
+ int cache_retry = 0;
+
+ pid = (ID)strtol(pid_str, (char **)NULL, 10);
slapi_ch_free_string(&pid_str);
- parent = id2entry(be, pid ,NULL, &retval);
- if (parent && cache_lock_entry(&inst->inst_cache, parent)) {
- /* Failed to obtain parent entry's entry lock */
- CACHE_RETURN(&(inst->inst_cache), &parent);
- retval = -1;
- goto error_return;
+
+ /*
+ * Its possible that the parent entry retrieved from the cache in id2entry
+ * could be removed before we lock it, because tombstone purging updated/replaced
+ * the parent. If we fail to lock the entry, just try again.
+ */
+ while(1){
+ parent = id2entry(be, pid ,NULL, &retval);
+ if (parent && (cache_retry = cache_lock_entry(&inst->inst_cache, parent))) {
+ /* Failed to obtain parent entry's entry lock */
+ if(cache_retry == RETRY_CACHE_LOCK &&
+ cache_retry_count < LDBM_CACHE_RETRY_COUNT)
+ {
+ /* try again */
+ DS_Sleep(PR_MillisecondsToInterval(100));
+ cache_retry_count++;
+ continue;
+ }
+ retval = -1;
+ CACHE_RETURN(&(inst->inst_cache), &parent);
+ goto error_return;
+ } else {
+ /* entry locked, move on */
+ break;
+ }
}
}
if (NULL == parent) {
@@ -502,8 +524,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
- /* MARK */
- updated_num = 1;
+
/*
* Replication urp_post_delete will delete the parent entry
* if it is a glue entry without any more children.
@@ -519,7 +540,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
}
}
}
- slapi_sdn_done(&parentsdn);
if(create_tombstone_entry)
{
@@ -1291,14 +1311,12 @@ diskfull_return:
slapi_ch_free((void**)&errbuf);
slapi_sdn_done(&nscpEntrySDN);
slapi_ch_free_string(&e_uniqueid);
+ slapi_sdn_done(&parentsdn);
if (pb->pb_conn)
{
slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" NSPRIu64 " op=%d\n",
(long long unsigned int)pb->pb_conn->c_connid, operation->o_opid);
}
- if(!updated_num && ldap_result_code != 32){
- slapi_log_error (SLAPI_LOG_FATAL,"MARK", "Failed to update numsubordinates\n");
- }
return rc;
}
9 years, 11 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5_replica.c | 8 ++-
ldap/servers/slapd/back-ldbm/idl_common.c | 6 ++
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 1
ldap/servers/slapd/back-ldbm/ldbm_search.c | 47 ++++++++++++++++++++++-
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 1
ldap/servers/slapd/operation.c | 1
ldap/servers/slapd/slap.h | 1
ldap/servers/slapd/slapi-plugin.h | 8 +--
ldap/servers/slapd/slapi-private.h | 44 +++++++++++----------
9 files changed, 89 insertions(+), 28 deletions(-)
New commits:
commit 48e2a96cc3369db2b8d739889be273700ca9c23b
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Apr 8 14:12:32 2014 -0400
Ticket 47767 - Nested tombstones become orphaned after purge
Bug Description: If there are nested tombstone entries, the parents will
always be purged first, which leaves its child entries orphaned.
Fix Description: When doing the tombstone purge, process the candidate list in
reverse order, which will remove the child entries before the
parent entries.
https://fedorahosted.org/389/ticket/47767
Reviewed by: nhosoi(Thanks!)
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 82c30c1..1cec805 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -2793,7 +2793,10 @@ process_reap_entry (Slapi_Entry *entry, void *cb_data)
"%s\n", slapi_entry_get_dn(entry));
}
}
- (*num_entriesp)++;
+ if(!is_ruv_tombstone_entry(entry)){
+ /* Don't update the count for the database tombstone entry */
+ (*num_entriesp)++;
+ }
return 0;
}
@@ -2878,7 +2881,8 @@ _replica_reap_tombstones(void *arg)
slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(replica->repl_root),
LDAP_SCOPE_SUBTREE, "(&(objectclass=nstombstone)(nscpentrydn=*))",
attrs, 0, ctrls, NULL,
- repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
+ repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
+ OP_FLAG_REVERSE_CANDIDATE_ORDER);
cb_data.rc = 0;
cb_data.num_entries = 0UL;
diff --git a/ldap/servers/slapd/back-ldbm/idl_common.c b/ldap/servers/slapd/back-ldbm/idl_common.c
index 584bba5..ee59ee2 100644
--- a/ldap/servers/slapd/back-ldbm/idl_common.c
+++ b/ldap/servers/slapd/back-ldbm/idl_common.c
@@ -494,3 +494,9 @@ ID idl_iterator_dereference_increment(idl_iterator *i, const IDList *idl)
return t;
}
+ID idl_iterator_dereference_decrement(idl_iterator *i, const IDList *idl)
+{
+ idl_iterator_decrement(i);
+ return idl_iterator_dereference(*i,idl);
+
+}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index d1ad3ef..a4b8d8e 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -1228,5 +1228,6 @@ diskfull_return:
{
slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" NSPRIu64 " op=%d\n", pb->pb_conn->c_connid, operation->o_opid);
}
+
return rc;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 552b65b..a097307 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -1343,6 +1343,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
int pr_idx = -1;
Slapi_Connection *conn;
Slapi_Operation *op;
+ int reverse_list = 0;
slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &basesdn );
if (NULL == basesdn) {
@@ -1370,6 +1371,18 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
slapi_pblock_get( pb, SLAPI_OPERATION, &op );
+ if((reverse_list = operation_is_flag_set(op, OP_FLAG_REVERSE_CANDIDATE_ORDER))){
+ /*
+ * Start at the end of the list and work our way forward. Since a single
+ * search can enter this function multiple times, we need to keep track
+ * of our state, and only initialize sr_current once.
+ */
+ if(!op->o_reverse_search_state){
+ sr->sr_current = sr->sr_candidates->b_nids;
+ op->o_reverse_search_state = REV_STARTED;
+ }
+ }
+
if ( !txn.back_txn_txn ) {
dblayer_txn_init( li, &txn );
slapi_pblock_set( pb, SLAPI_TXN, txn.back_txn_txn );
@@ -1469,8 +1482,32 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
goto bail;
}
- /* get the entry */
- id = idl_iterator_dereference_increment(&(sr->sr_current), sr->sr_candidates);
+ /*
+ * Get the entry ID
+ */
+ if(reverse_list){
+ /*
+ * This is probably a tombstone reaping, we need to process in the candidate
+ * list in reserve order, or else we can orphan tombstone entries by removing
+ * it's parent tombstone entry first.
+ */
+ id = idl_iterator_dereference_decrement(&(sr->sr_current), sr->sr_candidates);
+ if((sr->sr_current == 0) && op->o_reverse_search_state != LAST_REV_ENTRY){
+ /*
+ * We hit the last entry and we need to process it, but the decrement
+ * function will keep returning the last entry. So we need to mark that
+ * we have hit the last entry so we know to stop on the next pass.
+ */
+ op->o_reverse_search_state = LAST_REV_ENTRY;
+ } else if(op->o_reverse_search_state == LAST_REV_ENTRY){
+ /* we're done */
+ id = NOID;
+ }
+ } else {
+ /* Process the candidate list in the normal order. */
+ id = idl_iterator_dereference_increment(&(sr->sr_current), sr->sr_candidates);
+ }
+
if ( id == NOID )
{
/* No more entries */
@@ -1481,6 +1518,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
}
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY, NULL );
delete_search_result_set(pb, &sr);
+ op->o_reverse_search_state = 0;
rc = 0;
goto bail;
}
@@ -1686,7 +1724,12 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
}
}
}
+
bail:
+ if(rc){
+ op->o_reverse_search_state = 0;
+ }
+
return rc;
}
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index d7b88ed..ee30c45 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -266,6 +266,7 @@ idl_iterator idl_iterator_increment(idl_iterator *i);
idl_iterator idl_iterator_decrement(idl_iterator *i);
ID idl_iterator_dereference(idl_iterator i, const IDList *idl);
ID idl_iterator_dereference_increment(idl_iterator *i, const IDList *idl);
+ID idl_iterator_dereference_decrement(idl_iterator *i, const IDList *idl);
size_t idl_sizeof(IDList *idl);
int idl_store_block(backend *be,DB *db,DBT *key,IDList *idl,DB_TXN *txn,struct attrinfo *a);
void idl_set_tune(int val);
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
index 01ebfef..3a58381 100644
--- a/ldap/servers/slapd/operation.c
+++ b/ldap/servers/slapd/operation.c
@@ -200,6 +200,7 @@ operation_new(int flags)
o->o_connid = 0;
o->o_next = NULL;
o->o_flags= flags;
+ o->o_reverse_search_state = 0;
if ( config_get_accesslog_level() & LDAP_DEBUG_TIMING ) {
o->o_interval = PR_IntervalNow();
} else {
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 2c8b2a6..42b6a1e 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1348,6 +1348,7 @@ typedef struct op {
struct slapi_operation_parameters o_params;
struct slapi_operation_results o_results;
int o_pagedresults_sizelimit;
+ int o_reverse_search_state;
} Operation;
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index f0dd555..39c50a9 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -196,10 +196,10 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...)
Used for DN. */
/* operation flags */
-#define SLAPI_OP_FLAG_INTERNAL 0x00020 /* An operation generated by the core server or a plugin. */
-#define SLAPI_OP_FLAG_NEVER_CHAIN 0x00800 /* Do not chain the operation */
-#define SLAPI_OP_FLAG_NO_ACCESS_CHECK 0x10000 /* Do not check for access control - bypass them */
-#define SLAPI_OP_FLAG_BYPASS_REFERRALS 0x40000 /* Useful for performing internal operations on read-only replica */
+#define SLAPI_OP_FLAG_INTERNAL 0x000020 /* An operation generated by the core server or a plugin. */
+#define SLAPI_OP_FLAG_NEVER_CHAIN 0x000800 /* Do not chain the operation */
+#define SLAPI_OP_FLAG_NO_ACCESS_CHECK 0x10000 /* Do not check for access control - bypass them */
+#define SLAPI_OP_FLAG_BYPASS_REFERRALS 0x40000 /* Useful for performing internal operations on read-only replica */
#define SLAPI_OC_FLAG_REQUIRED 0x0001
#define SLAPI_OC_FLAG_ALLOWED 0x0002
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 11f10e8..5b940e9 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -396,43 +396,47 @@ slapi_filter_to_string_internal( const struct slapi_filter *f, char *buf, size_t
/* operation.c */
-#define OP_FLAG_PS 0x00001
-#define OP_FLAG_PS_CHANGESONLY 0x00002
-#define OP_FLAG_GET_EFFECTIVE_RIGHTS 0x00004
-#define OP_FLAG_REPLICATED 0x00008 /* A Replicated Operation */
-#define OP_FLAG_REPL_FIXUP 0x00010 /* A Fixup Operation,
+#define OP_FLAG_PS 0x000001
+#define OP_FLAG_PS_CHANGESONLY 0x000002
+#define OP_FLAG_GET_EFFECTIVE_RIGHTS 0x000004
+#define OP_FLAG_REPLICATED 0x000008 /* A Replicated Operation */
+#define OP_FLAG_REPL_FIXUP 0x000010 /* A Fixup Operation,
* generated as a consequence
* of a Replicated Operation.
*/
-#define OP_FLAG_INTERNAL SLAPI_OP_FLAG_INTERNAL /* 0x00020 */
-#define OP_FLAG_ACTION_LOG_ACCESS 0x00040
-#define OP_FLAG_ACTION_LOG_AUDIT 0x00080
-#define OP_FLAG_ACTION_SCHEMA_CHECK 0x00100
-#define OP_FLAG_ACTION_LOG_CHANGES 0x00200
-#define OP_FLAG_ACTION_INVOKE_FOR_REPLOP 0x00400
-#define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x0800 */
-#define OP_FLAG_TOMBSTONE_ENTRY 0x01000
-#define OP_FLAG_RESURECT_ENTRY 0x02000
-#define OP_FLAG_LEGACY_REPLICATION_DN 0x04000 /* Operation done by legacy
+#define OP_FLAG_INTERNAL SLAPI_OP_FLAG_INTERNAL /* 0x000020 */
+#define OP_FLAG_ACTION_LOG_ACCESS 0x000040
+#define OP_FLAG_ACTION_LOG_AUDIT 0x000080
+#define OP_FLAG_ACTION_SCHEMA_CHECK 0x000100
+#define OP_FLAG_ACTION_LOG_CHANGES 0x000200
+#define OP_FLAG_ACTION_INVOKE_FOR_REPLOP 0x000400
+#define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x000800 */
+#define OP_FLAG_TOMBSTONE_ENTRY 0x001000
+#define OP_FLAG_RESURECT_ENTRY 0x002000
+#define OP_FLAG_LEGACY_REPLICATION_DN 0x004000 /* Operation done by legacy
* replication DN
*/
-#define OP_FLAG_ACTION_NOLOG 0x08000 /* Do not log the entry in
+#define OP_FLAG_ACTION_NOLOG 0x008000 /* Do not log the entry in
* audit log or change log
*/
-#define OP_FLAG_SKIP_MODIFIED_ATTRS 0x10000 /* Do not update the
+#define OP_FLAG_SKIP_MODIFIED_ATTRS 0x010000 /* Do not update the
* modifiersname,
* modifiedtimestamp, etc.
* attributes
*/
-#define OP_FLAG_REPL_RUV 0x20000 /* Flag to tell to the backend
+#define OP_FLAG_REPL_RUV 0x020000 /* Flag to tell to the backend
* that the entry to be added/
* modified is RUV. This info
* is used to skip VLV op.
* (see #329951)
*/
-#define OP_FLAG_PAGED_RESULTS 0x40000 /* simple paged results */
-#define OP_FLAG_SERVER_SIDE_SORTING 0x80000 /* server side sorting */
+#define OP_FLAG_PAGED_RESULTS 0x040000 /* simple paged results */
+#define OP_FLAG_SERVER_SIDE_SORTING 0x080000 /* server side sorting */
+#define OP_FLAG_REVERSE_CANDIDATE_ORDER 0x100000 /* reverse the search candidate list */
+/* reverse search states */
+#define REV_STARTED 1
+#define LAST_REV_ENTRY 2
CSN *operation_get_csn(Slapi_Operation *op);
void operation_set_csn(Slapi_Operation *op,CSN *csn);
9 years, 11 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5_replica.c | 8 ++-
ldap/servers/slapd/back-ldbm/idl_common.c | 6 ++
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 8 +++
ldap/servers/slapd/back-ldbm/ldbm_search.c | 47 ++++++++++++++++++++++-
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 1
ldap/servers/slapd/operation.c | 1
ldap/servers/slapd/slap.h | 1
ldap/servers/slapd/slapi-plugin.h | 8 +--
ldap/servers/slapd/slapi-private.h | 44 +++++++++++----------
9 files changed, 95 insertions(+), 29 deletions(-)
New commits:
commit 203970e7ee8350a5d805895daf2f8884934c25b9
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Apr 8 14:12:32 2014 -0400
Ticket 47767 - Nested tombstones become orphaned after purge
Bug Description: If there are nested tombstone entries, the parents will
always be purged first, which leaves its child entries orphaned.
Fix Description: When doing the tombstone purge, process the candidate list in
reverse order, which will remove the child entries before the
parent entries.
https://fedorahosted.org/389/ticket/47767
Reviewed by: nhosoi(Thanks!)
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 8d64641..8cd2eaf 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -2849,7 +2849,10 @@ process_reap_entry (Slapi_Entry *entry, void *cb_data)
"%s\n", slapi_entry_get_dn(entry));
}
}
- (*num_entriesp)++;
+ if(!is_ruv_tombstone_entry(entry)){
+ /* Don't update the count for the database tombstone entry */
+ (*num_entriesp)++;
+ }
return 0;
}
@@ -2934,7 +2937,8 @@ _replica_reap_tombstones(void *arg)
slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(replica->repl_root),
LDAP_SCOPE_SUBTREE, "(objectclass=nstombstone)",
attrs, 0, ctrls, NULL,
- repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
+ repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
+ OP_FLAG_REVERSE_CANDIDATE_ORDER);
cb_data.rc = 0;
cb_data.num_entries = 0UL;
diff --git a/ldap/servers/slapd/back-ldbm/idl_common.c b/ldap/servers/slapd/back-ldbm/idl_common.c
index 584bba5..ee59ee2 100644
--- a/ldap/servers/slapd/back-ldbm/idl_common.c
+++ b/ldap/servers/slapd/back-ldbm/idl_common.c
@@ -494,3 +494,9 @@ ID idl_iterator_dereference_increment(idl_iterator *i, const IDList *idl)
return t;
}
+ID idl_iterator_dereference_decrement(idl_iterator *i, const IDList *idl)
+{
+ idl_iterator_decrement(i);
+ return idl_iterator_dereference(*i,idl);
+
+}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 367ab99..51dc83f 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -98,6 +98,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
int opreturn = 0;
int free_delete_existing_entry = 0;
int not_an_error = 0;
+ int updated_num = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -501,7 +502,8 @@ ldbm_back_delete( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
-
+ /* MARK */
+ updated_num = 1;
/*
* Replication urp_post_delete will delete the parent entry
* if it is a glue entry without any more children.
@@ -1294,5 +1296,9 @@ diskfull_return:
slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" NSPRIu64 " op=%d\n",
(long long unsigned int)pb->pb_conn->c_connid, operation->o_opid);
}
+
+ if(!updated_num && ldap_result_code != 32){
+ slapi_log_error (SLAPI_LOG_FATAL,"MARK", "Failed to update numsubordinates\n");
+ }
return rc;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 00a1f51..1dcf698 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -1388,6 +1388,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
int pr_idx = -1;
Slapi_Connection *conn;
Slapi_Operation *op;
+ int reverse_list = 0;
slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &basesdn );
if (NULL == basesdn) {
@@ -1415,6 +1416,18 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
slapi_pblock_get( pb, SLAPI_OPERATION, &op );
+ if((reverse_list = operation_is_flag_set(op, OP_FLAG_REVERSE_CANDIDATE_ORDER))){
+ /*
+ * Start at the end of the list and work our way forward. Since a single
+ * search can enter this function multiple times, we need to keep track
+ * of our state, and only initialize sr_current once.
+ */
+ if(!op->o_reverse_search_state){
+ sr->sr_current = sr->sr_candidates->b_nids;
+ op->o_reverse_search_state = REV_STARTED;
+ }
+ }
+
if ( !txn.back_txn_txn ) {
dblayer_txn_init( li, &txn );
slapi_pblock_set( pb, SLAPI_TXN, txn.back_txn_txn );
@@ -1514,8 +1527,32 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
goto bail;
}
- /* get the entry */
- id = idl_iterator_dereference_increment(&(sr->sr_current), sr->sr_candidates);
+ /*
+ * Get the entry ID
+ */
+ if(reverse_list){
+ /*
+ * This is probably a tombstone reaping, we need to process in the candidate
+ * list in reserve order, or else we can orphan tombstone entries by removing
+ * it's parent tombstone entry first.
+ */
+ id = idl_iterator_dereference_decrement(&(sr->sr_current), sr->sr_candidates);
+ if((sr->sr_current == 0) && op->o_reverse_search_state != LAST_REV_ENTRY){
+ /*
+ * We hit the last entry and we need to process it, but the decrement
+ * function will keep returning the last entry. So we need to mark that
+ * we have hit the last entry so we know to stop on the next pass.
+ */
+ op->o_reverse_search_state = LAST_REV_ENTRY;
+ } else if(op->o_reverse_search_state == LAST_REV_ENTRY){
+ /* we're done */
+ id = NOID;
+ }
+ } else {
+ /* Process the candidate list in the normal order. */
+ id = idl_iterator_dereference_increment(&(sr->sr_current), sr->sr_candidates);
+ }
+
if ( id == NOID )
{
/* No more entries */
@@ -1526,6 +1563,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
}
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY, NULL );
delete_search_result_set(pb, &sr);
+ op->o_reverse_search_state = 0;
rc = 0;
goto bail;
}
@@ -1731,7 +1769,12 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
}
}
}
+
bail:
+ if(rc){
+ op->o_reverse_search_state = 0;
+ }
+
return rc;
}
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index d168714..6372f50 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -272,6 +272,7 @@ idl_iterator idl_iterator_increment(idl_iterator *i);
idl_iterator idl_iterator_decrement(idl_iterator *i);
ID idl_iterator_dereference(idl_iterator i, const IDList *idl);
ID idl_iterator_dereference_increment(idl_iterator *i, const IDList *idl);
+ID idl_iterator_dereference_decrement(idl_iterator *i, const IDList *idl);
size_t idl_sizeof(IDList *idl);
int idl_store_block(backend *be,DB *db,DBT *key,IDList *idl,DB_TXN *txn,struct attrinfo *a);
void idl_set_tune(int val);
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
index 9e55b60..0b77db4 100644
--- a/ldap/servers/slapd/operation.c
+++ b/ldap/servers/slapd/operation.c
@@ -200,6 +200,7 @@ operation_new(int flags)
o->o_connid = 0;
o->o_next = NULL;
o->o_flags= flags;
+ o->o_reverse_search_state = 0;
if ( config_get_accesslog_level() & LDAP_DEBUG_TIMING ) {
o->o_interval = PR_IntervalNow();
} else {
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index b88bf99..e9b11f1 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1377,6 +1377,7 @@ typedef struct op {
struct slapi_operation_parameters o_params;
struct slapi_operation_results o_results;
int o_pagedresults_sizelimit;
+ int o_reverse_search_state;
} Operation;
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 8291ab4..c021685 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -199,10 +199,10 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...)
#define SLAPI_ATTR_FLAG_NOEXPOSE 0x0800 /* the attr value is not exposed */
/* operation flags */
-#define SLAPI_OP_FLAG_INTERNAL 0x00020 /* An operation generated by the core server or a plugin. */
-#define SLAPI_OP_FLAG_NEVER_CHAIN 0x00800 /* Do not chain the operation */
-#define SLAPI_OP_FLAG_NO_ACCESS_CHECK 0x10000 /* Do not check for access control - bypass them */
-#define SLAPI_OP_FLAG_BYPASS_REFERRALS 0x40000 /* Useful for performing internal operations on read-only replica */
+#define SLAPI_OP_FLAG_INTERNAL 0x000020 /* An operation generated by the core server or a plugin. */
+#define SLAPI_OP_FLAG_NEVER_CHAIN 0x000800 /* Do not chain the operation */
+#define SLAPI_OP_FLAG_NO_ACCESS_CHECK 0x10000 /* Do not check for access control - bypass them */
+#define SLAPI_OP_FLAG_BYPASS_REFERRALS 0x40000 /* Useful for performing internal operations on read-only replica */
#define SLAPI_OC_FLAG_REQUIRED 0x0001
#define SLAPI_OC_FLAG_ALLOWED 0x0002
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 306d3af..51329ba 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -404,43 +404,47 @@ char *slapi_filter_to_string_internal( const struct slapi_filter *f, char *buf,
/* operation.c */
-#define OP_FLAG_PS 0x00001
-#define OP_FLAG_PS_CHANGESONLY 0x00002
-#define OP_FLAG_GET_EFFECTIVE_RIGHTS 0x00004
-#define OP_FLAG_REPLICATED 0x00008 /* A Replicated Operation */
-#define OP_FLAG_REPL_FIXUP 0x00010 /* A Fixup Operation,
+#define OP_FLAG_PS 0x000001
+#define OP_FLAG_PS_CHANGESONLY 0x000002
+#define OP_FLAG_GET_EFFECTIVE_RIGHTS 0x000004
+#define OP_FLAG_REPLICATED 0x000008 /* A Replicated Operation */
+#define OP_FLAG_REPL_FIXUP 0x000010 /* A Fixup Operation,
* generated as a consequence
* of a Replicated Operation.
*/
-#define OP_FLAG_INTERNAL SLAPI_OP_FLAG_INTERNAL /* 0x00020 */
-#define OP_FLAG_ACTION_LOG_ACCESS 0x00040
-#define OP_FLAG_ACTION_LOG_AUDIT 0x00080
-#define OP_FLAG_ACTION_SCHEMA_CHECK 0x00100
-#define OP_FLAG_ACTION_LOG_CHANGES 0x00200
-#define OP_FLAG_ACTION_INVOKE_FOR_REPLOP 0x00400
-#define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x0800 */
-#define OP_FLAG_TOMBSTONE_ENTRY 0x01000
-#define OP_FLAG_RESURECT_ENTRY 0x02000
-#define OP_FLAG_LEGACY_REPLICATION_DN 0x04000 /* Operation done by legacy
+#define OP_FLAG_INTERNAL SLAPI_OP_FLAG_INTERNAL /* 0x000020 */
+#define OP_FLAG_ACTION_LOG_ACCESS 0x000040
+#define OP_FLAG_ACTION_LOG_AUDIT 0x000080
+#define OP_FLAG_ACTION_SCHEMA_CHECK 0x000100
+#define OP_FLAG_ACTION_LOG_CHANGES 0x000200
+#define OP_FLAG_ACTION_INVOKE_FOR_REPLOP 0x000400
+#define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x000800 */
+#define OP_FLAG_TOMBSTONE_ENTRY 0x001000
+#define OP_FLAG_RESURECT_ENTRY 0x002000
+#define OP_FLAG_LEGACY_REPLICATION_DN 0x004000 /* Operation done by legacy
* replication DN
*/
-#define OP_FLAG_ACTION_NOLOG 0x08000 /* Do not log the entry in
+#define OP_FLAG_ACTION_NOLOG 0x008000 /* Do not log the entry in
* audit log or change log
*/
-#define OP_FLAG_SKIP_MODIFIED_ATTRS 0x10000 /* Do not update the
+#define OP_FLAG_SKIP_MODIFIED_ATTRS 0x010000 /* Do not update the
* modifiersname,
* modifiedtimestamp, etc.
* attributes
*/
-#define OP_FLAG_REPL_RUV 0x20000 /* Flag to tell to the backend
+#define OP_FLAG_REPL_RUV 0x020000 /* Flag to tell to the backend
* that the entry to be added/
* modified is RUV. This info
* is used to skip VLV op.
* (see #329951)
*/
-#define OP_FLAG_PAGED_RESULTS 0x40000 /* simple paged results */
-#define OP_FLAG_SERVER_SIDE_SORTING 0x80000 /* server side sorting */
+#define OP_FLAG_PAGED_RESULTS 0x040000 /* simple paged results */
+#define OP_FLAG_SERVER_SIDE_SORTING 0x080000 /* server side sorting */
+#define OP_FLAG_REVERSE_CANDIDATE_ORDER 0x100000 /* reverse the search candidate list */
+/* reverse search states */
+#define REV_STARTED 1
+#define LAST_REV_ENTRY 2
CSN *operation_get_csn(Slapi_Operation *op);
void operation_set_csn(Slapi_Operation *op,CSN *csn);
9 years, 11 months