From 9bf3ccd0bff1de157660c1bfd0f923775f7b6dff Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 30 Mar 2002 08:52:20 +0000 Subject: [PATCH] allow attribute exclusion list in selective replica --- servers/slapd/config.c | 21 ++++++++++++++---- servers/slapd/proto-slap.h | 2 +- servers/slapd/repl.c | 43 +++++++++++++++++++++++++++++++------ servers/slapd/slap.h | 1 + servers/slapd/tools/mimic.c | 2 +- 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/servers/slapd/config.c b/servers/slapd/config.c index b9badcaed7..28ba0d17a7 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -1830,16 +1830,29 @@ read_config( const char *fname ) #endif break; } - } else if ( strncasecmp( cargv[i], "attr=", 5 ) == 0 ) { - if ( add_replica_attrs( be, nr, cargv[i] + 5 ) ) { + + } else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) { + int exclude = 0; + char *arg = cargv[i] + 4; + + if ( arg[0] == '!' ) { + arg++; + exclude = 1; + } + + if ( arg[0] != '=' ) { + continue; + } + + if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) { #ifdef NEW_LOGGING LDAP_LOG(( "config", LDAP_LEVEL_INFO, "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n", - fname, lineno, cargv[i] + 5 )); + fname, lineno, arg + 1 )); #else Debug( LDAP_DEBUG_ANY, "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n", - fname, lineno, cargv[i] + 5 ); + fname, lineno, arg + 1 ); #endif return( 1 ); } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 562c429127..e23a04c549 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -715,7 +715,7 @@ LDAP_SLAPD_F (int) add_replica_info LDAP_P(( Backend *be, LDAP_SLAPD_F (int) add_replica_suffix LDAP_P(( Backend *be, int nr, const char *suffix )); LDAP_SLAPD_F (int) add_replica_attrs LDAP_P(( Backend *be, - int nr, char *attrs )); + int nr, char *attrs, int exclude )); LDAP_SLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op, struct berval *dn, struct berval *ndn, void *change )); diff --git a/servers/slapd/repl.c b/servers/slapd/repl.c index 3057d4891e..6f2b3ac262 100644 --- a/servers/slapd/repl.c +++ b/servers/slapd/repl.c @@ -41,6 +41,8 @@ add_replica_info( be->be_replica[ i ] = ch_calloc( sizeof( struct slap_replica_info ), 1 ); be->be_replica[ i ]->ri_host = ch_strdup( host ); + be->be_replica[ i ]->ri_nsuffix = NULL; + be->be_replica[ i ]->ri_attrs = NULL; be->be_replica[ i + 1 ] = NULL; return( i ); @@ -77,9 +79,19 @@ int add_replica_attrs( Backend *be, int nr, - char *attrs + char *attrs, + int exclude ) { + if ( be->be_replica[nr]->ri_attrs != NULL ) { + if ( be->be_replica[nr]->ri_exclude != exclude ) { + fprintf( stderr, "attr selective replication directive '%s' conflicts with previous one (discarded)\n", attrs ); + ch_free( be->be_replica[nr]->ri_attrs ); + be->be_replica[nr]->ri_attrs = NULL; + } + } + + be->be_replica[nr]->ri_exclude = exclude; be->be_replica[nr]->ri_attrs = str2anlist( be->be_replica[nr]->ri_attrs, attrs, "," ); return ( be->be_replica[nr]->ri_attrs == NULL ); @@ -203,7 +215,16 @@ replog( /* fall thru */ case LDAP_REQ_MODIFY: for ( ml = change; ml != NULL; ml = ml->sml_next ) { - if ( ad_inlist( ml->sml_desc, be->be_replica[i]->ri_attrs ) ) { + int is_in, exclude; + + is_in = ad_inlist( ml->sml_desc, be->be_replica[i]->ri_attrs ); + exclude = be->be_replica[i]->ri_exclude; + + /* + * there might be a more clever way to do this test, + * but this way, at least, is comprehensible :) + */ + if ( ( is_in && !exclude ) || ( !is_in && exclude ) ) { subsets = 1; first = ml; break; @@ -216,7 +237,12 @@ replog( case LDAP_REQ_ADD: e = change; for ( a = e->e_attrs; a != NULL; a = a->a_next ) { - if ( ad_inlist( a->a_desc, be->be_replica[i]->ri_attrs ) ) { + int is_in, exclude; + + is_in = ad_inlist( a->a_desc, be->be_replica[i]->ri_attrs ); + exclude = be->be_replica[i]->ri_exclude; + + if ( ( is_in && !exclude ) || ( !is_in && exclude ) ) { subsets = 1; first = a; break; @@ -267,8 +293,12 @@ replog1( ml = first ? first : change; for ( ; ml != NULL; ml = ml->sml_next ) { char *type; - if ( ri && ri->ri_attrs && !ad_inlist( ml->sml_desc, ri->ri_attrs ) ) { - continue; + if ( ri && ri->ri_attrs ) { + int is_in = ad_inlist( ml->sml_desc, ri->ri_attrs ); + + if ( ( !is_in && !ri->ri_exclude ) || ( is_in && ri->ri_exclude ) ) { + continue; + } } type = ml->sml_desc->ad_cname.bv_val; switch ( ml->sml_op ) { @@ -296,7 +326,8 @@ replog1( a = first ? first : e->e_attrs; for ( ; a != NULL; a=a->a_next ) { if ( ri && ri->ri_attrs ) { - if ( !ad_inlist( a->a_desc, ri->ri_attrs ) ) { + int is_in = ad_inlist( a->a_desc, ri->ri_attrs ); + if ( ( !is_in && !ri->ri_exclude ) || ( is_in && ri->ri_exclude ) ) { continue; } /* If the list includes objectClass names, diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 146626b628..dc88b57cc5 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1006,6 +1006,7 @@ struct slap_replica_info { char *ri_host; /* supersedes be_replica */ struct berval **ri_nsuffix; /* array of suffixes this replica accepts */ AttributeName *ri_attrs; /* attrs to replicate, NULL=all */ + int ri_exclude; /* 1 => exclude ri_attrs */ }; struct slap_limits_set { diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c index f53f1bde64..3db426bac4 100644 --- a/servers/slapd/tools/mimic.c +++ b/servers/slapd/tools/mimic.c @@ -201,7 +201,7 @@ int add_replica_suffix( Backend *be, int nr, const char *suffix ) return 0; } -int add_replica_attrs( Backend *be, int nr, char *attrs ) +int add_replica_attrs( Backend *be, int nr, char *attrs, int exclude ) { return 0; } -- 2.39.5