Commit 7f882daf authored by Jong Hyuk Choi's avatar Jong Hyuk Choi
Browse files

Schema checking option for LDAP Sync replication

parent 8dc1ac85
......@@ -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
......
......@@ -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 ) ) {
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 ) {
......
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment