From 7f882daf159013d8d4694216eddebd313e528828 Mon Sep 17 00:00:00 2001 From: Jong Hyuk Choi Date: Wed, 3 Sep 2003 21:42:52 +0000 Subject: [PATCH] Schema checking option for LDAP Sync replication --- doc/man/man5/slapd.conf.5 | 14 +++ servers/slapd/config.c | 35 +++--- servers/slapd/modify.c | 40 ++++--- servers/slapd/slap.h | 6 +- servers/slapd/syncrepl.c | 101 +++--------------- tests/data/slapd-syncrepl-slave-persist1.conf | 2 +- tests/data/slapd-syncrepl-slave-persist2.conf | 2 +- tests/data/slapd-syncrepl-slave-persist3.conf | 2 +- tests/data/slapd-syncrepl-slave-refresh1.conf | 2 +- tests/data/slapd-syncrepl-slave-refresh2.conf | 2 +- 10 files changed, 65 insertions(+), 141 deletions(-) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 8ed4221bab..633cd317b5 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -1112,6 +1112,7 @@ If specified multiple times, each url is provided. .B [searchbase=] .B [filter=] .B [attrs=] +.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 diff --git a/servers/slapd/config.c b/servers/slapd/config.c index bc215559d8..14b0388409 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -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 ) ) { diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 95af77aa0d..5ab98d6c81 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -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; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index c62d40d993..44a718f8fb 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -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; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 057afa5c78..c7743996cc 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -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 ) { diff --git a/tests/data/slapd-syncrepl-slave-persist1.conf b/tests/data/slapd-syncrepl-slave-persist1.conf index ff78f84067..fb925e456c 100644 --- a/tests/data/slapd-syncrepl-slave-persist1.conf +++ b/tests/data/slapd-syncrepl-slave-persist1.conf @@ -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 diff --git a/tests/data/slapd-syncrepl-slave-persist2.conf b/tests/data/slapd-syncrepl-slave-persist2.conf index bab32b0d85..3e36b665b5 100644 --- a/tests/data/slapd-syncrepl-slave-persist2.conf +++ b/tests/data/slapd-syncrepl-slave-persist2.conf @@ -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 diff --git a/tests/data/slapd-syncrepl-slave-persist3.conf b/tests/data/slapd-syncrepl-slave-persist3.conf index b3dbd61c89..bb3d315b9b 100644 --- a/tests/data/slapd-syncrepl-slave-persist3.conf +++ b/tests/data/slapd-syncrepl-slave-persist3.conf @@ -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 diff --git a/tests/data/slapd-syncrepl-slave-refresh1.conf b/tests/data/slapd-syncrepl-slave-refresh1.conf index b1279c835e..5245f1a800 100644 --- a/tests/data/slapd-syncrepl-slave-refresh1.conf +++ b/tests/data/slapd-syncrepl-slave-refresh1.conf @@ -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 diff --git a/tests/data/slapd-syncrepl-slave-refresh2.conf b/tests/data/slapd-syncrepl-slave-refresh2.conf index 64f66f07cc..5499fcd466 100644 --- a/tests/data/slapd-syncrepl-slave-refresh2.conf +++ b/tests/data/slapd-syncrepl-slave-refresh2.conf @@ -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 -- 2.39.5