]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
Plug mutex/rwlock leaks (destroy them)
[openldap] / servers / slapd / syncrepl.c
index 02236b0bac751228b1b92cd6e521a9b8ab320694..b2f7cd3be65f1764f49c9b2220e6fe4a4cda56c6 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003-2009 The OpenLDAP Foundation.
+ * Copyright 2003-2010 The OpenLDAP Foundation.
  * Portions Copyright 2003 by IBM Corporation.
  * Portions Copyright 2003-2008 by Howard Chu, Symas Corporation.
  * All rights reserved.
@@ -131,6 +131,8 @@ static int syncrepl_updateCookie(
                                        struct sync_cookie * );
 static struct berval * slap_uuidstr_from_normalized(
                                        struct berval *, struct berval *, void * );
+static int syncrepl_add_glue_ancestors(
+       Operation* op, Entry *e );
 
 /* callback functions */
 static int dn_callback( Operation *, SlapReply * );
@@ -1413,6 +1415,11 @@ do_syncrepl(
                si->si_refreshDelete = 0;
                si->si_refreshPresent = 0;
 
+               if ( si->si_presentlist ) {
+                   avl_free( si->si_presentlist, ch_free );
+                   si->si_presentlist = NULL;
+               }
+
                /* use main DB when retrieving contextCSN */
                op->o_bd = si->si_wbe;
                op->o_dn = op->o_bd->be_rootdn;
@@ -1559,10 +1566,11 @@ static slap_verbmasks modops[] = {
        { BER_BVNULL, 0 }
 };
 
-static Modifications *
+static int
 syncrepl_accesslog_mods(
        syncinfo_t *si,
-       struct berval *vals
+       struct berval *vals,
+       struct Modifications **modres
 )
 {
        char *colon;
@@ -1571,7 +1579,7 @@ syncrepl_accesslog_mods(
        struct berval bv, bv2;
        short op;
        Modifications *mod = NULL, *modlist = NULL, **modtail;
-       int i;
+       int i, rc = 0;
 
        modtail = &modlist;
 
@@ -1588,7 +1596,13 @@ syncrepl_accesslog_mods(
                bv.bv_len = colon - bv.bv_val;
                if ( slap_bv2ad( &bv, &ad, &text ) ) {
                        /* Invalid */
-                       continue;
+                       Debug( LDAP_DEBUG_ANY, "syncrepl_accesslog_mods: %s "
+                               "Invalid attribute %s, %s\n",
+                               si->si_ridtxt, bv.bv_val, text );
+                       slap_mods_free( modlist, 1 );
+                       modlist = NULL;
+                       rc = -1;
+                       break;
                }
 
                /* Ignore dynamically generated attrs */
@@ -1633,16 +1647,18 @@ syncrepl_accesslog_mods(
                        mod->sml_numvals++;
                }
        }
-       return modlist;
+       *modres = modlist;
+       return rc;
 }
 
-static Modifications *
+static int
 syncrepl_changelog_mods(
        syncinfo_t *si,
-       struct berval *vals
+       struct berval *vals,
+       struct Modifications **modres
 )
 {
-       return NULL;    /* FIXME */
+       return -1;      /* FIXME */
 }
 
 static int
@@ -1737,10 +1753,11 @@ syncrepl_message_to_op(
                } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_mod ) ) {
                        /* Parse attribute into modlist */
                        if ( si->si_syncdata == SYNCDATA_ACCESSLOG ) {
-                               modlist = syncrepl_accesslog_mods( si, bvals );
+                               rc = syncrepl_accesslog_mods( si, bvals, &modlist );
                        } else {
-                               modlist = syncrepl_changelog_mods( si, bvals );
+                               rc = syncrepl_changelog_mods( si, bvals, &modlist );
                        }
+                       if ( rc ) goto done;
                } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newRdn ) ) {
                        rdn = bvals[0];
                } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_delRdn ) ) {
@@ -2552,7 +2569,19 @@ retry_add:;
                                mod->sml_next = m2;
                        }
                        op->o_bd = si->si_wbe;
+retry_modrdn:;
                        rc = op->o_bd->be_modrdn( op, &rs_modify );
+
+                       /* NOTE: noSuchObject should result because the new superior
+                        * has not been added yet (ITS#6472) */
+                       if ( rc == LDAP_NO_SUCH_OBJECT && !BER_BVISNULL( op->orr_nnewSup )) {
+                               Operation op2 = *op;
+                               rc = syncrepl_add_glue_ancestors( &op2, entry );
+                               if ( rc == LDAP_SUCCESS ) {
+                                       goto retry_modrdn;
+                               }
+                       }
+               
                        op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );
                        op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );
 
@@ -2878,15 +2907,15 @@ syncrepl_del_nonpresent(
        return;
 }
 
-int
-syncrepl_add_glue(
+static int
+syncrepl_add_glue_ancestors(
        Operation* op,
        Entry *e )
 {
        Backend *be = op->o_bd;
        slap_callback cb = { NULL };
        Attribute       *a;
-       int     rc;
+       int     rc = LDAP_SUCCESS;
        int suffrdns;
        int i;
        struct berval dn = BER_BVNULL;
@@ -3013,6 +3042,34 @@ syncrepl_add_glue(
                ndn.bv_len = e->e_nname.bv_len - (ndn.bv_val - e->e_nname.bv_val);
        }
 
+       return rc;
+}
+
+int
+syncrepl_add_glue(
+       Operation* op,
+       Entry *e )
+{
+       slap_callback cb = { NULL };
+       int     rc;
+       Backend *be = op->o_bd;
+       SlapReply       rs_add = {REP_RESULT};
+
+       rc = syncrepl_add_glue_ancestors( op, e );
+       switch ( rc ) {
+       case LDAP_SUCCESS:
+       case LDAP_ALREADY_EXISTS:
+               break;
+
+       default:
+               return rc;
+       }
+
+       op->o_tag = LDAP_REQ_ADD;
+       op->o_callback = &cb;
+       cb.sc_response = null_callback;
+       cb.sc_private = NULL;
+
        op->o_req_dn = e->e_name;
        op->o_req_ndn = e->e_nname;
        op->ora_e = e;
@@ -3246,10 +3303,12 @@ attr_cmp( Operation *op, Attribute *old, Attribute *new,
                 * Also use replace op if attr has no equality matching rule.
                 * (ITS#5781)
                 */
-               if ( nn && no < o &&
+               if ( ( nn || ( no > 0 && no < o ) ) &&
                        ( old->a_desc == slap_schema.si_ad_objectClass ||
-                        !old->a_desc->ad_type->sat_equality ))
+                        !old->a_desc->ad_type->sat_equality ) )
+               {
                        no = o;
+               }
 
                i = j;
                /* all old values were deleted, just use the replace op */
@@ -4538,9 +4597,10 @@ add_syncrepl(
                return 1;
        } else {
                Debug( LDAP_DEBUG_CONFIG,
-                       "Config: ** successfully added syncrepl \"%s\"\n",
+                       "Config: ** successfully added syncrepl %s \"%s\"\n",
+                       si->si_ridtxt,
                        BER_BVISNULL( &si->si_bindconf.sb_uri ) ?
-                       "(null)" : si->si_bindconf.sb_uri.bv_val, 0, 0 );
+                       "(null)" : si->si_bindconf.sb_uri.bv_val, 0 );
                if ( c->be->be_syncinfo ) {
                        syncinfo_t *sip;