From e5d1a517274f6b523c8ed60abe23f899b1967c07 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Thu, 15 May 2014 16:17:00 -0700 Subject: [PATCH 212/225] Ticket #47780 - Some VLV search request causes memory leaks Fix description: . Modified idl_free interface as follows so that passed idl is cleared with NULL once the IDList is successfully freed. -idl_free(IDList *idl) +idl_free(IDList **idl) This change is used to clean up search candidates when ldbm_back_ search_cleanup (ldbm_search.c) is called as an error return. The cleanup function frees the search candidates when it's not NULL and it's not assigned to sr_candidates field in the search result. This fixes a memory leak when VLV/Sort op fails. . ldbm_back_search_cleanup (ldbm_search.c) calls slapi_send_ldap_result if an ldap error is passed to the function. The logic used to be "if (ldap_result>=LDAP_SUCCESS)", which is based upon that mozldap return codes are all positive. Supporting openldap library, there is a chance to get a negative return code (e.g. LDAP_PARAM_ERROR == -9). This patch supports the negative return codes, as well. . In ldbm_back_search (ldbm_search.c) vlv_filter_candidates could ruturn errors such as and LDAP_TIMELIMIT_EXCEEDED, LDAP_ADMINLIMIT_ EXCEEDED. The search results are supposed to be returned to the client with the error code if the control is not critical. The code is added. . The VLV operation stores the result in vlv_response_control.result in ldbm_back_search (ldbm_search.c), which occurs at 3 places, vlv_ filter_candidates, sort_candidates and vlv_trim_candidates_txn. The return code from the latter calls used to override the former return code. This patch fixes it to respect the former return code. https://fedorahosted.org/389/ticket/47780 Reviewed by rmeggins@redhat.com (Thank you, Rich!!) (cherry picked from commit 1118cc9b61a60c704250080d6af8785e4f8d28af) (cherry picked from commit e9f86dab95fd600b414cf1c4cf6f7c733348b758) (cherry picked from commit ff4c7a7b3f65589f93d88aadfcbe95976a9b31a9) (cherry picked from commit bd0fe25aaeea3edda7f4bd0d02d5617791aa058f) --- ldap/servers/slapd/back-ldbm/ancestorid.c | 28 +-- ldap/servers/slapd/back-ldbm/filterindex.c | 50 ++--- ldap/servers/slapd/back-ldbm/idl.c | 92 ++++----- ldap/servers/slapd/back-ldbm/idl_common.c | 12 +- ldap/servers/slapd/back-ldbm/idl_new.c | 8 +- ldap/servers/slapd/back-ldbm/import-merge.c | 6 +- ldap/servers/slapd/back-ldbm/import-threads.c | 4 +- ldap/servers/slapd/back-ldbm/index.c | 22 +-- ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c | 2 +- ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 4 +- ldap/servers/slapd/back-ldbm/ldbm_search.c | 257 ++++++++++++++++--------- ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 23 +-- ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 2 +- ldap/servers/slapd/back-ldbm/seq.c | 3 +- ldap/servers/slapd/back-ldbm/vlv.c | 2 +- 15 files changed, 289 insertions(+), 226 deletions(-) diff --git a/ldap/servers/slapd/back-ldbm/ancestorid.c b/ldap/servers/slapd/back-ldbm/ancestorid.c index 8722b68..54b08ad 100644 --- a/ldap/servers/slapd/back-ldbm/ancestorid.c +++ b/ldap/servers/slapd/back-ldbm/ancestorid.c @@ -136,7 +136,7 @@ static int ldbm_get_nonleaf_ids(backend *be, DB_TXN *txn, IDList **idl) LDAPDebug(LDAP_DEBUG_TRACE, "found %lu nodes for ancestorid\n", (u_long)IDL_NIDS(nodes), 0, 0); } else { - idl_free(nodes); + idl_free(&nodes); *idl = NULL; } @@ -264,7 +264,7 @@ static int ldbm_ancestorid_default_create_index(backend *be) /* Insert into ancestorid for this node */ if (id2idl_hash_lookup(ht, &id, &ididl)) { descendants = idl_union_allids(be, ai_aid, ididl->idl, children); - idl_free(children); + idl_free(&children); if (id2idl_hash_remove(ht, &id) == 0) { LDAPDebug(LDAP_DEBUG_ANY, "ancestorid hash_remove failed\n", 0,0,0); } else { @@ -279,21 +279,21 @@ static int ldbm_ancestorid_default_create_index(backend *be) /* Get parentid for this entry */ ret = ldbm_parentid(be, txn, id, &parentid); if (ret != 0) { - idl_free(descendants); + idl_free(&descendants); break; } /* A suffix entry does not have a parent */ if (parentid == NOID) { - idl_free(descendants); + idl_free(&descendants); continue; } /* Insert into ancestorid for this node's parent */ if (id2idl_hash_lookup(ht, &parentid, &ididl)) { IDList *idl = idl_union_allids(be, ai_aid, ididl->idl, descendants); - idl_free(descendants); - idl_free(ididl->idl); + idl_free(&descendants); + idl_free(&(ididl->idl)); ididl->idl = idl; } else { ididl = (id2idl*)slapi_ch_calloc(1,sizeof(id2idl)); @@ -324,7 +324,7 @@ static int ldbm_ancestorid_default_create_index(backend *be) id2idl_hash_destroy(ht); /* Free any leftover idlists */ - idl_free(nodes); + idl_free(&nodes); /* Release the parentid file */ if (db_pid != NULL) { @@ -456,7 +456,7 @@ static int ldbm_ancestorid_new_idl_create_index(backend *be) /* Insert into ancestorid for this node */ ret = idl_store_block(be, db_aid, &key, children, txn, ai_aid); if (ret != 0) { - idl_free(children); + idl_free(&children); break; } @@ -467,13 +467,13 @@ static int ldbm_ancestorid_new_idl_create_index(backend *be) slapi_log_error(SLAPI_LOG_FATAL, sourcefile, "Error: ldbm_parentid on node index [" ID_FMT "] of [" ID_FMT "]\n", nids, nodes->b_nids); - idl_free(children); + idl_free(&children); goto out; } /* A suffix entry does not have a parent */ if (parentid == NOID) { - idl_free(children); + idl_free(&children); break; } @@ -485,7 +485,7 @@ static int ldbm_ancestorid_new_idl_create_index(backend *be) /* Insert into ancestorid for this node's parent */ ret = idl_store_block(be, db_aid, &key, children, txn, ai_aid); if (ret != 0) { - idl_free(children); + idl_free(&children); goto out; } id = parentid; @@ -504,7 +504,7 @@ static int ldbm_ancestorid_new_idl_create_index(backend *be) } /* Free any leftover idlists */ - idl_free(nodes); + idl_free(&nodes); /* Release the parentid file */ if (db_pid != NULL) { @@ -583,7 +583,7 @@ static int ldbm_parentid(backend *be, DB_TXN *txn, ID id, ID *ppid) static void id2idl_free(id2idl **ididl) { - idl_free((*ididl)->idl); + idl_free(&((*ididl)->idl)); slapi_ch_free((void**)ididl); } @@ -785,7 +785,7 @@ static int ldbm_ancestorid_index_update( break; } node_id = idl_firstid(idl); - idl_free(idl); + idl_free(&idl); } /* Update ancestorid for the base entry */ diff --git a/ldap/servers/slapd/back-ldbm/filterindex.c b/ldap/servers/slapd/back-ldbm/filterindex.c index a213815..0998920 100644 --- a/ldap/servers/slapd/back-ldbm/filterindex.c +++ b/ldap/servers/slapd/back-ldbm/filterindex.c @@ -399,7 +399,7 @@ presence_candidates( LDAPDebug(LDAP_DEBUG_TRACE, "fallback to eq index as pres index gave allids\n", 0, 0, 0); - idl_free(idl); + idl_free(&idl); idl = index_range_read_ext(pb, be, type, indextype_EQUALITY, SLAPI_OP_GREATER_OR_EQUAL, NULL, NULL, 0, &txn, err, allidslimit); @@ -481,7 +481,7 @@ extensible_candidates( else if (keys == NULL || keys[0] == NULL) { /* no keys */ - idl_free (idl); + idl_free (&idl); idl = idl_allids (be); } else @@ -516,8 +516,8 @@ extensible_candidates( else { IDList* tmp = idl_intersection (be, idl2, idl3); - idl_free (idl2); - idl_free (idl3); + idl_free (&idl2); + idl_free (&idl3); idl2 = tmp; } if (idl2 == NULL) break; /* look no further */ @@ -529,8 +529,8 @@ extensible_candidates( else if (idl2 != NULL) { IDList* tmp = idl_union (be, idl, idl2); - idl_free (idl); - idl_free (idl2); + idl_free (&idl); + idl_free (&idl2); idl = tmp; } } @@ -797,7 +797,7 @@ list_candidates( { LDAPDebug( LDAP_DEBUG_TRACE, "<= list_candidates NULL\n", 0, 0, 0 ); - idl_free( idl ); + idl_free( &idl ); idl = NULL; goto out; } @@ -807,7 +807,7 @@ list_candidates( == NULL && ftype == LDAP_FILTER_AND ) { LDAPDebug( LDAP_DEBUG_TRACE, "<= list_candidates NULL\n", 0, 0, 0 ); - idl_free( idl ); + idl_free( &idl ); idl = NULL; goto out; } @@ -822,18 +822,24 @@ list_candidates( } } else if ( ftype == LDAP_FILTER_AND ) { if (isnot) { - IDList *new_idl = NULL; - int notin_result = 0; - notin_result = idl_notin( be, idl, tmp, &new_idl ); - if (notin_result) { - idl_free(idl); - idl = new_idl; + /* + * If tmp is NULL or ALLID, idl_notin just duplicates idl. + * We don't have to do it. + */ + if (!tmp && !idl_is_allids(tmp)) { + IDList *new_idl = NULL; + int notin_result = 0; + notin_result = idl_notin( be, idl, tmp, &new_idl ); + if (notin_result) { + idl_free(&idl); + idl = new_idl; + } } } else { idl = idl_intersection(be, idl, tmp); - idl_free( tmp2 ); + idl_free( &tmp2 ); } - idl_free( tmp ); + idl_free( &tmp ); /* stop if the list has gotten too small */ if ((idl == NULL) || (idl_length(idl) <= FILTER_TEST_THRESHOLD)) @@ -843,8 +849,8 @@ list_candidates( slapi_pblock_get( pb, SLAPI_OPERATION, &operation ); idl = idl_union( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); + idl_free( &tmp ); + idl_free( &tmp2 ); /* stop if we're already committed to an exhaustive * search. :( */ @@ -853,7 +859,7 @@ list_candidates( if (op_is_pagedresults(operation)) { int nids = IDL_NIDS(idl); if ( allidslimit > 0 && nids > allidslimit ) { - idl_free( idl ); + idl_free( &idl ); idl = idl_allids( be ); } } @@ -976,7 +982,7 @@ keys2idl( } #endif if ( idl2 == NULL ) { - idl_free( idl ); + idl_free( &idl ); idl = NULL; break; } @@ -988,8 +994,8 @@ keys2idl( tmp = idl; idl = idl_intersection(be, idl, idl2); - idl_free( idl2 ); - idl_free( tmp ); + idl_free( &idl2 ); + idl_free( &tmp ); if ( idl == NULL ) { break; } diff --git a/ldap/servers/slapd/back-ldbm/idl.c b/ldap/servers/slapd/back-ldbm/idl.c index 76ee252..67fa711 100644 --- a/ldap/servers/slapd/back-ldbm/idl.c +++ b/ldap/servers/slapd/back-ldbm/idl.c @@ -280,12 +280,12 @@ idl_old_fetch( if ( ! INDIRECT_BLOCK( idl ) ) { /* make sure we have the current value of highest id */ if ( ALLIDS(idl) ) { - idl_free( idl ); + idl_free( &idl ); idl = idl_allids( be ); } return( idl ); } - idl_free( idl ); + idl_free( &idl ); /* Taking a transaction is expensive; so we try and optimize for the common case by not taking one above. If we have a indirect block; we need to take a transaction and re-read @@ -307,7 +307,7 @@ idl_old_fetch( dblayer_read_txn_commit(li,&s_txn); /* make sure we have the current value of highest id */ if ( ALLIDS(idl) ) { - idl_free( idl ); + idl_free( &idl ); idl = idl_allids( be ); } return( idl ); @@ -367,7 +367,7 @@ idl_old_fetch( dblayer_read_txn_commit(li,&s_txn); tmp[i] = NULL; slapi_ch_free((void**)&kstr ); - idl_free( idl ); + idl_free( &idl ); /* allocate space for the big block */ idl = idl_alloc( nids ); @@ -384,7 +384,7 @@ idl_old_fetch( tmp[i]->b_nids * sizeof(ID) ); nids += tmp[i]->b_nids; - idl_free( tmp[i] ); + idl_free( &tmp[i] ); } slapi_ch_free((void**)&tmp ); @@ -629,7 +629,7 @@ idl_old_insert_key( rc, (msg = dblayer_strerror( rc )) ? msg : "", 0 ); } - idl_free( idl ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); return( rc ); } @@ -655,10 +655,10 @@ idl_old_insert_key( case 3: /* id not inserted - block must be split */ /* check threshold for marking this an all-id block */ if ( a->ai_idl->idl_maxindirect < 2 ) { - idl_free( idl ); + idl_free( &idl ); idl = idl_allids( be ); rc = idl_store( be, db, key, idl, txn ); - idl_free( idl ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); if ( rc != 0 && rc != DB_LOCK_DEADLOCK) @@ -673,7 +673,7 @@ idl_old_insert_key( } idl_split_block( idl, id, &tmp, &tmp2 ); - idl_free( idl ); + idl_free( &idl ); /* create the header indirect block */ idl = idl_alloc( 3 ); @@ -686,9 +686,9 @@ idl_old_insert_key( /* store it */ rc = idl_store( be, db, key, idl, txn ); if ( rc != 0 ) { - idl_free( idl ); - idl_free( tmp ); - idl_free( tmp2 ); + idl_free( &idl ); + idl_free( &tmp ); + idl_free( &tmp2 ); if ( rc != DB_LOCK_DEADLOCK ) { LDAPDebug( LDAP_DEBUG_ANY, "idl_insert_key 3 BAD %d %s\n", @@ -712,9 +712,9 @@ idl_old_insert_key( k2.dsize = strlen( kstr ) + 1; rc = idl_store( be, db, &k2, tmp2, txn ); if ( rc != 0 ) { - idl_free( idl ); - idl_free( tmp ); - idl_free( tmp2 ); + idl_free( &idl ); + idl_free( &tmp ); + idl_free( &tmp2 ); if ( rc != DB_LOCK_DEADLOCK ) { LDAPDebug( LDAP_DEBUG_ANY, "idl_insert_key 4 BAD %d %s\n", @@ -726,12 +726,12 @@ idl_old_insert_key( "idl_insert_key", "split", key, id); slapi_ch_free((void**)&kstr ); - idl_free( tmp ); - idl_free( tmp2 ); + idl_free( &tmp ); + idl_free( &tmp2 ); break; } - idl_free( idl ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); if ( rc != 0 && rc != DB_LOCK_DEADLOCK ) { @@ -759,7 +759,7 @@ idl_old_insert_key( (u_long)id, key.dptr, i); #endif idl_unlock_list(a->ai_idl,key); - idl_free( idl ); + idl_free( &idl ); return( 0 ); } if ( i != 0 ) { @@ -783,7 +783,7 @@ idl_old_insert_key( LDAPDebug( LDAP_DEBUG_ANY, "nonexistent continuation block (%s)\n", k2.dptr, 0, 0 ); idl_unlock_list(a->ai_idl,key); - idl_free( idl ); + idl_free( &idl ); slapi_ch_free((void**)&kstr ); return( -1 ); } @@ -911,9 +911,9 @@ idl_old_insert_key( slapi_ch_free( (void **)&(k2.dptr) ); slapi_ch_free( (void **)&(k3.dptr) ); - idl_free( tmp ); - idl_free( tmp2 ); - idl_free( idl ); + idl_free( &tmp ); + idl_free( &tmp2 ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); return( rc ); @@ -941,7 +941,7 @@ idl_old_insert_key( * which is not correct. */ rc = 0; - idl_free( tmp2 ); + idl_free( &tmp2 ); break; } if ( rc != 0 ) { @@ -986,7 +986,7 @@ idl_old_insert_key( /* store allid block in place of header block */ if ( 0 == rc ) { - idl_free( idl ); + idl_free( &idl ); idl = idl_allids( be ); rc = idl_store( be, db, key, idl, txn ); if (NULL != disposition) { @@ -996,14 +996,14 @@ idl_old_insert_key( slapi_ch_free( (void **)&(k2.dptr) ); slapi_ch_free( (void **)&(k3.dptr) ); - idl_free( idl ); - idl_free( tmp ); + idl_free( &idl ); + idl_free( &tmp ); idl_unlock_list(a->ai_idl,key); return( rc ); } idl_split_block( tmp, id, &tmp2, &tmp3 ); - idl_free( tmp ); + idl_free( &tmp ); /* create a new updated indirect header block */ tmp = idl_alloc( idl->b_nmax + 1 ); @@ -1021,8 +1021,8 @@ idl_old_insert_key( /* store the header block */ rc = idl_store( be, db, key, tmp, txn ); if ( rc != 0 ) { - idl_free( tmp2 ); - idl_free( tmp3 ); + idl_free( &tmp2 ); + idl_free( &tmp3 ); break; } @@ -1033,8 +1033,8 @@ idl_old_insert_key( k2.dsize = strlen( kstr ) + 1; rc = idl_store( be, db, &k2, tmp2, txn ); if ( rc != 0 ) { - idl_free( tmp2 ); - idl_free( tmp3 ); + idl_free( &tmp2 ); + idl_free( &tmp3 ); break; } @@ -1045,22 +1045,22 @@ idl_old_insert_key( k2.dsize = strlen( kstr ) + 1; rc = idl_store( be, db, &k2, tmp3, txn ); if ( rc != 0 ) { - idl_free( tmp2 ); - idl_free( tmp3 ); + idl_free( &tmp2 ); + idl_free( &tmp3 ); break; } idl_check_indirect (tmp, i, tmp2, tmp3, "idl_insert_key", "indirect split", key, id); - idl_free( tmp2 ); - idl_free( tmp3 ); + idl_free( &tmp2 ); + idl_free( &tmp3 ); break; } slapi_ch_free( (void **)&(k2.dptr) ); slapi_ch_free( (void **)&(k3.dptr) ); - idl_free( tmp ); - idl_free( idl ); + idl_free( &tmp ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); return( rc ); } @@ -1096,7 +1096,7 @@ int idl_old_store_block( /* If so, store an ALLIDS block */ IDList *all = idl_allids(be); ret = idl_store(be,db,key,all,txn); - idl_free(all); + idl_free(&all); } else { /* Then , is it a block which is smaller than the size at which it needs splitting ? */ if (idl->b_nids <= (ID)priv->idl_maxids) { @@ -1155,7 +1155,7 @@ int idl_old_store_block( make_cont_key(&cont_key,key,lead_id); /* Now store the continuation block */ ret = idl_store(be,db,&cont_key,this_cont_block,txn); - idl_free(this_cont_block); + idl_free(&this_cont_block); slapi_ch_free(&(cont_key.data)); if ( ret != 0 && ret != DB_LOCK_DEADLOCK ) { @@ -1177,7 +1177,7 @@ int idl_old_store_block( } done: /* Free master block */ - idl_free(master_block); + idl_free(&master_block); return ret; } @@ -1438,7 +1438,7 @@ idl_old_delete_key( break; } - idl_free( idl ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); LDAPDebug( LDAP_DEBUG_TRACE, "<= idl_delete_key(%s,%lu) %d (not indirect)\n", key->dptr, (u_long)id, rc ); @@ -1459,7 +1459,7 @@ idl_old_delete_key( } /* id smaller than smallest id - not there */ if ( i == 0 && id < idl->b_ids[i] ) { - idl_free( idl ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); LDAPDebug( LDAP_DEBUG_TRACE, "<= idl_delete_key(%s,%lu) -666 (id not found)\n", key->dptr, (u_long)id, 0 ); @@ -1472,7 +1472,7 @@ idl_old_delete_key( /* get the block to delete from */ make_cont_key( &contkey, key, idl->b_ids[i] ); if ( (didl = idl_fetch_one( li, db, &contkey, txn, &rc )) == NULL ) { - idl_free( idl ); + idl_free( &idl ); idl_unlock_list(a->ai_idl,key); if ( rc != DB_LOCK_DEADLOCK ) { @@ -1559,8 +1559,8 @@ idl_old_delete_key( rc = 0; break; } - idl_free( idl ); - idl_free( didl ); + idl_free( &idl ); + idl_free( &didl ); slapi_ch_free( (void **)&(contkey.dptr) ); idl_unlock_list(a->ai_idl,key); if ( rc != 0 && rc != DB_LOCK_DEADLOCK ) diff --git a/ldap/servers/slapd/back-ldbm/idl_common.c b/ldap/servers/slapd/back-ldbm/idl_common.c index ee59ee2..216bfb0 100644 --- a/ldap/servers/slapd/back-ldbm/idl_common.c +++ b/ldap/servers/slapd/back-ldbm/idl_common.c @@ -85,13 +85,13 @@ idl_allids( backend *be ) } void -idl_free( IDList *idl ) /* JCM - pass in ** */ +idl_free( IDList **idl ) { - if ( idl == NULL ) { + if ((NULL == idl) || (NULL == *idl)) { return; } - slapi_ch_free((void**)&idl ); + slapi_ch_free((void**)idl); } @@ -151,7 +151,7 @@ idl_append_extend(IDList **orig_idl, ID id) /* copy over the existing contents */ idl_new->b_nids = idl->b_nids; memcpy(idl_new->b_ids, idl->b_ids, sizeof(ID) * idl->b_nids); - idl_free(idl); + idl_free(&idl); idl = idl_new; } @@ -243,7 +243,7 @@ idl_intersection( } if ( ni == 0 ) { - idl_free( n ); + idl_free( &n ); return( NULL ); } n->b_nids = ni; @@ -355,7 +355,7 @@ idl_notin( } if ( ni == n->b_nmax ) { - idl_free( n ); + idl_free( &n ); *new_result = idl_allids( be ); } else { n->b_nids = ni; diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c index 936c19f..1591e84 100644 --- a/ldap/servers/slapd/back-ldbm/idl_new.c +++ b/ldap/servers/slapd/back-ldbm/idl_new.c @@ -277,7 +277,7 @@ IDList * idl_new_fetch( idl_rc = idl_append_extend(&idl, id); if (idl_rc) { LDAPDebug(LDAP_DEBUG_ANY, "unable to extend id list (err=%d)\n", idl_rc, 0, 0); - idl_free(idl); idl = NULL; + idl_free(&idl); goto error; } @@ -314,7 +314,7 @@ IDList * idl_new_fetch( idl_rc = idl_append_extend(&idl, id); if (idl_rc) { LDAPDebug(LDAP_DEBUG_ANY, "unable to extend id list (err=%d)\n", idl_rc); - idl_free(idl); idl = NULL; + idl_free(&idl); goto error; } #if defined(DB_ALLIDS_ON_READ) @@ -330,7 +330,7 @@ IDList * idl_new_fetch( #endif if (ret != DB_NOTFOUND) { - idl_free(idl); idl = NULL; + idl_free(&idl); ldbm_nasty(filename,59,ret); goto error; } @@ -339,7 +339,7 @@ IDList * idl_new_fetch( /* check for allids value */ if (idl != NULL && idl->b_nids == 1 && idl->b_ids[0] == ALLID) { - idl_free(idl); + idl_free(&idl); idl = idl_allids(be); LDAPDebug(LDAP_DEBUG_TRACE, "idl_new_fetch %s returns allids\n", key.data, 0, 0); diff --git a/ldap/servers/slapd/back-ldbm/import-merge.c b/ldap/servers/slapd/back-ldbm/import-merge.c index 9d7af3e..e01bf88 100644 --- a/ldap/servers/slapd/back-ldbm/import-merge.c +++ b/ldap/servers/slapd/back-ldbm/import-merge.c @@ -169,8 +169,8 @@ static int import_merge_insert_input_queue(backend *be, import_merge_queue_entry IDList *new_idl = idl_union(be, current_entry->thang.payload.idl, idl); - idl_free(current_entry->thang.payload.idl); - idl_free(idl); + idl_free(&(current_entry->thang.payload.idl)); + idl_free(&idl); current_entry->thang.payload.idl = new_idl; /* Add this file id into the entry's referenced list */ (current_entry->file_referenced_list)[fileno] = 1; @@ -567,7 +567,7 @@ static int import_merge_one_file(ImportWorkerInfo *worker, int passes, ret = idl_store_block(be, output_file, &key, thang.payload.idl, NULL, worker->index_info->ai); /* Free the key we got back from the queue */ - idl_free(thang.payload.idl); + idl_free(&(thang.payload.idl)); thang.payload.idl = NULL; } slapi_ch_free(&(key.data)); diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c index e615bb1..44fd35e 100644 --- a/ldap/servers/slapd/back-ldbm/import-threads.c +++ b/ldap/servers/slapd/back-ldbm/import-threads.c @@ -2005,7 +2005,7 @@ foreman_do_entrydn(ImportJob *job, FifoItem *fi) */ if (IDL) { ID id = idl_firstid(IDL); /* entrydn is a single attr */ - idl_free(IDL); + idl_free(&IDL); if (id != entry->ep_id) { /* case (2) */ import_log_notice(job, "Duplicated entrydn detected: \"%s\": " "Entry ID: (%d, %d)", @@ -2031,7 +2031,7 @@ foreman_do_entrydn(ImportJob *job, FifoItem *fi) "\"%s\" found at line %d of file \"%s\"", slapi_entry_get_dn(entry->ep_entry), fi->line, fi->filename); - idl_free(IDL); + idl_free(&IDL); /* skip this one */ fi->bad = FIFOITEM_BAD; job->skipped++; diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c index 2d5b535..90d1d23 100644 --- a/ldap/servers/slapd/back-ldbm/index.c +++ b/ldap/servers/slapd/back-ldbm/index.c @@ -197,7 +197,7 @@ index_put_idl(index_buffer_bin *bin,backend *be, DB_TXN *txn,struct attrinfo *a) goto error; } slapi_ch_free( &(bin->key.data) ); - idl_free(bin->value); + idl_free(&(bin->value)); /* If we're already at allids, store an allids block to prevent needless accumulation of blocks */ if (old_idl && ALLIDS(old_idl)) { bin->value = idl_allids(be); @@ -207,10 +207,10 @@ index_put_idl(index_buffer_bin *bin,backend *be, DB_TXN *txn,struct attrinfo *a) } error: if (old_idl) { - idl_free(old_idl); + idl_free(&old_idl); } if (new_idl && need_to_freed_new_idl) { - idl_free(new_idl); + idl_free(&new_idl); } dblayer_release_index_file( be, a, db ); return ret; @@ -268,8 +268,7 @@ index_buffer_terminate(void *h) for (i = 0; i < handle->buffer_size; i++) { bin = &(handle->bins[i]); if (bin->value) { - idl_free(bin->value); - bin->value = NULL; + idl_free(&(bin->value)); } slapi_ch_free(&(bin->key.data)); } @@ -1511,9 +1510,7 @@ index_range_read_ext( */ /* Check to see if we've already looked too hard */ if (idl != NULL && lookthrough_limit != -1 && idl->b_nids > (ID)lookthrough_limit) { - if (NULL != idl) { - idl_free(idl); - } + idl_free(&idl); idl = idl_allids( be ); LDAPDebug(LDAP_DEBUG_TRACE, "index_range_read lookthrough_limit exceeded\n", 0, 0, 0); @@ -1538,10 +1535,7 @@ index_range_read_ext( * when the connection is closed by the client). */ if ( slapi_op_abandoned( pb )) { - if (NULL != idl) { - idl_free(idl); - idl = NULL; - } + idl_free(&idl); LDAPDebug(LDAP_DEBUG_TRACE, "index_range_read - operation abandoned\n", 0, 0, 0); break; /* clean up happens outside the while() loop */ @@ -1577,7 +1571,7 @@ index_range_read_ext( /* idl tmp only contains one id */ /* append it at the end here; sort idlist at the end */ if (ALLIDS(tmp)) { - idl_free(idl); + idl_free(&idl); idl = tmp; } else { ID id; @@ -1588,7 +1582,7 @@ index_range_read_ext( 1097, *err); } } - idl_free(tmp); + idl_free(&tmp); } if (ALLIDS(idl)) { LDAPDebug(LDAP_DEBUG_TRACE, "index_range_read hit an allids value\n", diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c index 38b407d..8369bcc 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c @@ -1090,7 +1090,7 @@ entryrdn_get_subordinates(backend *be, bail: if (rc && subordinates && *subordinates) { - idl_free(*subordinates); + idl_free(subordinates); } slapi_ch_free_string(&keybuf); slapi_ch_free((void **)&elem); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c index 4e5ce45..09d8f05 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c @@ -1451,7 +1451,7 @@ common_return: slapi_ch_free((void**)&child_dns); if (ldap_result_matcheddn && 0 != strcmp(ldap_result_matcheddn, "NULL")) slapi_ch_free((void**)&ldap_result_matcheddn); - idl_free(children); + idl_free(&children); slapi_sdn_done(&dn_newdn); slapi_sdn_done(&dn_newrdn); slapi_sdn_done(&dn_parentdn); @@ -2170,7 +2170,7 @@ moddn_get_children(back_txn *ptxn, } } } while (id!=NOID); - idl_free(candidates); + idl_free(&candidates); slapi_sdn_done(&parentsdn); } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c index 746528e..626ba2e 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_search.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c @@ -46,6 +46,16 @@ #include "back-ldbm.h" #include "vlv_srch.h" +/* + * Used for ldap_result passed to ldbm_back_search_cleanup. + * If (ldap_result == LDBM_SRCH_DEFAULT_RESULT) || (ldap_result == LDAP_SUCCESS), + * don't call slapi_send_ldap_result. + * Note: mozldap ldap_result codes are all positive; openldap result codes could + * be negative values. OL (-1) is LDAP_SERVER_DOWN. Thus, it's safe to + * borrow the value here. + */ +#define LDBM_SRCH_DEFAULT_RESULT (-1) + /* prototypes */ static int build_candidate_list( Slapi_PBlock *pb, backend *be, struct backentry *e, const char * base, int scope, @@ -160,12 +170,14 @@ ldbm_back_search_cleanup(Slapi_PBlock *pb, char* ldap_result_description, int function_result, struct vlv_request *vlv_request_control, - struct backentry *e) + struct backentry *e, + IDList *candidates) { int estimate = 0; /* estimated search result count */ backend *be; ldbm_instance *inst; back_search_result_set *sr = NULL; + int free_candidates = 1; slapi_pblock_get( pb, SLAPI_BACKEND, &be ); inst = (ldbm_instance *) be->be_instance_info; @@ -175,20 +187,27 @@ ldbm_back_search_cleanup(Slapi_PBlock *pb, { sort_spec_free(sort_control); } - if(ldap_result>=LDAP_SUCCESS) - { + if ((ldap_result != LDBM_SRCH_DEFAULT_RESULT) && (ldap_result != LDAP_SUCCESS)) { slapi_send_ldap_result( pb, ldap_result, NULL, ldap_result_description, 0, NULL ); } /* code to free the result set if we don't need it */ /* We get it and check to see if the structure was ever used */ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); if (sr) { - if (function_result) { + if (function_result) { /* failed case */ slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate); slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL); + if (sr->sr_candidates == candidates) { + free_candidates = 0; + } delete_search_result_set(pb, &sr); + } else if (sr->sr_candidates == candidates) { /* succeeded case */ + free_candidates = 0; } } + if (free_candidates) { + idl_free(&candidates); + } if (vlv_request_control) { berval_done(&vlv_request_control->value); @@ -331,7 +350,7 @@ ldbm_back_search( Slapi_PBlock *pb ) back_search_result_set *sr = NULL; /* Fix for bugid #394184, SD, 20 Jul 00 */ - int tmp_err = -1; /* must be lower than LDAP_SUCCESS */ + int tmp_err = LDBM_SRCH_DEFAULT_RESULT; char * tmp_desc = NULL; /* end Fix for defect #394184 */ @@ -383,9 +402,29 @@ ldbm_back_search( Slapi_PBlock *pb ) if(r!=0) { /* Badly formed SORT control */ - return ldbm_back_search_cleanup(pb, li, sort_control, - LDAP_PROTOCOL_ERROR, "Sort Control", - SLAPI_FAIL_GENERAL, NULL, NULL); + if (is_sorting_critical_orig) { + /* RFC 4511 4.1.11 the server must not process the operation + * and return LDAP_UNAVAILABLE_CRITICAL_EXTENSION + */ + return ldbm_back_search_cleanup(pb, li, sort_control, + LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "Sort Control", + SLAPI_FAIL_GENERAL, NULL, NULL, candidates); + } else { + PRUint64 conn_id; + int op_id; + + /* Just ignore the control */ + sort = 0; + slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id); + slapi_pblock_get(pb, SLAPI_OPERATION_ID, &op_id); + + LDAPDebug(LDAP_DEBUG_ANY, + "Warning: Sort control ignored for conn=%d op=%d\n", + conn_id, op_id, 0); + } + } else { + /* set this operation includes the server side sorting */ + operation->o_flags |= OP_FLAG_SERVER_SIDE_SORTING; } /* set this operation includes the server side sorting */ operation->o_flags |= OP_FLAG_SERVER_SIDE_SORTING; @@ -401,30 +440,49 @@ ldbm_back_search( Slapi_PBlock *pb ) if(r!=LDAP_SUCCESS) { /* Badly formed VLV control */ - return ldbm_back_search_cleanup(pb, li, sort_control, - r, "VLV Control", SLAPI_FAIL_GENERAL, - &vlv_request_control, NULL); - } - { - /* Access Control Check to see if the client is allowed to use the VLV Control. */ - Slapi_Entry *feature; - char dn[128]; - char *dummyAttr = "dummy#attr"; - char *dummyAttrs[2] = { NULL, NULL }; - - dummyAttrs[0] = dummyAttr; - - /* This dn is normalized. */ - PR_snprintf(dn,sizeof(dn),"dn: oid=%s,cn=features,cn=config",LDAP_CONTROL_VLVREQUEST); - feature= slapi_str2entry(dn,0); - r= plugin_call_acl_plugin (pb, feature, dummyAttrs, NULL, SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL); - slapi_entry_free(feature); - if(r!=LDAP_SUCCESS) + if (is_vlv_critical) { + /* RFC 4511 4.1.11 the server must not process the operation + * and return LDAP_UNAVAILABLE_CRITICAL_EXTENSION + */ + return ldbm_back_search_cleanup(pb, li, sort_control, + LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "VLV Control", SLAPI_FAIL_GENERAL, + &vlv_request_control, NULL, candidates); + } else { + PRUint64 conn_id; + int op_id; + + /* Just ignore the control */ + virtual_list_view = 0; + slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id); + slapi_pblock_get(pb, SLAPI_OPERATION_ID, &op_id); + + LDAPDebug(LDAP_DEBUG_ANY, + "Warning: VLV control ignored for conn=%d op=%d\n", + conn_id, op_id, 0); + } + + } else { { - /* Client isn't allowed to do this. */ - return ldbm_back_search_cleanup(pb, li, sort_control, - r, "VLV Control", SLAPI_FAIL_GENERAL, - &vlv_request_control, NULL); + /* Access Control Check to see if the client is allowed to use the VLV Control. */ + Slapi_Entry *feature; + int rc; + char dn[128]; + char *dummyAttr = "dummy#attr"; + char *dummyAttrs[2] = {NULL, NULL}; + + dummyAttrs[0] = dummyAttr; + + /* This dn is normalized. */ + PR_snprintf(dn, sizeof (dn), "dn: oid=%s,cn=features,cn=config", LDAP_CONTROL_VLVREQUEST); + feature = slapi_str2entry(dn, 0); + rc = plugin_call_acl_plugin(pb, feature, dummyAttrs, NULL, SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL); + slapi_entry_free(feature); + if (rc != LDAP_SUCCESS) { + /* Client isn't allowed to do this. */ + return ldbm_back_search_cleanup(pb, li, sort_control, + rc, "VLV Control", SLAPI_FAIL_GENERAL, + &vlv_request_control, NULL, candidates); + } } } /* @@ -438,7 +496,7 @@ ldbm_back_search( Slapi_PBlock *pb ) /* Can't have a VLV control without a SORT control */ return ldbm_back_search_cleanup(pb, li, sort_control, LDAP_SORT_CONTROL_MISSING, "VLV Control", - SLAPI_FAIL_GENERAL, &vlv_request_control, NULL); + SLAPI_FAIL_GENERAL, &vlv_request_control, NULL, candidates); } } } @@ -491,13 +549,13 @@ ldbm_back_search( Slapi_PBlock *pb ) { return ldbm_back_search_cleanup(pb, li, sort_control, LDAP_UNWILLING_TO_PERFORM, ctrlstr, - SLAPI_FAIL_GENERAL, &vlv_request_control, NULL); + SLAPI_FAIL_GENERAL, &vlv_request_control, NULL, candidates); } else { return ldbm_back_search_cleanup(pb, li, sort_control, LDAP_VIRTUAL_LIST_VIEW_ERROR, ctrlstr, - SLAPI_FAIL_GENERAL, &vlv_request_control, NULL); + SLAPI_FAIL_GENERAL, &vlv_request_control, NULL, candidates); } } else @@ -512,7 +570,7 @@ ldbm_back_search( Slapi_PBlock *pb ) sort_make_sort_response_control(pb, LDAP_UNWILLING_TO_PERFORM, NULL); return ldbm_back_search_cleanup(pb, li, sort_control, LDAP_UNAVAILABLE_CRITICAL_EXTENSION, ctrlstr, - SLAPI_FAIL_GENERAL, &vlv_request_control, NULL); + SLAPI_FAIL_GENERAL, &vlv_request_control, NULL, candidates); } else /* vlv and sorting are not critical, so ignore the control */ { @@ -546,7 +604,7 @@ ldbm_back_search( Slapi_PBlock *pb ) { /* error or referral sent by find_entry */ return ldbm_back_search_cleanup(pb, li, sort_control, - -1, NULL, 1, &vlv_request_control, NULL); + LDBM_SRCH_DEFAULT_RESULT, NULL, 1, &vlv_request_control, NULL, candidates); } } @@ -569,6 +627,7 @@ ldbm_back_search( Slapi_PBlock *pb ) /* * Build a list of IDs for this entry and scope */ + vlv_response_control.result = LDAP_SUCCESS; if ((NULL != controls) && (sort) && (vlv)) { /* This candidate list is for vlv, no need for sort only. */ switch (vlv_search_build_candidate_list(pb, basesdn, &vlv_rc, @@ -579,12 +638,12 @@ ldbm_back_search( Slapi_PBlock *pb ) return ldbm_back_search_cleanup(pb, li, sort_control, vlv_rc, "VLV Control", SLAPI_FAIL_GENERAL, - &vlv_request_control, e); + &vlv_request_control, e, candidates); case VLV_BLD_LIST_FAILED: return ldbm_back_search_cleanup(pb, li, sort_control, vlv_response_control.result, NULL, SLAPI_FAIL_GENERAL, - &vlv_request_control, e); + &vlv_request_control, e, candidates); case LDAP_SUCCESS: /* Log to the access log the particulars of this sort request */ @@ -605,7 +664,7 @@ ldbm_back_search( Slapi_PBlock *pb ) LDAP_OPERATIONS_ERROR, "Sort Response Control", SLAPI_FAIL_GENERAL, - &vlv_request_control, e); + &vlv_request_control, e, candidates); } } } @@ -616,9 +675,9 @@ ldbm_back_search( Slapi_PBlock *pb ) if (rc) { /* Error result sent by build_candidate_list */ - return ldbm_back_search_cleanup(pb, li, sort_control, -1, - NULL, rc, - &vlv_request_control, e); + return ldbm_back_search_cleanup(pb, li, sort_control, + LDBM_SRCH_DEFAULT_RESULT, NULL, rc, + &vlv_request_control, e, candidates); } /* * If we're sorting then we must check what administrative @@ -644,25 +703,33 @@ ldbm_back_search( Slapi_PBlock *pb ) * If we're presenting a virtual list view, then apply the * search filter before sorting. */ - if (virtual_list_view && (NULL != candidates)) - { - int r = 0; + if (virtual_list_view && candidates) { IDList *idl = NULL; Slapi_Filter *filter = NULL; slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ); - r = vlv_filter_candidates(be, pb, candidates, basesdn, - scope, filter, &idl, - lookthrough_limit, time_up); - if(r == 0) - { - idl_free(candidates); - candidates= idl; - } - else - { + rc = vlv_filter_candidates(be, pb, candidates, basesdn, + scope, filter, &idl, + lookthrough_limit, time_up); + switch (rc) { + case LDAP_SUCCESS: /* Everything OK */ + case LDAP_TIMELIMIT_EXCEEDED: /* Timeout */ + case LDAP_ADMINLIMIT_EXCEEDED: /* Admin limit exceeded */ + vlv_response_control.result = rc; + idl_free(&candidates); + candidates = idl; + break; + case LDAP_UNWILLING_TO_PERFORM: /* Too hard */ + default: return ldbm_back_search_cleanup(pb, li, sort_control, - r, NULL, -1, - &vlv_request_control, e); + rc, NULL, -1, + &vlv_request_control, e, candidates); + } + if (is_vlv_critical && rc) { + idl_free(&candidates); + candidates = idl_alloc(0); + tmp_err = rc; + tmp_desc = "VLV Response Control"; + goto vlv_bail; } } /* @@ -680,7 +747,7 @@ ldbm_back_search( Slapi_PBlock *pb ) return ldbm_back_search_cleanup(pb, li, sort_control, LDAP_PROTOCOL_ERROR, "Sort Response Control", -1, - &vlv_request_control, e); + &vlv_request_control, e, candidates); } } else @@ -714,21 +781,24 @@ ldbm_back_search( Slapi_PBlock *pb ) /* replace the hard coded return value by the appropriate * LDAP error code */ switch (sort_return_value) { - case LDAP_SUCCESS: /* Everything OK */ - vlv_response_control.result= LDAP_SUCCESS; + case LDAP_SUCCESS: + /* + * we don't want to override an error from vlv + * vlv_response_control.result= LDAP_SUCCESS; + */ break; case LDAP_PROTOCOL_ERROR: /* A protocol error */ return ldbm_back_search_cleanup(pb, li, sort_control, LDAP_PROTOCOL_ERROR, "Sort Control", -1, - &vlv_request_control, e); + &vlv_request_control, e, candidates); case LDAP_UNWILLING_TO_PERFORM: /* Too hard */ case LDAP_OPERATIONS_ERROR: /* Operation error */ case LDAP_TIMELIMIT_EXCEEDED: /* Timeout */ - vlv_response_control.result= LDAP_TIMELIMIT_EXCEEDED; - break; case LDAP_ADMINLIMIT_EXCEEDED: /* Admin limit exceeded */ - vlv_response_control.result = LDAP_ADMINLIMIT_EXCEEDED; + if (!vlv_response_control.result) { + vlv_response_control.result = sort_return_value; + } break; case LDAP_OTHER: /* Abandoned */ abandoned = 1; /* So that we don't return a result code */ @@ -747,11 +817,10 @@ ldbm_back_search( Slapi_PBlock *pb ) /* Fix for bugid #394184, SD, 05 Jul 00 */ /* we were not actually returning unavailableCriticalExtension; now fixed (hopefully !) */ - if (is_sorting_critical && (0 != sort_return_value)) - { - idl_free(candidates); + if (is_sorting_critical && sort_return_value) { + idl_free(&candidates); candidates = idl_alloc(0); - tmp_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; + tmp_err = sort_return_value; tmp_desc = "Sort Response Control"; } /* end Fix for bugid #394184 */ @@ -761,9 +830,9 @@ ldbm_back_search( Slapi_PBlock *pb ) sort_return_value, sort_error_type ) ) { return ldbm_back_search_cleanup(pb, li, sort_control, - (abandoned?-1:LDAP_PROTOCOL_ERROR), + (abandoned?LDBM_SRCH_DEFAULT_RESULT:LDAP_PROTOCOL_ERROR), "Sort Response Control", -1, - &vlv_request_control, e); + &vlv_request_control, e, candidates); } } } @@ -771,10 +840,9 @@ ldbm_back_search( Slapi_PBlock *pb ) * If we're presenting a virtual list view, then the candidate list * must be trimmed down to just the range of entries requested. */ - if (virtual_list_view) - { - if (NULL != candidates && candidates->b_nids>0) - { + if (virtual_list_view) { + if (candidates && (candidates->b_nids > 0) && + !vlv_response_control.result) { IDList *idl= NULL; back_txn txn = {NULL}; slapi_pblock_get(pb, SLAPI_TXN, &txn.back_txn_txn); @@ -783,7 +851,7 @@ ldbm_back_search( Slapi_PBlock *pb ) &vlv_request_control, &idl, &vlv_response_control, &txn); if(vlv_response_control.result==0) { - idl_free(candidates); + idl_free(&candidates); candidates = idl; } else @@ -791,26 +859,23 @@ ldbm_back_search( Slapi_PBlock *pb ) return ldbm_back_search_cleanup(pb, li, sort_control, vlv_response_control.result, NULL, -1, - &vlv_request_control, e); + &vlv_request_control, e, candidates); } - } - else - { + } else { vlv_response_control.targetPosition = 0; vlv_response_control.contentCount = 0; - vlv_response_control.result = LDAP_SUCCESS; + /* vlv_response_control.result = LDAP_SUCCESS; Don't override */ } } } - if (virtual_list_view) - { - if(LDAP_SUCCESS != - vlv_make_response_control( pb, &vlv_response_control )) - { +vlv_bail: + if (virtual_list_view) { + if (LDAP_SUCCESS != + vlv_make_response_control( pb, &vlv_response_control )) { return ldbm_back_search_cleanup(pb, li, sort_control, - (abandoned?-1:LDAP_PROTOCOL_ERROR), + (abandoned?LDBM_SRCH_DEFAULT_RESULT:LDAP_PROTOCOL_ERROR), "VLV Response Control", -1, - &vlv_request_control, e); + &vlv_request_control, e, candidates); } /* Log the VLV operation */ vlv_print_access_log(pb,&vlv_request_control,&vlv_response_control); @@ -840,7 +905,7 @@ ldbm_back_search( Slapi_PBlock *pb ) PR_Unlock(inst->inst_config_mutex); if (ri) { - idl_free(candidates); + idl_free(&candidates); candidates = idl_alloc(0); tmp_err = LDAP_UNWILLING_TO_PERFORM; tmp_desc = "Search is not indexed"; @@ -903,10 +968,10 @@ ldbm_back_search( Slapi_PBlock *pb ) } /* Fix for bugid #394184, SD, 05 Jul 00 */ - /* tmp_err == -1: no error */ + /* tmp_err == LDBM_SRCH_DEFAULT_RESULT: no error */ return ldbm_back_search_cleanup(pb, li, sort_control, tmp_err, tmp_desc, - (tmp_err == -1 ? 0 : -1), - &vlv_request_control, NULL); + (tmp_err == LDBM_SRCH_DEFAULT_RESULT ? 0 : LDBM_SRCH_DEFAULT_RESULT), + &vlv_request_control, NULL, candidates); /* end Fix for bugid #394184 */ } @@ -1167,14 +1232,14 @@ subtree_candidates( e->ep_id, &descendants, &txn, 0); idl_insert(&descendants, e->ep_id); candidates = idl_intersection(be, candidates, descendants); - idl_free(tmp); - idl_free(descendants); + idl_free(&tmp); + idl_free(&descendants); } else if (!has_tombstone_filter) { *err = ldbm_ancestorid_read_ext(be, &txn, e->ep_id, &descendants, allidslimit); idl_insert(&descendants, e->ep_id); candidates = idl_intersection(be, candidates, descendants); - idl_free(tmp); - idl_free(descendants); + idl_free(&tmp); + idl_free(&descendants); } /* else == has_tombstone_filter: do nothing */ } @@ -1802,7 +1867,7 @@ delete_search_result_set( Slapi_PBlock *pb, back_search_result_set **sr ) } if ( NULL != (*sr)->sr_candidates ) { - idl_free( (*sr)->sr_candidates ); + idl_free( &((*sr)->sr_candidates) ); } rc = slapi_filter_apply((*sr)->sr_norm_filter, ldbm_search_free_compiled_filter, NULL, &filt_errs); diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c index 51ff62b..76eea2c 100644 --- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c @@ -291,7 +291,7 @@ int add_op_attrs(Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *ep, if ( (idl = index_read( be, LDBM_ENTRYDN_STR, indextype_EQUALITY, &bv, NULL, &err )) != NULL ) { pid = idl_firstid( idl ); - idl_free( idl ); + idl_free( &idl ); } else { /* empty idl */ if ( 0 != err && DB_NOTFOUND != err ) { @@ -591,7 +591,7 @@ int update_subordinatecounts(backend *be, import_subcount_stuff *mothers, /* We get the count from the IDL */ sub_count = idl->b_nids; } - idl_free(idl); + idl_free(&idl); } /* Did we get the count ? */ if (found_count) { @@ -889,8 +889,7 @@ static IDList *ldbm_fetch_subtrees(backend *be, char **include, int *err) continue; } id = idl_firstid(idl); - idl_free(idl); - idl = NULL; + idl_free(&idl); } /* @@ -928,8 +927,8 @@ static IDList *ldbm_fetch_subtrees(backend *be, char **include, int *err) idltotal = idl; } else if (idl) { idltmp = idl_union(be, idltotal, idl); - idl_free(idltotal); - idl_free(idl); + idl_free(&idltotal); + idl_free(&idl); idltotal = idltmp; } } /* for (i = 0; include[i]; i++) */ @@ -1331,8 +1330,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb ) /* allids list is no help at all -- revert to trawling * the whole list. */ ok_index = 0; - idl_free(idl); - idl = NULL; + idl_free(&idl); } idindex = 0; } @@ -1588,7 +1586,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb ) } bye: if (idl) { - idl_free(idl); + idl_free(&idl); } if (dbc) { dbc->c_close(dbc); @@ -1619,7 +1617,7 @@ bye: } ldbm_back_free_incl_excl(include_suffix, exclude_suffix); - idl_free(eargs.pre_exported_idl); + idl_free(&(eargs.pre_exported_idl)); return( return_value ); } @@ -1933,8 +1931,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb) } } else if (ALLIDS(idl)) { /* that's no help. */ - idl_free(idl); - idl = NULL; + idl_free(&idl); } } @@ -2443,7 +2440,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb) err_out: backentry_free( &ep ); /* if ep or *ep is NULL, it does nothing */ if (idl) { - idl_free(idl); + idl_free(&idl); } else { dbc->c_close(dbc); } diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h index f3c84a1..499c92b 100644 --- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -232,7 +232,7 @@ struct backentry * id2entry( backend *be, ID id, back_txn *txn, int *err ); * idl.c */ IDList * idl_alloc( NIDS nids ); -void idl_free( IDList *idl ); +void idl_free( IDList **idl ); NIDS idl_length(IDList *idl); int idl_is_allids(IDList *idl); int idl_append(IDList *idl, ID id); diff --git a/ldap/servers/slapd/back-ldbm/seq.c b/ldap/servers/slapd/back-ldbm/seq.c index ab473bd..a947438 100644 --- a/ldap/servers/slapd/back-ldbm/seq.c +++ b/ldap/servers/slapd/back-ldbm/seq.c @@ -235,6 +235,7 @@ ldbm_back_seq( Slapi_PBlock *pb ) key.flags = 0; for (retry_count = 0; retry_count < IDL_FETCH_RETRY_COUNT; retry_count++) { err = NEW_IDL_DEFAULT; + idl_free(&idl); idl = idl_fetch( be, db, &key, NULL, ai, &err ); if(err == DB_LOCK_DEADLOCK) { ldbm_nasty("ldbm_back_seq deadlock retry", 1600, err); @@ -289,7 +290,7 @@ ldbm_back_seq( Slapi_PBlock *pb ) } CACHE_RETURN( &inst->inst_cache, &e ); } - idl_free( idl ); + idl_free( &idl ); } dblayer_release_index_file( be, ai, db ); diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c index dcc42fa..ad38889 100644 --- a/ldap/servers/slapd/back-ldbm/vlv.c +++ b/ldap/servers/slapd/back-ldbm/vlv.c @@ -1112,7 +1112,7 @@ int vlv_build_idl(PRUint32 start, PRUint32 stop, DB *db, DBC *dbc, goto done; error: - if (idl) idl_free(idl); + if (idl) idl_free(&idl); done: return rc; -- 1.8.1.4