]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Tue, 29 Jun 2004 23:45:49 +0000 (23:45 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 29 Jun 2004 23:45:49 +0000 (23:45 +0000)
31 files changed:
servers/slapd/add.c
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/ctxcsn.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/dn2entry.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/search.c
servers/slapd/bind.c
servers/slapd/config.c
servers/slapd/connection.c
servers/slapd/controls.c
servers/slapd/daemon.c
servers/slapd/extended.c
servers/slapd/filterentry.c
servers/slapd/limits.c
servers/slapd/oc.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/schema_init.c
servers/slapd/schema_prep.c
servers/slapd/search.c
servers/slapd/slap.h
servers/slapd/slapd.conf
servers/slapd/slapi/slapi_utils.c
servers/slapd/syncrepl.c
servers/slapd/value.c

index da0ae87789e1e80a7f817bfd2196231236fed38e..db2b0743ba93db6ac0d8ed50b2fc490472477be6 100644 (file)
@@ -82,7 +82,7 @@ do_add( Operation *op, SlapReply *rs )
                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) );
@@ -125,12 +125,12 @@ do_add( Operation *op, SlapReply *rs )
                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;
                }
 
@@ -168,7 +168,7 @@ do_add( Operation *op, SlapReply *rs )
                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;
        }
 
@@ -383,7 +383,6 @@ do_add( Operation *op, SlapReply *rs )
 #endif /* LDAP_SLAPI */
 
 done:
-
        slap_graduate_commit_csn( op );
 
        if( modlist != NULL ) {
index 476043febe5cdc61f20072f005d60cef05e7b810..104b289d7a39ed1b5cb7d739eab2f25136f04c41 100644 (file)
@@ -49,6 +49,7 @@ bdb_add(Operation *op, SlapReply *rs )
        Entry           *ctxcsn_e;
        int                     ctxcsn_added = 0;
 
+       LDAPControl **postread_ctrl = NULL;
        LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
        int num_ctrls = 0;
 
@@ -60,6 +61,8 @@ bdb_add(Operation *op, SlapReply *rs )
                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 );
@@ -344,23 +347,6 @@ retry:     /* transaction retry */
                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, &lt2, 
                bdb->bi_db_opflags );
@@ -462,6 +448,26 @@ retry:     /* transaction retry */
                }
        }
 
+       /* 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";
@@ -495,13 +501,23 @@ retry:    /* transaction retry */
                }
 
                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 ) {
@@ -555,5 +571,9 @@ done:
                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;
 }
index 3420b0d9a15cfb12c55cf6ee38a7d8e1325168b3..e3846c9b9b64acd1c4236b9019bbb6cd7bc11e96 100644 (file)
@@ -92,7 +92,13 @@ typedef struct bdb_entry_info {
        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
@@ -129,6 +135,7 @@ typedef struct bdb_cache {
        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
index 6002a9b83d94c87d935f6c1d9c7d496315d94ec2..85d4d052d4e1654100987793919095b3e0fe6bd7 100644 (file)
@@ -74,8 +74,8 @@ bdb_cache_entry_db_relock(
 
        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;
@@ -121,8 +121,8 @@ bdb_cache_entry_db_lock( DB_ENV *env, u_int32_t locker, EntryInfo *ei,
        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);
@@ -532,7 +532,7 @@ bdb_cache_lru_add(
                        /* 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,
@@ -655,45 +655,53 @@ again:    ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
                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
+                               }
+
                        }
                }
        }
@@ -749,11 +757,23 @@ bdb_cache_add(
 {
        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, ',' );
@@ -1166,7 +1186,7 @@ bdb_cache_delete_entry(
        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 );
index a76bae3331ca556e23a662fa5b0381c601e20ac1..294362430fc618a7b5d7f1d326548c18e3e859b9 100644 (file)
@@ -259,6 +259,7 @@ bdb_get_commit_csn(
        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 )) {
@@ -282,21 +283,16 @@ consumer_ctxcsn_retry :
                                }
                                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 ) {
@@ -345,15 +341,12 @@ provider_ctxcsn_retry :
                                                                        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;
@@ -366,9 +359,10 @@ 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 );
@@ -377,15 +371,17 @@ txn_retry:
                                                                &ltid, 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;
                        }
@@ -393,21 +389,22 @@ 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;
@@ -415,9 +412,8 @@ txn_retry:
                        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 ) {
@@ -433,5 +429,16 @@ txn_retry:
                }
        }
 
-       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;
 }
index cdd614bb4c8d578026aadbcb331b196a0ab00d0e..148230ec01419f82c4c69cc716a66853a7647e82 100644 (file)
@@ -48,14 +48,18 @@ bdb_delete( Operation *op, SlapReply *rs )
        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 );
@@ -67,6 +71,10 @@ retry:       /* transaction retry */
                        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 );
@@ -197,7 +205,19 @@ retry:     /* transaction retry */
                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 ) {
@@ -219,9 +239,6 @@ retry:      /* transaction retry */
                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:
@@ -346,8 +363,12 @@ retry:     /* transaction retry */
 
        /* 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, 
@@ -358,7 +379,6 @@ retry:      /* transaction retry */
 #endif
                        goto return_results;
                }
-               ctrls[++num_ctrls] = NULL;
        }
 
        /* nested transaction */
@@ -480,8 +500,6 @@ retry:      /* transaction retry */
                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 );
