X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsyncrepl.c;h=b12ecd2cb6ff869b8fa77b20558b3ef373ea903b;hb=9184d038ead9aeabff5b7c0bb2ed0d1e6bc95c8c;hp=e8e3017fc76173073738ac863e649c497be541c4;hpb=fd3cf2b5edebcc228591efa34fd035e3b1d76bb1;p=openldap diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index e8e3017fc7..b12ecd2cb6 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -35,9 +35,11 @@ #ifdef LDAP_SYNCREPL +#include "ldap_rq.h" + static Entry* -syncrepl_message_to_entry ( LDAP *, Operation *, LDAPMessage *, Modifications *, - int*, struct berval *, struct berval * ); +syncrepl_message_to_entry ( LDAP *, Operation *, LDAPMessage *, + Modifications **, int*, struct berval *, struct berval * ); static int syncrepl_entry( LDAP *, Operation*, Entry*, Modifications*, @@ -59,7 +61,7 @@ slap_mods_check_syncrepl( Operation *, Modifications **, static int slap_mods_opattrs_syncrepl( Operation *, Modifications *, Modifications **, - const char **, char *, size_t ); + const char **, char *, size_t ); static int slap_mods2entry_syncrepl( Modifications *, Entry **, int, @@ -67,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 * ); @@ -75,6 +78,8 @@ static AttributeDescription **add_descs_lastmod; static AttributeDescription **del_descs; static AttributeDescription **del_descs_lastmod; +struct runqueue_s syncrepl_rq; + void init_syncrepl() { @@ -114,20 +119,25 @@ 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}; - LDAPControl c[2], **sctrls = NULL, **rctrls = NULL, *rctrlp; - BerElement *sync_ber; - struct berval *sync_bvalp; + LDAPControl c[2]; + LDAPControl **sctrls = NULL; + LDAPControl **rctrls = NULL; + LDAPControl *rctrlp = NULL; + BerElement *sync_ber = NULL; + struct berval *sync_bvalp = NULL; - BerElement *ctrl_ber; - BerElement *res_ber; + BerElement *ctrl_ber = NULL; + BerElement *res_ber = NULL; LDAP *ld = NULL; - LDAPMessage *res = NULL, *msg; + LDAPMessage *res = NULL; + LDAPMessage *msg = NULL; ber_int_t msgid; @@ -139,11 +149,11 @@ do_syncrepl( struct berval *retdata = NULL; int sync_info_arrived = 0; - Entry *entry; + Entry *entry = NULL; int syncstate; - struct berval syncUUID; - struct berval syncCookie; + struct berval syncUUID = { 0, NULL }; + struct berval syncCookie = { 0, NULL }; int rc; int err; @@ -151,17 +161,18 @@ do_syncrepl( int syncinfo_arrived = 0; int cancel_response = 0; - char **tmp; - AttributeDescription** descs; + char **tmp = NULL; + AttributeDescription** descs = NULL; Connection conn; Operation op = {0}; slap_callback cb; - void *memctx; + void *memctx = NULL; ber_len_t memsiz; int i, j, k, n; + int rc_efree; struct berval base_bv = { 0, NULL }; struct berval pbase = { 0, NULL }; @@ -172,10 +183,9 @@ do_syncrepl( struct berval psub = { 0, NULL }; struct berval nsub = { 0, NULL }; char substr[64]; - Modifications *modlist; - - char *def_filter_str; - struct berval def_filter_bv = { 0, NULL }; + Modifications *modlist = NULL; + Modifications *ml, *mlnext; + char *def_filter_str = NULL; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 ); @@ -314,6 +324,27 @@ do_syncrepl( si->ctx = ctx; + op.o_tmpmemctx = NULL; /* FIXME : to use per-thread mem context */ + op.o_tag = LDAP_REQ_SEARCH; + op.o_dn = si->updatedn; + op.o_ndn = si->updatedn; + op.o_callback = &cb; + op.o_time = slap_get_time(); + op.o_managedsait = 1; + op.o_threadctx = si->ctx; + op.o_bd = be; + op.o_conn = &conn; + op.o_connid = op.o_conn->c_connid; + op.ors_scope = LDAP_SCOPE_BASE; + op.ors_deref = LDAP_DEREF_NEVER; + op.ors_slimit = -1; + op.ors_tlimit = -1; + op.ors_attrsonly = 0; + op.ors_attrs = NULL; + op.ors_filter = str2filter( def_filter_str = "(objectClass=*)" ); + ber_str2bv( def_filter_str, strlen( def_filter_str ), 1, + &op.ors_filterstr ); + si->conn = &conn; conn.c_send_ldap_result = slap_send_ldap_result; conn.c_send_search_entry = slap_send_search_entry; @@ -330,13 +361,12 @@ do_syncrepl( build_new_dn( &op.o_req_dn, &pbase, &psubrdn ); build_new_dn( &op.o_req_ndn, &nbase, &nsubrdn ); - op.o_tag = LDAP_REQ_SEARCH; - op.o_ndn = be->be_rootndn; - psub = be->be_nsuffix[0]; - op.o_callback = &cb; - op.o_time = slap_get_time(); - op.o_managedsait = 1; - op.o_threadctx = si->ctx; + ch_free( base_bv.bv_val ); + ch_free( pbase.bv_val ); + ch_free( nbase.bv_val ); + ch_free( sub_bv.bv_val ); + ch_free( psubrdn.bv_val ); + ch_free( nsubrdn.bv_val ); /* set callback function */ cb.sc_response = cookie_callback; @@ -344,24 +374,18 @@ do_syncrepl( /* search subentry to retrieve cookie */ si->syncCookie = NULL; + be->be_search( &op, &rs ); - op.o_bd = be; - op.o_conn = &conn; - op.o_connid = op.o_conn->c_connid; - op.ors_scope = LDAP_SCOPE_BASE; - op.ors_deref = LDAP_DEREF_NEVER; - op.ors_slimit = -1; - op.ors_tlimit = -1; - op.ors_attrsonly = 0; - op.ors_attrs = NULL; - op.ors_filter = str2filter( def_filter_str = "(objectClass=*)" ); - ber_str2bv( def_filter_str, strlen( def_filter_str ), 1, - &op.ors_filterstr ); + 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 ); - be->be_search( &op, &rs ); + psub = be->be_nsuffix[0]; /* setup LDAP SYNC control */ sync_ber = ber_alloc_t( LBER_USE_DER ); + ber_set_option( sync_ber, LBER_OPT_BER_MEMCTX, op.o_tmpmemctx ); if ( si->syncCookie ) { ber_printf( sync_ber, "{eO}", abs(si->type), si->syncCookie ); @@ -375,7 +399,7 @@ do_syncrepl( } ber_free( sync_ber, 1 ); - sctrls = (LDAPControl**) ch_calloc( 3, sizeof(LDAPControl*) ); + sctrls = (LDAPControl**) sl_calloc( 3, sizeof(LDAPControl*), op.o_tmpmemctx ); c[0].ldctl_oid = LDAP_CONTROL_SYNC; c[0].ldctl_value = (*sync_bvalp); @@ -397,7 +421,7 @@ do_syncrepl( err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, sctrls ); ber_bvfree( sync_bvalp ); - free( sctrls ); + ch_free( sctrls ); if ( err != LDAP_OPT_SUCCESS ) fprintf( stderr, "Could not set controls : %d\n", err ); @@ -422,8 +446,7 @@ do_syncrepl( /* Add Attributes */ - for ( n = 0; si->attrs[ n ] != NULL; n++ ) - ; + for ( n = 0; si->attrs[ n ] != NULL; n++ ) ; if ( si->lastmod == LASTMOD_REQ ) { descs = add_descs_lastmod; @@ -442,8 +465,7 @@ do_syncrepl( #endif } si->attrs = tmp; - si->attrs[ n++ ] = ( char * ) strndup( descs[i]->ad_cname.bv_val, - descs[i]->ad_cname.bv_len ); + si->attrs[ n++ ] = ch_strdup ( descs[i]->ad_cname.bv_val ); si->attrs[ n ] = NULL; } @@ -454,7 +476,7 @@ do_syncrepl( NULL, -1, &msgid ); if( rc != LDAP_SUCCESS ) { - fprintf( stderr, "syncrepl: ldap_search_ext (%d)\n", + fprintf( stderr, "syncrepl: ldap_search_ext: %s (%d)\n", ldap_err2string( rc ), rc ); return NULL; } @@ -467,14 +489,18 @@ do_syncrepl( { switch( ldap_msgtype( msg ) ) { case LDAP_RES_SEARCH_ENTRY: - entry = syncrepl_message_to_entry( ld, &op, msg, modlist, &syncstate, &syncUUID, &syncCookie ); - syncrepl_entry( ld, &op, entry, modlist, - syncstate, &syncUUID, - &syncCookie, - !syncinfo_arrived ); + entry = syncrepl_message_to_entry( ld, &op, msg, + &modlist, &syncstate, &syncUUID, &syncCookie ); + rc_efree = syncrepl_entry( ld, &op, entry, modlist, + syncstate, &syncUUID, &syncCookie, !syncinfo_arrived ); if ( syncCookie.bv_len ) { - syncrepl_updateCookie( ld, &op, &psub, - &syncCookie ); + syncrepl_updateCookie( ld, &op, &psub, &syncCookie ); + } + if ( rc_efree ) + entry_free( entry ); + for ( ml = modlist; ml != NULL; ml = mlnext ) { + mlnext = ml->sml_next; + ber_memfree( ml ); } break; @@ -492,11 +518,15 @@ do_syncrepl( ldap_parse_result( ld, msg, &err, NULL, NULL, NULL, &rctrls, 0 ); if ( rctrls ) { rctrlp = *rctrls; - ctrl_ber = ber_init( &rctrlp->ldctl_value ); + ctrl_ber = ber_alloc_t( LBER_USE_DER ); + ber_set_option( ctrl_ber, LBER_OPT_BER_MEMCTX, op.o_tmpmemctx ); + ber_write( ctrl_ber, rctrlp->ldctl_value.bv_val, rctrlp->ldctl_value.bv_len, 0 ); + ber_reset( ctrl_ber, 1 ); + ber_scanf( ctrl_ber, "{" ); if ( ber_peek_tag( ctrl_ber, &len ) == LDAP_SYNC_TAG_COOKIE ) { - ber_scanf( ctrl_ber, "m", &syncCookie ); + ber_scanf( ctrl_ber, "o", &syncCookie ); } } if (si->type == LDAP_SYNC_REFRESH_AND_PERSIST) { @@ -505,19 +535,24 @@ do_syncrepl( ber_bvfree( si->syncCookie ); si->syncCookie = ber_dupbv( NULL, &syncCookie ); } + if ( ctrl_ber ) + ber_free( ctrl_ber, 1 ); goto done; } - else + else { + if ( ctrl_ber ) + ber_free( ctrl_ber, 1 ); break; + } } else { if ( syncCookie.bv_len ) { - syncrepl_updateCookie( ld, - &op, &psub, - &syncCookie ); + syncrepl_updateCookie( ld, &op, &psub, &syncCookie ); } - goto restart; + syncrepl_del_nonpresent( ld, &op ); + if ( ctrl_ber ) + ber_free( ctrl_ber, 1 ); + goto done; } -restart_loop: break; case LDAP_RES_INTERMEDIATE_RESP: @@ -541,8 +576,8 @@ restart_loop: } if ( ber_peek_tag( res_ber, &len ) - == LDAP_SYNC_TAG_COOKIE ) { - ber_scanf( res_ber, "m}", &syncCookie ); + == LDAP_SYNC_TAG_COOKIE ) { + ber_scanf( res_ber, "o}", &syncCookie ); if ( syncCookie.bv_len ) { ber_bvfree( si->syncCookie ); si->syncCookie = ber_dupbv( NULL, &syncCookie ); @@ -601,20 +636,27 @@ restart_loop: Debug( LDAP_DEBUG_ANY, "do_syncrepl : unknown result\n", 0, 0, 0 ); #endif - return NULL; } -restart: - sleep(si->interval * 60); - goto restart_loop; -// set alarm clock to send signal to slapd -// should set the signal handler beforehand -// the signal handler re execute do_syncrepl() - done: + if ( syncCookie.bv_val ) + ch_free( syncCookie.bv_val ); + if ( syncUUID.bv_val ) + ch_free( syncUUID.bv_val ); + 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; } @@ -623,7 +665,7 @@ syncrepl_message_to_entry( LDAP *ld, Operation *op, LDAPMessage *msg, - Modifications *modlist, + Modifications **modlist, int *syncstate, struct berval *syncUUID, struct berval *syncCookie @@ -632,19 +674,19 @@ syncrepl_message_to_entry( Entry *e; BerElement *ber = NULL; BerElement *tmpber; - struct berval bv; + struct berval bv = {0, NULL}; Modifications tmp; Modifications *mod; - Modifications **modtail = &modlist; + Modifications **modtail = modlist; Backend *be = op->o_bd; const char *text; char txtbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof txtbuf; - struct berval **bvals; + struct berval **bvals = NULL; char *dn; - struct berval bdn; + struct berval bdn = {0, NULL}; Attribute *attr; struct berval empty_bv = { 0, NULL }; int rc; @@ -657,7 +699,9 @@ syncrepl_message_to_entry( LDAPControl** rctrls = NULL; BerElement* ctrl_ber; - modlist = NULL; + ber_tag_t tag; + + *modlist = NULL; if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) { #ifdef NEW_LOGGING @@ -686,19 +730,19 @@ syncrepl_message_to_entry( } e = ( Entry * ) ch_calloc( 1, sizeof( Entry )); - dnPrettyNormal( NULL, &bdn, &e->e_name, &e->e_nname, NULL ); + dnPrettyNormal( NULL, &bdn, &e->e_name, &e->e_nname, op->o_tmpmemctx ); 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) ); + mod = (Modifications *) ch_malloc( sizeof( Modifications )); - mod->sml_op = LDAP_MOD_ADD; + mod->sml_op = LDAP_MOD_REPLACE; mod->sml_next = NULL; mod->sml_desc = NULL; mod->sml_type = tmp.sml_type; @@ -709,16 +753,16 @@ syncrepl_message_to_entry( modtail = &mod->sml_next; } - if ( ber_scanf( ber, "}") == LBER_ERROR ) { + if ( ber_scanf( ber, "}") == LBER_ERROR ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_message_to_entry: ber_scanf failed\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_message_to_entry: ber_scanf failed\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: ber_scanf failed\n", - 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: ber_scanf failed\n", + 0, 0, 0 ); #endif return NULL; - } + } ber_free( ber, 0 ); tmpber = ldap_get_message_ber( msg ); @@ -741,11 +785,15 @@ syncrepl_message_to_entry( if ( rctrls ) { rctrlp = *rctrls; - ctrl_ber = ber_init( &rctrlp->ldctl_value ); - ber_scanf( ctrl_ber, "{em", syncstate, syncUUID ); + ctrl_ber = ber_alloc_t( LBER_USE_DER ); + ber_set_option( ctrl_ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx ); + ber_write( ctrl_ber, rctrlp->ldctl_value.bv_val, rctrlp->ldctl_value.bv_len, 0 ); + ber_reset( ctrl_ber, 1 ); + ber_scanf( ctrl_ber, "{eo", syncstate, syncUUID ); if ( ber_peek_tag( ctrl_ber, &len ) == LDAP_SYNC_TAG_COOKIE ) { - ber_scanf( ctrl_ber, "m}", syncCookie ); + ber_scanf( ctrl_ber, "o}", syncCookie ); } + ber_free( ctrl_ber, 1 ); } else { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR,"syncrepl_message_to_entry : " @@ -761,51 +809,51 @@ syncrepl_message_to_entry( goto done; } - if ( modlist == NULL ) { + if ( *modlist == NULL ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_message_to_entry: no attributes\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_message_to_entry: no attributes\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: no attributes\n", - 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: no attributes\n", + 0, 0, 0 ); #endif - } + } - rc = slap_mods_check_syncrepl( op, &modlist, &text, txtbuf, textlen, NULL ); + rc = slap_mods_check_syncrepl( op, modlist, &text, txtbuf, textlen, NULL ); if ( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_message_to_entry: mods check (%s)\n", text, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_message_to_entry: mods check (%s)\n", text, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods check (%s)\n", - text, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods check (%s)\n", + text, 0, 0 ); #endif return NULL; } - rc = slap_mods_opattrs_syncrepl( op, modlist, modtail, + rc = slap_mods_opattrs_syncrepl( op, *modlist, modtail, &text,txtbuf, textlen ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_message_to_entry: mods opattrs (%s)\n", text, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_message_to_entry: mods opattrs (%s)\n", text, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods opattrs (%s)\n", - text, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods opattrs (%s)\n", + text, 0, 0 ); #endif return NULL; } - rc = slap_mods2entry_syncrepl( modlist, &e, 1, &text, txtbuf, textlen ); + rc = slap_mods2entry_syncrepl( *modlist, &e, 1, &text, txtbuf, textlen ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_message_to_entry: mods2entry (%s)\n", text, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_message_to_entry: mods2entry (%s)\n", text, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods2entry (%s)\n", - text, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods2entry (%s)\n", + text, 0, 0 ); #endif } @@ -816,7 +864,7 @@ done: return e; } -int +int syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 ) { const struct berval *uuid1 = v_uuid1; @@ -841,110 +889,144 @@ syncrepl_entry( Backend *be = op->o_bd; syncinfo_t *si = ( syncinfo_t * ) be->syncinfo; slap_callback cb; - struct berval normdn = {0, NULL}; - struct berval prettydn = {0, NULL}; struct berval csn_bv = {0, NULL}; struct berval *syncuuid_bv = NULL; char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; SlapReply rs = {REP_RESULT}; - int rc; + int rc = LDAP_SUCCESS; + + struct berval base_bv = {0, NULL}; char *filterstr; - struct berval filterstr_bv; Filter *filter; Attribute *a; - if ( syncstate == LDAP_SYNC_PRESENT ) { + if ( refresh && + ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD )) { syncuuid_bv = ber_dupbv( NULL, syncUUID ); avl_insert( &si->presentlist, (caddr_t) syncuuid_bv, - syncuuid_cmp, avl_dup_error ); - return; + syncuuid_cmp, avl_dup_error ); + } + + if ( syncstate == LDAP_SYNC_PRESENT ) { + if ( e ) + return 1; + else + return 0; } if ( !attr_find( e->e_attrs, slap_schema.si_ad_entryUUID )) { attr_merge_one( e, slap_schema.si_ad_entryUUID, syncUUID, syncUUID ); } - filterstr = (char *) ch_malloc( strlen("entryUUID=") + syncUUID->bv_len + 1 ); + filterstr = (char *) sl_malloc( strlen("entryUUID=") + syncUUID->bv_len + 1, op->o_tmpmemctx ); strcpy( filterstr, "entryUUID=" ); strcat( filterstr, syncUUID->bv_val ); si->e = e; si->syncUUID = syncUUID; + si->syncUUID_ndn = NULL; filter = str2filter( filterstr ); - ber_str2bv( filterstr, strlen(filterstr), 1, &filterstr_bv ); + ber_str2bv( filterstr, strlen(filterstr), 1, &op->ors_filterstr ); ch_free( filterstr ); + op->ors_filter = filter; + op->ors_scope = LDAP_SCOPE_SUBTREE; - dnPrettyNormal( 0, &(e->e_name), &prettydn, &normdn, NULL ); - - free(e->e_name.bv_val); - free(e->e_nname.bv_val); - e->e_name = prettydn; - e->e_nname = normdn; - 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 { +#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; - break; + return 1; case LDAP_SYNC_DELETE : op->o_tag = LDAP_REQ_DELETE; be->be_delete( op, &rs ); - entry_free( e ); si->e = NULL; - break; + return 1; default : #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, @@ -953,7 +1035,7 @@ sync_add_retry: Debug( LDAP_DEBUG_ANY, "unknown syncstate\n", 0, 0, 0 ); #endif - return; + return 1; } } @@ -969,10 +1051,12 @@ syncrepl_del_nonpresent( struct berval base_bv = {0, NULL}; Filter *filter; SlapReply rs = {REP_RESULT}; - struct berval filterstr_bv; + struct berval filterstr_bv = {0, NULL}; + struct nonpresent_entry *np_list, *np_prev; ber_str2bv( si->base, strlen(si->base), 1, &base_bv ); - dnPrettyNormal(0, &base_bv, &op->o_req_dn, &op->o_req_ndn, NULL ); + dnPrettyNormal(0, &base_bv, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); + ch_free( base_bv.bv_val ); filter = str2filter( si->filterstr ); @@ -981,16 +1065,44 @@ syncrepl_del_nonpresent( op->o_callback = &cb; op->o_tag = LDAP_REQ_SEARCH; - op->ors_scope = LDAP_SCOPE_BASE; + op->ors_scope = si->scope; op->ors_deref = LDAP_DEREF_NEVER; op->ors_slimit = -1; op->ors_tlimit = -1; op->ors_attrsonly = 0; op->ors_attrs = NULL; - op->ors_filter = str2filter( si->filterstr ); + op->ors_filter = filter; ber_str2bv( si->filterstr, strlen( si->filterstr ), 1, &op->ors_filterstr ); be->be_search( op, &rs ); + + if ( !LDAP_LIST_EMPTY( &si->nonpresentlist ) ) { + np_list = LDAP_LIST_FIRST( &si->nonpresentlist ); + while ( np_list != NULL ) { + LDAP_LIST_REMOVE( np_list, np_link ); + np_prev = np_list; + np_list = LDAP_LIST_NEXT( np_list, np_link ); + op->o_tag = LDAP_REQ_DELETE; + op->o_callback = &cb; + cb.sc_response = null_callback; + cb.sc_private = si; + op->o_req_dn = *np_prev->dn; + op->o_req_ndn = *np_prev->ndn; + op->o_bd->be_delete( op, &rs ); + ber_bvfree( np_prev->dn ); + ber_bvfree( np_prev->ndn ); + op->o_req_dn.bv_val = NULL; + op->o_req_ndn.bv_val = NULL; + ch_free( np_prev ); + } + } + + if ( op->o_req_dn.bv_val ) + ch_free( op->o_req_dn.bv_val ); + if ( op->o_req_ndn.bv_val ) + ch_free( op->o_req_ndn.bv_val ); + filter_free( op->ors_filter ); + ch_free( op->ors_filterstr.bv_val ); } @@ -1029,25 +1141,33 @@ syncrepl_add_glue( ber_dupbv( &dn, &e->e_nname ); ber_dupbv( &pdn, &e->e_nname ); + while ( !be_issuffix ( be, &pdn )) { dnParent( &dn, &pdn ); + ch_free( dn.bv_val ); ber_dupbv( &dn, &pdn ); levels++; } for ( i = 0; i <= levels; i++ ) { glue = (Entry*) ch_calloc( 1, sizeof(Entry) ); + ch_free( dn.bv_val ); + ch_free( pdn.bv_val ); ber_dupbv( &dn, &e->e_nname ); ber_dupbv( &pdn, &e->e_nname ); j = levels - i; for ( k = 0; k < j; k++ ) { dnParent( &dn, &pdn ); + ch_free( dn.bv_val ); ber_dupbv( &dn, &pdn ); } - dnPrettyNormal( 0, &dn, &pdn, &ndn, NULL ); + dnPrettyNormal( 0, &dn, &pdn, &ndn, op->o_tmpmemctx ); ber_dupbv( &glue->e_name, &pdn ); ber_dupbv( &glue->e_nname, &ndn ); + ch_free( dn.bv_val ); + ch_free( pdn.bv_val ); + ch_free( ndn.bv_val ); a = ch_calloc( 1, sizeof( Attribute )); a->a_desc = slap_schema.si_ad_objectClass; @@ -1083,10 +1203,12 @@ syncrepl_add_glue( op->o_req_ndn = glue->e_nname; op->ora_e = glue; rc = be->be_add ( op, &rs ); - if ( rc == LDAP_SUCCESS ) + if ( rc == LDAP_SUCCESS ) { be_entry_release_w( op, glue ); - else + } else { + /* incl. ALREADY EXIST */ entry_free( glue ); + } } } @@ -1103,14 +1225,16 @@ syncrepl_updateCookie( { Backend *be = op->o_bd; syncinfo_t *si = ( syncinfo_t * ) be->syncinfo; + Modifications *ml; + Modifications *mlnext; Modifications *mod; Modifications *modlist; Modifications **modtail = &modlist; - struct berval* ocbva; - struct berval* cnbva; - struct berval* ssbva; - struct berval* scbva; + struct berval* ocbva = NULL; + struct berval* cnbva = NULL; + struct berval* ssbva = NULL; + struct berval* scbva = NULL; char substr[64]; char rdnstr[67]; @@ -1158,7 +1282,6 @@ syncrepl_updateCookie( sprintf( rdnstr, "cn=%s", substr ); ber_str2bv( substr, strlen( substr ), 1, &cnbva[0] ); ber_str2bv( rdnstr, strlen( rdnstr ), 1, &psubrdn ); - free( substr ); cnbva[1].bv_len = 0; cnbva[1].bv_val = NULL; mod = (Modifications *) ch_malloc( sizeof( Modifications )); @@ -1185,7 +1308,7 @@ syncrepl_updateCookie( *modtail = mod; modtail = &mod->sml_next; - ber_str2bv( " ", 1, 1, &ssbva[0] ); + ber_str2bv( "{}", strlen("{}"), 1, &ssbva[0] ); ssbva[1].bv_len = 0; ssbva[1].bv_val = NULL; mod = (Modifications *) ch_malloc( sizeof( Modifications )); @@ -1203,10 +1326,10 @@ syncrepl_updateCookie( if ( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_updateCookie: mods check (%s)\n", text, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_updateCookie: mods check (%s)\n", text, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods check (%s)\n", + Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods check (%s)\n", text, 0, 0 ); #endif } @@ -1216,10 +1339,10 @@ syncrepl_updateCookie( if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_updateCookie: mods opattrs (%s)\n", text, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_updateCookie: mods opattrs (%s)\n", text, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods opattrs (%s)\n", + Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods opattrs (%s)\n", text, 0, 0 ); #endif } @@ -1227,7 +1350,9 @@ syncrepl_updateCookie( e = ( Entry * ) ch_calloc( 1, sizeof( Entry )); build_new_dn( &sub_bv, pdn, &psubrdn ); - dnPrettyNormal( NULL, &sub_bv, &e->e_name, &e->e_nname, NULL ); + dnPrettyNormal( NULL, &sub_bv, &e->e_name, &e->e_nname, op->o_tmpmemctx ); + ch_free( sub_bv.bv_val ); + ch_free( psubrdn.bv_val ); e->e_attrs = NULL; @@ -1235,10 +1360,10 @@ syncrepl_updateCookie( if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_updateCookie: mods2entry (%s)\n", text, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "syncrepl_updateCookie: mods2entry (%s)\n", text, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods2entry (%s)\n", + Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods2entry (%s)\n", text, 0, 0 ); #endif } @@ -1250,12 +1375,6 @@ syncrepl_updateCookie( op->o_req_dn = e->e_name; op->o_req_ndn = e->e_nname; - /* - for( mod = modlist; mod != NULL; mod = mod->sml_next ) { - mod->sml_op = LDAP_MOD_REPLACE; - } - */ - /* update persistent cookie */ update_cookie_retry: op->o_tag = LDAP_REQ_MODIFY; @@ -1263,8 +1382,8 @@ update_cookie_retry: rc = be->be_modify( op, &rs ); if ( rc != LDAP_SUCCESS ) { if ( rc == LDAP_REFERRAL || - rc == LDAP_NO_SUCH_OBJECT || - rc == DB_NOTFOUND ) { + rc == LDAP_NO_SUCH_OBJECT || + rc == DB_NOTFOUND ) { op->o_tag = LDAP_REQ_ADD; op->ora_e = e; rc = be->be_add( op, &rs ); @@ -1272,8 +1391,8 @@ update_cookie_retry: if ( rc == LDAP_ALREADY_EXISTS ) { goto update_cookie_retry; } else if ( rc == LDAP_REFERRAL || - rc == LDAP_NO_SUCH_OBJECT || - rc == DB_NOTFOUND ) { + rc == LDAP_NO_SUCH_OBJECT || + rc == DB_NOTFOUND ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "cookie will be non-persistent\n", @@ -1294,6 +1413,8 @@ update_cookie_retry: rc, 0, 0 ); #endif } + } else { + goto done; } } else { #ifdef NEW_LOGGING @@ -1305,19 +1426,31 @@ update_cookie_retry: #endif } } + + if ( e != NULL ) + entry_free( e ); + +done : + + for ( ml = modlist; ml != NULL; ml = mlnext ) { + mlnext = ml->sml_next; + free( ml ); + } + + return; } static int slap_mods_check_syncrepl( Operation *op, - Modifications **mlp, - const char **text, - char *textbuf, - size_t textlen, + Modifications **mlp, + const char **text, + char *textbuf, + size_t textlen, void *ctx ) { - int rc; + int rc; Backend *be = op->o_bd; syncinfo_t *si = ( syncinfo_t * ) be->syncinfo; AttributeDescription** descs; @@ -1327,19 +1460,19 @@ int slap_mods_check_syncrepl( Modifications *ml = *mlp; while ( ml != NULL ) { - AttributeDescription *ad = NULL; + AttributeDescription *ad = NULL; - /* convert to attribute description */ - rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, text ); + /* convert to attribute description */ + rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, text ); - if( rc != LDAP_SUCCESS ) { - snprintf( textbuf, textlen, "%s: %s", - ml->sml_type.bv_val, *text ); - *text = textbuf; - return rc; - } + if( rc != LDAP_SUCCESS ) { + snprintf( textbuf, textlen, "%s: %s", + ml->sml_type.bv_val, *text ); + *text = textbuf; + return rc; + } - ad = ml->sml_desc; + ad = ml->sml_desc; if ( si->lastmod == LASTMOD_REQ ) { descs = del_descs_lastmod; @@ -1363,312 +1496,298 @@ int slap_mods_check_syncrepl( } } - if( slap_syntax_is_binary( ad->ad_type->sat_syntax ) - && !slap_ad_is_binary( ad )) - { - /* attribute requires binary transfer */ - snprintf( textbuf, textlen, - "%s: requires ;binary transfer", - ml->sml_type.bv_val ); - *text = textbuf; - return LDAP_UNDEFINED_TYPE; - } - - if( !slap_syntax_is_binary( ad->ad_type->sat_syntax ) - && slap_ad_is_binary( ad )) - { - /* attribute requires binary transfer */ - snprintf( textbuf, textlen, - "%s: disallows ;binary transfer", - ml->sml_type.bv_val ); - *text = textbuf; - return LDAP_UNDEFINED_TYPE; - } - - if( slap_ad_is_tag_range( ad )) { - /* attribute requires binary transfer */ - snprintf( textbuf, textlen, - "%s: inappropriate use of tag range option", - ml->sml_type.bv_val ); - *text = textbuf; - return LDAP_UNDEFINED_TYPE; - } - - if ( is_at_obsolete( ad->ad_type ) && - ( ml->sml_op == LDAP_MOD_ADD || ml->sml_values != NULL ) ) - { - /* - * attribute is obsolete, - * only allow replace/delete with no values - */ - snprintf( textbuf, textlen, - "%s: attribute is obsolete", - ml->sml_type.bv_val ); - *text = textbuf; - return LDAP_CONSTRAINT_VIOLATION; - } - - /* - * check values - */ - if( ml->sml_values != NULL ) { - ber_len_t nvals; - slap_syntax_validate_func *validate = - ad->ad_type->sat_syntax->ssyn_validate; - slap_syntax_transform_func *pretty = - ad->ad_type->sat_syntax->ssyn_pretty; - - if( !pretty && !validate ) { - *text = "no validator for syntax"; - snprintf( textbuf, textlen, - "%s: no validator for syntax %s", - ml->sml_type.bv_val, - ad->ad_type->sat_syntax->ssyn_oid ); - *text = textbuf; - return LDAP_INVALID_SYNTAX; - } - - /* - * check that each value is valid per syntax - * and pretty if appropriate - */ - for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) { - struct berval pval; - if( pretty ) { - rc = pretty( ad->ad_type->sat_syntax, - &ml->sml_values[nvals], &pval, - ctx ); - } else { - rc = validate( ad->ad_type->sat_syntax, - &ml->sml_values[nvals] ); - } - - if( rc != 0 ) { - snprintf( textbuf, textlen, - "%s: value #%ld invalid per syntax", - ml->sml_type.bv_val, (long) nvals ); - *text = textbuf; - return LDAP_INVALID_SYNTAX; - } - - if( pretty ) { - ber_memfree( ml->sml_values[nvals].bv_val ); - ml->sml_values[nvals] = pval; - } - } - - /* - * a rough single value check... an additional check is needed - * to catch add of single value to existing single valued attribute - */ - if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE) - && nvals > 1 && is_at_single_value( ad->ad_type )) - { - snprintf( textbuf, textlen, - "%s: multiple values provided", - ml->sml_type.bv_val ); - *text = textbuf; - return LDAP_CONSTRAINT_VIOLATION; - } - - if( nvals && ad->ad_type->sat_equality && - ad->ad_type->sat_equality->smr_normalize ) - { - ml->sml_nvalues = ch_malloc( (nvals+1)*sizeof(struct berval) ); - for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) { - rc = ad->ad_type->sat_equality->smr_normalize( - 0, - ad->ad_type->sat_syntax, - ad->ad_type->sat_equality, - &ml->sml_values[nvals], &ml->sml_nvalues[nvals], - ctx ); - if( rc ) { + if( slap_syntax_is_binary( ad->ad_type->sat_syntax ) + && !slap_ad_is_binary( ad )) { + /* attribute requires binary transfer */ + snprintf( textbuf, textlen, + "%s: requires ;binary transfer", + ml->sml_type.bv_val ); + *text = textbuf; + return LDAP_UNDEFINED_TYPE; + } + + if( !slap_syntax_is_binary( ad->ad_type->sat_syntax ) + && slap_ad_is_binary( ad )) { + /* attribute requires binary transfer */ + snprintf( textbuf, textlen, + "%s: disallows ;binary transfer", + ml->sml_type.bv_val ); + *text = textbuf; + return LDAP_UNDEFINED_TYPE; + } + + if( slap_ad_is_tag_range( ad )) { + /* attribute requires binary transfer */ + snprintf( textbuf, textlen, + "%s: inappropriate use of tag range option", + ml->sml_type.bv_val ); + *text = textbuf; + return LDAP_UNDEFINED_TYPE; + } + + if ( is_at_obsolete( ad->ad_type ) && + ( ml->sml_op == LDAP_MOD_ADD || ml->sml_values != NULL ) ) { + /* + * attribute is obsolete, + * only allow replace/delete with no values + */ + snprintf( textbuf, textlen, + "%s: attribute is obsolete", + ml->sml_type.bv_val ); + *text = textbuf; + return LDAP_CONSTRAINT_VIOLATION; + } + + /* + * check values + */ + if( ml->sml_values != NULL ) { + ber_len_t nvals; + slap_syntax_validate_func *validate = + ad->ad_type->sat_syntax->ssyn_validate; + slap_syntax_transform_func *pretty = + ad->ad_type->sat_syntax->ssyn_pretty; + + if( !pretty && !validate ) { + *text = "no validator for syntax"; + snprintf( textbuf, textlen, + "%s: no validator for syntax %s", + ml->sml_type.bv_val, + ad->ad_type->sat_syntax->ssyn_oid ); + *text = textbuf; + return LDAP_INVALID_SYNTAX; + } + + /* + * check that each value is valid per syntax + * and pretty if appropriate + */ + for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) { + struct berval pval = {0, NULL}; + if( pretty ) { + rc = pretty( ad->ad_type->sat_syntax, + &ml->sml_values[nvals], &pval, ctx ); + } else { + rc = validate( ad->ad_type->sat_syntax, + &ml->sml_values[nvals] ); + } + + if( rc != 0 ) { + snprintf( textbuf, textlen, + "%s: value #%ld invalid per syntax", + ml->sml_type.bv_val, (long) nvals ); + *text = textbuf; + return LDAP_INVALID_SYNTAX; + } + + if( pretty ) { + ber_memfree( ml->sml_values[nvals].bv_val ); + ml->sml_values[nvals] = pval; + } + } + + /* + * a rough single value check... an additional check is needed + * to catch add of single value to existing single valued attribute + */ + if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE) + && nvals > 1 && is_at_single_value( ad->ad_type )) { + snprintf( textbuf, textlen, + "%s: multiple values provided", + ml->sml_type.bv_val ); + *text = textbuf; + return LDAP_CONSTRAINT_VIOLATION; + } + + if( nvals && ad->ad_type->sat_equality && + ad->ad_type->sat_equality->smr_normalize ) { + ml->sml_nvalues = ch_malloc( (nvals+1)*sizeof(struct berval) ); + for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) { + rc = ad->ad_type->sat_equality->smr_normalize( 0, + ad->ad_type->sat_syntax, ad->ad_type->sat_equality, + &ml->sml_values[nvals], &ml->sml_nvalues[nvals], ctx ); + if( rc ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, DETAIL1, - "str2entry: NULL (ssyn_normalize %d)\n", - rc, 0, 0 ); + LDAP_LOG( OPERATION, DETAIL1, + "str2entry: NULL (ssyn_normalize %d)\n", rc, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "<= str2entry NULL (ssyn_normalize %d)\n", - rc, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "<= str2entry NULL (ssyn_normalize %d)\n", rc, 0, 0 ); #endif - snprintf( textbuf, textlen, - "%s: value #%ld normalization failed", - ml->sml_type.bv_val, (long) nvals ); - *text = textbuf; - return rc; - } - } - ml->sml_nvalues[nvals].bv_val = NULL; - ml->sml_nvalues[nvals].bv_len = 0; - } - } + snprintf( textbuf, textlen, + "%s: value #%ld normalization failed", + ml->sml_type.bv_val, (long) nvals ); + *text = textbuf; + return rc; + } + } + ml->sml_nvalues[nvals].bv_val = NULL; + ml->sml_nvalues[nvals].bv_len = 0; + } + } prevml = ml; ml = ml->sml_next; - } + } - return LDAP_SUCCESS; + return LDAP_SUCCESS; } static int slap_mods_opattrs_syncrepl( - Operation *op, - Modifications *mods, - Modifications **modtail, - const char **text, - char *textbuf, size_t textlen ) + Operation *op, + Modifications *mods, + Modifications **modtail, + const char **text, + char *textbuf, size_t textlen ) { - struct berval name, timestamp, csn; - struct berval nname; - char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; - char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; - Modifications *mod; + struct berval name = {0, NULL}; + struct berval timestamp = {0, NULL}; + struct berval csn = {0, NULL}; + struct berval nname = {0, NULL}; + char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; + Modifications *mod; Backend *be = op->o_bd; syncinfo_t *si = ( syncinfo_t * ) be->syncinfo; - // int mop = op->o_tag == LDAP_REQ_ADD ? LDAP_MOD_ADD : LDAP_MOD_REPLACE; int mop = LDAP_MOD_REPLACE; - assert( modtail != NULL ); - assert( *modtail == NULL ); - - if( si->lastmod == LASTMOD_GEN ) { - struct tm *ltm; - time_t now = slap_get_time(); - - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - ltm = gmtime( &now ); - lutil_gentime( timebuf, sizeof(timebuf), ltm ); - - csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), 0, 0 ); - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); - csn.bv_val = csnbuf; - - timestamp.bv_val = timebuf; - timestamp.bv_len = strlen(timebuf); - - if( op->o_dn.bv_len == 0 ) { - name.bv_val = SLAPD_ANONYMOUS; - name.bv_len = sizeof(SLAPD_ANONYMOUS)-1; - nname = name; - } else { - name = op->o_dn; - nname = op->o_ndn; - } - } - - if( op->o_tag == LDAP_REQ_ADD ) { - struct berval tmpval; - - if( global_schemacheck ) { - int rc = mods_structural_class( mods, &tmpval, - text, textbuf, textlen ); - if( rc != LDAP_SUCCESS ) { - return rc; - } - - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); + assert( modtail != NULL ); + assert( *modtail == NULL ); + + if( si->lastmod == LASTMOD_GEN ) { + struct tm *ltm; + time_t now = slap_get_time(); + + ldap_pvt_thread_mutex_lock( &gmtime_mutex ); + ltm = gmtime( &now ); + lutil_gentime( timebuf, sizeof(timebuf), ltm ); + + csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), 0, 0 ); + ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); + csn.bv_val = csnbuf; + + timestamp.bv_val = timebuf; + timestamp.bv_len = strlen(timebuf); + + if( op->o_dn.bv_len == 0 ) { + name.bv_val = SLAPD_ANONYMOUS; + name.bv_len = sizeof(SLAPD_ANONYMOUS)-1; + nname = name; + } else { + name = op->o_dn; + nname = op->o_ndn; + } + } + + if( op->o_tag == LDAP_REQ_ADD ) { + struct berval tmpval = {0, NULL}; + + if( global_schemacheck ) { + int rc = mods_structural_class( mods, &tmpval, + text, textbuf, textlen ); + if( rc != LDAP_SUCCESS ) { + return rc; + } + + mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = mop; - mod->sml_type.bv_val = NULL; - mod->sml_desc = slap_schema.si_ad_structuralObjectClass; - mod->sml_values = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &tmpval ); - mod->sml_values[1].bv_len = 0; - mod->sml_values[1].bv_val = NULL; - assert( mod->sml_values[0].bv_val ); - mod->sml_nvalues = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_nvalues[0], &tmpval ); - mod->sml_nvalues[1].bv_len = 0; - mod->sml_nvalues[1].bv_val = NULL; - assert( mod->sml_nvalues[0].bv_val ); - *modtail = mod; - modtail = &mod->sml_next; - } - - if( si->lastmod == LASTMOD_GEN ) { - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_type.bv_val = NULL; - mod->sml_desc = slap_schema.si_ad_creatorsName; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &name ); - mod->sml_values[1].bv_len = 0; - mod->sml_values[1].bv_val = NULL; - assert( mod->sml_values[0].bv_val ); - mod->sml_nvalues = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_nvalues[0], &nname ); - mod->sml_nvalues[1].bv_len = 0; - mod->sml_nvalues[1].bv_val = NULL; - assert( mod->sml_nvalues[0].bv_val ); - *modtail = mod; - modtail = &mod->sml_next; - - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_type.bv_val = NULL; - mod->sml_desc = slap_schema.si_ad_createTimestamp; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], ×tamp ); - mod->sml_values[1].bv_len = 0; - mod->sml_values[1].bv_val = NULL; - assert( mod->sml_values[0].bv_val ); - mod->sml_nvalues = NULL; - *modtail = mod; - modtail = &mod->sml_next; - } - } - - if( si->lastmod == LASTMOD_GEN ) { - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_type.bv_val = NULL; - mod->sml_desc = slap_schema.si_ad_entryCSN; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &csn ); - mod->sml_values[1].bv_len = 0; - mod->sml_values[1].bv_val = NULL; - assert( mod->sml_values[0].bv_val ); - mod->sml_nvalues = NULL; - *modtail = mod; - modtail = &mod->sml_next; - - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_type.bv_val = NULL; - mod->sml_desc = slap_schema.si_ad_modifiersName; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &name ); - mod->sml_values[1].bv_len = 0; - mod->sml_values[1].bv_val = NULL; - assert( mod->sml_values[0].bv_val ); - mod->sml_nvalues = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_nvalues[0], &nname ); - mod->sml_nvalues[1].bv_len = 0; - mod->sml_nvalues[1].bv_val = NULL; - assert( mod->sml_nvalues[0].bv_val ); - *modtail = mod; - modtail = &mod->sml_next; - - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_type.bv_val = NULL; - mod->sml_desc = slap_schema.si_ad_modifyTimestamp; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], ×tamp ); - mod->sml_values[1].bv_len = 0; - mod->sml_values[1].bv_val = NULL; - assert( mod->sml_values[0].bv_val ); - mod->sml_nvalues = NULL; - *modtail = mod; - modtail = &mod->sml_next; - } - - *modtail = NULL; - return LDAP_SUCCESS; + mod->sml_type.bv_val = NULL; + mod->sml_desc = slap_schema.si_ad_structuralObjectClass; + mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_values[0], &tmpval ); + mod->sml_values[1].bv_len = 0; + mod->sml_values[1].bv_val = NULL; + assert( mod->sml_values[0].bv_val ); + mod->sml_nvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_nvalues[0], &tmpval ); + mod->sml_nvalues[1].bv_len = 0; + mod->sml_nvalues[1].bv_val = NULL; + assert( mod->sml_nvalues[0].bv_val ); + *modtail = mod; + modtail = &mod->sml_next; + } + + if( si->lastmod == LASTMOD_GEN ) { + mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_type.bv_val = NULL; + mod->sml_desc = slap_schema.si_ad_creatorsName; + mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_values[0], &name ); + mod->sml_values[1].bv_len = 0; + mod->sml_values[1].bv_val = NULL; + assert( mod->sml_values[0].bv_val ); + mod->sml_nvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_nvalues[0], &nname ); + mod->sml_nvalues[1].bv_len = 0; + mod->sml_nvalues[1].bv_val = NULL; + assert( mod->sml_nvalues[0].bv_val ); + *modtail = mod; + modtail = &mod->sml_next; + + mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_type.bv_val = NULL; + mod->sml_desc = slap_schema.si_ad_createTimestamp; + mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_values[0], ×tamp ); + mod->sml_values[1].bv_len = 0; + mod->sml_values[1].bv_val = NULL; + assert( mod->sml_values[0].bv_val ); + mod->sml_nvalues = NULL; + *modtail = mod; + modtail = &mod->sml_next; + } + } + + if( si->lastmod == LASTMOD_GEN ) { + mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_type.bv_val = NULL; + mod->sml_desc = slap_schema.si_ad_entryCSN; + mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_values[0], &csn ); + mod->sml_values[1].bv_len = 0; + mod->sml_values[1].bv_val = NULL; + assert( mod->sml_values[0].bv_val ); + mod->sml_nvalues = NULL; + *modtail = mod; + modtail = &mod->sml_next; + + mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_type.bv_val = NULL; + mod->sml_desc = slap_schema.si_ad_modifiersName; + mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_values[0], &name ); + mod->sml_values[1].bv_len = 0; + mod->sml_values[1].bv_val = NULL; + assert( mod->sml_values[0].bv_val ); + mod->sml_nvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_nvalues[0], &nname ); + mod->sml_nvalues[1].bv_len = 0; + mod->sml_nvalues[1].bv_val = NULL; + assert( mod->sml_nvalues[0].bv_val ); + *modtail = mod; + modtail = &mod->sml_next; + + mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_type.bv_val = NULL; + mod->sml_desc = slap_schema.si_ad_modifyTimestamp; + mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_values[0], ×tamp ); + mod->sml_values[1].bv_len = 0; + mod->sml_values[1].bv_val = NULL; + assert( mod->sml_values[0].bv_val ); + mod->sml_nvalues = NULL; + *modtail = mod; + modtail = &mod->sml_next; + } + + *modtail = NULL; + return LDAP_SUCCESS; } @@ -1828,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, @@ -1840,6 +1974,7 @@ nonpresent_callback( struct berval* present_uuid = NULL; slap_callback cb; SlapReply rs_cb = {REP_RESULT}; + struct nonpresent_entry *np_entry; if ( rs->sr_type == REP_RESULT ) { count = avl_free( si->presentlist, avl_ber_bvfree ); @@ -1850,17 +1985,14 @@ nonpresent_callback( if ( a == NULL ) return 0; - present_uuid = avl_find( si->presentlist, - &a->a_vals[0], syncuuid_cmp ); - + present_uuid = avl_find( si->presentlist, &a->a_vals[0], syncuuid_cmp ); + if ( present_uuid == NULL ) { - op->o_tag = LDAP_REQ_DELETE; - op->o_callback = &cb; - cb.sc_response = null_callback; - cb.sc_private = si; - op->o_req_dn = rs->sr_entry->e_name; - op->o_req_ndn = rs->sr_entry->e_nname; - op->o_bd->be_delete( op, &rs_cb ); + np_entry = (struct nonpresent_entry *) + ch_calloc( 1, sizeof( struct nonpresent_entry )); + np_entry->dn = ber_dupbv( NULL, &rs->sr_entry->e_name ); + np_entry->ndn = ber_dupbv( NULL, &rs->sr_entry->e_nname ); + LDAP_LIST_INSERT_HEAD( &si->nonpresentlist, np_entry, np_link ); } else { avl_delete( &si->presentlist, &a->a_vals[0], syncuuid_cmp ); @@ -1879,10 +2011,10 @@ null_callback( ) { if ( rs->sr_err != LDAP_SUCCESS && - rs->sr_err != LDAP_REFERRAL && - rs->sr_err != LDAP_ALREADY_EXISTS && - rs->sr_err != LDAP_NO_SUCH_OBJECT && - rs->sr_err != DB_NOTFOUND ) { + rs->sr_err != LDAP_REFERRAL && + rs->sr_err != LDAP_ALREADY_EXISTS && + rs->sr_err != LDAP_NO_SUCH_OBJECT && + rs->sr_err != DB_NOTFOUND ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "null_callback : error code 0x%x\n", @@ -1890,10 +2022,50 @@ null_callback( #else Debug( LDAP_DEBUG_ANY, "null_callback : error code 0x%x\n", - rs->sr_err, 0, 0 ); + rs->sr_err, 0, 0 ); #endif } 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