]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/syncprov.c
More for prev commit - set entryCSN as well.
[openldap] / servers / slapd / overlays / syncprov.c
index ceb2d9eea6237fa2686236940eeae1e8e30cc817..a62d0a0d0d8829ca15a8d54f9adcb78d6aafc56a 100644 (file)
@@ -383,6 +383,9 @@ findbase_cb( Operation *op, SlapReply *rs )
        return LDAP_SUCCESS;
 }
 
+static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL };
+static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
+
 static int
 syncprov_findbase( Operation *op, fbase_cookie *fc )
 {
@@ -422,6 +425,8 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
                fop.ors_tlimit = SLAP_NO_LIMIT;
                fop.ors_attrs = slap_anlist_no_attrs;
                fop.ors_attrsonly = 1;
+               fop.ors_filter = &generic_filter;
+               fop.ors_filterstr = generic_filterstr;
 
                fop.o_bd->bd_info = on->on_info->oi_orig;
                rc = fop.o_bd->be_search( &fop, &frs );
@@ -445,12 +450,10 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
                case LDAP_SCOPE_SUBTREE:
                        fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base );
                        break;
-#ifdef LDAP_SCOPE_SUBORDINATE
                case LDAP_SCOPE_SUBORDINATE:
                        fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base ) &&
                                !dn_match( fc->fdn, &fc->fss->s_base );
                        break;
-#endif
                }
        }
 
@@ -478,9 +481,11 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
  * CSN, and generate Present records for them. We always collect this result
  * in SyncID sets, even if there's only one match.
  */
-#define        FIND_MAXCSN     1
-#define        FIND_CSN        2
-#define        FIND_PRESENT    3
+typedef enum find_csn_t {
+       FIND_MAXCSN     = 1,
+       FIND_CSN        = 2,
+       FIND_PRESENT    = 3
+} find_csn_t;
 
 static int
 findmax_cb( Operation *op, SlapReply *rs )
@@ -503,7 +508,11 @@ findcsn_cb( Operation *op, SlapReply *rs )
 {
        slap_callback *sc = op->o_callback;
 
-       if ( rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS ) {
+       /* We just want to know that at least one exists, so it's OK if
+        * we exceed the unchecked limit.
+        */
+       if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ||
+               (rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS )) {
                sc->sc_private = (void *)1;
        }
        return LDAP_SUCCESS;
@@ -559,7 +568,7 @@ findpres_cb( Operation *op, SlapReply *rs )
 }
 
 static int
-syncprov_findcsn( Operation *op, int mode )
+syncprov_findcsn( Operation *op, find_csn_t mode )
 {
        slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
        syncprov_info_t         *si = on->on_bi.bi_private;
@@ -576,10 +585,10 @@ syncprov_findcsn( Operation *op, int mode )
 #else
        AttributeAssertion eq = { NULL, BER_BVNULL };
 #endif
-       int i, rc = LDAP_SUCCESS;
        fpres_cookie pcookie;
        sync_control *srs = NULL;
-       int findcsn_retry = 1;
+       struct slap_limits_set fc_limits;
+       int i, rc = LDAP_SUCCESS, findcsn_retry = 1;
 
        if ( mode != FIND_MAXCSN ) {
                srs = op->o_controls[slap_cids.sc_LDAPsync];
@@ -630,6 +639,8 @@ again:
                /* On retry, look for <= */
                } else {
                        cf.f_choice = LDAP_FILTER_LE;
+                       fop.ors_limit = &fc_limits;
+                       fc_limits.lms_s_unchecked = 1;
                        fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
                                cf.f_av_value.bv_val );
                }
@@ -729,7 +740,8 @@ syncprov_free_syncop( syncops *so )
 
 /* Send a persistent search response */
 static int
-syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry **e, int mode)
+syncprov_sendresp( Operation *op, opcookie *opc, syncops *so,
+       Entry **e, int mode )
 {
        slap_overinst *on = opc->son;
 
@@ -1214,9 +1226,9 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
        syncprov_info_t         *si = on->on_bi.bi_private;
        Modifications mod;
        Operation opm;
+       SlapReply rsm = { 0 };
        struct berval bv[2];
        slap_callback cb = {0};
-       int manage = get_manageDSAit(op);
 
        mod.sml_values = bv;
        bv[1].bv_val = NULL;
@@ -1236,8 +1248,12 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
        opm.o_req_ndn = op->o_bd->be_nsuffix[0];
        opm.o_bd->bd_info = on->on_info->oi_orig;
        opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;
-       opm.o_bd->be_modify( &opm, rs );
-       opm.o_managedsait = manage;
+       SLAP_DBFLAGS( opm.o_bd ) |= SLAP_DBFLAG_NOLASTMOD;
+       opm.o_bd->be_modify( &opm, &rsm );
+       SLAP_DBFLAGS( opm.o_bd ) ^= SLAP_DBFLAG_NOLASTMOD;
+       if ( mod.sml_next != NULL ) {
+               slap_mods_free( mod.sml_next, 1 );
+       }
 }
 
 static void