@@ -561,11 +579,22 @@ retry:    /* transaction retry */
                }
 
                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 );
@@ -620,6 +649,9 @@ return_results:
        }
 
 done:
+       if ( p )
+               bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
+
        /* free entry */
        if( e != NULL ) {
                if ( rs->sr_err == LDAP_SUCCESS ) {
@@ -635,5 +667,9 @@ done:
                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;
 }
index 25d79e5256d97ce2142db101b2d9dbe34235b48a..c221edaa08a61036d69b676ec46625c05a61ea38 100644 (file)
@@ -38,7 +38,7 @@ bdb_dn2entry(
        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 );
@@ -56,10 +56,11 @@ bdb_dn2entry(
                         * 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 );
@@ -72,8 +73,9 @@ bdb_dn2entry(
                } 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;
                }
        }
index 3bc535b21197dbb804ff1a8ca16b2d82b7b084ae..9742b9ca24bd3e513be4c7fa2cc7d678a1968994 100644 (file)
@@ -447,6 +447,8 @@ bdb_db_open( BackendDB *be )
                return rc;
        }
 
+       bdb->bi_dbenv->lock_id(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
+
        /* <insert> open (and create) index databases */
        return 0;
 }
index c8d65d789fb030cf8e0b65301b6aa1b96d0e9890..ce0195e35d5a01a5bb5879780b36fdc4900a17b1 100644 (file)
@@ -116,8 +116,11 @@ int bdb_modify_internal(
                        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 );
@@ -353,6 +356,8 @@ bdb_modify( Operation *op, SlapReply *rs )
 
        int             num_retries = 0;
 
+       LDAPControl **preread_ctrl = NULL;
+       LDAPControl **postread_ctrl = NULL;
        LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
        int num_ctrls = 0;
 
@@ -364,11 +369,15 @@ bdb_modify( Operation *op, SlapReply *rs )
        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 ) {
@@ -462,7 +471,9 @@ retry:      /* transaction retry */
        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 )
@@ -505,7 +516,9 @@ retry:      /* transaction retry */
                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",
@@ -530,16 +543,31 @@ retry:    /* transaction retry */
        }
 
        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,
@@ -550,8 +578,6 @@ retry:      /* transaction retry */
 #endif
                        goto return_results;
                }
-               ctrls[++num_ctrls] = NULL;
-               op->o_preread = 0; /* prevent redo on retry */
        }
 
        /* nested transaction */
@@ -561,7 +587,8 @@ retry:      /* transaction retry */
        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",
