]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
Build without HAVE_TLS
[openldap] / servers / slapd / syncrepl.c
index 6dd40777f5d6295b9c7dc2a670856d0e3f3961c3..b12ecd2cb6ff869b8fa77b20558b3ef373ea903b 100644 (file)
@@ -69,6 +69,7 @@ slap_mods2entry_syncrepl( Modifications *, Entry **, int,
 
 /* callback functions */
 static int cookie_callback( struct slap_op *, struct slap_rep * );
+static int dn_callback( struct slap_op *, struct slap_rep * );
 static int nonpresent_callback( struct slap_op *, struct slap_rep * );
 static int null_callback( struct slap_op *, struct slap_rep * );
 
@@ -118,7 +119,8 @@ do_syncrepl(
        void    *ctx,
        void    *arg )
 {
-       Backend *be = arg;
+       struct re_s* rtask = arg;
+       Backend *be = rtask->arg;
        syncinfo_t *si = ( syncinfo_t * ) be->syncinfo;
 
        SlapReply       rs = {REP_RESULT};
@@ -498,7 +500,7 @@ do_syncrepl(
                                        entry_free( entry );
                                for ( ml = modlist; ml != NULL; ml = mlnext ) {
                                        mlnext = ml->sml_next;
-                                       free( ml );
+                                       ber_memfree( ml );
                                }
                                break;
 
@@ -634,7 +636,6 @@ do_syncrepl(
                Debug( LDAP_DEBUG_ANY,
                        "do_syncrepl : unknown result\n", 0, 0, 0 );
 #endif
-               return NULL;
        }
 
 done:
@@ -646,6 +647,16 @@ done:
        if ( res )
                ldap_msgfree( res );
        ldap_unbind( ld );
+
+       ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+       ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask );
+       if ( si->type == LDAP_SYNC_REFRESH_ONLY ) {
+               ldap_pvt_runqueue_resched( &syncrepl_rq, rtask );
+       } else {
+               ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
+       }
+       ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+
        return NULL;
 }
 
@@ -688,6 +699,8 @@ syncrepl_message_to_entry(
        LDAPControl**   rctrls = NULL;
        BerElement*     ctrl_ber;
 
+       ber_tag_t       tag;
+
        *modlist = NULL;
 
        if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) {
@@ -721,10 +734,10 @@ syncrepl_message_to_entry(
 
        e->e_attrs = NULL;
 
-       for ( rc = ldap_get_attribute_ber( ld, msg, ber, &tmp.sml_type, &tmp.sml_bvalues);
-                 rc == LDAP_SUCCESS;
-                 rc = ldap_get_attribute_ber( ld, msg, ber, &tmp.sml_type, &tmp.sml_bvalues))
-       {
+       while ( ber_remaining( ber ) ) {
+               tag = ber_scanf( ber, "{mW}", &tmp.sml_type, &tmp.sml_values );
+
+               if ( tag == LBER_ERROR ) break;
                if ( tmp.sml_type.bv_val == NULL ) break;
 
                mod  = (Modifications *) ch_malloc( sizeof( Modifications ));
@@ -851,7 +864,7 @@ done:
        return e;
 }
 
-int 
+int
 syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 )
 {
        const struct berval *uuid1 = v_uuid1;
@@ -881,13 +894,12 @@ syncrepl_entry(
        char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
 
        SlapReply       rs = {REP_RESULT};
-       int rc;
+       int rc = LDAP_SUCCESS;
+
+       struct berval base_bv = {0, NULL};
 
-#if 0 /* FIXME : UUID search required first */
        char *filterstr;
-       struct berval filterstr_bv;
        Filter *filter;
-#endif
 
        Attribute *a;
 
@@ -909,74 +921,103 @@ syncrepl_entry(
                attr_merge_one( e, slap_schema.si_ad_entryUUID, syncUUID, syncUUID );
        }
 
-#if 0 /* FIXME : UUID search required first */
        filterstr = (char *) sl_malloc( strlen("entryUUID=") + syncUUID->bv_len + 1, op->o_tmpmemctx ); 
        strcpy( filterstr, "entryUUID=" );
        strcat( filterstr, syncUUID->bv_val );
-#endif
 
        si->e = e;
        si->syncUUID = syncUUID;
+       si->syncUUID_ndn = NULL;
 
-#if 0 /* FIXME : UUID search required first */
        filter = str2filter( filterstr );
-       ber_str2bv( filterstr, strlen(filterstr), 1, &filterstr_bv );
+       ber_str2bv( filterstr, strlen(filterstr), 1, &op->ors_filterstr );
        ch_free( filterstr );
-#endif
+       op->ors_filter = filter;
+       op->ors_scope = LDAP_SCOPE_SUBTREE;
 
-       op->o_req_dn = e->e_name;
-       op->o_req_ndn = e->e_nname;
+       /* get syncrepl cookie of shadow replica from subentry */
+       ber_str2bv( si->base, strlen(si->base), 1, &base_bv ); 
+       dnPrettyNormal( 0, &base_bv, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx );
+       ch_free( base_bv.bv_val );
 
+       /* set callback function */
        op->o_callback = &cb;
-       cb.sc_response = null_callback;
+       cb.sc_response = dn_callback;
        cb.sc_private = si;
 
+       be->be_search( op, &rs );
+
+       ch_free( op->o_req_dn.bv_val );
+       ch_free( op->o_req_ndn.bv_val );
+       filter_free( op->ors_filter );
+       ch_free( op->ors_filterstr.bv_val );
+
+       cb.sc_response = null_callback;
+
+       if ( si->syncUUID_ndn )
+               printf("syncUUID_ndn = %s\n", si->syncUUID_ndn );
+
        switch ( syncstate ) {
        case LDAP_SYNC_ADD :
        case LDAP_SYNC_MODIFY :
-sync_add_retry:
-               op->o_tag = LDAP_REQ_MODIFY;
-               op->orm_modlist = modlist;
-               rc = be->be_modify( op, &rs );
-               if ( rc != LDAP_SUCCESS ) {
-                       if ( rc == LDAP_REFERRAL ||
-                                rc == LDAP_NO_SUCH_OBJECT ||
-                                rc == DB_NOTFOUND ) {
-                               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 ) {
-                                               goto sync_add_retry;
-                                       } else if ( rc == LDAP_REFERRAL ||
-                                                               rc == LDAP_NO_SUCH_OBJECT ||
-                                                               rc == DB_NOTFOUND ) {
-                                               syncrepl_add_glue(ld, op, e,
-                                                       modlist, syncstate,
-                                                       syncUUID, syncCookie);
-                                       } else {
+
+               rc = LDAP_SUCCESS;
+
+               if ( si->syncUUID_ndn ) {
+                       op->o_req_dn = *si->syncUUID_ndn;
+                       op->o_req_ndn = *si->syncUUID_ndn;
+                       op->o_tag = LDAP_REQ_DELETE;
+                       rc = be->be_delete( op, &rs );
+               }
+
+               if ( rc == LDAP_SUCCESS ||
+                        rc == LDAP_REFERRAL ||
+                        rc == LDAP_NO_SUCH_OBJECT ||
+                        rc == DB_NOTFOUND ) {
+                       op->o_tag = LDAP_REQ_ADD;
+                       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 ) {
 #ifdef NEW_LOGGING
-                                               LDAP_LOG( OPERATION, ERR,
-                                                       "be_add failed (%d)\n",
-                                                       rc, 0, 0 );
+                                       LDAP_LOG( OPERATION, ERR,
+                                               "be_add failed : already exists (%d)\n",
+                                               rc, 0, 0 );
 #else
-                                               Debug( LDAP_DEBUG_ANY,
-                                                       "be_add failed (%d)\n",
-                                                       rc, 0, 0 );
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "be_add failed : already exists (%d)\n",
+                                               rc, 0, 0 );
 #endif
-                                       }
+                               } else if ( rc == LDAP_REFERRAL ||
+                                                       rc == LDAP_NO_SUCH_OBJECT ||
+                                                       rc == DB_NOTFOUND ) {
+                                       syncrepl_add_glue(ld, op, e,
+                                               modlist, syncstate,
+                                               syncUUID, syncCookie);
                                } else {
-                                       return 0;
+#ifdef NEW_LOGGING
+                                       LDAP_LOG( OPERATION, ERR,
+                                               "be_add failed (%d)\n",
+                                               rc, 0, 0 );
+#else
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "be_add failed (%d)\n",
+                                               rc, 0, 0 );
+#endif
                                }
                        } else {
+                               return 0;
+                       }
+               } else {
 #ifdef NEW_LOGGING
-                               LDAP_LOG( OPERATION, ERR,
-                                       "be_modify failed (%d)\n", rc, 0, 0 );
+                       LDAP_LOG( OPERATION, ERR,
+                               "be_modify/be_delete failed (%d)\n", rc, 0, 0 );
 #else
-                               Debug( LDAP_DEBUG_ANY,
-                                       "be_modify failed (%d)\n", rc, 0, 0 );
+                       Debug( LDAP_DEBUG_ANY,
+                               "be_modify/be_delete failed (%d)\n", rc, 0, 0 );
 #endif
-                       }
                }
 
                si->e = NULL;
@@ -1906,6 +1947,21 @@ cookie_callback(
        return LDAP_SUCCESS;
 }
 
+static int
+dn_callback(
+       Operation*      op,
+       SlapReply*      rs
+)
+{
+       syncinfo_t *si = op->o_callback->sc_private;
+       
+       if ( rs->sr_type == REP_SEARCH ) {
+               si->syncUUID_ndn = &rs->sr_entry->e_nname;
+       }
+
+       return LDAP_SUCCESS;
+}
+
 static int
 nonpresent_callback(
        Operation*      op,
@@ -1972,4 +2028,44 @@ null_callback(
        return LDAP_SUCCESS;
 }
 
+
+char **
+str2clist( char **out, char *in, const char *brkstr )
+{
+       char    *str;
+       char    *s;
+       char    *lasts;
+       int     i, j;
+       const char *text;
+       char    **new;
+
+       /* find last element in list */
+       for (i = 0; out && out[i]; i++);
+       
+       /* protect the input string from strtok */
+       str = ch_strdup( in );
+
+       /* Count words in string */
+       j=1;
+       for ( s = str; *s; s++ ) {
+               if ( strchr( brkstr, *s ) != NULL ) {
+                       j++;
+               }
+       }
+
+       out = ch_realloc( out, ( i + j + 1 ) * sizeof( char * ) );
+       new = out + i;
+       for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
+               s != NULL;
+               s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
+       {
+               *new = ch_strdup( s );
+               new++;
+       }
+
+       *new = NULL;
+       free( str );
+       return( out );
+}
+
 #endif