]> git.sur5r.net Git - openldap/commitdiff
ITS#2747, Reorganize syncrepl, fix some memleaks. More remain.
authorHoward Chu <hyc@openldap.org>
Sat, 18 Oct 2003 14:13:37 +0000 (14:13 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 18 Oct 2003 14:13:37 +0000 (14:13 +0000)
servers/slapd/backend.c
servers/slapd/config.c
servers/slapd/proto-slap.h
servers/slapd/slap.h
servers/slapd/syncrepl.c

index 7458a2b910be7914833aa963d4579ea08840209c..3a536f4082bd7108cc8cdb643f5b26289365876e 100644 (file)
@@ -244,8 +244,6 @@ int backend_startup(Backend *be)
        int i;
        int rc = 0;
 
-       init_syncrepl();
-
        if( ! ( nBackendDB > 0 ) ) {
                /* no databases */
 #ifdef NEW_LOGGING
@@ -377,6 +375,7 @@ int backend_startup(Backend *be)
                if ( backendDB[i].syncinfo != NULL ) {
                        syncinfo_t *si = ( syncinfo_t * ) backendDB[i].syncinfo;
                        si->be = &backendDB[i];
+                       init_syncrepl(si);
                        ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
                        ldap_pvt_runqueue_insert( &syncrepl_rq, si->interval,
                                                        do_syncrepl, (void *) backendDB[i].syncinfo );
index 39c83671062a689af169a804c193767096654adb..fed67ef677f1a46e7ffc13f9fc502dad79e976a9 100644 (file)
@@ -2782,9 +2782,9 @@ add_syncrepl(
                ber_dupbv( &si->updatedn, &be->be_rootndn );
        si->bindmethod = LDAP_AUTH_SIMPLE;
        si->schemachecking = 0;
-       si->filterstr = "(objectclass=*)";
+       ber_str2bv( "(objectclass=*)", sizeof("(objectclass=*)")-1, 0, &si->filterstr );
        if ( be->be_suffix && be->be_suffix[0].bv_val )
-               si->base = ch_strdup( be->be_suffix[0].bv_val );
+               ber_dupbv( &si->base, &be->be_nsuffix[0] );
        si->scope = LDAP_SCOPE_SUBTREE;
        si->attrsonly = 0;
        si->attrs = (char **) ch_calloc( 1, sizeof( char * ));
@@ -2914,14 +2914,11 @@ parse_syncrepl_line(
                        }
                } else if ( !strncasecmp( cargv[ i ],
                                UPDATEDNSTR, sizeof( UPDATEDNSTR ) - 1 ) ) {
-                       char *str;
                        struct berval updatedn = {0, NULL};
                        val = cargv[ i ] + sizeof( UPDATEDNSTR );
-                       str = ch_strdup( val );
-                       ber_str2bv( str, strlen(str), 1, &updatedn );
+                       ber_str2bv( val, 0, 0, &updatedn );
+                       ch_free( si->updatedn.bv_val );
                        dnNormalize( 0, NULL, NULL, &updatedn, &si->updatedn, NULL );
-                       ch_free( str );
-                       ch_free( updatedn.bv_val );
                } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR,
                                sizeof( BINDMETHSTR ) - 1 ) ) {
                        val = cargv[ i ] + sizeof( BINDMETHSTR );
@@ -2987,11 +2984,17 @@ parse_syncrepl_line(
                } else if ( !strncasecmp( cargv[ i ],
                                FILTERSTR, sizeof( FILTERSTR ) - 1 ) ) {
                        val = cargv[ i ] + sizeof( FILTERSTR );
-                       si->filterstr = ch_strdup( val );
+                       ber_str2bv( val, 0, 1, &si->filterstr );
                } else if ( !strncasecmp( cargv[ i ],
                                SEARCHBASESTR, sizeof( SEARCHBASESTR ) - 1 ) ) {
+                       struct berval bv;
                        val = cargv[ i ] + sizeof( SEARCHBASESTR );
-                       si->base = ch_strdup( val );
+                       ch_free( si->base.bv_val );
+                       ber_str2bv( val, 0, 0, &bv );
+                       if ( dnNormalize( 0, NULL, NULL, &bv, &si->base, NULL )) {
+                               fprintf( stderr, "Invalid base DN \"%s\"\n", val );
+                               return 1;
+                       }
                } else if ( !strncasecmp( cargv[ i ],
                                SCOPESTR, sizeof( SCOPESTR ) - 1 ) ) {
                        val = cargv[ i ] + sizeof( SCOPESTR );
index b46aad30858df1aca202b6b9bd6d8cdb63b1ccc9..930ef949d5d36693ab8e53f9a3bdfdb6e4bdf0f9 100644 (file)
@@ -1177,11 +1177,8 @@ LDAP_SLAPD_F (int) do_extended LDAP_P((Operation *op, SlapReply *rs));
 
 LDAP_SLAPD_V (struct runqueue_s) syncrepl_rq;
 
-LDAP_SLAPD_F (void) init_syncrepl LDAP_P(());
+LDAP_SLAPD_F (void) init_syncrepl LDAP_P((syncinfo_t *));
 LDAP_SLAPD_F (void*) do_syncrepl LDAP_P((void *, void *));
-LDAP_SLAPD_F (int) ldap_sync_search LDAP_P((
-                                       syncinfo_t *, LDAP *, LDAPControl **,
-                                       LDAPControl **, int *));
 LDAP_SLAPD_F (Entry*) syncrepl_message_to_entry LDAP_P((
                                        syncinfo_t *, LDAP *, Operation *, LDAPMessage *,
                                        Modifications **, int*, struct berval *, struct berval * ));
index 98b0ffa002699bda9f9c11495c104536d9595b71..d5e612a8e2b0bd693648ba939bde00822c557e68 100644 (file)
@@ -1318,8 +1318,8 @@ typedef struct syncinfo_s {
         char                   *srvtab;
                int                             schemachecking;
         Filter                 *filter;
-        char                   *filterstr;
-        char                   *base;
+        struct berval          filterstr;
+        struct berval          base;
         int                            scope;
         int                            attrsonly;
         char                   **attrs;
@@ -1987,7 +1987,6 @@ typedef struct slap_op {
 
        ValuesReturnFilter *o_vrFilter; /* ValuesReturnFilter */
 
-       syncinfo_t*     o_si;
        int o_nocaching;
 
 #ifdef LDAP_SLAPI
index fb65fe472db41ab4632f4fc5aa8ac9058b8596b1..d4548cfbc24874218e39259b7c74deab5ff732a3 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  */
+/* Modified by Howard Chu
+ *
+ * Copyright (c) 2003 by Howard Chu, Symas Corporation
+ *
+ * Modifications provided under the terms of the OpenLDAP public license.
+ */
 
 #include "portable.h"
 
 
 #include "ldap_rq.h"
 
-static const struct berval slap_syncrepl_bvc = BER_BVC("syncreplxxx");
-static const struct berval slap_syncrepl_cn_bvc = BER_BVC("cn=syncreplxxx");
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
+
+#define SYNCREPL_STR   "syncreplxxx"
+#define CN_STR "cn="
+
+static const struct berval slap_syncrepl_bvc = BER_BVC(SYNCREPL_STR);
+static const struct berval slap_syncrepl_cn_bvc = BER_BVC(CN_STR SYNCREPL_STR);
 
 static void
-syncrepl_del_nonpresent( LDAP *, Operation * );
+syncrepl_del_nonpresent( LDAP *, Operation *, syncinfo_t * );
 
 /* 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 * );
-static int contextcsn_callback( Operation*, SlapReply* );
 
-static AttributeDescription **sync_descs;
+static AttributeDescription *sync_descs[4];
 
 struct runqueue_s syncrepl_rq;
 
 void
-init_syncrepl()
+init_syncrepl(syncinfo_t *si)
 {
-       sync_descs = ch_malloc( 4 * sizeof( AttributeDescription * ));
-       sync_descs[0] = slap_schema.si_ad_objectClass;
-       sync_descs[1] = slap_schema.si_ad_structuralObjectClass;
-       sync_descs[2] = slap_schema.si_ad_entryCSN;
-       sync_descs[3] = NULL;
+       int i, j, k, n;
+       char **tmp;
+
+       if ( !sync_descs[0] ) {
+               sync_descs[0] = slap_schema.si_ad_objectClass;
+               sync_descs[1] = slap_schema.si_ad_structuralObjectClass;
+               sync_descs[2] = slap_schema.si_ad_entryCSN;
+               sync_descs[3] = NULL;
+       }
+
+       for ( n = 0; si->attrs[ n ] != NULL; n++ ) ;
+
+       if ( n ) {
+               /* Delete Attributes */
+               for ( i = 0; sync_descs[i] != NULL; i++ ) {
+                       for ( j = 0; si->attrs[j] != NULL; j++ ) {
+                               if ( !strcmp( si->attrs[j], sync_descs[i]->ad_cname.bv_val )) {
+                                       ch_free( si->attrs[j] );
+                                       for ( k = j; si->attrs[k] != NULL; k++ ) {
+                                               si->attrs[k] = si->attrs[k+1];
+                                       }
+                               }
+                       }
+               }
+               for ( n = 0; si->attrs[ n ] != NULL; n++ );
+               tmp = ( char ** ) ch_realloc( si->attrs, ( n + 4 ) * sizeof( char * ));
+               if ( tmp == NULL ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
+#endif
+               }
+       } else {
+               tmp = ( char ** ) ch_realloc( si->attrs, 5 * sizeof( char * ));
+               if ( tmp == NULL ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
+#endif
+               }
+               tmp[ n++ ] = ch_strdup( "*" );
+       }
+       
+       si->attrs = tmp;
+
+       /* Add Attributes */
+
+       for ( i = 0; sync_descs[ i ] != NULL; i++ ) {
+               si->attrs[ n++ ] = ch_strdup ( sync_descs[i]->ad_cname.bv_val );
+               si->attrs[ n ] = NULL;
+       }
 }
 
-int
+static int
 ldap_sync_search(
        syncinfo_t *si,
        LDAP *ld,
-       LDAPControl **sctrls,
-       LDAPControl **cctrls,
+       void *ctx,
        int *msgidp )
 {
-       BerElement      *ber;
-       int timelimit;
-       ber_int_t id;
-
-       int rc;
-       BerElement      *sync_ber = NULL;
-       struct berval *sync_bvalp = NULL;
-       LDAPControl c[2];
-       LDAPControl **ctrls;
-       int err;
+       BerElementBuffer berbuf;
+       BerElement *ber = (BerElement *)&berbuf;
+       LDAPControl c[2], *ctrls[3];
        struct timeval timeout;
+       int rc;
 
-    /* setup LDAP SYNC control */
-    sync_ber = ber_alloc_t( LBER_USE_DER );
-    ber_set_option( sync_ber, LBER_OPT_BER_MEMCTX, NULL );
-
-    if ( si->syncCookie ) {
-        ber_printf( sync_ber, "{eO}", abs(si->type), si->syncCookie );
-    } else {
-        ber_printf( sync_ber, "{e}", abs(si->type) );
-    }
-
-    if ( ber_flatten( sync_ber, &sync_bvalp ) == LBER_ERROR ) {
-        ber_free( sync_ber, 1 );
-        return LBER_ERROR;
-    }
-    ber_free( sync_ber, 1 );
-
-    ctrls = (LDAPControl**) sl_calloc( 3, sizeof(LDAPControl*), NULL );
-
-    c[0].ldctl_oid = LDAP_CONTROL_SYNC;
-    c[0].ldctl_value = (*sync_bvalp);
-    c[0].ldctl_iscritical = si->type < 0;
-    ctrls[0] = &c[0];
-
-    if ( si->authzId ) {
-        c[1].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
-        c[1].ldctl_value.bv_val = si->authzId;
-        c[1].ldctl_value.bv_len = strlen( si->authzId );
-        c[1].ldctl_iscritical = 1;
-        ctrls[1] = &c[1];
-    } else {
-        ctrls[1] = NULL;
-    }
+       /* setup LDAP SYNC control */
+       ber_init2( ber, NULL, LBER_USE_DER );
+       ber_set_option( ber, LBER_OPT_BER_MEMCTX, &ctx );
 
-    ctrls[2] = NULL;
+       if ( si->syncCookie ) {
+               ber_printf( ber, "{eO}", abs(si->type), si->syncCookie );
+       } else {
+               ber_printf( ber, "{e}", abs(si->type) );
+       }
 
-    err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
+       if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 )) == LBER_ERROR ) {
+               ber_free_buf( ber );
+               return rc;
+       }
 
-    ber_bvfree( sync_bvalp );
-    ch_free( ctrls );
+       c[0].ldctl_oid = LDAP_CONTROL_SYNC;
+       c[0].ldctl_iscritical = si->type < 0;
+       ctrls[0] = &c[0];
 
-    if ( err != LDAP_OPT_SUCCESS )
-        fprintf( stderr, "Could not set controls : %d\n", err );
+       if ( si->authzId ) {
+               c[1].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
+               ber_str2bv( si->authzId, 0, 0, &c[1].ldctl_value );
+               c[1].ldctl_iscritical = 1;
+               ctrls[1] = &c[1];
+               ctrls[2] = NULL;
+       } else {
+               ctrls[1] = NULL;
+       }
 
        timeout.tv_sec = si->tlimit > 0 ? si->tlimit : 1;
+       timeout.tv_usec = 0;
 
-       rc = ldap_search_ext( ld, si->base, si->scope, si->filterstr,
-                                                 si->attrs, si->attrsonly, sctrls, cctrls,
+       rc = ldap_search_ext( ld, si->base.bv_val, si->scope, si->filterstr.bv_val,
+                                                 si->attrs, si->attrsonly, ctrls, NULL,
                                                  si->tlimit < 0 ? NULL : &timeout,
                                                  si->slimit, msgidp );
+       ber_free_buf( ber );
 
        return rc;
 }
 
+static const Listener dummy_list = { {0, ""}, {0, ""} };
+
 void *
 do_syncrepl(
        void    *ctx,
@@ -141,18 +183,11 @@ do_syncrepl(
 {
        struct re_s* rtask = arg;
        syncinfo_t *si = ( syncinfo_t * ) rtask->arg;
-       Backend *be = si->be;
+       Backend *be;
 
-       SlapReply       rs = {REP_RESULT};
-
-       LDAPControl     c[2];
-       LDAPControl     **sctrls = NULL;
        LDAPControl     **rctrls = NULL;
        LDAPControl     *rctrlp = NULL;
-       BerElement      *sync_ber = NULL;
-       struct berval   *sync_bvalp = NULL;
 
-       BerElement      *ctrl_ber = NULL;
        BerElement      *res_ber = NULL;
 
        LDAP    *ld = NULL;
@@ -161,10 +196,6 @@ do_syncrepl(
 
        ber_int_t       msgid;
 
-       int             nresponses, nreferences, nextended, npartial;
-       int             nresponses_psearch;
-
-       int             cancel_msgid = -1;
        char            *retoid = NULL;
        struct berval   *retdata = NULL;
 
@@ -181,31 +212,20 @@ do_syncrepl(
        ber_len_t       len;
        int     syncinfo_arrived = 0;
 
-       char **tmp = NULL;
-       AttributeDescription** descs = NULL;
-
-       Connection conn;
+       Connection conn = {0};
        Operation op = {0};
        slap_callback   cb;
 
        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 };
-       struct berval nbase = { 0, NULL };
-       struct berval psubrdn = { 0, NULL };
-       struct berval nsubrdn = { 0, NULL };
        struct berval psub = { 0, NULL };
-       struct berval nsub = { 0, NULL };
        Modifications   *modlist = NULL;
-       Modifications   *ml, *mlnext;
-       char *def_filter_str = NULL;
 
-       struct berval slap_syncrepl_cn_bv = BER_BVNULL;
+       char syncrepl_cbuf[sizeof(CN_STR SYNCREPL_STR)];
+       struct berval syncrepl_cn_bv = {sizeof(syncrepl_cbuf)-1, syncrepl_cbuf};
 
        const char              *text;
        int                             match;
@@ -223,7 +243,7 @@ do_syncrepl(
                return NULL;
 
        if ( abs(si->type) != LDAP_SYNC_REFRESH_ONLY &&
-            abs(si->type) != LDAP_SYNC_REFRESH_AND_PERSIST ) {
+               abs(si->type) != LDAP_SYNC_REFRESH_AND_PERSIST ) {
                return NULL;
        }
 
@@ -234,14 +254,15 @@ do_syncrepl(
        rc = ldap_initialize( &ld, si->provideruri );
        if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, ERR, "do_syncrepl: "
-                       "ldap_initialize failed (%s)\n",
+               LDAP_LOG( OPERATION, ERR,
+                       "do_syncrepl: ldap_initialize failed (%s)\n",
                        si->provideruri, 0, 0 );
 #else
-               Debug( LDAP_DEBUG_ANY, "do_syncrepl: "
-                       "ldap_initialize failed (%s)\n",
+               Debug( LDAP_DEBUG_ANY,
+                       "do_syncrepl: ldap_initialize failed (%s)\n",
                        si->provideruri, 0, 0 );
 #endif
+               return NULL;
        }
 
        op.o_protocol = LDAP_VERSION3;
@@ -292,10 +313,10 @@ do_syncrepl(
 
                defaults = lutil_sasl_defaults( ld,
                                si->saslmech,
-                               si->realm,
-                               si->authcId,
-                               si->passwd,
-                               si->authzId );
+                                       si->realm,
+                                       si->authcId,
+                                       si->passwd,
+                                       si->authzId );
 
                rc = ldap_sasl_interactive_bind_s( ld,
                                si->binddn,
@@ -305,6 +326,8 @@ do_syncrepl(
                                lutil_sasl_interact,
                                defaults );
 
+               lutil_sasl_freedefs( defaults );
+
                /* FIXME : different error behaviors according to
                        1) return code
                        2) on err policy : exit, retry, backoff ...
@@ -342,6 +365,16 @@ do_syncrepl(
        /* set thread context in syncinfo */
        si->ctx = ctx;
 
+       be = si->be;
+
+       si->conn = &conn;
+       conn.c_connid = -1;
+       conn.c_send_ldap_result = slap_send_ldap_result;
+       conn.c_send_search_entry = slap_send_search_entry;
+       conn.c_send_search_reference = slap_send_search_reference;
+       conn.c_listener = (Listener *)&dummy_list;
+       conn.c_peer_name = slap_empty_bv;
+
        /* set memory context */
 #define SLAB_SIZE 1048576
        memsiz = SLAB_SIZE;
@@ -349,119 +382,44 @@ do_syncrepl(
        op.o_tmpmemctx = memctx;
        op.o_tmpmfuncs = &sl_mfuncs;
 
-       op.o_si = si;
-       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_managedsait = 1;
        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 = 0;
-       op.ors_tlimit = 0;
-       op.ors_attrsonly = 0;
-       op.ors_attrs = NULL;
-       op.ors_filter = str2filter_x( &op, def_filter_str = "(objectClass=*)" );
-       ber_str2bv( def_filter_str, 0, 0, &op.ors_filterstr );
-
-       si->conn = &conn;
-       conn.c_send_ldap_result = slap_send_ldap_result;
-       conn.c_send_search_entry = slap_send_search_entry;
-       conn.c_send_search_reference = slap_send_search_reference;
+#if defined( LDAP_SLAPI )
+       op.o_pb = slapi_pblock_new();
+       slapi_x_create_object_extensions( SLAPI_X_EXT_OPERATION, &op );
+#endif /* defined( LDAP_SLAPI ) */
 
        /* get syncrepl cookie of shadow replica from subentry */
-       ber_str2bv( si->base, 0, 0, &base_bv ); 
-       dnPrettyNormal( 0, &base_bv, &pbase, &nbase, op.o_tmpmemctx );
-
-       ber_dupbv( &slap_syncrepl_cn_bv, (struct berval *) &slap_syncrepl_cn_bvc );
-       slap_syncrepl_cn_bv.bv_len = snprintf( slap_syncrepl_cn_bv.bv_val,
-                                                                               slap_syncrepl_cn_bvc.bv_len,
-                                                                               "cn=syncrepl%d", si->id );
-       build_new_dn( &op.o_req_dn, &pbase, &slap_syncrepl_cn_bv, op.o_tmpmemctx );
-       build_new_dn( &op.o_req_ndn, &nbase, &slap_syncrepl_cn_bv, op.o_tmpmemctx );
 
-       /* set callback function */
-       cb.sc_response = cookie_callback;
-       cb.sc_private = si;
+       snprintf(syncrepl_cbuf, sizeof(syncrepl_cbuf), CN_STR "syncrepl%d",
+               si->id );
+       build_new_dn( &op.o_req_ndn, &si->base, &syncrepl_cn_bv, op.o_tmpmemctx );
+       op.o_req_dn = op.o_req_ndn;
 
-       /* search subentry to retrieve cookie */
        si->syncCookie = NULL;
-       be->be_search( &op, &rs );
-
-       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 );
-       if ( op.ors_filter )
-               filter_free( op.ors_filter );
-       if ( op.ors_filterstr.bv_val )
-               ch_free( op.ors_filterstr.bv_val );
-       if ( slap_syncrepl_cn_bv.bv_val )
-               ch_free( slap_syncrepl_cn_bv.bv_val );
-       if ( pbase.bv_val )
-               ch_free( pbase.bv_val );
-       if ( nbase.bv_val )
-               ch_free( nbase.bv_val );
+       backend_attribute( &op, NULL, &op.o_req_ndn,
+               slap_schema.si_ad_syncreplCookie, &si->syncCookie );
 
        ber_dupbv( &syncCookie_req, si->syncCookie );
 
        psub = be->be_nsuffix[0];
 
-       for ( n = 0; si->attrs[ n ] != NULL; n++ ) ;
-
-       if ( n != 0 ) {
-               /* Delete Attributes */
-               descs = sync_descs;
-               for ( i = 0; descs[i] != NULL; i++ ) {
-                       for ( j = 0; si->attrs[j] != NULL; j++ ) {
-                               if ( !strcmp( si->attrs[j], descs[i]->ad_cname.bv_val )) {
-                                       ch_free( si->attrs[j] );
-                                       for ( k = j; si->attrs[k] != NULL; k++ ) {
-                                               si->attrs[k] = si->attrs[k+1];
-                                       }
-                               }
-                       }
-               }
-               for ( n = 0; si->attrs[ n ] != NULL; n++ );
-               tmp = ( char ** ) ch_realloc( si->attrs, ( n + 4 ) * sizeof( char * ));
-               if ( tmp == NULL ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 );
-#else
-                       Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
-#endif
-               }
-       } else {
-               tmp = ( char ** ) ch_realloc( si->attrs, 5 * sizeof( char * ));
-               if ( tmp == NULL ) {
+       rc = ldap_sync_search( si, ld, memctx, &msgid );
+       if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 );
+                       LDAP_LOG ( OPERATION, ERR, "do_syncrepl: "
+                               "ldap_search_ext: %s (%d)\n", ldap_err2string( rc ), rc, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
+                       Debug( LDAP_DEBUG_ANY, "do_syncrepl: "
+                               "ldap_search_ext: %s (%d)\n", ldap_err2string( rc ), rc, 0 );
 #endif
-               }
-               tmp[ n++ ] = ch_strdup( "*" );
-       }
-       
-       descs = sync_descs;
-       si->attrs = tmp;
-
-       /* Add Attributes */
-
-       for ( i = 0; descs[ i ] != NULL; i++ ) {
-               si->attrs[ n++ ] = ch_strdup ( descs[i]->ad_cname.bv_val );
-               si->attrs[ n ] = NULL;
-       }
-
-       rc = ldap_sync_search( si, ld, NULL, NULL, &msgid );
-       if( rc != LDAP_SUCCESS ) {
-               fprintf( stderr, "syncrepl: ldap_search_ext: %s (%d)\n",
-                                                       ldap_err2string( rc ), rc );
                return NULL;
        }
 
@@ -472,7 +430,6 @@ do_syncrepl(
        }
 
        while (( rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, tout_p, &res )) >= 0 ) {
-
                if ( rc == 0 ) {
                        if ( slapd_abrupt_shutdown ) {
                                break;
@@ -482,8 +439,8 @@ do_syncrepl(
                }
 
                for ( msg = ldap_first_message( ld, res );
-                     msg != NULL;
-                     msg = ldap_next_message( ld, msg ) )
+                         msg != NULL;
+                         msg = ldap_next_message( ld, msg ) )
                {
                        syncCookie.bv_len = 0; syncCookie.bv_val = NULL;
                        switch( ldap_msgtype( msg ) ) {
@@ -516,17 +473,18 @@ do_syncrepl(
                        case LDAP_RES_SEARCH_RESULT:
                                ldap_parse_result( ld, msg, &err, NULL, NULL, NULL, &rctrls, 0 );
                                if ( rctrls ) {
+                                       BerElementBuffer berbuf;
+                                       BerElement      *ctrl_ber;
                                        rctrlp = *rctrls;
-                                       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 );
+                                       ctrl_ber = (BerElement *)&berbuf;
+                                       ber_init2( ctrl_ber, &rctrlp->ldctl_value, LBER_USE_DER );
 
                                        ber_scanf( ctrl_ber, "{" /*"}"*/);
                                        if ( ber_peek_tag( ctrl_ber, &len )
                                                == LDAP_SYNC_TAG_COOKIE ) {
                                                ber_scanf( ctrl_ber, "o", &syncCookie );
                                        }
+                                       ldap_controls_free( rctrls );
                                }
                                value_match( &match, slap_schema.si_ad_entryCSN,
                                                        slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
@@ -540,8 +498,6 @@ do_syncrepl(
                                        if ( syncCookie.bv_len && match < 0) {
                                                syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie );
                                        }
-                                       if ( ctrl_ber )
-                                               ber_free( ctrl_ber, 1 );
                                        goto done;
                                } else {
                                        /* FIXME : different error behaviors according to
@@ -552,10 +508,8 @@ do_syncrepl(
                                                syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie);
                                        }
                                        if ( si->sync_mode == LDAP_SYNC_STATE_MODE && match < 0 ) {
-                                                       syncrepl_del_nonpresent( ld, &op );
+                                                       syncrepl_del_nonpresent( ld, &op, si );
                                        }
-                                       if ( ctrl_ber )
-                                               ber_free( ctrl_ber, 1 );
                                        goto done;
                                }
                                break;
@@ -594,7 +548,7 @@ do_syncrepl(
 
                                        if ( syncstate == LDAP_SYNC_STATE_MODE_DONE ) {
                                                if ( match < 0 ) {
-                                                       syncrepl_del_nonpresent( ld, &op );
+                                                       syncrepl_del_nonpresent( ld, &op, si );
                                                }
                                                si->sync_mode = LDAP_SYNC_LOG_MODE;
                                        } else if ( syncstate == LDAP_SYNC_LOG_MODE_DONE ) {
@@ -642,10 +596,14 @@ do_syncrepl(
                                break;
 
                        }
-                       if ( syncCookie.bv_val )
+                       if ( syncCookie.bv_val ) {
                                ch_free( syncCookie.bv_val );
-                       if ( syncUUID.bv_val )
+                               syncCookie.bv_val = NULL;
+                       }
+                       if ( syncUUID.bv_val ) {
                                ch_free( syncUUID.bv_val );
+                               syncUUID.bv_val = NULL;
+                       }
                }
                ldap_msgfree( res );
        }
@@ -667,6 +625,11 @@ do_syncrepl(
        }
 
 done:
+#if defined( LDAP_SLAPI )
+       if ( op.o_pb ) slapi_pblock_destroy( op.o_pb );
+       slapi_x_free_object_extensions( SLAPI_X_EXT_OPERATION, &op );
+#endif /* defined( LDAP_SLAPI ) */
+
        if ( syncCookie.bv_val )
                ch_free( syncCookie.bv_val );
        if ( syncCookie_req.bv_val )
@@ -703,37 +666,22 @@ syncrepl_message_to_entry(
        struct berval   *syncCookie
 )
 {
-       Entry           *e;
+       Entry           *e = NULL;
        BerElement      *ber = NULL;
-       BerElement      *tmpber;
-       struct berval   bv = {0, NULL};
        Modifications   tmp;
        Modifications   *mod;
        Modifications   **modtail = modlist;
-       Backend         *be = op->o_bd;
 
        const char      *text;
        char txtbuf[SLAP_TEXT_BUFLEN];
        size_t textlen = sizeof txtbuf;
 
-       struct berval   **bvals = NULL;
-       char            *dn;
        struct berval   bdn = {0, NULL};
-       Attribute       *attr;
-       struct berval   empty_bv = { 0, NULL };
        int             rc;
-       char            *a;
 
        ber_len_t       len;
        LDAPControl*    rctrlp;
        LDAPControl**   rctrls = NULL;
-       BerElement*     ctrl_ber;
-
-       ber_tag_t       tag;
-
-       Modifications *ml = NULL;
-       AttributeDescription** descs;
-       int i;
 
        *modlist = NULL;
 
@@ -750,6 +698,18 @@ syncrepl_message_to_entry(
 
        op->o_tag = LDAP_REQ_ADD;
 
+       rc = ldap_get_entry_controls( ld, msg, &rctrls );
+       if ( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, ERR,
+                       "syncrepl_message_to_entry : control get failed (%d)", rc, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "syncrepl_message_to_entry : control get failed (%d)", rc, 0, 0 );
+#endif
+               goto done;
+       }
+
        rc = ldap_get_dn_ber( ld, msg, &ber, &bdn );
 
        if ( rc != LDAP_SUCCESS ) {
@@ -763,16 +723,12 @@ syncrepl_message_to_entry(
                return NULL;
        }
 
-       e = ( Entry * ) ch_calloc( 1, sizeof( Entry ));
-       dnPrettyNormal( NULL, &bdn, &e->e_name, &e->e_nname, NULL );
-
-       e->e_attrs = NULL;
+       e = ( Entry * ) sl_calloc( 1, sizeof( Entry ), op->o_tmpmemctx);
+       dnPrettyNormal( NULL, &bdn, &e->e_name, &e->e_nname, op->o_tmpmemctx );
 
        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;
+               if ( (ber_scanf( ber, "{mW}", &tmp.sml_type, &tmp.sml_values ) ==
+                       LBER_ERROR ) || ( tmp.sml_type.bv_val == NULL )) break;
 
                mod  = (Modifications *) ch_malloc( sizeof( Modifications ));
 
@@ -787,46 +743,17 @@ syncrepl_message_to_entry(
                modtail = &mod->sml_next;
        }
 
-       if ( ber_scanf( ber, "}") == LBER_ERROR ) {
-#ifdef NEW_LOGGING
-               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 );
-#endif
-               return NULL;
-       }
-
-       ber_free( ber, 0 );
-       tmpber = ldap_get_message_ber( msg );
-       ber = ber_dup( tmpber );
-
-       ber_scanf( ber, "{xx" );
-
-       rc = ldap_pvt_get_controls( ber, &rctrls );
-       if ( rc != LDAP_SUCCESS ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, ERR,
-                       "syncrepl_message_to_entry : control get failed (%d)", rc, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_ANY,
-                       "syncrepl_message_to_entry : control get failed (%d)", rc, 0, 0 );
-#endif
-               return NULL;
-       }
-
        if ( rctrls ) {
+               BerElementBuffer berbuf;
+               BerElement      *ctrl_ber;
+
                rctrlp = *rctrls;
-               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 );
+               ctrl_ber = (BerElement *)&berbuf;
+               ber_init2( ctrl_ber, &rctrlp->ldctl_value, LBER_USE_DER );
                ber_scanf( ctrl_ber, "{eo", syncstate, syncUUID );
                if ( ber_peek_tag( ctrl_ber, &len ) == LDAP_SYNC_TAG_COOKIE ) {
                        ber_scanf( ctrl_ber, "o}", syncCookie );
                }
-               ber_free( ctrl_ber, 1 );
                ldap_controls_free( rctrls );
        } else {
 #ifdef NEW_LOGGING
@@ -839,6 +766,7 @@ syncrepl_message_to_entry(
        }
 
        if ( *syncstate == LDAP_SYNC_PRESENT || *syncstate == LDAP_SYNC_DELETE ) {
+               rc = 1;
                goto done;
        }
 
@@ -852,21 +780,6 @@ syncrepl_message_to_entry(
 #endif
        }
 
-       ml = *modlist;
-       while ( ml != NULL ) {
-               AttributeDescription *ad = NULL;
-        rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, &text );
-
-               if( rc != LDAP_SUCCESS ) {
-                       e = NULL;
-                       goto done;
-               }
-
-               ad = ml->sml_desc;
-               ml->sml_desc = NULL;
-               ml = ml->sml_next;
-       }
-
        rc = slap_mods_check( *modlist, 1, &text, txtbuf, textlen, NULL );
 
        if ( rc != LDAP_SUCCESS ) {
@@ -877,7 +790,7 @@ syncrepl_message_to_entry(
                Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods check (%s)\n",
                                text, 0, 0 );
 #endif
-               return NULL;
+               goto done;
        }
        
        rc = slap_mods2entry( *modlist, &e, 1, 1, &text, txtbuf, textlen);
@@ -892,8 +805,11 @@ syncrepl_message_to_entry(
        }
 
 done:
-
        ber_free ( ber, 0 );
+       if ( rc != LDAP_SUCCESS ) {
+               entry_free( e );
+               e = NULL;
+       }
 
        return e;
 }
@@ -923,20 +839,11 @@ syncrepl_entry(
 {
        Backend *be = op->o_bd;
        slap_callback   cb;
-       struct berval   csn_bv = {0, NULL};
        struct berval   *syncuuid_bv = NULL;
-       char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
 
        SlapReply       rs = {REP_RESULT};
        int rc = LDAP_SUCCESS;
 
-       struct berval base_bv = {0, NULL};
-
-       char *filterstr;
-       Filter *filter;
-
-       Attribute *a;
-
        if ( refresh &&
                        ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD )) {
                syncuuid_bv = ber_dupbv( NULL, syncUUID );
@@ -952,24 +859,21 @@ syncrepl_entry(
                }
        }
 
-       filterstr = (char *) sl_malloc( strlen("entryUUID=") + syncUUID->bv_len + 1,
+       op->ors_filterstr.bv_len = strlen("entryUUID=") + syncUUID->bv_len;
+       op->ors_filterstr.bv_val = (char *) sl_malloc( op->ors_filterstr.bv_len + 1,
                                                                        op->o_tmpmemctx ); 
-       strcpy( filterstr, "entryUUID=" );
-       strcat( filterstr, syncUUID->bv_val );
+       strcpy( op->ors_filterstr.bv_val, "entryUUID=" );
+       strcat( op->ors_filterstr.bv_val, syncUUID->bv_val );
 
        si->e = e;
        si->syncUUID_ndn = NULL;
 
-       filter = str2filter( filterstr );
-       ber_str2bv( filterstr, strlen(filterstr), 1, &op->ors_filterstr );
-       ch_free( filterstr );
-       op->ors_filter = filter;
+       op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );
        op->ors_scope = LDAP_SCOPE_SUBTREE;
 
        /* 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 );
+       op->o_req_dn = si->base;
+       op->o_req_ndn = si->base;
 
        /* set callback function */
        op->o_callback = &cb;
@@ -980,14 +884,10 @@ syncrepl_entry(
 
        rc = be->be_search( op, &rs );
 
-       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 );
        if ( op->ors_filter )
-               filter_free( op->ors_filter );
+               filter_free_x( op, op->ors_filter );
        if ( op->ors_filterstr.bv_val )
-               ch_free( op->ors_filterstr.bv_val );
+               sl_free( op->ors_filterstr.bv_val, op->o_tmpmemctx );
 
        cb.sc_response = null_callback;
        cb.sc_private = si;
@@ -1102,23 +1002,17 @@ syncrepl_entry(
 static void
 syncrepl_del_nonpresent(
        LDAP *ld,
-       Operation *op
+       Operation *op,
+       syncinfo_t *si
 )
 {
        Backend* be = op->o_bd;
-       syncinfo_t *si = op->o_si;
        slap_callback   cb;
-       struct berval   base_bv = {0, NULL};
-       Filter *filter;
        SlapReply       rs = {REP_RESULT};
-       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, op->o_tmpmemctx );
-       ch_free( base_bv.bv_val );
-
-       filter = str2filter( si->filterstr );
+       op->o_req_dn = si->base;
+       op->o_req_ndn = si->base;
 
        cb.sc_response = nonpresent_callback;
        cb.sc_private = si;
@@ -1131,21 +1025,15 @@ syncrepl_del_nonpresent(
        op->ors_tlimit = 0;
        op->ors_attrsonly = 0;
        op->ors_attrs = NULL;
-       op->ors_filter = filter;
-       ber_str2bv( si->filterstr, strlen( si->filterstr ), 1, &op->ors_filterstr );
+       op->ors_filter = str2filter_x( op, si->filterstr.bv_val );
+       op->ors_filterstr = si->filterstr;
 
        op->o_nocaching = 1;
        be->be_search( op, &rs );
        op->o_nocaching = 0;
 
-       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 );
        if ( op->ors_filter )
-               filter_free( op->ors_filter );
-       if ( op->ors_filterstr.bv_val )
-               ch_free( op->ors_filterstr.bv_val );
+               filter_free_x( op, op->ors_filter );
 
        if ( !LDAP_LIST_EMPTY( &si->nonpresentlist ) ) {
                np_list = LDAP_LIST_FIRST( &si->nonpresentlist );
@@ -1185,11 +1073,9 @@ syncrepl_add_glue(
 )
 {
        Backend *be = op->o_bd;
-       struct berval   uuid_bv = {0, NULL};
        slap_callback cb;
        Attribute       *a;
        int     rc;
-       char    uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
        int levels = 0;
        int i, j, k;
        struct berval dn = {0, NULL};
@@ -1541,27 +1427,6 @@ avl_ber_bvfree( void *bv )
        ch_free ( (char *) bv );
 }
 
-static int
-cookie_callback(
-       Operation* op,
-       SlapReply* rs
-)
-{
-       syncinfo_t *si = op->o_callback->sc_private;
-       Attribute *a;
-
-       if ( rs->sr_type != REP_SEARCH ) return LDAP_SUCCESS;
-
-       a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_syncreplCookie );
-
-       if ( a == NULL ) {
-               si->syncCookie = NULL;
-       } else {
-               si->syncCookie = ber_dupbv( NULL, &a->a_vals[0] );
-       }
-       return LDAP_SUCCESS;
-}
-
 static int
 dn_callback(
        Operation*      op,
@@ -1601,8 +1466,6 @@ nonpresent_callback(
        Attribute *a;
        int count = 0;
        struct berval* present_uuid = NULL;
-       slap_callback cb;
-       SlapReply       rs_cb = {REP_RESULT};
        struct nonpresent_entry *np_entry;
 
        if ( rs->sr_type == REP_RESULT ) {
@@ -1642,8 +1505,6 @@ null_callback(
        SlapReply*      rs
 )
 {
-       syncinfo_t *si = op->o_callback->sc_private;
-
        if ( rs->sr_err != LDAP_SUCCESS &&
                 rs->sr_err != LDAP_REFERRAL &&
                 rs->sr_err != LDAP_ALREADY_EXISTS &&
@@ -1670,7 +1531,6 @@ slap_create_syncrepl_entry(
 )
 {
        Entry* e;
-       int rc;
 
        struct berval bv;