]> git.sur5r.net Git - openldap/commitdiff
Schema checking option for LDAP Sync replication
authorJong Hyuk Choi <jongchoi@openldap.org>
Wed, 3 Sep 2003 21:42:52 +0000 (21:42 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Wed, 3 Sep 2003 21:42:52 +0000 (21:42 +0000)
doc/man/man5/slapd.conf.5
servers/slapd/config.c
servers/slapd/modify.c
servers/slapd/slap.h
servers/slapd/syncrepl.c
tests/data/slapd-syncrepl-slave-persist1.conf
tests/data/slapd-syncrepl-slave-persist2.conf
tests/data/slapd-syncrepl-slave-persist3.conf
tests/data/slapd-syncrepl-slave-refresh1.conf
tests/data/slapd-syncrepl-slave-refresh2.conf

index 8ed4221babf91409dc5429483bbccea2704c818a..633cd317b59deddde54cd0bdb37197f4207c6230 100644 (file)
@@ -1112,6 +1112,7 @@ If specified multiple times, each url is provided.
 .B [searchbase=<base DN>]
 .B [filter=<filter str>]
 .B [attrs=<attr list>]
+.B [schemachecking=on|off]
 .B [scope=sub|one|base]
 .B [type=refreshOnly|refreshAndPersist]
 .B [interval=dd:hh:mm]
@@ -1155,6 +1156,19 @@ is
 The replication provider site is specified by
 .B provider
 as an LDAP URI.
+If 
+.B schemachecking
+is
+.B on,
+every replicated entry will be checked for its schema
+when it is stored in the consumer replica.
+The consumer slapd should retrieve attributes of an entry
+that are required by the schema definition.
+If 
+.B schemachecking
+is
+.B off,
+entries will be stored without checking the schema conformance.
 A
 .B bindmethod
 of 
index bc215559d8f4cc8aa680acbba2fb1e4b4cbec2ce..14b03884095e4a3413fcf77d47814e60e5720f36 100644 (file)
@@ -2740,18 +2740,16 @@ add_syncrepl(
 
        si = be->syncinfo = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
 
-       /* set default values; FIXME : add others */
        si->tls = TLS_OFF;
        if ( be->be_rootndn.bv_val )
                ber_dupbv( &si->updatedn, &be->be_rootndn );
        si->bindmethod = LDAP_AUTH_SIMPLE;
-       si->lastmod = LASTMOD_NO;
+       si->schemachecking = 0;
        si->filterstr = "(objectclass=*)";
        if ( be->be_suffix && be->be_suffix[0].bv_val )
                si->base = ch_strdup( be->be_suffix[0].bv_val );
        si->scope = LDAP_SCOPE_SUBTREE;
        si->attrsonly = 0;
-       si->attrsexclude = 0;
        si->attrs = (char **) ch_calloc( 1, sizeof( char * ));
        si->attrs[0] = NULL;
        si->type = LDAP_SYNC_REFRESH_ONLY;
@@ -2795,7 +2793,9 @@ add_syncrepl(
                        "Config: ** successfully added syncrepl \"%s\"\n",
                        si->provideruri == NULL ? "(null)" : si->provideruri, 0, 0 );
 #endif
-               be->be_flags |= SLAP_BFLAG_NO_SCHEMA_CHECK;
+               if ( !si->schemachecking ) {
+                       be->be_flags |= SLAP_BFLAG_NO_SCHEMA_CHECK;
+               }
                si->be = be;
        }
 }
@@ -2819,6 +2819,7 @@ add_syncrepl(
 #define STARTTLSSTR            "starttls"
 #define CRITICALSTR            "critical"
 
+#define SCHEMASTR              "schemachecking"
 #define FILTERSTR              "filter"
 #define SEARCHBASESTR  "searchbase"
 #define SCOPESTR               "scope"
@@ -2938,17 +2939,15 @@ parse_syncrepl_line(
                                free( si->srvtab );
                        }
                        si->srvtab = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], LASTMODSTR,