@@ -591,29 +618,13 @@ retry:    /* transaction retry */
                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 ) {
@@ -628,6 +639,8 @@ retry:      /* transaction retry */
                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";
@@ -647,10 +660,31 @@ retry:    /* transaction retry */
                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";
@@ -663,6 +697,8 @@ retry:      /* transaction retry */
                switch( rc ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
+                       attrs_free( dummy.e_attrs ); 
+                       dummy.e_attrs = NULL;
                        goto retry;
                }
 
@@ -675,20 +711,42 @@ retry:    /* transaction 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 );
@@ -754,5 +812,14 @@ done:
        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;
 }
index 749f6571deefbf33906fd52d3e7475a4218ae1e9..8d29504e7cf869ef2932866d2c2766e54a234d17 100644 (file)
@@ -60,6 +60,8 @@ bdb_modrdn( Operation *op, SlapReply *rs )
 
        int             num_retries = 0;
 
+       LDAPControl **preread_ctrl = NULL;
+       LDAPControl **postread_ctrl = NULL;
        LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
        int num_ctrls = 0;
 
@@ -73,6 +75,8 @@ bdb_modrdn( Operation *op, SlapReply *rs )
        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,
@@ -789,8 +793,12 @@ retry:     /* transaction retry */
        }
 
        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,
@@ -801,8 +809,6 @@ retry:      /* transaction retry */
 #endif
                        goto return_results;
                }                   
-               ctrls[++num_ctrls] = NULL;
-               op->o_preread = 0;  /* prevent redo on retry */
        }
 
        /* nested transaction */
@@ -888,11 +894,22 @@ retry:    /* transaction retry */
        }
 
        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 */
@@ -919,24 +936,6 @@ retry:     /* transaction 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_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 ) {
@@ -959,37 +958,35 @@ retry:    /* transaction retry */
                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;
@@ -1008,6 +1005,25 @@ retry:   /* transaction 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_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";
@@ -1034,20 +1050,42 @@ retry:  /* transaction 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_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 ) {
@@ -1154,5 +1192,13 @@ done:
                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;
 }
index 8561e1ca5d9f205b829593057ccd31e22ba6071a..40a9f5a86788b538decb779960bbe3f768aef619 100644 (file)
@@ -537,10 +537,19 @@ int bdb_locker_id( Operation *op, DB_ENV *env, int *locker );
 #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,
@@ -548,7 +557,6 @@ int bdb_do_search(
        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
index 552f30a108698eb4c23c7534912474c7c5a7bff0..31a8776796c353338a434a7b98a1c93fdcde326f 100644 (file)
@@ -361,6 +361,18 @@ int bdb_search( Operation *op, SlapReply *rs )
        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.
  */
@@ -408,14 +420,18 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        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 ) {
@@ -509,14 +525,19 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
                }
        }
 
-       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 ) {
@@ -532,7 +553,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        } 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 );
        }
 
@@ -545,14 +566,16 @@ dn2entry_retry:
                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;
        }
 
@@ -592,7 +615,8 @@ dn2entry_retry:
                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;
@@ -634,7 +658,8 @@ dn2entry_retry:
                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 );
@@ -895,7 +920,7 @@ loop_begin:
 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) {
@@ -1468,7 +1493,8 @@ done:
                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 );
 
