From: Kurt Zeilenga Date: Wed, 16 Jun 2004 20:19:55 +0000 (+0000) Subject: Changes from HEAD, including X-Git-Tag: OPENLDAP_REL_ENG_2_2_14~9 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=82c1b0d1f0a27e374961c910473f549878e81e24;p=openldap Changes from HEAD, including + Fixed back-bdb ignore deadlock bug (ITS#3188) + Fixed back-bdb pagedResults no end cookie bug (ITS#3161) + Fixed back-bdb pagedResults clear controls bug (ITS#3182) + Fixed back-bdb pagedResults ignore control bug + Fixed slapd internal search limit bugs (ITS#3183) + Added slapd -l USER/DAEMON options (ITS#3187) + Build environments + Fixed back-sql trace build --- diff --git a/CHANGES b/CHANGES index badf5dce02..b7bf6c09f6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,15 @@ OpenLDAP 2.2 Change Log +OpenLDAP 2.2.14 Engineering + Fixed back-bdb ignore deadlock bug (ITS#3188) + Fixed back-bdb pagedResults no end cookie bug (ITS#3161) + Fixed back-bdb pagedResults clear controls bug (ITS#3182) + Fixed back-bdb pagedResults ignore control bug + Fixed slapd internal search limit bugs (ITS#3183) + Added slapd -l USER/DAEMON options (ITS#3187) + Build environments + Fixed back-sql trace builds + OpenLDAP 2.2.13 Release Fixed pcache CSN pending segfault (ITS#3180) Added libldap cert check extension (ITS#3134) diff --git a/build/version.var b/build/version.var index 6ff20d9df8..8e3bd80d83 100644 --- a/build/version.var +++ b/build/version.var @@ -15,7 +15,7 @@ ol_package=OpenLDAP ol_major=2 ol_minor=2 -ol_patch=13 +ol_patch=X ol_api_inc=20213 ol_api_current=7 ol_api_revision=6 diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index d6dd366165..6002a9b83d 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -290,6 +290,16 @@ bdb_cache_find_ndn( ptr = ndn->bv_val + ndn->bv_len - op->o_bd->be_nsuffix[0].bv_len; ei.bei_nrdn.bv_val = ptr; ei.bei_nrdn.bv_len = op->o_bd->be_nsuffix[0].bv_len; + /* Skip to next rdn if suffix is empty */ + if ( ei.bei_nrdn.bv_len == 0 ) { + for (ptr = ei.bei_nrdn.bv_val - 2; ptr > ndn->bv_val + && !DN_SEPARATOR(*ptr); ptr--) /* empty */; + if ( ptr >= ndn->bv_val ) { + if (DN_SEPARATOR(*ptr)) ptr++; + ei.bei_nrdn.bv_len = ei.bei_nrdn.bv_val - ptr; + ei.bei_nrdn.bv_val = ptr; + } + } eip = &bdb->bi_cache.c_dntree; } @@ -784,19 +794,20 @@ bdb_cache_modify( DB_LOCK *lock ) { EntryInfo *ei = BEI(e); - + int rc; /* Get write lock on data */ - bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock ); + rc = bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock ); /* If we've done repeated mods on a cached entry, then e_attrs * is no longer contiguous with the entry, and must be freed. */ - if ( (void *)e->e_attrs != (void *)(e+1) ) { - attrs_free( e->e_attrs ); + if ( ! rc ) { + if ( (void *)e->e_attrs != (void *)(e+1) ) { + attrs_free( e->e_attrs ); + } + e->e_attrs = newAttrs; } - e->e_attrs = newAttrs; - - return 0; + return rc; } /* @@ -814,10 +825,11 @@ bdb_cache_modrdn( { EntryInfo *ei = BEI(e), *pei; struct berval rdn; - int rc = 0; + int rc; /* Get write lock on data */ - bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock ); + rc = bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock ); + if ( rc ) return rc; /* If we've done repeated mods on a cached entry, then e_attrs * is no longer contiguous with the entry, and must be freed. @@ -900,7 +912,13 @@ bdb_cache_delete( bdb_cache_entryinfo_lock( ei ); /* Get write lock on the data */ - bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock ); + rc = bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock ); + if ( rc ) { + /* couldn't lock, undo and give up */ + ei->bei_state ^= CACHE_ENTRY_DELETED; + bdb_cache_entryinfo_unlock( ei ); + return rc; + } /* set cache write lock */ ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock ); diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 84758b89f8..cdd614bb4c 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -545,8 +545,13 @@ retry: /* transaction retry */ goto return_results; } } else { - bdb_cache_delete( &bdb->bi_cache, e, bdb->bi_dbenv, + rc = bdb_cache_delete( &bdb->bi_cache, e, bdb->bi_dbenv, locker, &lock ); + switch( rc ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { if ( ctxcsn_added ) { diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c index 19dc5d3074..528c57815f 100644 --- a/servers/slapd/back-bdb/dn2id.c +++ b/servers/slapd/back-bdb/dn2id.c @@ -630,6 +630,18 @@ hdb_dn2id_add( key.size = sizeof(ID); key.flags = DB_DBT_USERMEM; + /* Need to make dummy root node once. Subsequent attempts + * will fail harmlessly. + */ + if ( eip->bei_id == 0 ) { + diskNode dummy = {0}; + data.data = &dummy; + data.size = sizeof(diskNode); + data.flags = DB_DBT_USERMEM; + + db->put( db, txn, &key, &data, DB_NODUPDATA ); + } + #ifdef SLAP_IDL_CACHE if ( bdb->bi_idl_cache_size ) { bdb_idl_cache_del( bdb, db, &key ); @@ -1102,7 +1114,7 @@ hdb_dn2idl( #endif cx.id = e->e_id; - cx.ei = BEI(e); + cx.ei = e->e_id ? BEI(e) : &bdb->bi_cache.c_dntree; cx.bdb = bdb; cx.db = cx.bdb->bi_dn2id->bdi_db; cx.prefix = op->ors_scope == LDAP_SCOPE_ONELEVEL diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index bc3e7ab48c..c8d65d789f 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -659,7 +659,12 @@ retry: /* transaction retry */ goto return_results; } } else { - bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock ); + rc = bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock ); + switch( rc ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { if ( ctxcsn_added ) { diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index ed817dedb8..749f6571de 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -1017,8 +1017,13 @@ retry: /* transaction retry */ } } else { - bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip, + rc = bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip, bdb->bi_dbenv, locker, &lock ); + switch( rc ) { + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto retry; + } if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { if ( ctxcsn_added ) { diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index cb060ac584..552f30a108 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -37,10 +37,10 @@ static int search_candidates( ID *ids, ID *scopes ); -static void send_pagerequest_response( +static void send_paged_response( Operation *op, SlapReply *rs, - ID lastid, + ID *lastid, int tentries ); /* Dereference aliases for a single alias entry. Return the final @@ -524,7 +524,9 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, ei_root.bei_e = &e_root; ei_root.bei_parent = &ei_root; e_root.e_private = &ei_root; - e_root.e_id = 1; + e_root.e_id = 0; + e_root.e_nname.bv_val=""; + e_root.e_name.bv_val=""; ei = &ei_root; rs->sr_err = LDAP_SUCCESS; } else { @@ -736,9 +738,9 @@ dn2entry_retry: } /* if not root and candidates exceed to-be-checked entries, abort */ - if ( sop->ors_limit /* isroot == TRUE */ - && sop->ors_limit->lms_s_unchecked != -1 - && BDB_IDL_N(candidates) > (unsigned) sop->ors_limit->lms_s_unchecked ) + if ( sop->ors_limit /* isroot == TRUE */ && + sop->ors_limit->lms_s_unchecked != -1 && + BDB_IDL_N(candidates) > (unsigned) sop->ors_limit->lms_s_unchecked ) { rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; send_ldap_result( sop, rs ); @@ -746,13 +748,14 @@ dn2entry_retry: goto done; } - if ( sop->ors_limit == NULL /* isroot == FALSE */ - || !sop->ors_limit->lms_s_pr_hide ) { + if ( sop->ors_limit == NULL /* isroot == FALSE */ || + !sop->ors_limit->lms_s_pr_hide ) + { tentries = BDB_IDL_N(candidates); } - if ( get_pagedresults(sop) ) { - if ( sop->o_pagedresults_state.ps_cookie == 0 ) { + if ( get_pagedresults(sop) > SLAP_NO_CONTROL ) { + if ( (ID)( sop->o_pagedresults_state.ps_cookie ) == 0 ) { id = bdb_idl_first( candidates, &cursor ); } else { @@ -763,20 +766,25 @@ dn2entry_retry: goto done; } for ( id = bdb_idl_first( candidates, &cursor ); - id != NOID && id <= (ID)( sop->o_pagedresults_state.ps_cookie ); - id = bdb_idl_next( candidates, &cursor ) ) /* empty */; + id != NOID && + id <= (ID)( sop->o_pagedresults_state.ps_cookie ); + id = bdb_idl_next( candidates, &cursor ) ) + { + /* empty */; + } } + if ( cursor == NOID ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, RESULTS, "bdb_search: no paged results candidates\n", - 0, 0, 0 ); + 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "bdb_search: no paged results candidates\n", 0, 0, 0 ); #endif - send_pagerequest_response( sop, rs, lastid, 0 ); + send_paged_response( sop, rs, &lastid, 0 ); rs->sr_err = LDAP_OTHER; goto done; @@ -873,7 +881,9 @@ loop_begin: } /* check time limit */ - if ( sop->ors_tlimit != -1 && slap_get_time() > stoptime ) { + if ( sop->ors_tlimit != SLAP_NO_LIMIT + && slap_get_time() > stoptime ) + { rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; rs->sr_ref = rs->sr_v2ref; send_ldap_result( sop, rs ); @@ -980,7 +990,7 @@ id2entry_retry: #endif case LDAP_SCOPE_SUBTREE: { EntryInfo *tmp; - for (tmp = BEI(e); tmp->bei_parent; + for (tmp = BEI(e); tmp; tmp = tmp->bei_parent ) { if ( tmp->bei_id == base.e_id ) { scopeok = 1; @@ -1071,6 +1081,7 @@ id2entry_retry: } else { rs->sr_err = LDAP_COMPARE_TRUE; } + } else { if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) { rc_sync = test_filter( sop, rs->sr_entry, &cookief ); @@ -1089,6 +1100,7 @@ id2entry_retry: #endif } entry_sync_state = LDAP_SYNC_ADD; + } else { if ( no_sync_state_change ) { goto loop_continue; @@ -1096,6 +1108,7 @@ id2entry_retry: entry_sync_state = LDAP_SYNC_PRESENT; } } + } else { rs->sr_err = test_filter( sop, rs->sr_entry, sop->oq_search.rs_filter ); @@ -1105,7 +1118,7 @@ id2entry_retry: if ( rs->sr_err == LDAP_COMPARE_TRUE ) { /* check size limit */ if ( --sop->ors_slimit == -1 && - sop->o_sync_slog_size == -1 ) + sop->o_sync_slog_size == -1 ) { if (!IS_PSEARCH) { bdb_cache_return_entry_r( bdb->bi_dbenv, @@ -1120,10 +1133,9 @@ id2entry_retry: goto done; } - if ( get_pagedresults(sop) ) { + if ( get_pagedresults(sop) > SLAP_NO_CONTROL ) { if ( rs->sr_nentries >= sop->o_pagedresults_size ) { - send_pagerequest_response( sop, rs, - lastid, tentries ); + send_paged_response( sop, rs, &lastid, tentries ); goto done; } lastid = id; @@ -1155,6 +1167,7 @@ id2entry_retry: } if (psid_e != NULL) free (psid_e); } + if ( ps_type == LDAP_PSEARCH_BY_ADD ) { entry_sync_state = LDAP_SYNC_ADD; } else if ( ps_type == LDAP_PSEARCH_BY_DELETE ) { @@ -1171,6 +1184,7 @@ id2entry_retry: rs->sr_err = LDAP_OTHER; goto done; } + if ( sop->o_sync_slog_size != -1 ) { if ( entry_sync_state == LDAP_SYNC_DELETE ) { result = slap_add_session_log( op, sop, e ); @@ -1198,6 +1212,7 @@ id2entry_retry: ctrls[num_ctrls] = NULL; rs->sr_ctrls = NULL; } + } else if ( ps_type == LDAP_PSEARCH_BY_PREMODIFY ) { struct psid_entry* psid_e; psid_e = (struct psid_entry *) ch_calloc(1, @@ -1217,6 +1232,7 @@ id2entry_retry: ps_type, 0, 0); #endif } + } else { if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) { if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */ @@ -1233,6 +1249,7 @@ id2entry_retry: sl_free( ctrls[--num_ctrls], sop->o_tmpmemctx ); ctrls[num_ctrls] = NULL; rs->sr_ctrls = NULL; + } else { /* PRESENT */ if ( sync_send_present_mode ) { result = slap_build_syncUUID_set( sop, @@ -1259,10 +1276,12 @@ id2entry_retry: syncUUID_set_cnt = 0; } } + } else { result = 1; } } + } else { rs->sr_attrs = sop->oq_search.rs_attrs; rs->sr_ctrls = NULL; @@ -1278,15 +1297,17 @@ id2entry_retry: case 1: /* entry not sent */ break; case -1: /* connection closed */ - if (!IS_PSEARCH) - bdb_cache_return_entry_r(bdb->bi_dbenv, - &bdb->bi_cache, e, &lock); + if (!IS_PSEARCH) { + bdb_cache_return_entry_r(bdb->bi_dbenv, + &bdb->bi_cache, e, &lock); + } e = NULL; rs->sr_entry = NULL; rs->sr_err = LDAP_OTHER; goto done; } } + } else { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, RESULTS, @@ -1339,6 +1360,7 @@ nochange: rs->sr_ctrls = NULL; slap_send_syncinfo( sop, rs, LDAP_TAG_SYNC_REFRESH_PRESENT, &cookie, 1, NULL, 0 ); + } else { if ( !no_sync_state_change ) { int slog_found = 0; @@ -1348,7 +1370,8 @@ nochange: { if ( ps_list->o_sync_slog_size > 0 ) { if ( ps_list->o_sync_state.sid == - sop->o_sync_state.sid ) { + sop->o_sync_state.sid ) + { slog_found = 1; break; } @@ -1363,6 +1386,7 @@ nochange: } ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock ); } + rs->sr_err = LDAP_SUCCESS; rs->sr_rspoid = LDAP_SYNC_INFO; rs->sr_ctrls = NULL; @@ -1370,9 +1394,8 @@ nochange: LDAP_TAG_SYNC_REFRESH_DELETE, &cookie, 1, NULL, 0 ); } - if ( cookie.bv_val ) { - ch_free( cookie.bv_val ); - } + if ( cookie.bv_val ) ch_free( cookie.bv_val ); + } else { /* refreshOnly mode */ struct berval cookie; @@ -1382,6 +1405,7 @@ nochange: if ( sync_send_present_mode ) { slap_build_sync_done_ctrl( sop, rs, ctrls, num_ctrls++, 1, &cookie, LDAP_SYNC_REFRESH_PRESENTS ); + } else { if ( !no_sync_state_change ) { int slog_found = 0; @@ -1403,6 +1427,7 @@ nochange: } ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock ); } + slap_build_sync_done_ctrl( sop, rs, ctrls, num_ctrls++, 1, &cookie, LDAP_SYNC_REFRESH_DELETES ); } @@ -1421,12 +1446,17 @@ nochange: ctrls[num_ctrls] = NULL; if ( cookie.bv_val ) ch_free( cookie.bv_val ); } + } else { rs->sr_ctrls = NULL; rs->sr_ref = rs->sr_v2ref; rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL; rs->sr_rspoid = NULL; - send_ldap_result( sop, rs ); + if ( get_pagedresults(sop) > SLAP_NO_CONTROL ) { + send_paged_response( sop, rs, NULL, 0 ); + } else { + send_ldap_result( sop, rs ); + } } } @@ -1670,26 +1700,26 @@ static int search_candidates( } static void -send_pagerequest_response( +send_paged_response( Operation *op, SlapReply *rs, - ID lastid, + ID *lastid, int tentries ) { LDAPControl ctrl, *ctrls[2]; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; - struct berval cookie = BER_BVNULL; + struct berval cookie = BER_BVC( "" ); PagedResultsCookie respcookie; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ENTRY, - "send_pagerequest_response: lastid: (0x%08lx) " + "send_paged_response: lastid: (0x%08lx) " "nentries: (0x%081x)\n", - lastid, rs->sr_nentries, NULL ); + lastid ? *lastid : 0, rs->sr_nentries, NULL ); #else - Debug(LDAP_DEBUG_ARGS, "send_pagerequest_response: lastid: (0x%08lx) " - "nentries: (0x%081x)\n", lastid, rs->sr_nentries, NULL ); + Debug(LDAP_DEBUG_ARGS, "send_paged_response: lastid: (0x%08lx) " + "nentries: (0x%081x)\n", lastid ? *lastid : 0, rs->sr_nentries, NULL ); #endif ctrl.ldctl_value.bv_val = NULL; @@ -1698,11 +1728,18 @@ send_pagerequest_response( ber_init2( ber, NULL, LBER_USE_DER ); - respcookie = ( PagedResultsCookie )lastid; + if ( lastid ) { + respcookie = ( PagedResultsCookie )(*lastid); + cookie.bv_len = sizeof( respcookie ); + cookie.bv_val = (char *)&respcookie; + + } else { + respcookie = ( PagedResultsCookie )0; + } + op->o_conn->c_pagedresults_state.ps_cookie = respcookie; - op->o_conn->c_pagedresults_state.ps_count = op->o_pagedresults_state.ps_count + rs->sr_nentries; - cookie.bv_len = sizeof( respcookie ); - cookie.bv_val = (char *)&respcookie; + op->o_conn->c_pagedresults_state.ps_count = + op->o_pagedresults_state.ps_count + rs->sr_nentries; /* * FIXME: we should consider sending an estimate of the entries @@ -1720,6 +1757,7 @@ send_pagerequest_response( rs->sr_ctrls = ctrls; rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); + rs->sr_ctrls = NULL; done: (void) ber_free_buf( ber ); diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c index 226866431c..6484e4db9e 100644 --- a/servers/slapd/back-bdb/tools.c +++ b/servers/slapd/back-bdb/tools.c @@ -204,21 +204,25 @@ static int bdb_tool_next_id( int hole ) { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; - struct berval dn = e->e_nname; - struct berval pdn; + struct berval dn = e->e_name; + struct berval ndn = e->e_nname; + struct berval pdn, npdn; EntryInfo *ei = NULL; int rc; - rc = bdb_cache_find_ndn( op, tid, &dn, &ei ); + if (ndn.bv_len == 0) return 0; + + rc = bdb_cache_find_ndn( op, tid, &ndn, &ei ); if ( ei ) bdb_cache_entryinfo_unlock( ei ); if ( rc == DB_NOTFOUND ) { - if ( be_issuffix( op->o_bd, &dn ) ) { - pdn = slap_empty_bv; - } else { + if ( !be_issuffix( op->o_bd, &ndn ) ) { dnParent( &dn, &pdn ); - e->e_nname = pdn; + dnParent( &ndn, &npdn ); + e->e_name = pdn; + e->e_nname = npdn; rc = bdb_tool_next_id( op, tid, e, text, 1 ); - e->e_nname = dn; + e->e_name = dn; + e->e_nname = ndn; if ( rc ) { return rc; } @@ -259,7 +263,7 @@ static int bdb_tool_next_id( } nhmax *= 2; } - ber_dupbv( &holes[nholes].dn, &dn ); + ber_dupbv( &holes[nholes].dn, &ndn ); holes[nholes++].id = e->e_id; } } else if ( !hole ) { diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 0cabb65f62..a4d1cf4754 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -79,7 +79,7 @@ ldap_back_search( /* should we check return values? */ if (op->ors_deref != -1) ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&op->ors_deref); - if (op->ors_tlimit != -1) { + if (op->ors_tlimit != SLAP_NO_LIMIT) { tv.tv_sec = op->ors_tlimit; tv.tv_usec = 0; } else { diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index 960209ba12..c21ecdd0b5 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -231,7 +231,9 @@ searchit: } /* check time limit */ - if ( op->ors_tlimit != -1 && slap_get_time() > stoptime ) { + if ( op->ors_tlimit != SLAP_NO_LIMIT + && slap_get_time() > stoptime ) + { rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; send_ldap_result( op, rs ); rc = LDAP_SUCCESS; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 2e239e3383..a1002c92c5 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -124,11 +124,11 @@ meta_back_search( Operation *op, SlapReply *rs ) ldap_set_option( lsc->ld, LDAP_OPT_DEREF, ( void * )&op->ors_deref); } - if ( op->ors_tlimit != -1 ) { + if ( op->ors_tlimit != SLAP_NO_LIMIT ) { ldap_set_option( lsc->ld, LDAP_OPT_TIMELIMIT, ( void * )&op->ors_tlimit); } - if ( op->ors_slimit != -1 ) { + if ( op->ors_slimit != SLAP_NO_LIMIT ) { ldap_set_option( lsc->ld, LDAP_OPT_SIZELIMIT, ( void * )&op->ors_slimit); } diff --git a/servers/slapd/back-passwd/search.c b/servers/slapd/back-passwd/search.c index 4f77968719..1317459fd5 100644 --- a/servers/slapd/back-passwd/search.c +++ b/servers/slapd/back-passwd/search.c @@ -69,11 +69,9 @@ passwd_back_search( AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; - op->ors_tlimit = (op->ors_tlimit > op->o_bd->be_timelimit || op->ors_tlimit < 1) ? op->o_bd->be_timelimit - : op->ors_tlimit; - stoptime = op->o_time + op->ors_tlimit; - op->ors_slimit = (op->ors_slimit > op->o_bd->be_sizelimit || op->ors_slimit < 1) ? op->o_bd->be_sizelimit - : op->ors_slimit; + if (op->ors_tlimit != SLAP_NO_LIMIT ) { + stoptime = op->o_time + op->ors_tlimit; + } /* Handle a query for the base of this backend */ if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) { @@ -150,7 +148,9 @@ passwd_back_search( } /* check time limit */ - if ( slap_get_time() > stoptime ) { + if ( op->ors_tlimit != SLAP_NO_LIMIT + && slap_get_time() > stoptime ) + { send_ldap_error( op, rs, LDAP_TIMELIMIT_EXCEEDED, NULL ); endpwent(); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index e62948adc5..88ee4496c8 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -470,7 +470,7 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc ) #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>backsql_oc2oc(): " "searching for objectclass with name=\"%s\"\n", - objclass, 0, 0 ); + oc->soc_cname.bv_val, 0, 0 ); #endif /* BACKSQL_TRACE */ tmp.bom_oc = oc; @@ -479,7 +479,7 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc ) if ( res != NULL ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): " "found name=\"%s\", id=%d\n", - BACKSQL_OC_NAME( res ), res->id, 0 ); + BACKSQL_OC_NAME( res ), res->bom_id, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): " "not found\n", 0, 0, 0 ); @@ -497,7 +497,7 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name ) #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>oc_with_name(): " "searching for objectclass with name=\"%s\"\n", - objclass, 0, 0 ); + oc_name->bv_val, 0, 0 ); #endif /* BACKSQL_TRACE */ tmp.bom_oc = oc_bvfind( oc_name ); @@ -556,7 +556,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad ) #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): " "searching for attribute \"%s\" for objectclass \"%s\"\n", - attr, BACKSQL_OC_NAME( objclass ), 0 ); + ad->ad_cname.bv_val, BACKSQL_OC_NAME( objclass ), 0 ); #endif /* BACKSQL_TRACE */ tmp.bam_ad = ad; diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 4f91920423..c4a74dedb0 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -1462,7 +1462,9 @@ backsql_search( Operation *op, SlapReply *rs ) } /* check time limit */ - if ( op->ors_tlimit != -1 && slap_get_time() > stoptime ) { + if ( op->ors_tlimit != SLAP_NO_LIMIT + && slap_get_time() > stoptime ) + { rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; rs->sr_ctrls = NULL; rs->sr_ref = rs->sr_v2ref; @@ -1604,8 +1606,9 @@ backsql_search( Operation *op, SlapReply *rs ) } entry_free( entry ); - if ( op->ors_slimit != -1 - && rs->sr_nentries >= op->ors_slimit ) { + if ( op->ors_slimit != SLAP_NO_LIMIT + && rs->sr_nentries >= op->ors_slimit ) + { rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; send_ldap_result( op, rs ); goto end_of_search; diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c index 4523b31377..1bb975f434 100644 --- a/servers/slapd/back-sql/util.c +++ b/servers/slapd/back-sql/util.c @@ -73,7 +73,7 @@ backsql_strcat( struct berbuf *dest, ... ) || dest->bb_val.bv_len == strlen( dest->bb_val.bv_val ) ); #ifdef BACKSQL_TRACE - Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n" ); + Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n", 0, 0, 0 ); #endif /* BACKSQL_TRACE */ va_start( strs, dest ); @@ -141,7 +141,7 @@ backsql_strfcat( struct berbuf *dest, const char *fmt, ... ) || dest->bb_val.bv_len == strlen( dest->bb_val.bv_val ) ); #ifdef BACKSQL_TRACE - Debug( LDAP_DEBUG_TRACE, "==>backsql_strfcat()\n" ); + Debug( LDAP_DEBUG_TRACE, "==>backsql_strfcat()\n", 0, 0, 0 ); #endif /* BACKSQL_TRACE */ va_start( strs, fmt ); diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c index 59ea867f52..c7f10b058f 100644 --- a/servers/slapd/backglue.c +++ b/servers/slapd/backglue.c @@ -194,7 +194,9 @@ glue_back_response ( Operation *op, SlapReply *rs ) switch(rs->sr_type) { case REP_SEARCH: - if ( gs->slimit != -1 && rs->sr_nentries >= gs->slimit ) { + if ( gs->slimit != SLAP_NO_LIMIT + && rs->sr_nentries >= gs->slimit ) + { rs->sr_err = gs->err = LDAP_SIZELIMIT_EXCEEDED; return -1; } @@ -313,14 +315,14 @@ glue_back_search ( Operation *op, SlapReply *rs ) continue; if (!dnIsSuffix(&gi->n[i].be->be_nsuffix[0], &b1->be_nsuffix[0])) continue; - if (tlimit0 != -1) { + if (tlimit0 != SLAP_NO_LIMIT) { op->ors_tlimit = stoptime - slap_get_time (); if (op->ors_tlimit <= 0) { rs->sr_err = gs.err = LDAP_TIMELIMIT_EXCEEDED; break; } } - if (slimit0 != -1) { + if (slimit0 != SLAP_NO_LIMIT) { op->ors_slimit = slimit0 - rs->sr_nentries; if (op->ors_slimit < 0) { rs->sr_err = gs.err = LDAP_SIZELIMIT_EXCEEDED; @@ -347,12 +349,20 @@ glue_back_search ( Operation *op, SlapReply *rs ) op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = op->o_bd->be_search(op, rs); + } else if (scope0 == LDAP_SCOPE_SUBTREE && + dn_match(&op->o_bd->be_nsuffix[0], &ndn)) + { + rs->sr_err = op->o_bd->be_search( op, rs ); + } else if (scope0 == LDAP_SCOPE_SUBTREE && dnIsSuffix(&op->o_bd->be_nsuffix[0], &ndn)) { op->o_req_dn = op->o_bd->be_suffix[0]; op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = op->o_bd->be_search( op, rs ); + if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) { + gs.err = LDAP_SUCCESS; + } } else if (dnIsSuffix(&ndn, &op->o_bd->be_nsuffix[0])) { rs->sr_err = op->o_bd->be_search( op, rs ); diff --git a/servers/slapd/config.c b/servers/slapd/config.c index df929414f4..9fa278a724 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -118,7 +118,6 @@ read_config( const char *fname, int depth ) struct berval vals[2]; char *replicahost; LDAPURLDesc *ludp; - static int lastmod = 1; static BackendInfo *bi = NULL; static BackendDB *be = NULL; @@ -2183,18 +2182,36 @@ read_config( const char *fname, int depth ) return( 1 ); } + + if ( be == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, "%s: line %d: lastmod" + " line must appear inside a database definition\n", + fname, lineno , 0 ); +#else + Debug( LDAP_DEBUG_ANY, "%s: line %d: lastmod" + " line must appear inside a database definition\n", + fname, lineno, 0 ); +#endif + return 1; + + } else if ( SLAP_NOLASTMODCMD(be) ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, "%s: line %d: lastmod" + " not available for %s database\n", + fname, lineno , be->bd_info->bi_type ); +#else + Debug( LDAP_DEBUG_ANY, "%s: line %d: lastmod" + " not available for %s databases\n", + fname, lineno, be->bd_info->bi_type ); +#endif + return 1; + } + if ( strcasecmp( cargv[1], "on" ) == 0 ) { - if ( be ) { - SLAP_DBFLAGS(be) &= ~SLAP_DBFLAG_NOLASTMOD; - } else { - lastmod = 1; - } + SLAP_DBFLAGS(be) &= ~SLAP_DBFLAG_NOLASTMOD; } else { - if ( be ) { - SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NOLASTMOD; - } else { - lastmod = 0; - } + SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NOLASTMOD; } #ifdef SIGHUP diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 3d428b03f0..341d7ab962 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -598,6 +598,7 @@ int get_ctrls( if (( sc->sc_mask & tagmask ) == tagmask ) { /* available extension */ + int rc; if( !sc->sc_parse ) { rs->sr_err = LDAP_OTHER; @@ -605,9 +606,12 @@ int get_ctrls( goto return_results; } - rs->sr_err = sc->sc_parse( op, rs, c ); - assert( rs->sr_err != LDAP_UNAVAILABLE_CRITICAL_EXTENSION ); - if( rs->sr_err != LDAP_SUCCESS ) goto return_results; + rc = sc->sc_parse( op, rs, c ); + assert( rc != LDAP_UNAVAILABLE_CRITICAL_EXTENSION ); + if ( rc ) { + rs->sr_err = rc; + goto return_results; + } if ( sc->sc_mask & SLAP_CTRL_FRONTEND ) { /* kludge to disable backend_control() check */ @@ -633,6 +637,7 @@ int get_ctrls( rs->sr_text = "critical extension is not recognized"; goto return_results; } +next_ctrl:; } return_results: @@ -915,9 +920,24 @@ static int parsePagedResults ( op->o_pagedresults_size = size; - op->o_pagedresults = ctrl->ldctl_iscritical - ? SLAP_CRITICAL_CONTROL - : SLAP_NONCRITICAL_CONTROL; + /* NOTE: according to RFC 2696 3.: + + If the page size is greater than or equal to the sizeLimit value, the + server should ignore the control as the request can be satisfied in a + single page. + + * NOTE: this assumes that the op->ors_slimit be set + * before the controls are parsed. + */ + if ( op->ors_slimit > 0 && size >= op->ors_slimit ) { + op->o_pagedresults = SLAP_IGNORED_CONTROL; + + } else if ( ctrl->ldctl_iscritical ) { + op->o_pagedresults = SLAP_CRITICAL_CONTROL; + + } else { + op->o_pagedresults = SLAP_NONCRITICAL_CONTROL; + } return LDAP_SUCCESS; } diff --git a/servers/slapd/limits.c b/servers/slapd/limits.c index 55fce61705..b32ea0be77 100644 --- a/servers/slapd/limits.c +++ b/servers/slapd/limits.c @@ -1001,11 +1001,11 @@ limits_check( Operation *op, SlapReply *rs ) op->ors_limit = NULL; if ( op->ors_tlimit == 0 ) { - op->ors_tlimit = -1; + op->ors_tlimit = SLAP_NO_LIMIT; } if ( op->ors_slimit == 0 ) { - op->ors_slimit = -1; + op->ors_slimit = SLAP_NO_LIMIT; } /* if not root, get appropriate limits */ @@ -1048,7 +1048,7 @@ limits_check( Operation *op, SlapReply *rs ) } /* if paged results is requested */ - if ( get_pagedresults( op ) ) { + if ( get_pagedresults( op ) > SLAP_NO_CONTROL ) { int slimit = -2; int pr_total; @@ -1084,7 +1084,7 @@ limits_check( Operation *op, SlapReply *rs ) if ( pr_total == -1 ) { slimit = -1; - } else if ( pr_total > 0 && ( op->ors_slimit == -1 || op->ors_slimit > pr_total ) ) { + } else if ( pr_total > 0 && ( op->ors_slimit == SLAP_NO_LIMIT || op->ors_slimit > pr_total ) ) { rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; send_ldap_result( op, rs ); rs->sr_err = LDAP_SUCCESS; diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 417104ecd3..2e7230c8fc 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -91,7 +91,6 @@ const char Versionstr[] = #endif #ifdef LOG_LOCAL4 - #define DEFAULT_SYSLOG_USER LOG_LOCAL4 typedef struct _str2intDispatch { @@ -100,7 +99,6 @@ typedef struct _str2intDispatch { int intVal; } STRDISP, *STRDISP_P; - /* table to compute syslog-options to integer */ static STRDISP syslog_types[] = { { "LOCAL0", sizeof("LOCAL0"), LOG_LOCAL0 }, @@ -111,11 +109,16 @@ static STRDISP syslog_types[] = { { "LOCAL5", sizeof("LOCAL5"), LOG_LOCAL5 }, { "LOCAL6", sizeof("LOCAL6"), LOG_LOCAL6 }, { "LOCAL7", sizeof("LOCAL7"), LOG_LOCAL7 }, +#ifdef LOG_USER + { "USER", sizeof("USER"), LOG_USER }, +#endif +#ifdef LOG_DAEMON + { "DAEMON", sizeof("DAEMON"), LOG_DAEMON }, +#endif { NULL, 0, 0 } }; -static int cnvt_str2int( char *, STRDISP_P, int ); - +static int cnvt_str2int( char *, STRDISP_P, int ); #endif /* LOG_LOCAL4 */ #define CHECK_NONE 0x00 diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index 5a88e95b2f..4567c93369 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -869,8 +869,8 @@ remove_query_data ( op->o_req_ndn = op->o_bd->be_nsuffix[0]; op->ors_scope = LDAP_SCOPE_SUBTREE; op->ors_deref = LDAP_DEREF_NEVER; - op->ors_slimit = -1; - op->ors_tlimit = -1; + op->ors_slimit = SLAP_NO_LIMIT; + op->ors_tlimit = SLAP_NO_LIMIT; op->ors_filter = &filter; op->ors_filterstr.bv_val = filter_str; op->ors_filterstr.bv_len = strlen(filter_str); diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 0599628d7d..388f90231d 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -483,6 +483,7 @@ slap_auxprop_lookup( op.o_req_dn = op.o_req_ndn; op.ors_scope = LDAP_SCOPE_BASE; op.ors_deref = LDAP_DEREF_NEVER; + op.ors_tlimit = SLAP_NO_LIMIT; op.ors_slimit = 1; op.ors_filter = &generic_filter; op.ors_filterstr = generic_filterstr; diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index dca9a0eb15..2b59052bd3 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -751,7 +751,7 @@ exact_match: op.o_connid = opx->o_connid; op.o_req_dn = op.o_req_ndn; op.oq_search.rs_slimit = 1; - op.oq_search.rs_tlimit = -1; + op.oq_search.rs_tlimit = SLAP_NO_LIMIT; op.o_sync_slog_size = -1; op.o_bd->be_search( &op, &rs ); @@ -943,7 +943,7 @@ void slap_sasl2dn( Operation *opx, #endif op.oq_search.rs_deref = LDAP_DEREF_NEVER; op.oq_search.rs_slimit = 1; - op.oq_search.rs_tlimit = -1; + op.oq_search.rs_tlimit = SLAP_NO_LIMIT; op.oq_search.rs_attrsonly = 1; op.o_req_dn = op.o_req_ndn; diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 4f8bd63c68..7a26363f5c 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1984,11 +1984,14 @@ integerBitOrMatch( /* safe to assume integers are NUL terminated? */ lValue = SLAP_STRTOL(value->bv_val, NULL, 10); - if(( lValue == SLAP_LONG_MIN || lValue == SLAP_LONG_MAX ) && errno == ERANGE ) { + if(( lValue == SLAP_LONG_MIN || lValue == SLAP_LONG_MAX ) && + errno == ERANGE ) + { return LDAP_CONSTRAINT_VIOLATION; } - lAssertedValue = SLAP_STRTOL(((struct berval *)assertedValue)->bv_val, NULL, 10); + lAssertedValue = SLAP_STRTOL( ((struct berval *)assertedValue)->bv_val, + NULL, 10); if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX ) && errno == ERANGE ) { diff --git a/servers/slapd/search.c b/servers/slapd/search.c index b920643a19..c35ef511a2 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -396,8 +396,12 @@ do_search( #endif /* LDAP_SLAPI */ /* actually do the search and send the result(s) */ - if ( op->o_bd->be_search && limits_check( op, rs ) == 0 ) { - (op->o_bd->be_search)( op, rs ); + if ( op->o_bd->be_search ) { + if ( limits_check( op, rs ) == 0 ) { + (op->o_bd->be_search)( op, rs ); + } + /* else limits_check() sends error */ + } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not supported within namingContext" ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 0ceb96e1d9..657cc146a6 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1300,6 +1300,9 @@ struct slap_limits_set { int lms_s_pr_total; }; +/* Note: this is different from LDAP_NO_LIMIT (0); slapd internal use only */ +#define SLAP_NO_LIMIT -1 + struct slap_limits { unsigned lm_flags; /* type of pattern */ #define SLAP_LIMITS_UNDEFINED 0x0000U @@ -1836,6 +1839,7 @@ struct slap_backend_info { slap_mask_t bi_flags; /* backend flags */ #define SLAP_BFLAG_MONITOR 0x0001U /* a monitor backend */ +#define SLAP_BFLAG_NOLASTMODCMD 0x0010U #define SLAP_BFLAG_INCREMENT 0x0100U #define SLAP_BFLAG_ALIASES 0x1000U #define SLAP_BFLAG_REFERRALS 0x2000U @@ -1849,6 +1853,8 @@ struct slap_backend_info { #define SLAP_REFERRALS(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_REFERRALS) #define SLAP_SUBENTRIES(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_SUBENTRIES) #define SLAP_DYNAMIC(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_DYNAMIC) +#define SLAP_NOLASTMODCMD(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_NOLASTMODCMD) +#define SLAP_LASTMODCMD(be) (!SLAP_NOLASTMODCMD(be)) char **bi_controls; /* supported controls */ @@ -2046,6 +2052,7 @@ typedef struct slap_op { char o_do_not_cache; /* don't cache groups from this op */ char o_is_auth_check; /* authorization in progress */ +#define SLAP_IGNORED_CONTROL -1 #define SLAP_NO_CONTROL 0 #define SLAP_NONCRITICAL_CONTROL 1 #define SLAP_CRITICAL_CONTROL 2 diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c index c001f0bbc3..3bf62449c4 100644 --- a/servers/slapd/slapi/slapi_ops.c +++ b/servers/slapd/slapi/slapi_ops.c @@ -1218,8 +1218,8 @@ slapi_search_internal( op->oq_search.rs_scope = scope; op->oq_search.rs_deref = 0; - op->oq_search.rs_slimit = LDAP_NO_LIMIT; - op->oq_search.rs_tlimit = LDAP_NO_LIMIT; + op->oq_search.rs_slimit = SLAP_NO_LIMIT; + op->oq_search.rs_tlimit = SLAP_NO_LIMIT; op->oq_search.rs_attrsonly = attrsonly; op->oq_search.rs_attrs = an; op->oq_search.rs_filter = filter;