-                               sizeof( LASTMODSTR ) - 1 ) ) {
-                       val = cargv[ i ] + sizeof( LASTMODSTR );
-                       if ( !strcasecmp( val, LMREQSTR )) {
-                               si->lastmod = LASTMOD_REQ;
-                       } else if ( !strcasecmp( val, LMGENSTR )) {
-                               si->lastmod = LASTMOD_GEN;
-                       } else if ( !strcasecmp( val, LMNOSTR )) {
-                               si->lastmod = LASTMOD_NO;
+               } else if ( !strncasecmp( cargv[ i ],
+                               SCHEMASTR, sizeof( SCHEMASTR ) - 1 ) ) {
+                       val = cargv[ i ] + sizeof( SCHEMASTR );
+                       if ( !strncasecmp( val, "on", sizeof( "on" ) - 1 )) {
+                               si->schemachecking = 1;
+                       } else if ( !strncasecmp( val, "off", sizeof( "off" ) - 1 ) ) {
+                               si->schemachecking = 0;
                        } else {
-                               si->lastmod = -1;
+                               si->schemachecking = 1;
                        }
                } else if ( !strncasecmp( cargv[ i ],
                                FILTERSTR, sizeof( FILTERSTR ) - 1 ) ) {
@@ -2977,13 +2976,7 @@ parse_syncrepl_line(
                        si->attrsonly = 1;
                } else if ( !strncasecmp( cargv[ i ],
                                ATTRSSTR, sizeof( ATTRSSTR ) - 1 ) ) {
-                       val = cargv[ i ] + sizeof( ATTRSSTR ) - 1;
-                       if ( *val == '!' ) {
-                               si->attrsexclude = 1;
-                               val++;
-                       }
-                       if ( *val++ != '=' )
-                               continue;
+                       val = cargv[ i ] + sizeof( ATTRSSTR );
                        str2clist( &si->attrs, val, "," );
                } else if ( !strncasecmp( cargv[ i ],
                                TYPESTR, sizeof( TYPESTR ) - 1 ) ) {
index 95af77aa0df84bf78d3a80c0591b863089ef8f23..5ab98d6c81227a74c950885809dad13ebc631802 100644 (file)
@@ -766,12 +766,10 @@ int slap_mods_opattrs(
        int mop = op->o_tag == LDAP_REQ_ADD
                ? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
 
-       syncinfo_t *si = op->o_si;
-
        assert( modtail != NULL );
        assert( *modtail == NULL );
 
-       if ( SLAP_LASTMOD(op->o_bd) && ( !si || si->lastmod == LASTMOD_GEN )) {
+       if ( SLAP_LASTMOD( op->o_bd )) {
                struct tm *ltm;
                time_t now = slap_get_time();
 
@@ -824,27 +822,25 @@ int slap_mods_opattrs(
                        modtail = &mod->sml_next;
                }
 
-               if ( SLAP_LASTMOD(op->o_bd) && ( !si || si->lastmod == LASTMOD_GEN )) {
+               if ( SLAP_LASTMOD( op->o_bd )) {
                        char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
 
-                       if ( !si ) {
-                               tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
-                               tmpval.bv_val = uuidbuf;
+                       tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
+                       tmpval.bv_val = uuidbuf;
                
-                               mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
-                               mod->sml_op = mop;
-                               mod->sml_type.bv_val = NULL;
-                               mod->sml_desc = slap_schema.si_ad_entryUUID;
-                               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 = 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_entryUUID;
+                       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 = NULL;
+                       *modtail = mod;
+                       modtail = &mod->sml_next;
 
                        mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                        mod->sml_op = mop;
@@ -879,7 +875,7 @@ int slap_mods_opattrs(
                }
        }
 
-       if ( SLAP_LASTMOD(op->o_bd) && ( !si || si->lastmod == LASTMOD_GEN )) {
+       if ( SLAP_LASTMOD( op->o_bd )) {
                mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                mod->sml_op = mop;
                mod->sml_type.bv_val = NULL;
index c62d40d993c913db64c6a56d39369778094a3762..44a718f8fb8546769e9f9aab5d2464c2b1149a30 100644 (file)
@@ -1305,16 +1305,12 @@ typedef struct syncinfo_s {
         char                   *authcId;
         char                   *authzId;
         char                   *srvtab;
-#define LASTMOD_REQ            0
-#define LASTMOD_GEN            1
-#define LASTMOD_NO             2
-        int                            lastmod;
+               int                             schemachecking;
         Filter                 *filter;
         char                   *filterstr;
         char                   *base;
         int                            scope;
         int                            attrsonly;
-               int                             attrsexclude;
         char                   **attrs;
         int                            type;
         time_t                 interval;
index 057afa5c78ef30ecf190cb6ea4755004b5bcf78a..c7743996cc76cdc7c83f4f898b308f94064858ca 100644 (file)
@@ -45,45 +45,18 @@ 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 **add_descs;
-static AttributeDescription **add_descs_lastmod;
-static AttributeDescription **del_descs;
-static AttributeDescription **del_descs_lastmod;
+static AttributeDescription **sync_descs;
 
 struct runqueue_s syncrepl_rq;
 
 void
 init_syncrepl()
 {
-       add_descs = ch_malloc( 2 * sizeof( AttributeDescription * ));
-       add_descs[0] = slap_schema.si_ad_objectClass;
-       add_descs[1] = NULL;
-
-       add_descs_lastmod = ch_malloc( 7 * sizeof( AttributeDescription * ));
-       add_descs_lastmod[0] = slap_schema.si_ad_objectClass;
-       add_descs_lastmod[1] = slap_schema.si_ad_creatorsName;
-       add_descs_lastmod[2] = slap_schema.si_ad_modifiersName;
-       add_descs_lastmod[3] = slap_schema.si_ad_createTimestamp;
-       add_descs_lastmod[4] = slap_schema.si_ad_modifyTimestamp;
-       add_descs_lastmod[5] = slap_schema.si_ad_entryCSN;
-       add_descs_lastmod[6] = NULL;
-
-       del_descs = ch_malloc( 9 * sizeof( AttributeDescription * ));
-       del_descs[0] = slap_schema.si_ad_structuralObjectClass;
-       del_descs[1] = slap_schema.si_ad_subschemaSubentry;
-       del_descs[2] = slap_schema.si_ad_hasSubordinates;
-       del_descs[3] = slap_schema.si_ad_creatorsName;
-       del_descs[4] = slap_schema.si_ad_modifiersName;
-       del_descs[5] = slap_schema.si_ad_createTimestamp;
-       del_descs[6] = slap_schema.si_ad_modifyTimestamp;
-       del_descs[7] = slap_schema.si_ad_entryCSN;
-       del_descs[8] = NULL;
-
-       del_descs_lastmod = ch_malloc( 4 * sizeof( AttributeDescription * ));
-       del_descs_lastmod[0] = slap_schema.si_ad_structuralObjectClass;
-       del_descs_lastmod[1] = slap_schema.si_ad_subschemaSubentry;
-       del_descs_lastmod[2] = slap_schema.si_ad_hasSubordinates;
-       del_descs_lastmod[3] = NULL;
+       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
@@ -430,11 +403,7 @@ do_syncrepl(
        psub = be->be_nsuffix[0];
 
        /* Delete Attributes */
-       if ( si->lastmod == LASTMOD_REQ ) {
-               descs = del_descs_lastmod;
-       } else {
-               descs = del_descs;
-       }
+       descs = sync_descs;
 
        for ( i = 0; descs[i] != NULL; i++ ) {
                for ( j = 0; si->attrs[j] != NULL; j++ ) {
@@ -451,15 +420,11 @@ do_syncrepl(
 
        for ( n = 0; si->attrs[ n ] != NULL; n++ ) ;
        
-       if ( si->lastmod == LASTMOD_REQ ) {
-               descs = add_descs_lastmod;
-       } else {
-               descs = add_descs;
-       }
+       descs = sync_descs;
 
        for ( i = 0; descs[i] != NULL; i++ ) {
                tmp = ( char ** ) ch_realloc( si->attrs,
-                               ( n + 2 ) * sizeof( char * ));
+                               ( n + 3 ) * sizeof( char * ));
                if ( tmp == NULL ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 );
@@ -719,8 +684,6 @@ syncrepl_message_to_entry(
 
        ber_tag_t       tag;
 
-       Modifications *prevml = NULL;
-       Modifications *nextml = NULL;
        Modifications *ml = NULL;
        AttributeDescription** descs;
        int i;
@@ -857,29 +820,6 @@ syncrepl_message_to_entry(
 
                ad = ml->sml_desc;
                ml->sml_desc = NULL;
-
-               if ( si->lastmod == LASTMOD_REQ ) {
-                       descs = del_descs_lastmod;
-               } else {
-                       descs = del_descs;
-               }
-
-               for ( i = 0; descs[i] != NULL; i++ ) {
-                       if ( ad == descs[i] ) {
-                               if ( prevml == NULL ) {
-                                       modlist = &ml->sml_next;
-                                       prevml = NULL;
-                               } else {
-                                       prevml->sml_next = ml->sml_next;
-                               }
-                               slap_mod_free( &ml->sml_mod, 0 );
-                               nextml = ml->sml_next;
-                               free( ml );
-                               ml = nextml;
-                               continue;
-                       }
-               }
-               prevml = ml;
                ml = ml->sml_next;
        }
 
@@ -896,20 +836,6 @@ syncrepl_message_to_entry(
                return NULL;
        }
        
-       rc = slap_mods_opattrs( 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 );
-#else
-               Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods opattrs (%s)\n",
-                               text, 0, 0 );
-#endif
-               return NULL;
-       }
-
        rc = slap_mods2entry( *modlist, &e, 1, 1, &text, txtbuf, textlen);
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -1037,9 +963,8 @@ syncrepl_entry(
                         rc == LDAP_REFERRAL ||
                         rc == LDAP_NO_SUCH_OBJECT ) {
 
-                       if ( !attr_find( e->e_attrs, slap_schema.si_ad_entryUUID )) {
-                               attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, syncUUID, op->o_tmpmemctx );
-                       }
+                       attr_delete( &e->e_attrs, slap_schema.si_ad_entryUUID );
+                       attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, syncUUID, op->o_tmpmemctx );
 
                        op->o_tag = LDAP_REQ_ADD;
                        op->ora_e = e;
@@ -1447,8 +1372,7 @@ syncrepl_updateCookie(
 
        for ( ml = modlist; ml != NULL; ml = mlnext ) {
                mlnext = ml->sml_next;
-               if ( ml->sml_desc == slap_schema.si_ad_structuralObjectClass )
-                       ml->sml_op = LDAP_MOD_REPLACE;
+               ml->sml_op = LDAP_MOD_REPLACE;
        }
 
        if( rc != LDAP_SUCCESS ) {
@@ -1494,6 +1418,7 @@ update_cookie_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 ) {
index ff78f8406720731c3e3b4e3160414eeb2fba3868..fb925e456c9f379d0fcfcf624ca16fa1dab0e085 100644 (file)
@@ -39,6 +39,6 @@ syncrepl id=1
                 searchbase="o=University of Michigan,c=US"
                 filter="(objectClass=*)"
                 attrs="*"
-                lastmod=req
+                schemachecking=off
                 scope=sub
                 type=refreshAndPersist
index bab32b0d85737aad2d0ed7660b87c6222203d67f..3e36b665b5756ebaabeeb359b8fd86b669a92146 100644 (file)
@@ -39,6 +39,6 @@ syncrepl id=1
                 searchbase="o=University of Michigan,c=US"
                 filter="(objectClass=*)"
                 attrs="*"
-                lastmod=req
+                schemachecking=off
                 scope=sub
                 type=refreshAndPersist
index b3dbd61c8962eb54e7b48c39c1dfce7c0177ae53..bb3d315b9b2e5a1985097ca98811b46acbab455e 100644 (file)
@@ -39,6 +39,6 @@ syncrepl id=1
                 searchbase="o=University of Michigan,c=US"
                 filter="(objectClass=*)"
                 attrs="*"
-                lastmod=req
+                schemachecking=off
                 scope=sub
                 type=refreshAndPersist
index b1279c835ec615179f6ca1b4ede5408d7dae7fc1..5245f1a8007b5e24ae120020d151faf1e0afd948 100644 (file)
@@ -39,7 +39,7 @@ syncrepl id=1
                 searchbase="o=University of Michigan,c=US"
                 filter="(objectClass=*)"
                 attrs="*"
-                lastmod=req
+                schemachecking=off
                 scope=sub
                 type=refreshOnly
                 interval=00:00:01
index 64f66f07cc3abc0099ff5af3dbeaab3f056dfe1c..5499fcd4668205afb34abeb7ec5eae9b97ed7443 100644 (file)
@@ -39,7 +39,7 @@ syncrepl id=1
                 searchbase="o=University of Michigan,c=US"
                 filter="(objectClass=*)"
                 attrs="*"
-                lastmod=req
+                schemachecking=off
                 scope=sub
                 type=refreshOnly
                 interval=00:00:01