@@ -2139,6 +2155,13 @@ sp_cf_gen(ConfigArgs *c)
                                rc = 1;
                        }
                        break;
+               case SP_USEHINT:
+                       if ( si->si_usehint ) {
+                               c->value_int = 1;
+                       } else {
+                               rc = 1;
+                       }
+                       break;
                }
                return rc;
        } else if ( c->op == LDAP_MOD_DELETE ) {
@@ -2159,13 +2182,42 @@ sp_cf_gen(ConfigArgs *c)
                        else
                                rc = LDAP_NO_SUCH_ATTRIBUTE;
                        break;
+               case SP_USEHINT:
+                       if ( si->si_usehint )
+                               si->si_usehint = 0;
+                       else
+                               rc = LDAP_NO_SUCH_ATTRIBUTE;
+                       break;
                }
                return rc;
        }
        switch ( c->type ) {
        case SP_CHKPT:
-               si->si_chkops = atoi( c->argv[1] );
-               si->si_chktime = atoi( c->argv[2] ) * 60;
+               if ( lutil_atoi( &si->si_chkops, c->argv[1] ) != 0 ) {
+                       sprintf( c->msg, "%s unable to parse checkpoint ops # \"%s\"",
+                               c->argv[0], c->argv[1] );
+                       Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+                       return ARG_BAD_CONF;
+               }
+               if ( si->si_chkops <= 0 ) {
+                       sprintf( c->msg, "%s invalid checkpoint ops # \"%d\"",
+                               c->argv[0], si->si_chkops );
+                       Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+                       return ARG_BAD_CONF;
+               }
+               if ( lutil_atoi( &si->si_chktime, c->argv[2] ) != 0 ) {
+                       sprintf( c->msg, "%s unable to parse checkpoint time \"%s\"",
+                               c->argv[0], c->argv[1] );
+                       Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+                       return ARG_BAD_CONF;
+               }
+               if ( si->si_chktime <= 0 ) {
+                       sprintf( c->msg, "%s invalid checkpoint time \"%d\"",
+                               c->argv[0], si->si_chkops );
+                       Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+                       return ARG_BAD_CONF;
+               }
+               si->si_chktime *= 60;
                break;
        case SP_SESSL: {
                sessionlog *sl;
@@ -2193,6 +2245,9 @@ sp_cf_gen(ConfigArgs *c)
        case SP_NOPRES:
                si->si_nopres = c->value_int;
                break;
+       case SP_USEHINT:
+               si->si_usehint = c->value_int;
+               break;
        }
        return rc;
 }
@@ -2440,6 +2495,7 @@ static int syncprov_parseCtrl (
                        rs->sr_text = "Sync control : cookie decoding error";
                        return LDAP_PROTOCOL_ERROR;
                }
+               tag = ber_peek_tag( ber, &len );
        }
        if ( tag == LDAP_TAG_RELOAD_HINT ) {
                if (( ber_scanf( ber, /*{*/ "b", &rhint )) == LBER_ERROR ) {
@@ -2481,7 +2537,7 @@ static int syncprov_parseCtrl (
 static slap_overinst           syncprov;
 
 int
-syncprov_init()
+syncprov_initialize()
 {
        int rc;
 
@@ -2514,6 +2570,8 @@ syncprov_init()
 
        syncprov.on_bi.bi_cf_ocs = spocs;
 
+       generic_filter.f_desc = slap_schema.si_ad_objectClass;
+
        rc = config_register_schema( spcfg, spocs );
        if ( rc ) return rc;
 
@@ -2524,7 +2582,7 @@ syncprov_init()
 int
 init_module( int argc, char *argv[] )
 {
-       return syncprov_init();
+       return syncprov_initialize();
 }
 #endif /* SLAPD_OVER_SYNCPROV == SLAPD_MOD_DYNAMIC */