]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
ITS#2919 move OpenLDAPtime to OpenLDAPperson
[openldap] / servers / slapd / syncrepl.c
index 93a5d3b35e1218e436c1c1387b603a4d4cd0bd11..58fca6ce87bf17e73c3ddae56545ec3c58d66460 100644 (file)
@@ -244,9 +244,9 @@ ldap_sync_search(
        c[0].ldctl_iscritical = si->si_type < 0;
        ctrls[0] = &c[0];
 
-       if ( si->si_authzId ) {
+       if ( si->si_bindconf.sb_authzId ) {
                c[1].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
-               ber_str2bv( si->si_authzId, 0, 0, &c[1].ldctl_value );
+               ber_str2bv( si->si_bindconf.sb_authzId, 0, 0, &c[1].ldctl_value );
                c[1].ldctl_iscritical = 1;
                ctrls[1] = &c[1];
                ctrls[2] = NULL;
@@ -282,11 +282,11 @@ do_syncrep1(
        psub = &si->si_be->be_nsuffix[0];
 
        /* Init connection to master */
-       rc = ldap_initialize( &si->si_ld, si->si_provideruri );
+       rc = ldap_initialize( &si->si_ld, si->si_provideruri.bv_val );
        if ( rc != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_ANY,
                        "do_syncrep1: ldap_initialize failed (%s)\n",
-                       si->si_provideruri, 0, 0 );
+                       si->si_provideruri.bv_val, 0, 0 );
                return rc;
        }
 
@@ -295,39 +295,40 @@ do_syncrep1(
 
        /* Bind to master */
 
-       if ( si->si_tls ) {
+       if ( si->si_bindconf.sb_tls ) {
                rc = ldap_start_tls_s( si->si_ld, NULL, NULL );
                if( rc != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_ANY,
                                "%s: ldap_start_tls failed (%d)\n",
-                               si->si_tls == SYNCINFO_TLS_CRITICAL ? "Error" : "Warning",
+                               si->si_bindconf.sb_tls == SB_TLS_CRITICAL ? "Error" : "Warning",
                                rc, 0 );
-                       if( si->si_tls == SYNCINFO_TLS_CRITICAL ) goto done;
+                       if( si->si_bindconf.sb_tls == SB_TLS_CRITICAL ) goto done;
                }
        }
 
-       if ( si->si_bindmethod == LDAP_AUTH_SASL ) {
+       if ( si->si_bindconf.sb_method == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
                void *defaults;
 
-               if ( si->si_secprops != NULL ) {
+               if ( si->si_bindconf.sb_secprops != NULL ) {
                        rc = ldap_set_option( si->si_ld,
-                               LDAP_OPT_X_SASL_SECPROPS, si->si_secprops);
+                               LDAP_OPT_X_SASL_SECPROPS, si->si_bindconf.sb_secprops);
 
                        if( rc != LDAP_OPT_SUCCESS ) {
                                Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option "
                                        "(%s,SECPROPS,\"%s\") failed!\n",
-                                       si->si_provideruri, si->si_secprops, 0 );
+                                       si->si_provideruri.bv_val, si->si_bindconf.sb_secprops, 0 );
                                goto done;
                        }
                }
 
-               defaults = lutil_sasl_defaults( si->si_ld, si->si_saslmech,
-                       si->si_realm, si->si_authcId, si->si_passwd, si->si_authzId );
+               defaults = lutil_sasl_defaults( si->si_ld, si->si_bindconf.sb_saslmech,
+                       si->si_bindconf.sb_realm, si->si_bindconf.sb_authcId,
+                       si->si_bindconf.sb_cred, si->si_bindconf.sb_authzId );
 
                rc = ldap_sasl_interactive_bind_s( si->si_ld,
-                               si->si_binddn,
-                               si->si_saslmech,
+                               si->si_bindconf.sb_binddn,
+                               si->si_bindconf.sb_saslmech,
                                NULL, NULL,
                                LDAP_SASL_QUIET,
                                lutil_sasl_interact,
@@ -346,7 +347,7 @@ do_syncrep1(
 
                        /* FIXME (see above comment) */
                        /* if Kerberos credentials cache is not active, retry */
-                       if ( strcmp( si->si_saslmech, "GSSAPI" ) == 0 &&
+                       if ( strcmp( si->si_bindconf.sb_saslmech, "GSSAPI" ) == 0 &&
                                rc == LDAP_LOCAL_ERROR )
                        {
                                rc = LDAP_SERVER_DOWN;
@@ -363,8 +364,8 @@ do_syncrep1(
 #endif
 
        } else {
-               rc = ldap_bind_s( si->si_ld,
-                       si->si_binddn, si->si_passwd, si->si_bindmethod );
+               rc = ldap_bind_s( si->si_ld, si->si_bindconf.sb_binddn,
+                       si->si_bindconf.sb_cred, si->si_bindconf.sb_method );
                if ( rc != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_ANY, "do_syncrep1: "
                                "ldap_bind_s failed (%d)\n", rc, 0, 0 );
@@ -430,10 +431,8 @@ do_syncrep1(
                        slap_sync_cookie_free( sc, 1 );
                }
 
-               if ( !BER_BVISNULL( &si->si_syncCookie.ctxcsn )) {
-                       slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
-                               &si->si_syncCookie.ctxcsn, si->si_syncCookie.rid );
-               }
+               slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
+                       &si->si_syncCookie.ctxcsn, si->si_syncCookie.rid );
        }
 
        rc = ldap_sync_search( si, op->o_tmpmemctx );
@@ -529,6 +528,10 @@ do_syncrep2(
                        msg != NULL;
                        msg = ldap_next_message( si->si_ld, msg ) )
                {
+                       if ( slapd_shutdown ) {
+                               rc = -2;
+                               goto done;
+                       }
                        switch( ldap_msgtype( msg ) ) {
                        case LDAP_RES_SEARCH_ENTRY:
                                ldap_get_entry_controls( si->si_ld, msg, &rctrls );
@@ -841,11 +844,14 @@ do_syncrepl(
        if ( si == NULL )
                return NULL;
 
+       ldap_pvt_thread_mutex_lock( &si->si_mutex );
+
        switch( abs( si->si_type )) {
        case LDAP_SYNC_REFRESH_ONLY:
        case LDAP_SYNC_REFRESH_AND_PERSIST:
                break;
        default:
+               ldap_pvt_thread_mutex_unlock( &si->si_mutex );
                return NULL;
        }
 
@@ -856,6 +862,7 @@ do_syncrepl(
                        ldap_unbind( si->si_ld );
                        si->si_ld = NULL;
                }
+               ldap_pvt_thread_mutex_unlock( &si->si_mutex );
                return NULL;
        }
 
@@ -949,6 +956,7 @@ do_syncrepl(
        }
        
        ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+       ldap_pvt_thread_mutex_unlock( &si->si_mutex );
 
        return NULL;
 }
@@ -1145,14 +1153,11 @@ syncrepl_entry(
        SlapReply       rs_add = {REP_RESULT};
        SlapReply       rs_modify = {REP_RESULT};
        Filter f = {0};
-       AttributeAssertion ava = {0};
+       AttributeAssertion ava = { NULL, BER_BVNULL, NULL };
        int rc = LDAP_SUCCESS;
        int ret = LDAP_SUCCESS;
 
        struct berval pdn = BER_BVNULL;
-       struct berval org_req_dn = BER_BVNULL;
-       struct berval org_req_ndn = BER_BVNULL;
-       int     org_managedsait;
        dninfo dni = {0};
        int     retry = 1;
 
@@ -1206,12 +1211,13 @@ syncrepl_entry(
        ava.aa_value = *syncUUID;
        op->ors_filter = &f;
 
-       op->ors_filterstr.bv_len = STRLENOF( "entryUUID=" ) + syncUUID->bv_len;
+       op->ors_filterstr.bv_len = STRLENOF( "(entryUUID=)" ) + syncUUID->bv_len;
        op->ors_filterstr.bv_val = (char *) slap_sl_malloc(
                op->ors_filterstr.bv_len + 1, op->o_tmpmemctx ); 
-       AC_MEMCPY( op->ors_filterstr.bv_val, "entryUUID=", STRLENOF( "entryUUID=" ) );
-       AC_MEMCPY( &op->ors_filterstr.bv_val[STRLENOF( "entryUUID=" )],
+       AC_MEMCPY( op->ors_filterstr.bv_val, "(entryUUID=", STRLENOF( "(entryUUID=" ) );
+       AC_MEMCPY( &op->ors_filterstr.bv_val[STRLENOF( "(entryUUID=" )],
                syncUUID->bv_val, syncUUID->bv_len );
+       op->ors_filterstr.bv_val[op->ors_filterstr.bv_len - 1] = ')';
        op->ors_filterstr.bv_val[op->ors_filterstr.bv_len] = '\0';
 
        op->o_tag = LDAP_REQ_SEARCH;
@@ -1248,7 +1254,7 @@ syncrepl_entry(
        cb.sc_response = null_callback;
        cb.sc_private = si;
 
-       if ( entry && entry->e_name.bv_val ) {
+       if ( entry && !BER_BVISNULL( &entry->e_name ) ) {
                Debug( LDAP_DEBUG_SYNC,
                                "syncrepl_entry: %s\n",
                                entry->e_name.bv_val, 0, 0 );
@@ -1258,15 +1264,23 @@ syncrepl_entry(
                                dni.dn.bv_val ? dni.dn.bv_val : "(null)", 0, 0 );
        }
 
-       org_req_dn = op->o_req_dn;
-       org_req_ndn = op->o_req_ndn;
-       org_managedsait = get_manageDSAit( op );
-       op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
-
        if ( syncstate != LDAP_SYNC_DELETE ) {
-               attr_delete( &entry->e_attrs, slap_schema.si_ad_entryUUID );
-               attr_merge_one( entry, slap_schema.si_ad_entryUUID,
-                       &syncUUID_strrep, syncUUID );
+               Attribute       *a = attr_find( entry->e_attrs, slap_schema.si_ad_entryUUID );
+
+               if ( a == NULL ) {
+                       /* add if missing */
+                       attr_merge_one( entry, slap_schema.si_ad_entryUUID,
+                               &syncUUID_strrep, syncUUID );
+
+               } else if ( !bvmatch( &a->a_nvals[0], syncUUID ) ) {
+                       /* replace only if necessary */
+                       if ( a->a_nvals != a->a_vals ) {
+                               ber_memfree( a->a_nvals[0].bv_val );
+                               ber_dupbv( &a->a_nvals[0], syncUUID );
+                       }
+                       ber_memfree( a->a_vals[0].bv_val );
+                       ber_dupbv( &a->a_vals[0], &syncUUID_strrep );
+               }
        }
 
        switch ( syncstate ) {
@@ -1512,17 +1526,11 @@ syncrepl_del_nonpresent(
        SlapReply       rs_modify = {REP_RESULT};
        struct nonpresent_entry *np_list, *np_prev;
        int rc;
-       Modifications *ml;
-       Modifications *mlnext;
-       Modifications *mod;
-       Modifications *modlist = NULL;
-       Modifications **modtail;
        AttributeName   an[2];
 
        struct berval pdn = BER_BVNULL;
        struct berval org_req_dn = BER_BVNULL;
        struct berval org_req_ndn = BER_BVNULL;
-       int     org_managedsait;
 
        op->o_req_dn = si->si_base;
        op->o_req_ndn = si->si_base;
@@ -1540,14 +1548,13 @@ syncrepl_del_nonpresent(
 
        if ( uuids ) {
                Filter uf;
-               AttributeAssertion eq;
+               AttributeAssertion eq = { NULL, BER_BVNULL, NULL };
                int i;
 
                op->ors_attrsonly = 1;
                op->ors_attrs = slap_anlist_no_attrs;
                op->ors_limit = NULL;
                op->ors_filter = &uf;
-               op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
 
                uf.f_ava = &eq;
                uf.f_av_desc = slap_schema.si_ad_entryUUID;
@@ -1571,7 +1578,6 @@ syncrepl_del_nonpresent(
                op->ors_filter = str2filter_x( op, si->si_filterstr.bv_val );
                op->ors_filterstr = si->si_filterstr;
                op->o_nocaching = 1;
-               op->o_managedsait = SLAP_CONTROL_NONE;
 
                if ( limits_check( op, &rs_search ) == 0 ) {
                        rc = be->be_search( op, &rs_search );
@@ -1579,10 +1585,12 @@ syncrepl_del_nonpresent(
                if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
        }
 
-       op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
        op->o_nocaching = 0;
 
        if ( !LDAP_LIST_EMPTY( &si->si_nonpresentlist ) ) {
+
+               slap_queue_csn( op, &si->si_syncCookie.ctxcsn );
+
                np_list = LDAP_LIST_FIRST( &si->si_nonpresentlist );
                while ( np_list != NULL ) {
                        LDAP_LIST_REMOVE( np_list, npe_link );
@@ -1597,37 +1605,27 @@ syncrepl_del_nonpresent(
                        rc = op->o_bd->be_delete( op, &rs_delete );
 
                        if ( rs_delete.sr_err == LDAP_NOT_ALLOWED_ON_NONLEAF ) {
-                               modtail = &modlist;
-                               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
-                               mod->sml_op = LDAP_MOD_REPLACE;
-                               mod->sml_desc = slap_schema.si_ad_objectClass;
-                               mod->sml_type = mod->sml_desc->ad_cname;
-                               mod->sml_values = &gcbva[0];
-                               *modtail = mod;
-                               modtail = &mod->sml_next;
-
-                               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
-                               mod->sml_op = LDAP_MOD_REPLACE;
-                               mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
-                               mod->sml_type = mod->sml_desc->ad_cname;
-                               mod->sml_values = &gcbva[1];
-                               *modtail = mod;
-                               modtail = &mod->sml_next;
+                               Modifications mod1, mod2;
+                               mod1.sml_op = LDAP_MOD_REPLACE;
+                               mod1.sml_desc = slap_schema.si_ad_objectClass;
+                               mod1.sml_type = mod1.sml_desc->ad_cname;
+                               mod1.sml_values = &gcbva[0];
+                               mod1.sml_nvalues = NULL;
+                               mod1.sml_next = &mod2;
+
+                               mod2.sml_op = LDAP_MOD_REPLACE;
+                               mod2.sml_desc = slap_schema.si_ad_structuralObjectClass;
+                               mod2.sml_type = mod2.sml_desc->ad_cname;
+                               mod2.sml_values = &gcbva[1];
+                               mod2.sml_nvalues = NULL;
+                               mod2.sml_next = NULL;
 
                                op->o_tag = LDAP_REQ_MODIFY;
-                               op->orm_modlist = modlist;
+                               op->orm_modlist = &mod1;
 
                                rc = be->be_modify( op, &rs_modify );
-
-                               for ( ml = modlist; ml != NULL; ml = mlnext ) {
-                                       mlnext = ml->sml_next;
-                                       free( ml );
-                               }
                        }
 
-                       org_managedsait = get_manageDSAit( op );
-                       op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
-
                        while ( rs_delete.sr_err == LDAP_SUCCESS &&
                                        op->o_delete_glue_parent ) {
                                op->o_delete_glue_parent = 0;
@@ -1645,17 +1643,14 @@ syncrepl_del_nonpresent(
                            }
                        }
 
-                       op->o_managedsait = org_managedsait;
-                       op->o_req_dn = org_req_dn;
-                       op->o_req_ndn = org_req_ndn;
                        op->o_delete_glue_parent = 0;
 
                        ber_bvfree( np_prev->npe_name );
                        ber_bvfree( np_prev->npe_nname );
-                       BER_BVZERO( &op->o_req_dn );
-                       BER_BVZERO( &op->o_req_ndn );
                        ch_free( np_prev );
                }
+
+               slap_graduate_commit_csn( op );
        }
 
        return;
@@ -2089,33 +2084,13 @@ avl_ber_bvfree( void *v_bv )
 void
 syncinfo_free( syncinfo_t *sie )
 {
-       if ( sie->si_provideruri ) {
-               ch_free( sie->si_provideruri );
-       }
-       if ( sie->si_provideruri_bv ) {
-               ber_bvarray_free( sie->si_provideruri_bv );
-       }
-       if ( sie->si_binddn ) {
-               ch_free( sie->si_binddn );
-       }
-       if ( sie->si_passwd ) {
-               ch_free( sie->si_passwd );
-       }
-       if ( sie->si_saslmech ) {
-               ch_free( sie->si_saslmech );
-       }
-       if ( sie->si_secprops ) {
-               ch_free( sie->si_secprops );
-       }
-       if ( sie->si_realm ) {
-               ch_free( sie->si_realm );
-       }
-       if ( sie->si_authcId ) {
-               ch_free( sie->si_authcId );
-       }
-       if ( sie->si_authzId ) {
-               ch_free( sie->si_authzId );
+       ldap_pvt_thread_mutex_destroy( &sie->si_mutex );
+       if ( !BER_BVISNULL( &sie->si_provideruri ) ) {
+               ch_free( sie->si_provideruri.bv_val );
        }
+
+       bindconf_free( &sie->si_bindconf );
+
        if ( sie->si_filterstr.bv_val ) {
                ch_free( sie->si_filterstr.bv_val );
        }