Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
#endif
send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
- return -1;
+ return SLAPD_DISCONNECT;
}
e = (Entry *) ch_calloc( 1, sizeof(Entry) );
if ( rtag == LBER_ERROR ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
- "do_add: conn %d decoding error \n", op->o_connid, 0, 0 );
+ "do_add: conn %d decoding error \n", op->o_connid, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY, "do_add: decoding error\n", 0, 0, 0 );
#endif
send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
- rs->sr_err = -1;
+ rs->sr_err = SLAPD_DISCONNECT;
goto done;
}
Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
#endif
send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
- rs->sr_err = -1;
+ rs->sr_err = SLAPD_DISCONNECT;
goto done;
}
#endif /* LDAP_SLAPI */
done:
-
slap_graduate_commit_csn( op );
if( modlist != NULL ) {
Entry *ctxcsn_e;
int ctxcsn_added = 0;
+ LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
op->oq_add.rs_e->e_name.bv_val, 0, 0);
#endif
+ ctrls[num_ctrls] = 0;
+
/* check entry's schema */
rs->sr_err = entry_schema_check( op->o_bd, op->oq_add.rs_e,
NULL, &rs->sr_text, textbuf, textlen );
goto return_results;;
}
- /* post-read */
- if( op->o_postread ) {
- if ( slap_read_controls( op, rs, op->oq_add.rs_e,
- &slap_post_read_bv, &ctrls[num_ctrls] ) )
- {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, DETAIL1,
- "<=- bdb_add: post-read failed!\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "<=- bdb_add: post-read failed!\n", 0, 0, 0 );
-#endif
- goto return_results;
- }
- ctrls[++num_ctrls] = NULL;
- }
-
/* nested transaction */
rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2,
bdb->bi_db_opflags );
}
}
+ /* post-read */
+ if( op->o_postread ) {
+ if( postread_ctrl == NULL ) {
+ postread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
+ if ( slap_read_controls( op, rs, op->oq_add.rs_e,
+ &slap_post_read_bv, postread_ctrl ) )
+ {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, DETAIL1,
+ "<=- bdb_add: post-read failed!\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "<=- bdb_add: post-read failed!\n", 0, 0, 0 );
+#endif
+ goto return_results;
+ }
+ }
+
if ( op->o_noop ) {
if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
}
if ( rs->sr_err == LDAP_SUCCESS && !op->o_no_psearch ) {
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
assert( BEI(e) );
LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch( op, rs, ps_list, e,
- LDAP_PSEARCH_BY_ADD );
+ rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_ADD );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_add: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_add: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
op->o_private = NULL;
}
+ if( postread_ctrl != NULL ) {
+ slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *postread_ctrl, &op->o_tmpmemctx );
+ }
return rs->sr_err;
}
struct bdb_entry_info *bei_parent;
ID bei_id;
- int bei_state;
+ /* we use the bei_id as a lockobj, but we need to make the size != 4
+ * to avoid conflicting with BDB's internal locks. So add a byte here
+ * that is always zero.
+ */
+ char bei_lockpad;
+
+ short bei_state;
#define CACHE_ENTRY_DELETED 1
#define CACHE_ENTRY_NO_KIDS 2
#define CACHE_ENTRY_NOT_LINKED 4
EntryInfo *c_lrutail; /* lru - rem lru entries from here */
ldap_pvt_thread_rdwr_t c_rwlock;
ldap_pvt_thread_mutex_t lru_mutex;
+ u_int32_t c_locker; /* used by lru cleaner */
} Cache;
#define CACHE_READ_LOCK 0
if ( !lock ) return 0;
- lockobj.data = ei;
- lockobj.size = sizeof(ei->bei_parent) + sizeof(ei->bei_id);
+ lockobj.data = &ei->bei_id;
+ lockobj.size = sizeof(ei->bei_id) + 1;
list[0].op = DB_LOCK_PUT;
list[0].lock = *lock;
else
db_rw = DB_LOCK_READ;
- lockobj.data = ei;
- lockobj.size = sizeof(ei->bei_parent) + sizeof(ei->bei_id);
+ lockobj.data = &ei->bei_id;
+ lockobj.size = sizeof(ei->bei_id) + 1;
rc = LOCK_GET(env, locker, tryOnly ? DB_LOCK_NOWAIT : 0,
&lockobj, db_rw, lock);
/* If we can successfully writelock it, then
* the object is idle.
*/
- if ( bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, elru, 1, 1,
+ if ( bdb_cache_entry_db_lock( bdb->bi_dbenv, bdb->bi_cache.c_locker, elru, 1, 1,
lockp ) == 0 ) {
/* If there's no entry, or this node is in
* the process of linking into the cache,
if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
rc = DB_NOTFOUND;
} else {
- bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, *eip, 0, 0, lock );
- if ( !(*eip)->bei_e ) {
- if (!ep) {
- rc = bdb_id2entry( op->o_bd, tid, id, &ep );
- }
- if ( rc == 0 ) {
- bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
- *eip, 1, 0, lock );
- /* Make sure no other modifier beat us to it */
- if ( (*eip)->bei_e ) {
- bdb_entry_return( ep );
- ep = NULL;
- } else {
- ep->e_private = *eip;
+ rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, *eip, 0, 0, lock );
+ /* entry is protected now, we don't need to hold the entryinfo */
+ if ( islocked ) {
+ bdb_cache_entryinfo_unlock( *eip );
+ islocked = 0;
+ }
+ if ( rc == 0 ) {
+ if ( !(*eip)->bei_e ) {
+ if (!ep) {
+ rc = bdb_id2entry( op->o_bd, tid, id, &ep );
+ }
+ if ( rc == 0 ) {
+ bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
+ *eip, 1, 0, lock );
+ /* Make sure no other modifier beat us to it */
+ if ( (*eip)->bei_e ) {
+ bdb_entry_return( ep );
+ ep = NULL;
+ } else {
+ ep->e_private = *eip;
#ifdef BDB_HIER
- bdb_fix_dn( ep, 0 );
+ bdb_fix_dn( ep, 0 );
#endif
- (*eip)->bei_e = ep;
+ (*eip)->bei_e = ep;
+ }
+ bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
+ *eip, 0, 0, lock );
}
- bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
- *eip, 0, 0, lock );
- }
- } else {
- /* If we had the entry already, this item
- * is on the LRU list.
- */
- lru_del = 1;
+ } else {
+ /* If we had the entry already, this item
+ * is on the LRU list.
+ */
+ lru_del = 1;
#ifdef BDB_HIER
- rc = bdb_fix_dn( (*eip)->bei_e, 1 );
- if ( rc ) {
- bdb_cache_entry_db_relock( bdb->bi_dbenv,
- locker, *eip, 1, 0, lock );
- /* check again in case other modifier did it already */
- if ( bdb_fix_dn( (*eip)->bei_e, 1 ) )
- rc = bdb_fix_dn( (*eip)->bei_e, 2 );
- bdb_cache_entry_db_relock( bdb->bi_dbenv,
- locker, *eip, 0, 0, lock );
- }
+ rc = bdb_fix_dn( (*eip)->bei_e, 1 );
+ if ( rc ) {
+ bdb_cache_entry_db_relock( bdb->bi_dbenv,
+ locker, *eip, 1, 0, lock );
+ /* check again in case other modifier did it already */
+ if ( bdb_fix_dn( (*eip)->bei_e, 1 ) )
+ rc = bdb_fix_dn( (*eip)->bei_e, 2 );
+ bdb_cache_entry_db_relock( bdb->bi_dbenv,
+ locker, *eip, 0, 0, lock );
+ }
#endif
+ }
+
}
}
}
{
EntryInfo *new, ei;
struct berval rdn = e->e_name;
+ DB_LOCK lock;
int rc;
ei.bei_id = e->e_id;
ei.bei_parent = eip;
ei.bei_nrdn = *nrdn;
+ ei.bei_lockpad = 0;
+
+ /* Lock this entry so that bdb_add can run to completion.
+ * It can only fail if BDB has run out of lock resources.
+ */
+ rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, &ei, 1, 0, &lock );
+ if ( rc ) {
+ bdb_cache_entryinfo_unlock( eip );
+ return rc;
+ }
+
#ifdef BDB_HIER
if ( nrdn->bv_len != e->e_nname.bv_len ) {
char *ptr = strchr( rdn.bv_val, ',' );
DB_LOCK *lock )
{
ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
- if ( bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, ei, 1, 1, lock ) == 0 )
+ if ( bdb_cache_entry_db_lock( bdb->bi_dbenv, bdb->bi_cache.c_locker, ei, 1, 1, lock ) == 0 )
{
if ( ei->bei_e && !(ei->bei_state & CACHE_ENTRY_NOT_LINKED )) {
LRU_DELETE( &bdb->bi_cache, ei );
int rc;
struct sync_cookie syncCookie = { NULL, -1, NULL};
syncinfo_t *si;
+ u_int32_t ctxcsn_locker = 0;
if ( op->o_sync_mode != SLAP_SYNC_NONE &&
!LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
}
break;
case LDAP_BUSY:
- ch_free( ctxcsn_ndn.bv_val );
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
- return LDAP_BUSY;
+ goto done;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto consumer_ctxcsn_retry;
case DB_NOTFOUND:
- ch_free( ctxcsn_ndn.bv_val );
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
- return LDAP_OTHER;
+ rs->sr_err = LDAP_OTHER;
+ goto done;
default:
- ch_free( ctxcsn_ndn.bv_val );
- ctxcsn_ndn.bv_val = NULL;
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
- return LDAP_OTHER;
+ rs->sr_err = LDAP_OTHER;
+ goto done;
}
if ( ctxcsn_e ) {
0, locker, ctxcsn_lock );
switch(rs->sr_err) {
case 0:
- ch_free( ctxcsn_ndn.bv_val );
if ( ctxcsn_ei ) {
ctxcsn_e = ctxcsn_ei->bei_e;
}
break;
case LDAP_BUSY:
- ch_free( ctxcsn_ndn.bv_val );
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
- return LDAP_BUSY;
+ goto done;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto provider_ctxcsn_retry;
if ( 0 ) {
txn_retry:
rs->sr_err = TXN_ABORT( ltid );
+ ltid = NULL;
if ( rs->sr_err != 0 ) {
rs->sr_err = LDAP_OTHER;
- return rs->sr_err;
+ goto done;
}
ldap_pvt_thread_yield();
bdb_trans_backoff( ++num_retries );
<id, bdb->bi_db_opflags );
if ( rs->sr_err != 0 ) {
rs->sr_err = LDAP_OTHER;
- return rs->sr_err;
+ goto done;
}
+ ctxcsn_locker = TXN_ID ( ltid );
+
rs->sr_err = bdb_csn_commit( op, rs, ltid, NULL, &suffix_ei,
- &ctxcsn_e, &ctxcsn_added, locker );
+ &ctxcsn_e, &ctxcsn_added, ctxcsn_locker );
switch( rs->sr_err ) {
case BDB_CSN_ABORT:
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
- return LDAP_OTHER;
+ rs->sr_err = LDAP_OTHER;
+ goto done;
case BDB_CSN_RETRY:
goto txn_retry;
}
rs->sr_err = TXN_PREPARE( ltid, gid );
if ( rs->sr_err != 0 ) {
rs->sr_err = LDAP_OTHER;
- return rs->sr_err;
+ goto done;
}
bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
- (struct berval *)&slap_ldapsync_cn_bv, locker );
+ (struct berval *)&slap_ldapsync_cn_bv, ctxcsn_locker );
rs->sr_err = TXN_COMMIT( ltid, 0 );
if ( rs->sr_err != 0 ) {
rs->sr_err = LDAP_OTHER;
- return rs->sr_err;
+ goto done;
}
rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
- 0, locker, ctxcsn_lock );
+ 0, ctxcsn_locker, ctxcsn_lock );
ch_free( ctxcsn_ndn.bv_val );
+ ctxcsn_ndn.bv_val = NULL;
if ( ctxcsn_ei ) {
ctxcsn_e = ctxcsn_ei->bei_e;
break;
default:
- ch_free( ctxcsn_ndn.bv_val );
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
- return LDAP_OTHER;
+ rs->sr_err = LDAP_OTHER;
+ goto done;
}
if ( ctxcsn_e ) {
}
}
- return LDAP_SUCCESS;
+ ltid = NULL;
+ rs->sr_err = LDAP_SUCCESS;
+
+done:
+ if( ltid != NULL ) {
+ TXN_ABORT( ltid );
+ }
+
+ if ( ctxcsn_ndn.bv_val != NULL )
+ ch_free( ctxcsn_ndn.bv_val );
+
+ return rs->sr_err;
}
Entry *ctxcsn_e;
int ctxcsn_added = 0;
+ LDAPControl **preread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
int parent_is_glue = 0;
int parent_is_leaf = 0;
+ ctrls[num_ctrls] = 0;
+
#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, ARGS, "==> bdb_delete: %s\n", op->o_req_dn.bv_val, 0, 0 );
+ LDAP_LOG ( OPERATION, ARGS, "==> bdb_delete: %s\n",
+ op->o_req_dn.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_ARGS, "==> bdb_delete: %s\n",
op->o_req_dn.bv_val, 0, 0 );
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
e = NULL;
}
+ if( p != NULL ) {
+ bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
+ p = NULL;
+ }
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1,
"==> bdb_delete: retrying...\n", 0, 0, 0 );
goto done;
}
- bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, locker, &plock );
+ rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, locker, &plock );
+ switch( rc ) {
+ case DB_LOCK_DEADLOCK:
+ case DB_LOCK_NOTGRANTED:
+ goto retry;
+ case 0:
+ case DB_NOTFOUND:
+ break;
+ default:
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
if ( eip ) p = eip->bei_e;
if ( pdn.bv_len != 0 ) {
rs->sr_err = access_allowed( op, p,
children, NULL, ACL_WRITE, NULL );
- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
- p = NULL;
-
if ( !rs->sr_err ) {
switch( opinfo.boi_err ) {
case DB_LOCK_DEADLOCK:
/* pre-read */
if( op->o_preread ) {
+ if( preread_ctrl == NULL ) {
+ preread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
if( slap_read_controls( op, rs, e,
- &slap_pre_read_bv, &ctrls[num_ctrls] ) )
+ &slap_pre_read_bv, preread_ctrl ) )
{
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1,
#endif
goto return_results;
}
- ctrls[++num_ctrls] = NULL;
}
/* nested transaction */
goto return_results;
}
- bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock );
- if ( eip ) p = eip->bei_e;
if ( pdn.bv_len != 0 ) {
parent_is_glue = is_entry_glue(p);
rs->sr_err = bdb_cache_children( op, lt2, p );
}
if ( rs->sr_err == LDAP_SUCCESS && !op->o_no_psearch ) {
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_DELETE );
+ rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_DELETE );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_delete: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_delete: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
rs->sr_err = TXN_COMMIT( ltid, 0 );
}
done:
+ if ( p )
+ bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
+
/* free entry */
if( e != NULL ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
op->o_private = NULL;
}
+ if( preread_ctrl != NULL ) {
+ slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *preread_ctrl, &op->o_tmpmemctx );
+ }
return rs->sr_err;
}
DB_LOCK *lock )
{
EntryInfo *ei = NULL;
- int rc;
+ int rc, rc2;
#ifdef NEW_LOGGING
LDAP_LOG ( CACHE, ARGS, "bdb_dn2entry(\"%s\")\n", dn->bv_val, 0, 0 );
* or not.
*/
*e = ei;
- if ( ei && ei->bei_id )
- bdb_cache_find_id( op, tid, ei->bei_id,
+ if ( ei && ei->bei_id ) {
+ rc2 = bdb_cache_find_id( op, tid, ei->bei_id,
&ei, 1, locker, lock );
- else if ( ei )
+ if ( rc2 ) rc = rc2;
+ } else if ( ei )
bdb_cache_entryinfo_unlock( ei );
} else if ( ei ) {
bdb_cache_entryinfo_unlock( ei );
} else if ( matched && rc == DB_NOTFOUND ) {
/* always return EntryInfo */
ei = ei->bei_parent;
- bdb_cache_find_id( op, tid, ei->bei_id, &ei, 1,
+ rc2 = bdb_cache_find_id( op, tid, ei->bei_id, &ei, 1,
locker, lock );
+ if ( rc2 ) rc = rc2;
*e = ei;
}
}
return rc;
}
+ bdb->bi_dbenv->lock_id(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
+
/* <insert> open (and create) index databases */
return 0;
}
break;
case LDAP_MOD_DELETE:
- if ( glue_attr_delete )
+ if ( glue_attr_delete ) {
+ err = LDAP_SUCCESS;
break;
+ }
+
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1,
"bdb_modify_internal: delete\n", 0, 0, 0 );
int num_retries = 0;
+ LDAPControl **preread_ctrl = NULL;
+ LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
int ctxcsn_added = 0;
#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, ENTRY, "bdb_modify: %s\n", op->o_req_dn.bv_val, 0, 0 );
+ LDAP_LOG ( OPERATION, ENTRY, "bdb_modify: %s\n",
+ op->o_req_dn.bv_val, 0, 0 );
#else
- Debug( LDAP_DEBUG_ARGS, "bdb_modify: %s\n", op->o_req_dn.bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_ARGS, "bdb_modify: %s\n",
+ op->o_req_dn.bv_val, 0, 0 );
#endif
+ ctrls[num_ctrls] = NULL;
+
if( 0 ) {
retry: /* transaction retry */
if( e != NULL ) {
e = ei->bei_e;
/* acquire and lock entry */
/* FIXME: dn2entry() should return non-glue entry */
- if (( rs->sr_err == DB_NOTFOUND ) || ( !manageDSAit && e && is_entry_glue( e ))) {
+ if (( rs->sr_err == DB_NOTFOUND ) ||
+ ( !manageDSAit && e && is_entry_glue( e )))
+ {
if ( e != NULL ) {
rs->sr_matched = ch_strdup( e->e_dn );
rs->sr_ref = is_entry_referral( e )
rs->sr_ref = get_entry_referrals( op, e );
#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, DETAIL1, "bdb_modify: entry is referral\n", 0, 0, 0 );
+ LDAP_LOG ( OPERATION, DETAIL1,
+ "bdb_modify: entry is referral\n",
+ 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"bdb_modify: entry is referral\n",
}
if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch(op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
+ rc = bdb_psearch(op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modify: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modify: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
if( op->o_preread ) {
+ if( preread_ctrl == NULL ) {
+ preread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
if ( slap_read_controls( op, rs, e,
- &slap_pre_read_bv, &ctrls[num_ctrls] ) )
+ &slap_pre_read_bv, preread_ctrl ) )
{
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1,
#endif
goto return_results;
}
- ctrls[++num_ctrls] = NULL;
- op->o_preread = 0; /* prevent redo on retry */
}
/* nested transaction */
if( rs->sr_err != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
- "bdb_modify: txn_begin(2) failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
+ "bdb_modify: txn_begin(2) failed: %s (%d)\n",
+ db_strerror(rs->sr_err), rs->sr_err, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"bdb_modify: txn_begin(2) failed: %s (%d)\n",
switch( rs->sr_err ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
+ attrs_free( dummy.e_attrs );
+ dummy.e_attrs = NULL;
goto retry;
}
goto return_results;
}
- if( op->o_postread ) {
- if( slap_read_controls( op, rs, e,
- &slap_post_read_bv, &ctrls[num_ctrls] ) )
- {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, DETAIL1,
- "<=- bdb_modify: post-read failed!\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "<=- bdb_modify: post-read failed!\n", 0, 0, 0 );
-#endif
- goto return_results;
- }
- ctrls[++num_ctrls] = NULL;
- op->o_postread = 0; /* prevent redo on retry */
- /* FIXME: should read entry on the last retry */
- }
-
/* change the entry itself */
rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy );
if ( rs->sr_err != 0 ) {
switch( rs->sr_err ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
+ attrs_free( dummy.e_attrs );
+ dummy.e_attrs = NULL;
goto retry;
}
rs->sr_text = "entry update failed";
case BDB_CSN_ABORT :
goto return_results;
case BDB_CSN_RETRY :
+ attrs_free( dummy.e_attrs );
+ dummy.e_attrs = NULL;
goto retry;
}
}
+ if( op->o_postread ) {
+ if( postread_ctrl == NULL ) {
+ postread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
+ if( slap_read_controls( op, rs, e,
+ &slap_post_read_bv, postread_ctrl ) )
+ {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, DETAIL1,
+ "<=- bdb_modify: post-read failed!\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "<=- bdb_modify: post-read failed!\n", 0, 0, 0 );
+#endif
+ goto return_results;
+ }
+ }
+
if( op->o_noop ) {
if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
switch( rc ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
+ attrs_free( dummy.e_attrs );
+ dummy.e_attrs = NULL;
goto retry;
}
if ( rs->sr_err == LDAP_SUCCESS ) {
/* Loop through in-scope entries for each psearch spec */
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+ rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modify: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modify: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
while ( pm_list != NULL ) {
- bdb_psearch(op, rs, pm_list->ps_op,
+ rc = bdb_psearch(op, rs, pm_list->ps_op,
e, LDAP_PSEARCH_BY_SCOPEOUT);
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modify: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modify: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
LDAP_LIST_REMOVE ( pm_list, ps_link );
pm_prev = pm_list;
pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
ch_free( pm_prev );
}
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
rs->sr_err = TXN_COMMIT( ltid, 0 );
if( e != NULL ) {
bdb_unlocked_cache_return_entry_w (&bdb->bi_cache, e);
}
+
+ if( preread_ctrl != NULL ) {
+ slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *preread_ctrl, &op->o_tmpmemctx );
+ }
+ if( postread_ctrl != NULL ) {
+ slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *postread_ctrl, &op->o_tmpmemctx );
+ }
return rs->sr_err;
}
int num_retries = 0;
+ LDAPControl **preread_ctrl = NULL;
+ LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
int parent_is_glue = 0;
int parent_is_leaf = 0;
+ ctrls[num_ctrls] = NULL;
+
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "==>bdb_modrdn(%s,%s,%s)\n",
op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
}
if( op->o_preread ) {
+ if( preread_ctrl == NULL ) {
+ preread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
if( slap_read_controls( op, rs, e,
- &slap_pre_read_bv, &ctrls[num_ctrls] ) )
+ &slap_pre_read_bv, preread_ctrl ) )
{
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1,
#endif
goto return_results;
}
- ctrls[++num_ctrls] = NULL;
- op->o_preread = 0; /* prevent redo on retry */
}
/* nested transaction */
}
if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
+ rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
/* modify entry */
goto return_results;
}
- if( op->o_postread ) {
- if( slap_read_controls( op, rs, e,
- &slap_post_read_bv, &ctrls[num_ctrls] ) )
- {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, DETAIL1,
- "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
-#endif
- goto return_results;
- }
- ctrls[++num_ctrls] = NULL;
- op->o_postread = 0; /* prevent redo on retry */
- /* FIXME: should read entry on the last retry */
- }
-
/* id2entry index */
rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e );
if ( rs->sr_err != 0 ) {
goto return_results;
}
- bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock );
- if ( eip ) p = eip->bei_e;
- if ( p_ndn.bv_len != 0 ) {
- parent_is_glue = is_entry_glue(p);
- rs->sr_err = bdb_cache_children( op, lt2, p );
- if ( rs->sr_err != DB_NOTFOUND ) {
- switch( rs->sr_err ) {
- case DB_LOCK_DEADLOCK:
- case DB_LOCK_NOTGRANTED:
- goto retry;
- case 0:
- break;
- default:
+ if ( p_ndn.bv_len != 0 ) {
+ parent_is_glue = is_entry_glue(p);
+ rs->sr_err = bdb_cache_children( op, lt2, p );
+ if ( rs->sr_err != DB_NOTFOUND ) {
+ switch( rs->sr_err ) {
+ case DB_LOCK_DEADLOCK:
+ case DB_LOCK_NOTGRANTED:
+ goto retry;
+ case 0:
+ break;
+ default:
#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, ERR,
- "<=- bdb_modrdn: has_children failed %s (%d)\n",
- db_strerror(rs->sr_err), rs->sr_err, 0 );
+ LDAP_LOG ( OPERATION, ERR,
+ "<=- bdb_modrdn: has_children failed %s (%d)\n",
+ db_strerror(rs->sr_err), rs->sr_err, 0 );
#else
- Debug(LDAP_DEBUG_ARGS,
- "<=- bdb_modrdn: has_children failed: %s (%d)\n",
- db_strerror(rs->sr_err), rs->sr_err, 0 );
+ Debug(LDAP_DEBUG_ARGS,
+ "<=- bdb_modrdn: has_children failed: %s (%d)\n",
+ db_strerror(rs->sr_err), rs->sr_err, 0 );
#endif
- rs->sr_err = LDAP_OTHER;
- rs->sr_text = "internal error";
- goto return_results;
- }
- parent_is_leaf = 1;
- }
- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
- p = NULL;
- }
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+ parent_is_leaf = 1;
+ }
+ bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
+ p = NULL;
+ }
if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
rs->sr_err = LDAP_OTHER;
}
}
+ if( op->o_postread ) {
+ if( postread_ctrl == NULL ) {
+ postread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
+ if( slap_read_controls( op, rs, e,
+ &slap_post_read_bv, postread_ctrl ) )
+ {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, DETAIL1,
+ "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#endif
+ goto return_results;
+ }
+ }
+
if( op->o_noop ) {
if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
if ( rs->sr_err == LDAP_SUCCESS ) {
/* Loop through in-scope entries for each psearch spec */
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+ rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
while ( pm_list != NULL ) {
- bdb_psearch(op, rs, pm_list->ps_op,
+ rc = bdb_psearch(op, rs, pm_list->ps_op,
e, LDAP_PSEARCH_BY_SCOPEOUT);
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
pm_prev = pm_list;
LDAP_LIST_REMOVE ( pm_list, ps_link );
pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
ch_free( pm_prev );
}
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
op->o_private = NULL;
}
+ if( preread_ctrl != NULL ) {
+ slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *preread_ctrl, &op->o_tmpmemctx );
+ }
+ if( postread_ctrl != NULL ) {
+ slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *postread_ctrl, &op->o_tmpmemctx );
+ }
return rs->sr_err;
}
#define bdb_abandon BDB_SYMBOL(abandon)
#define bdb_cancel BDB_SYMBOL(cancel)
#define bdb_do_search BDB_SYMBOL(do_search)
+#define bdb_psearch BDB_SYMBOL(psearch)
BI_op_abandon bdb_abandon;
BI_op_cancel bdb_cancel;
+int bdb_psearch(
+ Operation *op,
+ SlapReply *rs,
+ Operation *ps_op,
+ Entry *entry,
+ int psearch_type
+);
+
int bdb_do_search(
Operation *op,
SlapReply *rs,
Entry *entry,
int psearch_type
);
-#define bdb_psearch(op, rs, sop, e, ps_type) bdb_do_search(op, rs, sop, e, ps_type)
/*
* trans.c
return bdb_do_search( op, rs, op, NULL, 0 );
}
+int bdb_psearch( Operation *op, SlapReply *rs, Operation *sop,
+ Entry *ps_e, int ps_type )
+{
+ int rc;
+
+ sop->o_private = op->o_private;
+ rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
+ sop->o_private = NULL;
+
+ return rc;
+}
+
/* For persistent searches, op is the currently executing operation,
* sop is the persistent search. For regular searches, sop = op.
*/
BerVarray syncUUID_set = NULL;
int syncUUID_set_cnt = 0;
+ struct bdb_op_info *opinfo = NULL;
+ DB_TXN *ltid = NULL;
+
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY, "bdb_search\n", 0, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "=> bdb_search\n",
- 0, 0, 0);
+ Debug( LDAP_DEBUG_TRACE, "=> bdb_search\n", 0, 0, 0);
#endif
attrs = sop->oq_search.rs_attrs;
+ opinfo = (struct bdb_op_info *) op->o_private;
+
if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST ) {
struct slap_session_entry *sent;
if ( sop->o_sync_state.sid >= 0 ) {
}
}
- rs->sr_err = LOCK_ID( bdb->bi_dbenv, &locker );
+ if ( opinfo ) {
+ ltid = opinfo->boi_txn;
+ locker = TXN_ID( ltid );
+ } else {
+ rs->sr_err = LOCK_ID( bdb->bi_dbenv, &locker );
- switch(rs->sr_err) {
- case 0:
- break;
- default:
- send_ldap_error( sop, rs, LDAP_OTHER, "internal error" );
- return rs->sr_err;
+ switch(rs->sr_err) {
+ case 0:
+ break;
+ default:
+ send_ldap_error( sop, rs, LDAP_OTHER, "internal error" );
+ return rs->sr_err;
+ }
}
if ( sop->o_req_ndn.bv_len == 0 ) {
} else {
dn2entry_retry:
/* get entry with reader lock */
- rs->sr_err = bdb_dn2entry( op, NULL, &sop->o_req_ndn, &ei,
+ rs->sr_err = bdb_dn2entry( op, ltid, &sop->o_req_ndn, &ei,
1, locker, &lock );
}
break;
case LDAP_BUSY:
send_ldap_error( sop, rs, LDAP_BUSY, "ldap server busy" );
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
+ if ( !opinfo )
+ LOCK_ID_FREE (bdb->bi_dbenv, locker );
return LDAP_BUSY;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto dn2entry_retry;
default:
send_ldap_error( sop, rs, LDAP_OTHER, "internal error" );
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
+ if ( !opinfo )
+ LOCK_ID_FREE (bdb->bi_dbenv, locker );
return rs->sr_err;
}
rs->sr_matched = matched_dn.bv_val;
send_ldap_result( sop, rs );
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
+ if ( !opinfo )
+ LOCK_ID_FREE (bdb->bi_dbenv, locker );
if ( rs->sr_ref ) {
ber_bvarray_free( rs->sr_ref );
rs->sr_ref = NULL;
rs->sr_matched = matched_dn.bv_val;
send_ldap_result( sop, rs );
- LOCK_ID_FREE (bdb->bi_dbenv, locker );
+ if ( !opinfo )
+ LOCK_ID_FREE (bdb->bi_dbenv, locker );
ber_bvarray_free( rs->sr_ref );
rs->sr_ref = NULL;
ber_memfree( matched_dn.bv_val );
id2entry_retry:
/* get the entry with reader lock */
ei = NULL;
- rs->sr_err = bdb_cache_find_id( op, NULL,
+ rs->sr_err = bdb_cache_find_id( op, ltid,
id, &ei, 0, locker, &lock );
if (rs->sr_err == LDAP_BUSY) {
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
+ if ( !opinfo )
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
ber_bvfree( search_context_csn );
LDAPControl ctrl, *ctrls[2];
BerElementBuffer berbuf;
BerElement *ber = (BerElement *)&berbuf;
- struct berval cookie = BER_BVC( "" );
PagedResultsCookie respcookie;
+ struct berval cookie;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY,
- "send_paged_response: lastid: (0x%08lx) "
- "nentries: (0x%081x)\n",
+ "send_paged_response: lastid=0x%08lx nentries=%d\n",
lastid ? *lastid : 0, rs->sr_nentries, NULL );
#else
- Debug(LDAP_DEBUG_ARGS, "send_paged_response: lastid: (0x%08lx) "
- "nentries: (0x%081x)\n", lastid ? *lastid : 0, rs->sr_nentries, NULL );
+ Debug(LDAP_DEBUG_ARGS,
+ "send_paged_response: lastid=0x%08lx nentries=%d\n",
+ lastid ? *lastid : 0, rs->sr_nentries, NULL );
#endif
ctrl.ldctl_value.bv_val = NULL;
} else {
respcookie = ( PagedResultsCookie )0;
+ cookie.bv_val = "";
+ cookie.bv_len = 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;
- /*
- * FIXME: we should consider sending an estimate of the entries
- * left, after appropriate security check is done
- */
- ber_printf( ber, "{iO}", tentries, &cookie );
+ /* return size of 0 -- no estimate */
+ ber_printf( ber, "{iO}", 0, &cookie );
if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) {
goto done;
int
do_bind(
Operation *op,
- SlapReply *rs
-)
+ SlapReply *rs )
{
BerElement *ber = op->o_ber;
ber_int_t version;
Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
#endif
send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
- rs->sr_err = -1;
+ rs->sr_err = SLAPD_DISCONNECT;
goto cleanup;
}
ber_dupbv( &op->o_conn->c_ndn, &op->o_conn->c_dn );
}
op->o_tmpfree( op->orb_edn.bv_val, op->o_tmpmemctx );
- op->orb_edn.bv_val = NULL;
- op->orb_edn.bv_len = 0;
+ BER_BVZERO( &op->orb_edn );
op->o_conn->c_authmech = op->o_conn->c_sasl_bind_mech;
- op->o_conn->c_sasl_bind_mech.bv_val = NULL;
- op->o_conn->c_sasl_bind_mech.bv_len = 0;
+ BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
op->o_conn->c_sasl_bind_in_progress = 0;
op->o_conn->c_sasl_ssf = op->orb_ssf;
LDAPURLDesc *ludp;
static BackendInfo *bi = NULL;
static BackendDB *be = NULL;
+ char *next;
+
vals[1].bv_val = NULL;
if ( cargc < 2 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing level in \"concurrency <level\" "
+ "%s: line %d: missing level in \"concurrency <level>\" "
" line\n", fname, lineno, 0 );
#else
Debug( LDAP_DEBUG_ANY,
return( 1 );
}
- c = atoi( cargv[1] );
+ c = strtol( cargv[1], &next, 10 );
+ if ( next == NULL || next[0] != '\0' ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: unable to parse level \"%s\" in \"concurrency <level>\" "
+ " line\n", fname, lineno, cargv[1] );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse level \"%s\" in \"concurrency <level>\" line\n",
+ fname, lineno, cargv[1] );
+#endif
+ return( 1 );
+ }
if( c < 1 ) {
#ifdef NEW_LOGGING
return( 1 );
}
- c = atoi( cargv[1] );
+ c = strtol( cargv[1], &next, 10 );
+ if (next == NULL || next[0] != '\0' ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: unable to parse count \"%s\" in \"threads <count>\" line\n",
+ fname, lineno, cargv[1] );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse count \"%s\" in \"threads <count>\" line\n",
+ fname, lineno, cargv[1] );
+#endif
+ return( 1 );
+ }
if( c < 0 ) {
#ifdef NEW_LOGGING
if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
lim->lms_s_soft = -1;
} else {
- char *next;
-
lim->lms_s_soft = strtol( cargv[i] , &next, 0 );
if ( next == cargv[i] ) {
#ifdef NEW_LOGGING
if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
lim->lms_t_soft = -1;
} else {
- char *next;
-
lim->lms_t_soft = strtol( cargv[i] , &next, 0 );
if ( next == cargv[i] ) {
#ifdef NEW_LOGGING
"%s: line %d: depth line must appear inside a database definition.\n",
fname, lineno, 0 );
#endif
- return 1;
+ return 1;
+ }
+
+ i = strtol( cargv[1], &next, 10 );
+ if ( next == NULL || next[0] != '\0' ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, INFO,
+ "%s: line %d: unable to parse depth \"%s\" in \"maxDerefDepth <depth>\" "
+ "line.\n", fname, lineno, cargv[1] );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse depth \"%s\" in \"maxDerefDepth <depth>\" "
+ "line.\n", fname, lineno, cargv[1] );
+#endif
+ return 1;
+ }
- } else if ((i = atoi(cargv[1])) < 0) {
+ if (i < 0) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, INFO,
"%s: line %d: depth must be positive.\n",
- fname, lineno ,0 );
+ fname, lineno, 0 );
#else
Debug( LDAP_DEBUG_ANY,
"%s: line %d: depth must be positive.\n",
fname, lineno, 0 );
#endif
- return 1;
-
+ return 1;
- } else {
- be->be_max_deref_depth = i;
- }
+ }
+ be->be_max_deref_depth = i;
/* set magic "root" dn for this database */
} else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
}
for( i=1; i < cargc; i++ ) {
- if( strncasecmp( cargv[i], "ssf=",
- sizeof("ssf") ) == 0 )
+ slap_ssf_t *tgt;
+ char *src;
+
+ if ( strncasecmp( cargv[i], "ssf=",
+ STRLENOF("ssf=") ) == 0 )
{
- set->sss_ssf =
- atoi( &cargv[i][sizeof("ssf")] );
+ tgt = &set->sss_ssf;
+ src = &cargv[i][STRLENOF("ssf=")];
- } else if( strncasecmp( cargv[i], "transport=",
- sizeof("transport") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "transport=",
+ STRLENOF("transport=") ) == 0 )
{
- set->sss_transport =
- atoi( &cargv[i][sizeof("transport")] );
+ tgt = &set->sss_transport;
+ src = &cargv[i][STRLENOF("transport=")];
- } else if( strncasecmp( cargv[i], "tls=",
- sizeof("tls") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "tls=",
+ STRLENOF("tls=") ) == 0 )
{
- set->sss_tls =
- atoi( &cargv[i][sizeof("tls")] );
+ tgt = &set->sss_tls;
+ src = &cargv[i][STRLENOF("tls=")];
- } else if( strncasecmp( cargv[i], "sasl=",
- sizeof("sasl") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "sasl=",
+ STRLENOF("sasl=") ) == 0 )
{
- set->sss_sasl =
- atoi( &cargv[i][sizeof("sasl")] );
+ tgt = &set->sss_sasl;
+ src = &cargv[i][STRLENOF("sasl=")];
- } else if( strncasecmp( cargv[i], "update_ssf=",
- sizeof("update_ssf") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "update_ssf=",
+ STRLENOF("update_ssf=") ) == 0 )
{
- set->sss_update_ssf =
- atoi( &cargv[i][sizeof("update_ssf")] );
+ tgt = &set->sss_update_ssf;
+ src = &cargv[i][STRLENOF("update_ssf=")];
- } else if( strncasecmp( cargv[i], "update_transport=",
- sizeof("update_transport") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "update_transport=",
+ STRLENOF("update_transport=") ) == 0 )
{
- set->sss_update_transport =
- atoi( &cargv[i][sizeof("update_transport")] );
+ tgt = &set->sss_update_transport;
+ src = &cargv[i][STRLENOF("update_transport=")];
- } else if( strncasecmp( cargv[i], "update_tls=",
- sizeof("update_tls") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "update_tls=",
+ STRLENOF("update_tls=") ) == 0 )
{
- set->sss_update_tls =
- atoi( &cargv[i][sizeof("update_tls")] );
+ tgt = &set->sss_update_tls;
+ src = &cargv[i][STRLENOF("update_tls=")];
- } else if( strncasecmp( cargv[i], "update_sasl=",
- sizeof("update_sasl") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "update_sasl=",
+ STRLENOF("update_sasl=") ) == 0 )
{
- set->sss_update_sasl =
- atoi( &cargv[i][sizeof("update_sasl")] );
+ tgt = &set->sss_update_sasl;
+ src = &cargv[i][STRLENOF("update_sasl=")];
- } else if( strncasecmp( cargv[i], "simple_bind=",
- sizeof("simple_bind") ) == 0 )
+ } else if ( strncasecmp( cargv[i], "simple_bind=",
+ STRLENOF("simple_bind=") ) == 0 )
{
- set->sss_simple_bind =
- atoi( &cargv[i][sizeof("simple_bind")] );
+ tgt = &set->sss_simple_bind;
+ src = &cargv[i][STRLENOF("simple_bind=")];
} else {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: unknown factor %S in "
+ "%s: line %d: unknown factor %s in "
"\"security <factors>\" line.\n",
fname, lineno, cargv[1] );
#else
return( 1 );
}
+
+ *tgt = strtol( src, &next, 10 );
+ if ( next == NULL || next[0] != '\0' ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: unable to parse factor \"%s\" in "
+ "\"security <factors>\" line.\n",
+ fname, lineno, cargv[1] );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse factor \"%s\" in \"security <factors>\" line\n",
+ fname, lineno, cargv[i] );
+#endif
+
+ return( 1 );
+ }
}
+
/* where to send clients when we don't hold it */
} else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
if ( cargc < 2 ) {
"%s: line %d: Error in debug directive, \"debug subsys level\"\n",
fname, lineno, 0 );
#endif
-
return( 1 );
}
- level = atoi( cargv[2] );
+ level = strtol( cargv[2], &next, 10 );
+ if ( next == NULL || next[0] != '\0' ){
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: unable to parse level \"%s\" in debug directive, "
+ "\"debug <subsys> <level>\"\n", fname, lineno , cargv[2] );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse level \"%s\" in debug directive, "
+ "\"debug <subsys> <level>\"\n", fname, lineno , cargv[2] );
+#endif
+ return( 1 );
+ }
+
if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
lutil_set_debug_level( cargv[1], level );
/* specify an Object Identifier macro */
if ( cargc < 2 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing level in \"loglevel <level>\""
+ "%s: line %d: missing level(s) in \"loglevel <level> [...]\""
" line.\n", fname, lineno , 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing level in \"loglevel <level>\" line\n",
+ "%s: line %d: missing level(s) in \"loglevel <level> [...]\" line\n",
fname, lineno, 0 );
#endif
ldap_syslog = 0;
for( i=1; i < cargc; i++ ) {
- ldap_syslog += atoi( cargv[1] );
+ int level = strtol( cargv[i], &next, 10 );
+ if ( next == NULL || next[0] != '\0' ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: unable to parse level \"%s\" in \"loglevel <level> [...]\""
+ " line.\n", fname, lineno , cargv[i] );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse level \"%s\" in \"loglevel <level> [...]\""
+ " line.\n", fname, lineno , cargv[i] );
+#endif
+ return( 1 );
+ }
+
+ ldap_syslog |= level;
}
/* list of sync replication information in this backend (slave only) */
si->si_attrs[0] = NULL;
si->si_type = LDAP_SYNC_REFRESH_ONLY;
si->si_interval = 86400;
+ si->si_retryinterval = 0;
+ si->si_retrynum_init = 0;
+ si->si_retrynum = 0;
si->si_syncCookie.ctxcsn = NULL;
si->si_syncCookie.octet_str = NULL;
si->si_syncCookie.sid = -1;
si->si_manageDSAit = 0;
- si->si_tlimit = -1;
- si->si_slimit = -1;
+ si->si_tlimit = 0;
+ si->si_slimit = 0;
si->si_syncUUID_ndn.bv_val = NULL;
si->si_syncUUID_ndn.bv_len = 0;
#define SLIMITSTR "sizelimit"
#define TLIMITSTR "timelimit"
+#define RETRYSTR "retry"
+
#define GOT_ID 0x0001
#define GOT_PROVIDER 0x0002
#define GOT_METHOD 0x0004
} else if ( !strncasecmp( cargv[ i ],
INTERVALSTR, sizeof( INTERVALSTR ) - 1 ) )
{
- char *hstr;
- char *mstr;
- char *dstr;
- char *sstr;
- int dd, hh, mm, ss;
val = cargv[ i ] + sizeof( INTERVALSTR );
- dstr = val;
- hstr = strchr( dstr, ':' );
- if ( hstr == NULL ) {
- fprintf( stderr, "Error: parse_syncrepl_line: "
- "invalid interval \"%s\"\n", val );
- return 1;
- }
- *hstr++ = '\0';
- mstr = strchr( hstr, ':' );
- if ( mstr == NULL ) {
- fprintf( stderr, "Error: parse_syncrepl_line: "
- "invalid interval \"%s\"\n", val );
- return 1;
- }
- *mstr++ = '\0';
- sstr = strchr( mstr, ':' );
- if ( sstr == NULL ) {
- fprintf( stderr, "Error: parse_syncrepl_line: "
- "invalid interval \"%s\"\n", val );
- return 1;
- }
- *sstr++ = '\0';
-
- dd = atoi( dstr );
- hh = atoi( hstr );
- mm = atoi( mstr );
- ss = atoi( sstr );
- if (( hh > 24 ) || ( hh < 0 ) ||
- ( mm > 60 ) || ( mm < 0 ) ||
- ( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) {
- fprintf( stderr, "Error: parse_syncrepl_line: "
- "invalid interval \"%s\"\n", val );
- return 1;
+ if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) {
+ si->si_interval = 0;
+ } else {
+ char *hstr;
+ char *mstr;
+ char *dstr;
+ char *sstr;
+ int dd, hh, mm, ss;
+ dstr = val;
+ hstr = strchr( dstr, ':' );
+ if ( hstr == NULL ) {
+ fprintf( stderr, "Error: parse_syncrepl_line: "
+ "invalid interval \"%s\"\n", val );
+ return 1;
+ }
+ *hstr++ = '\0';
+ mstr = strchr( hstr, ':' );
+ if ( mstr == NULL ) {
+ fprintf( stderr, "Error: parse_syncrepl_line: "
+ "invalid interval \"%s\"\n", val );
+ return 1;
+ }
+ *mstr++ = '\0';
+ sstr = strchr( mstr, ':' );
+ if ( sstr == NULL ) {
+ fprintf( stderr, "Error: parse_syncrepl_line: "
+ "invalid interval \"%s\"\n", val );
+ return 1;
+ }
+ *sstr++ = '\0';
+
+ dd = atoi( dstr );
+ hh = atoi( hstr );
+ mm = atoi( mstr );
+ ss = atoi( sstr );
+ if (( hh > 24 ) || ( hh < 0 ) ||
+ ( mm > 60 ) || ( mm < 0 ) ||
+ ( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) {
+ fprintf( stderr, "Error: parse_syncrepl_line: "
+ "invalid interval \"%s\"\n", val );
+ return 1;
+ }
+ si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss;
}
- si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss;
-
if ( si->si_interval < 0 ) {
fprintf( stderr, "Error: parse_syncrepl_line: "
"invalid interval \"%ld\"\n",
(long) si->si_interval);
return 1;
}
+ } else if ( !strncasecmp( cargv[ i ],
+ RETRYSTR, sizeof( RETRYSTR ) - 1 ) )
+ {
+ char *str;
+ char **retry_list;
+ int j, k, n;
+
+ val = cargv[ i ] + sizeof( RETRYSTR );
+ retry_list = (char **) ch_calloc( 1, sizeof( char * ));
+ retry_list[0] = NULL;
+
+ str2clist( &retry_list, val, " ,\t" );
+
+ for ( k = 0; retry_list && retry_list[k]; k++ ) ;
+ n = k / 2;
+ if ( k % 2 ) {
+ fprintf( stderr,
+ "Error: incomplete syncrepl retry list\n" );
+ for ( k = 0; retry_list && retry_list[k]; k++ ) {
+ ch_free( retry_list[k] );
+ }
+ ch_free( retry_list );
+ exit( EXIT_FAILURE );
+ }
+ si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
+ si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
+ si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
+ for ( j = 0; j < n; j++ ) {
+ si->si_retryinterval[j] = atoi( retry_list[j*2] );
+ if ( *retry_list[j*2+1] == '+' ) {
+ si->si_retrynum_init[j] = -1;
+ si->si_retrynum[j] = -1;
+ j++;
+ break;
+ } else {
+ si->si_retrynum_init[j] = atoi( retry_list[j*2+1] );
+ si->si_retrynum[j] = atoi( retry_list[j*2+1] );
+ }
+ }
+ si->si_retrynum_init[j] = -2;
+ si->si_retrynum[j] = -2;
+ si->si_retryinterval[j] = 0;
+
+ for ( k = 0; retry_list && retry_list[k]; k++ ) {
+ ch_free( retry_list[k] );
+ }
+ ch_free( retry_list );
} else if ( !strncasecmp( cargv[ i ],
MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) )
{
static void *
connection_operation( void *ctx, void *arg_v )
{
- int rc = SLAPD_DISCONNECT;
+ int rc = LDAP_OTHER;
Operation *op = arg_v;
SlapReply rs = {REP_RESULT};
ber_tag_t tag = op->o_tag;
op->o_threadctx = ctx;
+ switch ( tag ) {
+ case LDAP_REQ_BIND:
+ case LDAP_REQ_UNBIND:
+ case LDAP_REQ_ADD:
+ case LDAP_REQ_DELETE:
+ case LDAP_REQ_MODRDN:
+ case LDAP_REQ_MODIFY:
+ case LDAP_REQ_COMPARE:
+ case LDAP_REQ_SEARCH:
+ case LDAP_REQ_ABANDON:
+ case LDAP_REQ_EXTENDED:
+ break;
+ default:
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONNECTION, INFO, "connection_operation: "
+ "conn %lu unknown LDAP request 0x%lx\n",
+ conn->c_connid, tag, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY, "connection_operation: "
+ "conn %lu unknown LDAP request 0x%lx\n",
+ conn->c_connid, tag, 0 );
+#endif
+ op->o_tag = LBER_ERROR;
+ rs.sr_err = LDAP_PROTOCOL_ERROR;
+ rs.sr_text = "unknown LDAP request";
+ send_ldap_disconnect( op, &rs );
+ rc = SLAPD_DISCONNECT;
+ goto operations_error;
+ }
+
if( conn->c_sasl_bind_in_progress && tag != LDAP_REQ_BIND ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, ERR,
#endif
send_ldap_error( op, &rs, LDAP_OPERATIONS_ERROR,
"SASL bind in progress" );
+ rc = LDAP_OPERATIONS_ERROR;
goto operations_error;
}
break;
default:
-#ifdef NEW_LOGGING
- LDAP_LOG( CONNECTION, INFO,
- "connection_operation: conn %lu unknown LDAP request 0x%lx\n",
- conn->c_connid, tag, 0 );
-#else
- Debug( LDAP_DEBUG_ANY, "unknown LDAP request 0x%lx\n",
- tag, 0, 0 );
-#endif
- op->o_tag = LBER_ERROR;
- rs.sr_err = LDAP_PROTOCOL_ERROR;
- rs.sr_text = "unknown LDAP request";
- send_ldap_disconnect( op, &rs );
- rc = -1;
- break;
+ /* not reachable */
+ assert( 0 );
}
-#ifdef SLAPD_MONITOR
- oldtag = tag;
-#endif /* SLAPD_MONITOR */
+operations_error:
if( rc == SLAPD_DISCONNECT ) tag = LBER_ERROR;
-operations_error:
ldap_pvt_thread_mutex_lock( &num_ops_mutex );
+
num_ops_completed++;
#ifdef SLAPD_MONITOR
switch (oldtag) {
case LDAP_REQ_EXTENDED:
num_ops_completed_[SLAP_OP_EXTENDED]++;
break;
+ default:
+ /* not reachable */
+ assert( 0 );
}
#endif /* SLAPD_MONITOR */
ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
if ( op->o_cancel == SLAP_CANCEL_REQ ) {
op->o_cancel = LDAP_TOO_LATE;
}
-
while ( op->o_cancel != SLAP_CANCEL_NONE &&
op->o_cancel != SLAP_CANCEL_DONE )
{
ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
if ( op->o_cancel != SLAP_CANCEL_ACK &&
- ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) {
+ ( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
+ {
sl_mem_detach( ctx, memctx );
- } else if (( op->o_sync_slog_size != -1 )) {
+
+ } else if ( op->o_sync_slog_size != -1 ) {
sl_mem_detach( ctx, memctx );
LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
LDAP_STAILQ_NEXT(op, o_next) = NULL;
conn->c_n_ops_executing--;
conn->c_n_ops_completed++;
+
} else {
LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
LDAP_STAILQ_NEXT(op, o_next) = NULL;
}
connection_resched( conn );
-
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
-
return NULL;
}
ldap_pvt_thread_start_t *func,
void *arg )
{
+ int rc;
Connection *c;
- if ( connection_init( s, (Listener *)&dummy_list, "", "", CONN_IS_CLIENT, 0, NULL ) < 0 ) {
- return -1;
- }
+ rc = connection_init( s, (Listener *)&dummy_list, "", "",
+ CONN_IS_CLIENT, 0, NULL );
+ if ( rc < 0 ) return -1;
c = connection_get( s );
c->c_clientfunc = func;
}
void connection_client_enable(
- ber_socket_t s
-)
+ ber_socket_t s )
{
slapd_set_read( s, 1 );
}
void connection_client_stop(
- ber_socket_t s
-)
+ ber_socket_t s )
{
Connection *c;
rc = dnX509peerNormalize( ssl, &authid );
if ( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
- LDAP_LOG( CONNECTION, INFO,
- "connection_read: conn %lu unable to get TLS client DN, "
- "error %d\n", c->c_connid, rc, 0 );
+ LDAP_LOG( CONNECTION, INFO, "connection_read: "
+ "conn %lu unable to get TLS client DN, error %d\n",
+ c->c_connid, rc, 0 );
#else
- Debug( LDAP_DEBUG_TRACE,
- "connection_read(%d): unable to get TLS client DN "
- "error=%d id=%lu\n",
- s, rc, c->c_connid );
+ Debug( LDAP_DEBUG_TRACE, "connection_read(%d): "
+ "unable to get TLS client DN, error=%d id=%lu\n",
+ s, rc, c->c_connid );
#endif
}
slap_sasl_external( c, c->c_tls_ssf, &authid );
op->o_preread_attrs = NULL;
op->o_postread_attrs = NULL;
op->o_vrFilter = NULL;
+ /* clear state if the connection is being reused from inactive */
+ if ( conn->c_conn_state == SLAP_C_INACTIVE ) {
+ memset( &conn->c_pagedresults_state, 0, sizeof( conn->c_pagedresults_state ) );
+ }
op->o_pagedresults_state = conn->c_pagedresults_state;
op->o_res_ber = NULL;
} else {
/* Initial request. Initialize state. */
+#if 0
+ if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) {
+ /* There's another pagedResults control on the
+ * same connection; reject new pagedResults controls
+ * (allowed by RFC2696) */
+ rs->sr_text = "paged results cookie unavailable; try later";
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ goto done;
+ }
+#endif
op->o_pagedresults_state.ps_cookie = 0;
op->o_pagedresults_state.ps_count = 0;
}
Listener ** slapd_get_listeners(void) {
return slap_listeners;
}
+
+void slap_wake_listener()
+{
+ WAKE_LISTENER(1);
+}
op->o_protocol, 0 ,0 );
#endif
send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "requires LDAPv3" );
- rs->sr_err = -1;
+ rs->sr_err = SLAPD_DISCONNECT;
goto done;
}
Debug( LDAP_DEBUG_ANY, "do_extended: ber_scanf failed\n", 0, 0 ,0 );
#endif
send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
- rs->sr_err = -1;
+ rs->sr_err = SLAPD_DISCONNECT;
goto done;
}
Debug( LDAP_DEBUG_ANY, "do_extended: ber_scanf failed\n", 0, 0 ,0 );
#endif
send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
- rs->sr_err = -1;
+ rs->sr_err = SLAPD_DISCONNECT;
goto done;
}
}
MatchingRuleAssertion *mra )
{
Attribute *a;
- void *memctx = op ? op->o_tmpmemctx : NULL;
+ void *memctx;
+ BER_MEMFREE_FN *memfree;
+
+ if ( op == NULL ) {
+ memctx = NULL;
+ memfree = slap_sl_free;
+ } else {
+ memctx = op->o_tmpmemctx;
+ memfree = op->o_tmpfree;
+ }
if ( mra->ma_desc ) {
/*
/* check search access */
if ( !access_allowed( op, e,
a->a_desc, &value, ACL_SEARCH, NULL ) ) {
- op->o_tmpfree( value.bv_val, memctx );
+ memfree( value.bv_val, memctx );
continue;
}
break;
}
}
- op->o_tmpfree( value.bv_val, memctx );
+ memfree( value.bv_val, memctx );
if ( rc != LDAP_SUCCESS ) return rc;
}
}
if ( !access_allowed( op, e,
ad, &value, ACL_SEARCH, NULL ) )
{
- op->o_tmpfree( value.bv_val, memctx );
+ memfree( value.bv_val, memctx );
continue;
}
}
bv, &value, &text );
if ( value.bv_val != mra->ma_value.bv_val ) {
- op->o_tmpfree( value.bv_val, memctx );
+ memfree( value.bv_val, memctx );
}
if ( rc == LDAP_SUCCESS && ret == 0 ) rc = LDAP_COMPARE_TRUE;
#include "slap.h"
+/* define to get an error if requesting limit higher than hard */
+#undef ABOVE_HARD_LIMIT_IS_ERROR
+
static char *
limits2str( unsigned i )
{
arg++;
if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) {
arg += STRLENOF( "soft=" );
- if ( strcasecmp( arg, "none" ) == 0 ) {
+ if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_t_soft = -1;
} else {
}
if ( soft == -1 ) {
- /* FIXME: use "none" instead */
+ /* FIXME: use "unlimited" instead; issue warning? */
}
limit->lms_t_soft = soft;
if ( strcasecmp( arg, "soft" ) == 0 ) {
limit->lms_t_hard = 0;
- } else if ( strcasecmp( arg, "none" ) == 0 ) {
+ } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_t_hard = -1;
} else {
}
if ( hard == -1 ) {
- /* FIXME: use "none" instead */
+ /* FIXME: use "unlimited" instead */
}
if ( hard == 0 ) {
} else if ( arg[0] == '=' ) {
arg++;
- if ( strcasecmp( arg, "none" ) == 0 ) {
+ if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_t_soft = -1;
} else {
arg++;
if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) {
arg += STRLENOF( "soft=" );
- if ( strcasecmp( arg, "none" ) == 0 ) {
+ if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_s_soft = -1;
} else {
}
if ( soft == -1 ) {
- /* FIXME: use "none" instead */
+ /* FIXME: use "unlimited" instead */
}
limit->lms_s_soft = soft;
if ( strcasecmp( arg, "soft" ) == 0 ) {
limit->lms_s_hard = 0;
- } else if ( strcasecmp( arg, "none" ) == 0 ) {
+ } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_s_hard = -1;
} else {
}
if ( hard == -1 ) {
- /* FIXME: use "none" instead */
+ /* FIXME: use "unlimited" instead */
}
if ( hard == 0 ) {
} else if ( strncasecmp( arg, "unchecked=", STRLENOF( "unchecked=" ) ) == 0 ) {
arg += STRLENOF( "unchecked=" );
- if ( strcasecmp( arg, "none" ) == 0 ) {
+ if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_s_unchecked = -1;
} else if ( strcasecmp( arg, "disabled" ) == 0 ) {
}
if ( unchecked == -1 ) {
- /* FIXME: use "none" instead */
+ /* FIXME: use "unlimited" instead */
}
limit->lms_s_unchecked = unchecked;
if ( strcasecmp( arg, "noEstimate" ) == 0 ) {
limit->lms_s_pr_hide = 1;
- } else if ( strcasecmp( arg, "none" ) == 0 ) {
+ } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_s_pr = -1;
} else {
}
if ( pr == -1 ) {
- /* FIXME: use "none" instead */
+ /* FIXME: use "unlimited" instead */
}
limit->lms_s_pr = pr;
} else if ( strncasecmp( arg, "prtotal=", STRLENOF( "prtotal=" ) ) == 0 ) {
arg += STRLENOF( "prtotal=" );
- if ( strcasecmp( arg, "none" ) == 0 ) {
+ if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_s_pr_total = -1;
} else if ( strcasecmp( arg, "disabled" ) == 0 ) {
}
if ( total == -1 ) {
- /* FIXME: use "none" instead */
+ /* FIXME: use "unlimited" instead */
}
if ( total == 0 ) {
} else if ( arg[0] == '=' ) {
arg++;
- if ( strcasecmp( arg, "none" ) == 0 ) {
+ if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
limit->lms_s_soft = -1;
} else {
assert( rs );
/* FIXME: should this be always true? */
assert( op->o_tag == LDAP_REQ_SEARCH);
-
+
+ /* protocol only allows 0..maxInt;
+ *
+ * internal searches:
+ * - may use SLAP_NO_LIMIT ( = -1 ) to indicate no limits;
+ * - should use slimit = N and tlimit = SLAP_NO_LIMIT to
+ * indicate searches that should return exactly N matches,
+ * and handle errors thru a callback (see for instance
+ * slap_sasl_match() and slap_sasl2dn())
+ */
+ if ( op->ors_tlimit == SLAP_NO_LIMIT && op->ors_slimit == SLAP_NO_LIMIT ) {
+ return 0;
+ }
+
/* allow root to set no limit */
if ( be_isroot( op ) ) {
op->ors_limit = NULL;
} else {
if ( op->ors_limit->lms_t_hard == 0 ) {
if ( op->ors_limit->lms_t_soft > 0
- && ( op->ors_tlimit < 0 || op->ors_tlimit > op->ors_limit->lms_t_soft ) ) {
+ && ( op->ors_tlimit > op->ors_limit->lms_t_soft ) ) {
op->ors_tlimit = op->ors_limit->lms_t_soft;
}
} else if ( op->ors_limit->lms_t_hard > 0 ) {
- if ( op->ors_tlimit < 0 || op->ors_tlimit > op->ors_limit->lms_t_hard ) {
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
+ if ( op->ors_tlimit == SLAP_MAX_LIMIT ) {
+ op->ors_tlimit = op->ors_limit->lms_t_hard;
+
+ } else if ( op->ors_tlimit > op->ors_limit->lms_t_hard ) {
/* error if exceeding hard limit */
rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
send_ldap_result( op, rs );
rs->sr_err = LDAP_SUCCESS;
return -1;
}
+#else /* ! ABOVE_HARD_LIMIT_IS_ERROR */
+ if ( op->ors_tlimit > op->ors_limit->lms_t_hard ) {
+ op->ors_tlimit = op->ors_limit->lms_t_hard;
+ }
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
}
}
}
if ( pr_total == -1 ) {
- slimit = -1;
+ if ( op->ors_slimit == 0 || op->ors_slimit == SLAP_MAX_LIMIT ) {
+ slimit = -1;
- } else if ( pr_total > 0 && ( op->ors_slimit == SLAP_NO_LIMIT || op->ors_slimit > pr_total ) ) {
+ } else {
+ slimit = op->ors_slimit - op->o_pagedresults_state.ps_count;
+ }
+
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
+ } else if ( pr_total > 0 && op->ors_slimit != SLAP_MAX_LIMIT
+ && ( 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;
return -1;
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
} else {
/* if no limit is required, use soft limit */
/* first round of pagedResults: set count to any appropriate limit */
- /* if the limit is set, check that it does not violate any limit */
- if ( op->ors_slimit > 0 ) {
- slimit2 = op->ors_slimit;
+ /* if the limit is set, check that it does not violate any server-side limit */
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
+ if ( op->ors_slimit == SLAP_MAX_LIMIT ) {
+ slimit2 = op->ors_slimit = pr_total;
+#else /* ! ABOVE_HARD_LIMIT_IS_ERROR */
+ if ( op->ors_slimit == SLAP_MAX_LIMIT || op->ors_slimit > pr_total ) {
+ slimit2 = op->ors_slimit = pr_total;
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
} else if ( op->ors_slimit == 0 ) {
slimit2 = pr_total;
} else {
- slimit2 = -1;
+ slimit2 = op->ors_slimit;
}
total = slimit2 - op->o_pagedresults_state.ps_count;
/* if got any limit, use it */
if ( slimit != -2 ) {
- if ( op->ors_slimit <= 0 ) {
+ if ( op->ors_slimit == 0 ) {
op->ors_slimit = slimit;
} else if ( slimit > 0 ) {
/* explicit hard limit: error if violated */
} else if ( op->ors_limit->lms_s_hard > 0 ) {
- if ( op->ors_slimit > op->ors_limit->lms_s_hard ) {
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
+ if ( op->ors_slimit == SLAP_MAX_LIMIT ) {
+ op->ors_slimit = op->ors_limit->lms_s_hard;
+
+ } else if ( op->ors_slimit > op->ors_limit->lms_s_hard ) {
/* if limit exceeds hard, error */
rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
send_ldap_result( op, rs );
rs->sr_err = LDAP_SUCCESS;
return -1;
}
+#else /* ! ABOVE_HARD_LIMIT_IS_ERROR */
+ if ( op->ors_slimit > op->ors_limit->lms_s_hard ) {
+ op->ors_slimit = op->ors_limit->lms_s_hard;
+ }
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
}
}
}
if ( code != 0 ) return code;
+ if( user && op ) return SLAP_SCHERR_CLASS_BAD_SUP;
code = oc_create_required( soc, soc->soc_at_oids_must, &op, err );
if ( code != 0 ) return code;
code = oc_create_allowed( soc, soc->soc_at_oids_may, &op, err );
if ( code != 0 ) return code;
- if( user && op ) return SLAP_SCHERR_CLASS_BAD_SUP;
+ if( user && op ) return SLAP_SCHERR_CLASS_BAD_USAGE;
code = oc_insert(soc,err);
return code;
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
+LDAP_SLAPD_F (void) slap_wake_listener LDAP_P((void));
LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
rs->sr_err, rs->sr_text ? rs->sr_text : "", NULL );
#endif
-
if ( op->o_protocol < LDAP_VERSION3 ) {
rs->sr_rspoid = NULL;
rs->sr_tag = req2res( op->o_tag );
*/
if ( op->o_pb != NULL ) {
slapi_int_pblock_set_operation( op->o_pb, op );
- slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err );
- slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text );
- slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched );
+ slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE,
+ (void *)rs->sr_err );
+ slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT,
+ (void *)rs->sr_text );
+ slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED,
+ (void *)rs->sr_matched );
- (void) slapi_int_call_plugins( op->o_bd, SLAPI_PLUGIN_PRE_RESULT_FN, op->o_pb );
+ (void) slapi_int_call_plugins( op->o_bd, SLAPI_PLUGIN_PRE_RESULT_FN,
+ op->o_pb );
}
#endif /* LDAP_SLAPI */
{
#ifdef NEW_LOGGING
LDAP_LOG( ACL, INFO,
- "send_search_entry: conn %lu access to attribute %s not "
+ "send_search_entry: conn %lu access to attribute %s not "
"allowed\n", op->o_connid, desc->ad_cname.bv_val, 0 );
#else
- Debug( LDAP_DEBUG_ACL, "acl: "
- "access to attribute %s not allowed\n",
- desc->ad_cname.bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_ACL, "send_search_entry: "
+ "conn %lu access to attribute %s not allowed\n",
+ op->o_connid, desc->ad_cname.bv_val, 0 );
#endif
continue;
}
#endif
if ( op->o_res_ber == NULL ) ber_free_buf( ber );
- send_ldap_error( op, rs, LDAP_OTHER, "encoding description error");
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "encoding description error");
goto error_return;
}
finish = 1;
#ifdef NEW_LOGGING
LDAP_LOG( ACL, INFO,
"send_search_entry: conn %lu "
- "access to attribute %s, value %d not allowed\n",
+ "access to attribute %s, value #%d not allowed\n",
op->o_connid, desc->ad_cname.bv_val, i );
#else
Debug( LDAP_DEBUG_ACL,
- "acl: access to attribute %s, "
- "value %d not allowed\n",
- desc->ad_cname.bv_val, i, 0 );
+ "send_search_entry: conn %lu "
+ "access to attribute %s, value #%d not allowed\n",
+ op->o_connid, desc->ad_cname.bv_val, i );
#endif
continue;
#endif
if ( op->o_res_ber == NULL ) ber_free_buf( ber );
- send_ldap_error( op, rs, LDAP_OTHER, "encoding description error");
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "encoding description error");
goto error_return;
}
}
"access to attribute %s not allowed\n",
op->o_connid, desc->ad_cname.bv_val, 0 );
#else
- Debug( LDAP_DEBUG_ACL, "send_search_entry: access to attribute %s "
- "not allowed\n", desc->ad_cname.bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_ACL,
+ "send_search_entry: conn %lu "
+ "access to attribute %s not allowed\n",
+ op->o_connid, desc->ad_cname.bv_val, 0 );
#endif
continue;
#endif
if ( op->o_res_ber == NULL ) ber_free_buf( ber );
- send_ldap_error( op, rs, LDAP_OTHER, "encoding description error" );
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "encoding description error" );
attrs_free( aa );
goto error_return;
}
for ( anp = rs->sr_attrs; anp->an_name.bv_val != NULL; anp++ ) {
rc = compute_evaluator( &ctx, anp->an_name.bv_val,
rs->sr_entry, slapi_int_compute_output_ber );
- if ( rc == 1 ) {
- break;
- }
+ if ( rc == 1 ) break;
}
} else {
/*
c.ldctl_oid = oid->bv_val;
c.ldctl_iscritical = 0;
- *ctrl = sl_calloc( 1, sizeof(LDAPControl), NULL );
+ if ( ctrl == NULL ) {
+ /* first try */
+ *ctrl = (LDAPControl *) sl_calloc( 1, sizeof(LDAPControl), NULL );
+ } else {
+ /* retry: free previous try */
+ slap_sl_free( (*ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ }
+
**ctrl = c;
return LDAP_SUCCESS;
}
return LDAP_SUCCESS;
}
+/*
+ * Syntax is [RFC2252]:
+ *
+
+6.3. Bit String
+
+ ( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )
+
+ Values in this syntax are encoded according to the following BNF:
+
+ bitstring = "'" *binary-digit "'B"
+
+ binary-digit = "0" / "1"
+
+ ...
+
+6.21. Name And Optional UID
+
+ ( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )
+
+ Values in this syntax are encoded according to the following BNF:
+
+ NameAndOptionalUID = DistinguishedName [ "#" bitstring ]
+
+ Although the '#' character may occur in a string representation of a
+ distinguished name, no additional special quoting is done. This
+ syntax has been added subsequent to RFC 1778.
+
+ Example:
+
+ 1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB#'0101'B
+
+ *
+ * draft-ietf-ldapbis-syntaxes-xx.txt says:
+ *
+
+3.3.2. Bit String
+
+ A value of the Bit String syntax is a sequence of binary digits. The
+ LDAP-specific encoding of a value of this syntax is defined by the
+ following ABNF:
+
+ BitString = SQUOTE *binary-digit SQUOTE "B"
+
+ binary-digit = "0" / "1"
+
+ The <SQUOTE> rule is defined in [MODELS].
+
+ Example:
+ '0101111101'B
+
+ The LDAP definition for the Bit String syntax is:
+
+ ( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )
+
+ This syntax corresponds to the BIT STRING ASN.1 type from [ASN.1].
+
+ ...
+
+3.3.21. Name and Optional UID
+
+ A value of the Name and Optional UID syntax is the distinguished name
+ [MODELS] of an entity optionally accompanied by a unique identifier
+ that serves to differentiate the entity from others with an identical
+ distinguished name.
+
+ The LDAP-specific encoding of a value of this syntax is defined by
+ the following ABNF:
+
+ NameAndOptionalUID = distinguishedName [ SHARP BitString ]
+
+ The <BitString> rule is defined in Section 3.3.2. The
+ <distinguishedName> rule is defined in [LDAPDN]. The <SHARP> rule is
+ defined in [MODELS].
+
+ Note that although the '#' character may occur in the string
+ representation of a distinguished name, no additional escaping of
+ this character is performed when a <distinguishedName> is encoded in
+ a <NameAndOptionalUID>.
+
+ Example:
+ 1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB#'0101'B
+
+ The LDAP definition for the Name and Optional UID syntax is:
+
+ ( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )
+
+ This syntax corresponds to the NameAndOptionalUID ASN.1 type from
+ [X.520].
+
+ *
+ * draft-ietf-ldapbis-models-xx.txt [MODELS] says:
+ *
+
+1.4. Common ABNF Productions
+
+ ...
+ SHARP = %x23 ; octothorpe (or sharp sign) ("#")
+ ...
+ SQUOTE = %x27 ; single quote ("'")
+ ...
+
+ *
+ * Note: normalization strips any leading "0"s, unless the
+ * bit string is exactly "'0'B", so the normalized example,
+ * in slapd, would result in
+ *
+ * 1.3.6.1.4.1.1466.0=#04024869,o=test,c=gb#'101'B
+ *
+ * Since draft-ietf-ldapbis-dn-xx.txt clarifies that SHARP,
+ * i.e. "#", doesn't have to be escaped except when at the
+ * beginning of a value, the definition of Name and Optional
+ * UID appears to be flawed, because there is no clear means
+ * to determine whether the UID part is present or not.
+ *
+ * Example:
+ *
+ * cn=Someone,dc=example,dc=com#'1'B
+ *
+ * could be either a NameAndOptionalUID with trailing UID, i.e.
+ *
+ * DN = "cn=Someone,dc=example,dc=com"
+ * UID = "'1'B"
+ *
+ * or a NameAndOptionalUID with no trailing UID, and the AVA
+ * in the last RDN made of
+ *
+ * attributeType = dc
+ * attributeValue = com#'1'B
+ *
+ * in fact "com#'1'B" is a valid IA5 string.
+ *
+ * As a consequence, current slapd code assumes that the
+ * presence of portions of a BitString at the end of the string
+ * representation of a NameAndOptionalUID means a BitString
+ * is expected, and cause an error otherwise. This is quite
+ * arbitrary, and might change in the future.
+ */
+
+
static int
nameUIDValidate(
Syntax *syntax,
struct berval *in )
{
int rc;
- struct berval dn;
+ struct berval dn, uid;
if( in->bv_len == 0 ) return LDAP_SUCCESS;
ber_dupbv( &dn, in );
if( !dn.bv_val ) return LDAP_OTHER;
- if( dn.bv_val[dn.bv_len-1] == 'B'
- && dn.bv_val[dn.bv_len-2] == '\'' )
- {
- /* assume presence of optional UID */
- ber_len_t i;
+ /* if there's a "#", try bitStringValidate()... */
+ uid.bv_val = strrchr( dn.bv_val, '#' );
+ if ( uid.bv_val ) {
+ uid.bv_val++;
+ uid.bv_len = dn.bv_len - ( uid.bv_val - dn.bv_val );
- for(i=dn.bv_len-3; i>1; i--) {
- if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
- break;
- }
+ rc = bitStringValidate( NULL, &uid );
+ if ( rc == LDAP_SUCCESS ) {
+ /* in case of success, trim the UID,
+ * otherwise treat it as part of the DN */
+ dn.bv_len -= uid.bv_len + 1;
+ uid.bv_val[-1] = '\0';
}
- if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
- ber_memfree( dn.bv_val );
- return LDAP_INVALID_SYNTAX;
- }
-
- /* trim the UID to allow use of dnValidate */
- dn.bv_val[i-1] = '\0';
- dn.bv_len = i-1;
}
rc = dnValidate( NULL, &dn );
return LDAP_INVALID_SYNTAX;
} else {
- int rc;
- struct berval dnval = *val;
- struct berval uidval = BER_BVNULL;
+ int rc;
+ struct berval dnval = *val;
+ struct berval uidval = BER_BVNULL;
- if( val->bv_val[val->bv_len-1] == 'B'
- && val->bv_val[val->bv_len-2] == '\'' )
- {
- uidval.bv_val=strrchr( val->bv_val, '#' );
- if( uidval.bv_val ) {
- dnval.bv_len = uidval.bv_val - dnval.bv_val;
- uidval.bv_len = val->bv_len - dnval.bv_len;
+ uidval.bv_val = strrchr( val->bv_val, '#' );
+ if ( uidval.bv_val ) {
+ uidval.bv_val++;
+ uidval.bv_len = val->bv_len - ( uidval.bv_val - val->bv_val );
- uidval.bv_len--;
- uidval.bv_val++;
+ rc = bitStringValidate( NULL, &uidval );
+
+ if ( rc == LDAP_SUCCESS ) {
+ ber_dupbv_x( &dnval, val, ctx );
+ dnval.bv_len -= uidval.bv_len + 1;
+ dnval.bv_val[dnval.bv_len] = '\0';
+
+ } else {
+ uidval.bv_val = NULL;
}
}
rc = dnPretty( syntax, &dnval, out, ctx );
- if( rc != LDAP_SUCCESS ) return rc;
+ if ( dnval.bv_val != val->bv_val ) {
+ slap_sl_free( dnval.bv_val, ctx );
+ }
+ if( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
if( uidval.bv_val ) {
- char *tmp = sl_realloc( out->bv_val, out->bv_len + uidval.bv_len + 2, ctx );
- int i, c, got1;
+ int i, c, got1;
+ char *tmp;
+
+ tmp = sl_realloc( out->bv_val, out->bv_len
+ + STRLENOF( "#" ) + uidval.bv_len + 1,
+ ctx );
if( tmp == NULL ) {
ber_memfree_x( out->bv_val, ctx );
return LDAP_OTHER;
}
out->bv_val = tmp;
out->bv_val[out->bv_len++] = '#';
+ out->bv_val[out->bv_len++] = '\'';
got1 = uidval.bv_len < sizeof("'0'B");
- for(i=0; i<uidval.bv_len; i++) {
+ for( i = 1; i < uidval.bv_len - 2; i++ ) {
c = uidval.bv_val[i];
switch(c) {
case '0':
break;
case '1':
got1 = 1;
- default:
out->bv_val[out->bv_len++] = c;
+ break;
}
}
+ out->bv_val[out->bv_len++] = '\'';
+ out->bv_val[out->bv_len++] = 'B';
out->bv_val[out->bv_len] = '\0';
}
}
} else {
struct berval uid = BER_BVNULL;
- if( out.bv_val[out.bv_len-1] == 'B'
- && out.bv_val[out.bv_len-2] == '\'' )
- {
- /* assume presence of optional UID */
- uid.bv_val = strrchr( out.bv_val, '#' );
+ uid.bv_val = strrchr( out.bv_val, '#' );
+ if ( uid.bv_val ) {
+ uid.bv_val++;
+ uid.bv_len = out.bv_len - ( uid.bv_val - out.bv_val );
- if( uid.bv_val == NULL ) {
- sl_free( out.bv_val, ctx );
- return LDAP_INVALID_SYNTAX;
+ rc = bitStringValidate( NULL, &uid );
+ if ( rc == LDAP_SUCCESS ) {
+ uid.bv_val[-1] = '\0';
+ out.bv_len -= uid.bv_len + 1;
+ } else {
+ uid.bv_val = NULL;
}
-
- uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
- out.bv_len -= uid.bv_len--;
-
- /* temporarily trim the UID */
- *(uid.bv_val++) = '\0';
}
rc = dnNormalize( 0, NULL, NULL, &out, normalized, ctx );
return LDAP_INVALID_SYNTAX;
}
- if( uid.bv_len ) {
- normalized->bv_val = ch_realloc( normalized->bv_val,
- normalized->bv_len + uid.bv_len + sizeof("#") );
+ if( uid.bv_val ) {
+ char *tmp;
+
+ tmp = ch_realloc( normalized->bv_val,
+ normalized->bv_len + uid.bv_len
+ + STRLENOF("#") + 1 );
+ if ( tmp == NULL ) {
+ ber_memfree_x( normalized->bv_val, ctx );
+ return LDAP_OTHER;
+ }
+
+ normalized->bv_val = tmp;
/* insert the separator */
normalized->bv_val[normalized->bv_len++] = '#';
struct berval valueDN = BER_BVNULL;
struct berval valueUID = BER_BVNULL;
- if( asserted->bv_len != 0 ) {
+ if( !BER_BVISEMPTY( asserted ) ) {
assertedDN = *asserted;
- if( assertedDN.bv_val[assertedDN.bv_len-1] == 'B'
- && assertedDN.bv_val[assertedDN.bv_len-2] == '\'' )
- {
- /* assume presence of optional UID */
- assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' );
-
- if( assertedUID.bv_val == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
+ assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' );
+ if ( !BER_BVISNULL( &assertedUID ) ) {
+ assertedUID.bv_val++;
+ assertedUID.bv_len = assertedDN.bv_len
+ - ( assertedUID.bv_val - assertedDN.bv_val );
- assertedUID.bv_len = assertedDN.bv_len -
- (assertedUID.bv_val - assertedDN.bv_val);
- assertedDN.bv_len -= assertedUID.bv_len--;
+ if ( bitStringValidate( NULL, &assertedUID ) == LDAP_SUCCESS ) {
+ assertedDN.bv_len -= assertedUID.bv_len + 1;
- /* trim the separator */
- assertedUID.bv_val++;
+ } else {
+ BER_BVZERO( &assertedUID );
+ }
}
}
- if( value->bv_len != 0 ) {
+ if ( !BER_BVISEMPTY( value ) ) {
valueDN = *value;
- if( valueDN.bv_val[valueDN.bv_len-1] == 'B'
- && valueDN.bv_val[valueDN.bv_len-2] == '\'' )
- {
- /* assume presence of optional UID */
- valueUID.bv_val = strrchr( valueDN.bv_val, '#' );
-
- if( valueUID.bv_val == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
+ valueUID.bv_val = strrchr( valueDN.bv_val, '#' );
+ if ( !BER_BVISNULL( &valueUID ) ) {
+ valueUID.bv_val++;
+ valueUID.bv_len = valueDN.bv_len
+ - ( valueUID.bv_val - valueDN.bv_val );
- valueUID.bv_len = valueDN.bv_len -
- (assertedUID.bv_val - assertedDN.bv_val);
- valueDN.bv_len -= valueUID.bv_len--;
+ if ( bitStringValidate( NULL, &valueUID ) == LDAP_SUCCESS ) {
+ valueDN.bv_len -= valueUID.bv_len + 1;
- /* trim the separator */
- valueUID.bv_val++;
+ } else {
+ BER_BVZERO( &valueUID );
+ }
}
}
if( valueUID.bv_len && assertedUID.bv_len ) {
+ match = valueUID.bv_len - assertedUID.bv_len;
+ if ( match ) {
+ *matchp = match;
+ return LDAP_SUCCESS;
+ }
+
match = memcmp( valueUID.bv_val, assertedUID.bv_val, valueUID.bv_len );
if( match ) {
*matchp = match;
* Integer conversion macros that will use the largest available
* type.
*/
-#if defined(HAVE_STRTOLL) && defined(LLONG_MAX) && defined(LLONG_MIN) && defined(HAVE_LONG_LONG)
+#if defined(HAVE_STRTOLL) && defined(LLONG_MAX) \
+ && defined(LLONG_MIN) && defined(HAVE_LONG_LONG)
# define SLAP_STRTOL(n,e,b) strtoll(n,e,b)
# define SLAP_LONG_MAX LLONG_MAX
# define SLAP_LONG_MIN LLONG_MIN
/* 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);
- if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX )
- && errno == ERANGE )
+ lAssertedValue = SLAP_STRTOL(((struct berval *)assertedValue)->bv_val,
+ NULL, 10);
+ if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX ) &&
+ errno == ERANGE )
{
return LDAP_CONSTRAINT_VIOLATION;
}
lAssertedValue = SLAP_STRTOL( ((struct berval *)assertedValue)->bv_val,
NULL, 10);
- if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX )
- && errno == ERANGE )
+ if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX ) &&
+ errno == ERANGE )
{
return LDAP_CONSTRAINT_VIOLATION;
}
/* validate serial number (strict for now) */
for( n=0; n < sn.bv_len; n++ ) {
- if( !ASCII_DIGIT(sn.bv_val[n]) ) {
- return LDAP_INVALID_SYNTAX;
- }
+ if( !ASCII_DIGIT(sn.bv_val[n]) ) return LDAP_INVALID_SYNTAX;
}
/* validate DN */
sn.bv_len -= n;
for( n=0; n < sn.bv_len; n++ ) {
- if( !ASCII_DIGIT(sn.bv_val[n]) ) {
- return LDAP_INVALID_SYNTAX;
- }
+ if( !ASCII_DIGIT(sn.bv_val[n]) ) return LDAP_INVALID_SYNTAX;
}
/* pretty DN */
}
} else {
+ int sep = 0;
while( OID_LEADCHAR( val.bv_val[0] ) ) {
- if ( val.bv_len == 1 ) {
- return LDAP_SUCCESS;
- }
-
- if ( val.bv_val[0] == '0' ) {
- break;
- }
-
val.bv_val++;
val.bv_len--;
- while ( OID_LEADCHAR( val.bv_val[0] )) {
- val.bv_val++;
- val.bv_len--;
-
- if ( val.bv_len == 0 ) {
- return LDAP_SUCCESS;
+ if ( val.bv_val[-1] != '0' ) {
+ while ( OID_LEADCHAR( val.bv_val[0] )) {
+ val.bv_val++;
+ val.bv_len--;
}
}
- if( !OID_SEPARATOR( val.bv_val[0] )) {
- break;
+ if( val.bv_len == 0 ) {
+ if( sep == 0 ) break;
+ return LDAP_SUCCESS;
}
+ if( !OID_SEPARATOR( val.bv_val[0] )) break;
+
+ sep++;
val.bv_val++;
val.bv_len--;
}
int
do_search(
Operation *op, /* info about the op to which we're responding */
- SlapReply *rs /* all the response data we'll send */
-) {
+ SlapReply *rs /* all the response data we'll send */ )
+{
struct berval base = BER_BVNULL;
ber_len_t siz, off, i;
int manageDSAit;
goto return_results;
}
+ if ( op->ors_tlimit < 0 || op->ors_tlimit > SLAP_MAX_LIMIT ) {
+ send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid time limit" );
+ goto return_results;
+ }
+
+ if ( op->ors_slimit < 0 || op->ors_slimit > SLAP_MAX_LIMIT ) {
+ send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid size limit" );
+ goto return_results;
+ }
+
switch( op->ors_scope ) {
case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL:
if( rs->sr_err == SLAPD_DISCONNECT ) {
rs->sr_err = LDAP_PROTOCOL_ERROR;
send_ldap_disconnect( op, rs );
+ rs->sr_err = SLAPD_DISCONNECT;
} else {
send_ldap_result( op, rs );
}
#endif /* LDAP_SLAPI */
return_results:;
+ if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) return rs->sr_err;
+ if ( ( op->o_sync_slog_size != -1 ) ) return rs->sr_err;
- if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
- return rs->sr_err;
-
- if ( ( op->o_sync_slog_size != -1 ) )
- return rs->sr_err;
-
- if( op->o_req_dn.bv_val != NULL) sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
- if( op->o_req_ndn.bv_val != NULL) sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+ if( !BER_BVISNULL( &op->o_req_dn ) ) {
+ slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
+ }
+ if( !BER_BVISNULL( &op->o_req_ndn ) ) {
+ slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+ }
- if( op->ors_filterstr.bv_val != NULL) op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+ if( !BER_BVISNULL( &op->ors_filterstr ) ) {
+ op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+ }
if( op->ors_filter != NULL) filter_free_x( op, op->ors_filter );
- if( op->ors_attrs != NULL ) op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
+ if( op->ors_attrs != NULL ) {
+ op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
+ }
+
#ifdef LDAP_SLAPI
if( attrs != NULL) op->o_tmpfree( attrs, op->o_tmpmemctx );
#endif /* LDAP_SLAPI */
/* Note: this is different from LDAP_NO_LIMIT (0); slapd internal use only */
#define SLAP_NO_LIMIT -1
+#define SLAP_MAX_LIMIT 2147483647
struct slap_limits {
unsigned lm_flags; /* type of pattern */
char **si_attrs;
int si_type;
time_t si_interval;
+ time_t *si_retryinterval;
+ int *si_retrynum_init;
+ int *si_retrynum;
struct sync_cookie si_syncCookie;
int si_manageDSAit;
int si_slimit;
# rootdn can always read and write EVERYTHING!
#######################################################################
-# ldbm database definitions
+# BDB database definitions
#######################################################################
database bdb
return 1;
}
- if ( !c->cac_attrsonly ) {
+ if ( !c->cac_attrsonly && a->a_vals != NULL ) {
for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
if ( !access_allowed( op, e,
desc, &a->a_vals[i], ACL_READ, &c->cac_acl_state)) {
ctrls[1] = NULL;
}
- timeout.tv_sec = si->si_tlimit > 0 ? si->si_tlimit : 1;
+ timeout.tv_sec = si->si_tlimit;
timeout.tv_usec = 0;
rc = ldap_search_ext( si->si_ld, si->si_base.bv_val, si->si_scope,
si->si_filterstr.bv_val, si->si_attrs, si->si_attrsonly,
- ctrls, NULL, si->si_tlimit < 0 ? NULL : &timeout,
+ ctrls, NULL, si->si_tlimit > 0 ? &timeout : NULL,
si->si_slimit, &msgid );
ber_free_buf( ber );
int first = 0;
int dostop = 0;
ber_socket_t s;
+ int i, defer = 1;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 );
arg );
} else {
connection_client_enable( s );
- }
+ }
} else if ( !first ) {
dostop = 1;
}
* 4) for Persist and Success, reschedule to defer
*/
ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+
if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) {
ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask );
}
connection_client_stop( s );
}
- if ( rc && rc != LDAP_SERVER_DOWN ) {
- ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
+ if ( rc == LDAP_SUCCESS ) {
+ if ( si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
+ defer = 0;
+ }
+ rtask->interval.tv_sec = si->si_interval;
+ ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, defer );
+ if ( si->si_retrynum ) {
+ for ( i = 0; si->si_retrynum_init[i] != -2; i++ ) {
+ si->si_retrynum[i] = si->si_retrynum_init[i];
+ }
+ si->si_retrynum[i] = -2;
+ }
} else {
- if ( rc == LDAP_SERVER_DOWN ||
- si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
- rc = 0;
- } else {
- rc = 1;
+ for ( i = 0; si->si_retrynum && si->si_retrynum[i] <= 0; i++ ) {
+ if ( si->si_retrynum[i] == -1 || si->si_retrynum[i] == -2 )
+ break;
+ }
+
+ if ( !si->si_retrynum || si->si_retrynum[i] == -2 ) {
+ ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
+ } else if ( si->si_retrynum[i] >= -1 ) {
+ if ( si->si_retrynum[i] > 0 )
+ si->si_retrynum[i]--;
+ rtask->interval.tv_sec = si->si_retryinterval[i];
+ ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
+ slap_wake_listener();
}
- ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, rc );
}
+
ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
return NULL;
struct berval syncUUID_strrep = BER_BVNULL;
struct berval uuid_bv = BER_BVNULL;
- SlapReply rs = {REP_RESULT};
+ SlapReply rs_search = {REP_RESULT};
+ SlapReply rs_delete = {REP_RESULT};
+ SlapReply rs_add = {REP_RESULT};
+ SlapReply rs_modify = {REP_RESULT};
Filter f = {0};
AttributeAssertion ava = {0};
int rc = LDAP_SUCCESS;
op->o_req_dn = si->si_base;
op->o_req_ndn = si->si_base;
+ op->o_time = slap_get_time();
+ op->ors_tlimit = SLAP_NO_LIMIT;
+ op->ors_slimit = 1;
+
/* set callback function */
op->o_callback = &cb;
cb.sc_response = dn_callback;
si->si_syncUUID_ndn.bv_val = NULL;
- if ( limits_check( op, &rs ) == 0 ) {
- rc = be->be_search( op, &rs );
+ if ( limits_check( op, &rs_search ) == 0 ) {
+ rc = be->be_search( op, &rs_search );
}
if ( op->ors_filterstr.bv_val ) {
cb.sc_response = null_callback;
cb.sc_private = si;
- if ( rc == LDAP_SUCCESS && si->si_syncUUID_ndn.bv_val )
- {
+ if ( rs_search.sr_err == LDAP_SUCCESS && si->si_syncUUID_ndn.bv_val ) {
char *subseq_ptr;
if ( syncstate != LDAP_SYNC_DELETE ) {
op->o_req_dn = si->si_syncUUID_ndn;
op->o_req_ndn = si->si_syncUUID_ndn;
op->o_tag = LDAP_REQ_DELETE;
- rc = be->be_delete( op, &rs );
+ rc = be->be_delete( op, &rs_delete );
org_req_dn = op->o_req_dn;
org_req_ndn = op->o_req_ndn;
op->o_ndn = op->o_bd->be_rootndn;
op->o_managedsait = 1;
- while ( rs.sr_err == LDAP_SUCCESS &&
- op->o_delete_glue_parent ) {
+ while ( rs_delete.sr_err == LDAP_SUCCESS && op->o_delete_glue_parent ) {
op->o_delete_glue_parent = 0;
if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
slap_callback cb = { NULL };
op->o_req_dn = pdn;
op->o_req_ndn = pdn;
op->o_callback = &cb;
- op->o_bd->be_delete( op, &rs );
+ op->o_bd->be_delete( op, &rs_delete );
} else {
break;
}
switch ( syncstate ) {
case LDAP_SYNC_ADD:
case LDAP_SYNC_MODIFY:
- if ( rc == LDAP_SUCCESS ||
- rc == LDAP_REFERRAL ||
- rc == LDAP_NO_SUCH_OBJECT ||
- rc == LDAP_NOT_ALLOWED_ON_NONLEAF )
+ if ( rs_search.sr_err == LDAP_SUCCESS ||
+ rs_search.sr_err == LDAP_REFERRAL ||
+ rs_search.sr_err == LDAP_NO_SUCH_OBJECT ||
+ rs_search.sr_err == LDAP_NOT_ALLOWED_ON_NONLEAF )
{
attr_delete( &e->e_attrs, slap_schema.si_ad_entryUUID );
attr_merge_one( e, slap_schema.si_ad_entryUUID,
op->ora_e = e;
op->o_req_dn = e->e_name;
op->o_req_ndn = e->e_nname;
- rc = be->be_add( op, &rs );
- if ( rc != LDAP_SUCCESS ) {
- if ( rc == LDAP_ALREADY_EXISTS ) {
+ rc = be->be_add( op, &rs_add );
+
+ if ( rs_add.sr_err != LDAP_SUCCESS ) {
+ if ( rs_add.sr_err == LDAP_ALREADY_EXISTS &&
+ rs_search.sr_err != LDAP_NO_SUCH_OBJECT ) {
Modifications *mod;
Modifications *modtail = modlist;
op->o_req_dn = e->e_name;
op->o_req_ndn = e->e_nname;
- rc = be->be_modify( op, &rs );
- if ( rc != LDAP_SUCCESS ) {
+ rc = be->be_modify( op, &rs_modify );
+ if ( rs_modify.sr_err != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
"syncrepl_entry : be_modify failed (%d)\n",
- rc, 0, 0 );
+ rs_modify.sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
"syncrepl_entry : be_modify failed (%d)\n",
- rc, 0, 0 );
+ rs_modify.sr_err, 0, 0 );
#endif
}
ret = 1;
goto done;
- } else if ( rc == LDAP_REFERRAL || rc == LDAP_NO_SUCH_OBJECT ) {
+ } else if ( rs_modify.sr_err == LDAP_REFERRAL ||
+ rs_modify.sr_err == LDAP_NO_SUCH_OBJECT ) {
syncrepl_add_glue( op, e );
ret = 0;
goto done;
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
"syncrepl_entry : be_add failed (%d)\n",
- rc, 0, 0 );
+ rs_add.sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
"syncrepl_entry : be_add failed (%d)\n",
- rc, 0, 0 );
+ rs_add.sr_err, 0, 0 );
#endif
ret = 1;
goto done;
} else {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
- "syncrepl_entry : be_search failed (%d)\n", rc, 0, 0 );
+ "syncrepl_entry : be_search failed (%d)\n",
+ rs_search.sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "syncrepl_entry : be_search failed (%d)\n", rc, 0, 0 );
+ "syncrepl_entry : be_search failed (%d)\n",
+ rs_search.sr_err, 0, 0 );
#endif
ret = 1;
goto done;
{
Backend* be = op->o_bd;
slap_callback cb = { NULL };
- SlapReply rs = {REP_RESULT};
+ SlapReply rs_search = {REP_RESULT};
+ SlapReply rs_delete = {REP_RESULT};
+ SlapReply rs_modify = {REP_RESULT};
struct nonpresent_entry *np_list, *np_prev;
int rc;
Modifications *ml;
op->o_tag = LDAP_REQ_SEARCH;
op->ors_scope = si->si_scope;
op->ors_deref = LDAP_DEREF_NEVER;
- op->ors_slimit = 0;
- op->ors_tlimit = 0;
+ op->o_time = slap_get_time();
+ op->ors_tlimit = SLAP_NO_LIMIT;
+ op->ors_slimit = SLAP_NO_LIMIT;
op->ors_attrsonly = 0;
op->ors_attrs = NULL;
op->ors_filter = str2filter_x( op, si->si_filterstr.bv_val );
op->o_nocaching = 1;
op->o_managedsait = 0;
- if ( limits_check( op, &rs ) == 0 ) {
- be->be_search( op, &rs );
+ if ( limits_check( op, &rs_search ) == 0 ) {
+ rc = be->be_search( op, &rs_search );
}
op->o_managedsait = 1;
cb.sc_private = si;
op->o_req_dn = *np_prev->npe_name;
op->o_req_ndn = *np_prev->npe_nname;
- rc = op->o_bd->be_delete( op, &rs );
+ rc = op->o_bd->be_delete( op, &rs_delete );
- if ( rc == LDAP_NOT_ALLOWED_ON_NONLEAF ) {
+ if ( rs_delete.sr_err == LDAP_NOT_ALLOWED_ON_NONLEAF ) {
mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
mod->sml_op = LDAP_MOD_REPLACE;
mod->sml_desc = slap_schema.si_ad_objectClass;
op->o_tag = LDAP_REQ_MODIFY;
op->orm_modlist = modlist;
- rc = be->be_modify( op, &rs );
+ rc = be->be_modify( op, &rs_modify );
for ( ml = modlist; ml != NULL; ml = mlnext ) {
mlnext = ml->sml_next;
op->o_ndn = op->o_bd->be_rootndn;
op->o_managedsait = 1;
- while ( rs.sr_err == LDAP_SUCCESS &&
+ while ( rs_delete.sr_err == LDAP_SUCCESS &&
op->o_delete_glue_parent ) {
op->o_delete_glue_parent = 0;
if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
op->o_req_ndn = pdn;
op->o_callback = &cb;
/* give it a root privil ? */
- op->o_bd->be_delete( op, &rs );
+ op->o_bd->be_delete( op, &rs_delete );
} else {
break;
}
struct berval dn = {0, NULL};
struct berval ndn = {0, NULL};
Entry *glue;
- SlapReply rs = {REP_RESULT};
+ SlapReply rs_add = {REP_RESULT};
char *ptr, *comma;
op->o_tag = LDAP_REQ_ADD;
op->o_req_dn = glue->e_name;
op->o_req_ndn = glue->e_nname;
op->ora_e = glue;
- rc = be->be_add ( op, &rs );
- if ( rc == LDAP_SUCCESS ) {
+ rc = be->be_add ( op, &rs_add );
+ if ( rs_add.sr_err == LDAP_SUCCESS ) {
be_entry_release_w( op, glue );
} else {
/* incl. ALREADY EXIST */
op->o_req_dn = e->e_name;
op->o_req_ndn = e->e_nname;
op->ora_e = e;
- rc = be->be_add ( op, &rs );
- if ( rc == LDAP_SUCCESS ) {
+ rc = be->be_add ( op, &rs_add );
+ if ( rs_add.sr_err == LDAP_SUCCESS ) {
be_entry_release_w( op, e );
} else {
entry_free( e );
struct berval slap_syncrepl_cn_bv = BER_BVNULL;
slap_callback cb = { NULL };
- SlapReply rs = {REP_RESULT};
+ SlapReply rs_add = {REP_RESULT};
+ SlapReply rs_modify = {REP_RESULT};
slap_sync_cookie_free( &si->si_syncCookie, 0 );
slap_dup_sync_cookie( &si->si_syncCookie, syncCookie );
update_cookie_retry:
op->o_tag = LDAP_REQ_MODIFY;
op->orm_modlist = modlist;
- rc = be->be_modify( op, &rs );
+ rc = be->be_modify( op, &rs_modify );
- if ( rc != LDAP_SUCCESS ) {
- if ( rc == LDAP_REFERRAL ||
- rc == LDAP_NO_SUCH_OBJECT ) {
+ if ( rs_modify.sr_err != LDAP_SUCCESS ) {
+ if ( rs_modify.sr_err == LDAP_REFERRAL ||
+ rs_modify.sr_err == LDAP_NO_SUCH_OBJECT ) {
op->o_tag = LDAP_REQ_ADD;
op->ora_e = e;
- rc = be->be_add( op, &rs );
- if ( rc != LDAP_SUCCESS ) {
- if ( rc == LDAP_ALREADY_EXISTS ) {
+ rc = be->be_add( op, &rs_add );
+ if ( rs_add.sr_err != LDAP_SUCCESS ) {
+ if ( rs_add.sr_err == LDAP_ALREADY_EXISTS ) {
goto update_cookie_retry;
- } else if ( rc == LDAP_REFERRAL ||
- rc == LDAP_NO_SUCH_OBJECT ) {
+ } else if ( rs_add.sr_err == LDAP_REFERRAL ||
+ rs_add.sr_err == LDAP_NO_SUCH_OBJECT ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
"cookie will be non-persistent\n",
} else {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
- "be_add failed (%d)\n",
- rc, 0, 0 );
+ "be_add failed (%d)\n", rs_add.sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "be_add failed (%d)\n",
- rc, 0, 0 );
+ "be_add failed (%d)\n", rs_add.sr_err, 0, 0 );
#endif
}
} else {
} else {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
- "be_modify failed (%d)\n", rc, 0, 0 );
+ "be_modify failed (%d)\n", rs_modify.sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "be_modify failed (%d)\n", rc, 0, 0 );
+ "be_modify failed (%d)\n", rs_modify.sr_err, 0, 0 );
#endif
}
}
if ( si->si_syncUUID_ndn.bv_val != NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
- "dn_callback : multiple entries match dn\n", 0, 0, 0 );
+ "dn_callback : consistency error - entryUUID is not unique\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "dn_callback : multiple entries match dn\n", 0, 0, 0 );
+ "dn_callback : consistency error - entryUUID is not unique\n", 0, 0, 0 );
#endif
} else {
ber_dupbv_x( &si->si_syncUUID_ndn, &rs->sr_entry->e_nname, op->o_tmpmemctx );
}
+ } else if ( rs->sr_type == REP_RESULT ) {
+ if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ERR,
+ "dn_callback : consistency error - entryUUID is not unique\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "dn_callback : consistency error - entryUUID is not unique\n", 0, 0, 0 );
+#endif
+ }
}
return LDAP_SUCCESS;
const char ** text )
{
int rc;
- struct berval nv1 = BER_BVNULL;
- struct berval nv2 = BER_BVNULL;
assert( mr != NULL );
}
rc = (mr->smr_match)( match, flags,
- ad->ad_type->sat_syntax,
- mr,
- nv1.bv_val != NULL ? &nv1 : v1,
- nv2.bv_val != NULL ? &nv2 : v2 );
+ ad->ad_type->sat_syntax, mr, v1, v2 );
- if (nv1.bv_val ) free( nv1.bv_val );
- if (nv2.bv_val ) free( nv2.bv_val );
return rc;
}