@@ -1709,17 +1735,17 @@ send_paged_response(
        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;
@@ -1735,17 +1761,16 @@ send_paged_response(
 
        } 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;
index 1423aca172aa19b10c948930a2976ce101c27c80..6a6698558743e492b47c8362edb7dbfa06af8092 100644 (file)
@@ -41,8 +41,7 @@
 int
 do_bind(
     Operation  *op,
-    SlapReply  *rs
-)
+    SlapReply  *rs )
 {
        BerElement *ber = op->o_ber;
        ber_int_t version;
@@ -117,7 +116,7 @@ do_bind(
                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;
        }
 
@@ -308,11 +307,9 @@ do_bind(
                                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;
index 9fa278a724d2c859036627aa080de83d356f4ca9..afcfdcf1f7d3f687c3f1aeb775313541d7c3e676 100644 (file)
@@ -120,6 +120,8 @@ read_config( const char *fname, int depth )
        LDAPURLDesc *ludp;
        static BackendInfo *bi = NULL;
        static BackendDB        *be = NULL;
+       char    *next;
+
 
        vals[1].bv_val = NULL;
 
@@ -259,7 +261,7 @@ read_config( const char *fname, int depth )
                        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,
@@ -270,7 +272,19 @@ read_config( const char *fname, int depth )
                                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
@@ -541,7 +555,19 @@ read_config( const char *fname, int depth )
                                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
@@ -815,8 +841,6 @@ read_config( const char *fname, int depth )
                                        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
@@ -895,8 +919,6 @@ read_config( const char *fname, int depth )
                                        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
@@ -1131,25 +1153,38 @@ read_config( const char *fname, int depth )
 "%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, lineno0 );
 #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 ) {
@@ -1504,64 +1539,67 @@ read_config( const char *fname, int depth )
                        }
 
                        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
@@ -1572,7 +1610,24 @@ read_config( const char *fname, int depth )
 
                                        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 ) {
@@ -1640,10 +1695,22 @@ read_config( const char *fname, int depth )
                                        "%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 */
@@ -1770,11 +1837,11 @@ read_config( const char *fname, int depth )
                        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
 
@@ -1784,7 +1851,21 @@ read_config( const char *fname, int depth )
                        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) */
@@ -2886,12 +2967,15 @@ add_syncrepl(
        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;
 
@@ -3002,6 +3086,8 @@ add_syncrepl(
 #define SLIMITSTR              "sizelimit"
 #define TLIMITSTR              "timelimit"
 
+#define RETRYSTR               "retry"
+
 #define GOT_ID                 0x0001
 #define GOT_PROVIDER   0x0002
 #define GOT_METHOD             0x0004
@@ -3190,54 +3276,104 @@ parse_syncrepl_line(
                } 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 ) )
                {
index e59a95c371cd9389dca503f25e5ee8948d7c4ec0..0309b877c8909ff50aae2b015d87ce53a48a306b 100644 (file)
@@ -948,7 +948,7 @@ void connection_done( Connection *c )
 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;
@@ -966,6 +966,36 @@ connection_operation( void *ctx, void *arg_v )
 
        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, 
@@ -978,6 +1008,7 @@ connection_operation( void *ctx, void *arg_v )
 #endif
                send_ldap_error( op, &rs, LDAP_OPERATIONS_ERROR,
                        "SASL bind in progress" );
+               rc = LDAP_OPERATIONS_ERROR;
                goto operations_error;
        }
 
@@ -1053,29 +1084,15 @@ connection_operation( void *ctx, void *arg_v )
                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) {
@@ -1109,6 +1126,9 @@ operations_error:
        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 );
@@ -1116,7 +1136,6 @@ operations_error:
        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 )
        {
@@ -1128,14 +1147,17 @@ operations_error:
        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;
@@ -1161,9 +1183,7 @@ operations_error:
        }
 
        connection_resched( conn );
-
        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
-
        return NULL;
 }
 
@@ -1174,11 +1194,12 @@ int connection_client_setup(
        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;
@@ -1190,15 +1211,13 @@ int connection_client_setup(
 }
 
 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;
 
@@ -1333,14 +1352,13 @@ int connection_read(ber_socket_t s)
                        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 );
@@ -1573,6 +1591,10 @@ connection_input(
        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;
index c43a95cbf36abfd8233a0d18693ce45192dab580..c1546e145f19bdbf6fd14f0ebfd3a28b6560df42 100644 (file)
@@ -918,6 +918,16 @@ static int parsePagedResults (
 
        } 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;
        }
index d7257eaffc29940f69a12ac82d958a11b05cd9ae..084e4394dbedf4ad95fc97845776741127ba3ca8 100644 (file)
@@ -2142,3 +2142,8 @@ void slapd_add_internal(ber_socket_t s, int isactive) {
 Listener ** slapd_get_listeners(void) {
        return slap_listeners;
 }
+
+void slap_wake_listener()
+{
+       WAKE_LISTENER(1);
+}
index 0abb6db23d38036b82e1ab48c754c10f7888eee7..27a06ad87cc291727a2db341035266fb877be51f 100644 (file)
@@ -163,7 +163,7 @@ do_extended(
                        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;
        }
 
@@ -175,7 +175,7 @@ do_extended(
                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;
        }
 
@@ -211,7 +211,7 @@ do_extended(
                        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;
                }
        }
