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)
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
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;
}
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;
}
/*
{
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.
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 );
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 ) {
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 );
#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
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 ) {
}
} 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 ) {
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
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 {
}
/* 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 );
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 {
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;
}
/* 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 );
#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;
} 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 );
#endif
}
entry_sync_state = LDAP_SYNC_ADD;
+
} else {
if ( no_sync_state_change ) {
goto loop_continue;
entry_sync_state = LDAP_SYNC_PRESENT;
}
}
+
} else {
rs->sr_err = test_filter( sop,
rs->sr_entry, sop->oq_search.rs_filter );
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,
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;
}
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 ) {
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 );
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,
ps_type, 0, 0);
#endif
}
+
} else {
if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) {
if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */
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,
syncUUID_set_cnt = 0;
}
}
+
} else {
result = 1;
}
}
+
} else {
rs->sr_attrs = sop->oq_search.rs_attrs;
rs->sr_ctrls = NULL;
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,
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;
{
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;
}
}
ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
}
+
rs->sr_err = LDAP_SUCCESS;
rs->sr_rspoid = LDAP_SYNC_INFO;
rs->sr_ctrls = NULL;
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;
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;
}
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 );
}
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 );
+ }
}
}
}
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;
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
rs->sr_ctrls = ctrls;
rs->sr_err = LDAP_SUCCESS;
send_ldap_result( op, rs );
+ rs->sr_ctrls = NULL;
done:
(void) ber_free_buf( ber );
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;
}
}
nhmax *= 2;
}
- ber_dupbv( &holes[nholes].dn, &dn );
+ ber_dupbv( &holes[nholes].dn, &ndn );
holes[nholes++].id = e->e_id;
}
} else if ( !hole ) {
/* 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 {
}
/* 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;
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);
}
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 ) ) {
}
/* 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 );
#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;
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 );
#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 );
#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;
}
/* 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;
}
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;
|| 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 );
|| 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 );
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;
}
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;
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 );
struct berval vals[2];
char *replicahost;
LDAPURLDesc *ludp;
- static int lastmod = 1;
static BackendInfo *bi = NULL;
static BackendDB *be = NULL;
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
if (( sc->sc_mask & tagmask ) == tagmask ) {
/* available extension */
+ int rc;
if( !sc->sc_parse ) {
rs->sr_err = LDAP_OTHER;
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 */
rs->sr_text = "critical extension is not recognized";
goto return_results;
}
+next_ctrl:;
}
return_results:
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;
}
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 */
}
/* if paged results is requested */
- if ( get_pagedresults( op ) ) {
+ if ( get_pagedresults( op ) > SLAP_NO_CONTROL ) {
int slimit = -2;
int pr_total;
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;
#endif
#ifdef LOG_LOCAL4
-
#define DEFAULT_SYSLOG_USER LOG_LOCAL4
typedef struct _str2intDispatch {
int intVal;
} STRDISP, *STRDISP_P;
-
/* table to compute syslog-options to integer */
static STRDISP syslog_types[] = {
{ "LOCAL0", sizeof("LOCAL0"), LOG_LOCAL0 },
{ "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
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);
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;
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 );
#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;
/* 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 )
{
#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" );
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
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
#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 */
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
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;