index 01455e8ba5946d4c54c1707169318cbc0ccbd129..ceba658ced0deb0379df1214f636862f8370100d 100644 (file)
@@ -203,7 +203,16 @@ static int test_mra_filter(
        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 ) {
                /*
@@ -267,7 +276,7 @@ static int test_mra_filter(
                        /* 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;
                        }
 
@@ -291,7 +300,7 @@ static int test_mra_filter(
                                        break;
                                }
                        }
-                       op->o_tmpfree( value.bv_val, memctx );
+                       memfree( value.bv_val, memctx );
                        if ( rc != LDAP_SUCCESS ) return rc;
                }
        }
@@ -348,7 +357,7 @@ static int test_mra_filter(
                                        if ( !access_allowed( op, e,
                                                ad, &value, ACL_SEARCH, NULL ) )
                                        {
-                                               op->o_tmpfree( value.bv_val, memctx );
+                                               memfree( value.bv_val, memctx );
                                                continue;
                                        }
                                }
@@ -358,7 +367,7 @@ static int test_mra_filter(
                                        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;
index b32ea0be77a63f5cfbb08f054a9838c1a9402207..c60e734068c3ff6eac2004c133f76448b56b6bd3 100644 (file)
@@ -23,6 +23,9 @@
 
 #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 )
 {
@@ -734,7 +737,7 @@ limits_parse_one(
                        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 {
@@ -750,7 +753,7 @@ limits_parse_one(
                                        }
 
                                        if ( soft == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead; issue warning? */
                                        }
 
                                        limit->lms_t_soft = soft;
@@ -761,7 +764,7 @@ limits_parse_one(
                                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 {
@@ -777,7 +780,7 @@ limits_parse_one(
                                        }
 
                                        if ( hard == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        if ( hard == 0 ) {
@@ -793,7 +796,7 @@ limits_parse_one(
                        
                } 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 {
@@ -817,7 +820,7 @@ limits_parse_one(
                        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 {
@@ -833,7 +836,7 @@ limits_parse_one(
                                        }
 
                                        if ( soft == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        limit->lms_s_soft = soft;
@@ -844,7 +847,7 @@ limits_parse_one(
                                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 {
@@ -860,7 +863,7 @@ limits_parse_one(
                                        }
 
                                        if ( hard == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        if ( hard == 0 ) {
@@ -872,7 +875,7 @@ limits_parse_one(
                                
                        } 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 ) {
@@ -891,7 +894,7 @@ limits_parse_one(
                                        }
 
                                        if ( unchecked == -1 ) {
-                                               /*  FIXME: use "none" instead */
+                                               /*  FIXME: use "unlimited" instead */
                                        }
 
                                        limit->lms_s_unchecked = unchecked;
@@ -902,7 +905,7 @@ limits_parse_one(
                                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 {
@@ -918,7 +921,7 @@ limits_parse_one(
                                        }
 
                                        if ( pr == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        limit->lms_s_pr = pr;
@@ -927,7 +930,7 @@ limits_parse_one(
                        } 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 ) {
@@ -950,7 +953,7 @@ limits_parse_one(
                                        }
 
                                        if ( total == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        if ( total == 0 ) {
@@ -966,7 +969,7 @@ limits_parse_one(
                        
                } 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 {
@@ -995,7 +998,20 @@ limits_check( Operation *op, SlapReply *rs )
        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;
@@ -1022,18 +1038,27 @@ limits_check( Operation *op, SlapReply *rs )
                } 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 */
                        }
                }
 
@@ -1082,13 +1107,22 @@ limits_check( Operation *op, SlapReply *rs )
                        }
 
                        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 */
@@ -1097,15 +1131,20 @@ limits_check( Operation *op, SlapReply *rs )
 
                                /* 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;
@@ -1140,7 +1179,7 @@ limits_check( Operation *op, SlapReply *rs )
                
                        /* 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 ) {
@@ -1173,13 +1212,22 @@ limits_check( Operation *op, SlapReply *rs )
 
                        /* 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 */
                        }
                }
 
index 78ebaa7c6083cd2dc0f1ee17044e8fd446542813..42fd967ec3701c95ae85de91ebd7e460a6d30f00 100644 (file)
@@ -469,6 +469,7 @@ oc_add(
        }
 
        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;
@@ -476,7 +477,7 @@ oc_add(
        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;
index 357bcf4809343a4cb2c6be694e31cc41957c836f..a6f349bf3249d97a56f4423b1580f9e3deba1b51 100644 (file)
@@ -420,6 +420,7 @@ LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive, int wake
 
 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));
index f591b5e6c29f09091fe92039a6db88038fcc47ac..cef4daee4b78848f7be12bb3d23318e3223eb3e8 100644 (file)
@@ -524,7 +524,6 @@ send_ldap_disconnect( Operation     *op, SlapReply *rs )
                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 );
@@ -614,11 +613,15 @@ slap_send_ldap_result( Operation *op, SlapReply *rs )
         */
        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 */
 
@@ -929,12 +932,12 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        {
 #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;
                        }
@@ -949,7 +952,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 #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;
@@ -963,13 +967,13 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 #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;
@@ -992,7 +996,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 #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;
                                        }
                                }
@@ -1129,8 +1134,10 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                                "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;
@@ -1147,7 +1154,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 #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;
                }
@@ -1232,9 +1240,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        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 {
                        /*
@@ -1664,7 +1670,14 @@ int slap_read_controls(
        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;
 }
index 7a26363f5ce5f33873749087d9097a622d911bea..b28477384c234cbab6c72400b32ca0d1950dd8a0 100644 (file)
@@ -738,38 +738,172 @@ bitStringValidate(
        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 );
@@ -802,38 +936,52 @@ nameUIDPretty(
                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':
@@ -841,11 +989,13 @@ nameUIDPretty(
                                                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';
                }
        }
@@ -880,22 +1030,18 @@ uniqueMemberNormalize(
        } 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 );
@@ -905,9 +1051,18 @@ uniqueMemberNormalize(
                        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++] = '#';
@@ -943,51 +1098,49 @@ uniqueMemberMatch(
        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;
@@ -1931,7 +2084,8 @@ numericStringNormalize(
  * 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
@@ -1956,13 +2110,16 @@ integerBitAndMatch(
 
        /* 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;
        }
@@ -1992,8 +2149,8 @@ integerBitOrMatch(
 
        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;
        }
@@ -2024,9 +2181,7 @@ serialNumberAndIssuerValidate(
 
        /* 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 */
@@ -2078,9 +2233,7 @@ serialNumberAndIssuerPretty(
        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 */
index 2835e2a93ed53879b2587e00cfa97efbaa803e36..9ebb77a1e8724e2a75dc9b67ac49fc512ba44b35 100644 (file)
@@ -57,31 +57,26 @@ oidValidate(
                }
 
        } 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--;
                }
index c35ef511a2fcde4130ea68fcfe4f862d9ab706cc..41984eac8684f403efea22f37e335b3bfcea22fd 100644 (file)
@@ -47,8 +47,8 @@ static void call_search_postop_plugins( Operation *op );
 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;
@@ -97,6 +97,16 @@ do_search(
                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:
@@ -150,6 +160,7 @@ do_search(
                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 );
                }
@@ -412,19 +423,24 @@ do_search(
 #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 */
index 9eb6795e7a6a59ee775a23fb7b810189871d997a..96ea47c23607642fb407f7359246ffeeeb70c061 100644 (file)
@@ -1302,6 +1302,7 @@ struct slap_limits_set {
 
 /* 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 */
@@ -1395,6 +1396,9 @@ typedef struct syncinfo_s {
         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;
index f7f251113d7088dfc1fc4fe79a01bf792e0fec25..2531929648c75629be58c928650e7d837cb5c2b3 100644 (file)
@@ -49,7 +49,7 @@ argsfile      %LOCALSTATEDIR%/run/slapd.args
 # rootdn can always read and write EVERYTHING!
 
 #######################################################################
-# ldbm database definitions
+# BDB database definitions
 #######################################################################
 
 database       bdb
index 1a082f425791d43447b14a93352c9376e334bed7..538651ac162a76fdc4951f1fe3eebc449667f8ef 100644 (file)
@@ -3584,7 +3584,7 @@ int slapi_int_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_
                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)) {
index 9ed5606acc5860f79ec983dcc39ea56881816aaf..94f1e5c3d3dff38647b475fac9f6920dee22784d 100644 (file)
@@ -153,12 +153,12 @@ ldap_sync_search(
                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 );
 
@@ -807,6 +807,7 @@ do_syncrepl(
        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 );
@@ -869,7 +870,7 @@ do_syncrepl(
                                                arg );
                                } else {
                                        connection_client_enable( s );
-                               }
+                               } 
                        } else if ( !first ) {
                                dostop = 1;
                        }
@@ -885,6 +886,7 @@ do_syncrepl(
         * 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 );
        }
@@ -893,17 +895,35 @@ do_syncrepl(
                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;
@@ -1061,7 +1081,10 @@ syncrepl_entry(
        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;
@@ -1108,6 +1131,10 @@ syncrepl_entry(
        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;
@@ -1115,8 +1142,8 @@ syncrepl_entry(
 
        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 ) {
@@ -1126,8 +1153,7 @@ syncrepl_entry(
        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 ) {
@@ -1144,7 +1170,7 @@ syncrepl_entry(
                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;
@@ -1155,8 +1181,7 @@ syncrepl_entry(
                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 };
@@ -1165,7 +1190,7 @@ syncrepl_entry(
                                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;
                    }
@@ -1184,10 +1209,10 @@ syncrepl_entry(
        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,
@@ -1197,10 +1222,12 @@ syncrepl_entry(
                        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;
 
@@ -1223,21 +1250,22 @@ syncrepl_entry(
                                        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;
@@ -1245,11 +1273,11 @@ syncrepl_entry(
 #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;
@@ -1262,10 +1290,12 @@ syncrepl_entry(
                } 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;
@@ -1313,7 +1343,9 @@ syncrepl_del_nonpresent(
 {
        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;
@@ -1340,8 +1372,9 @@ syncrepl_del_nonpresent(
        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 );
@@ -1350,8 +1383,8 @@ syncrepl_del_nonpresent(
        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;
@@ -1371,9 +1404,9 @@ syncrepl_del_nonpresent(
                        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;
@@ -1393,7 +1426,7 @@ syncrepl_del_nonpresent(
                                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;
@@ -1410,7 +1443,7 @@ syncrepl_del_nonpresent(
                        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 )) {
@@ -1421,7 +1454,7 @@ syncrepl_del_nonpresent(
                                        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;
                            }
@@ -1461,7 +1494,7 @@ syncrepl_add_glue(
        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;
@@ -1537,8 +1570,8 @@ syncrepl_add_glue(
                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 */
@@ -1565,8 +1598,8 @@ syncrepl_add_glue(
        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 );
@@ -1624,7 +1657,8 @@ syncrepl_updateCookie(
        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 );
@@ -1730,19 +1764,19 @@ syncrepl_updateCookie(
 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",
@@ -1755,12 +1789,10 @@ update_cookie_retry:
                                } 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 {
@@ -1770,10 +1802,10 @@ update_cookie_retry:
                } 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
                }
        }
@@ -1843,14 +1875,24 @@ dn_callback(
                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;
index 893803def992d74cba5d292812aa852b12c9c1db..3a71d10514fd4f190bfb188681da8ecf20516862 100644 (file)
@@ -215,8 +215,6 @@ value_match(
        const char ** text )
 {
        int rc;
-       struct berval nv1 = BER_BVNULL;
-       struct berval nv2 = BER_BVNULL;
 
        assert( mr != NULL );
 
@@ -225,13 +223,8 @@ value_match(
        }
 
        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;
 }