From 1780b2121e6b77ed10510ee7459edb73b3263db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Wed, 7 Jan 2026 15:04:47 +0000 Subject: [PATCH] ITS#9022 Introduce -o remove-sids= to slapadd --- doc/man/man8/slapadd.8 | 11 +++++++++-- servers/slapd/slapadd.c | 19 ++++++++++++++++++- servers/slapd/slapcommon.c | 32 ++++++++++++++++++++++++++++++-- servers/slapd/slapcommon.h | 2 ++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/doc/man/man8/slapadd.8 b/doc/man/man8/slapadd.8 index 0840c4a84c..884f3ced5f 100644 --- a/doc/man/man8/slapadd.8 +++ b/doc/man/man8/slapadd.8 @@ -147,13 +147,20 @@ Possible generic options/values are: syslog\-level= (see `\-S' in slapd(8)) syslog\-user= (see `\-l' in slapd(8)) - schema-check={yes|no} - value-check={yes|no} + schema\-check={yes|no} + value\-check={yes|no} + remove\-sids={[,,...]} .in The \fIschema\-check\fR option toggles schema checking (default on); the \fIvalue\-check\fR option toggles value checking (default off). The latter is incompatible with \fB-q\fR. + +The \fIremove\-sids\fR option accepts a list of sids to ignore from the file, +corresponding CSNs in \fBentryCSN\fR and \fBcontextCSN\fR attributes will be +replaced with freshly generated CSNs using the server ID configured by +\fB-S\fR. Using it also implies \fB-w\fR: overwrite syncrepl context +information. .TP .B \-q enable quick (fewer integrity checks) mode. Does fewer consistency checks diff --git a/servers/slapd/slapadd.c b/servers/slapd/slapadd.c index 8886107814..1f5a5b021a 100644 --- a/servers/slapd/slapadd.c +++ b/servers/slapd/slapadd.c @@ -214,6 +214,9 @@ again: struct berval nname; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + Attribute *a; + int entrysid = -1; + enum { GOT_NONE = 0x0, GOT_CSN = 0x1, @@ -267,12 +270,21 @@ again: attr_merge( e, slap_schema.si_ad_createTimestamp, vals, NULL ); } - if( attr_find( e->e_attrs, slap_schema.si_ad_entryCSN ) + if( (a = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN )) == NULL ) { got &= ~GOT_CSN; vals[0] = csn; attr_merge( e, slap_schema.si_ad_entryCSN, vals, NULL ); + } else if ( a->a_numvals != 1 || + (entrysid = slap_parse_csn_sid( &a->a_vals[0] )) < 0 ) { + Debug( LDAP_DEBUG_ANY, "%s: warning, " + "%s values not valid in entry dn=\"%s\"\n", + progname, slap_schema.si_ad_entryCSN->ad_cname.bv_val, + e->e_name.bv_val ); + } else if ( sids_to_remove[entrysid] ) { + ber_bvreplace( &a->a_vals[0], &csn ); + ber_bvreplace( &a->a_nvals[0], &csn ); } if( attr_find( e->e_attrs, slap_schema.si_ad_modifiersName ) @@ -367,6 +379,11 @@ slapadd( int argc, char **argv ) if ( isatty (2) ) enable_meter = 1; slap_tool_init( progname, SLAPADD, argc, argv ); + if ( sids_to_remove[csnsid] ) { + fprintf( stderr, "%s: remove-sids contains configured serverID %u.\n", + progname, csnsid ); + exit( EXIT_FAILURE ); + } if( !be->be_entry_open || !be->be_entry_close || diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index b3ff1923ea..f5f9f33d64 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -255,6 +255,32 @@ parse_slapopt( int tool, int *mode ) break; } + } else if ( ( strncasecmp( optarg, "remove-sids", len ) == 0 ) ) { + switch ( tool ) { + case SLAPADD: + { + char *arg = strtok( p, "," ); + if ( !arg ) { + Debug( LDAP_DEBUG_ANY, "remove-sids needs an argument.\n" ); + return -1; + } + do { + unsigned int u; + if ( lutil_atou( &u, arg ) || u > SLAP_SYNC_SID_MAX ) { + Debug( LDAP_DEBUG_ANY, "unable to parse remove-sids=\"%s\".\n", arg ); + return -1; + } + sids_to_remove[u] = 1; + update_ctxcsn = 1; + } while ( (arg = strtok( NULL, "," )) ); + } + break; + + default: + Debug( LDAP_DEBUG_ANY, "remove-sids meaningless for tool.\n" ); + break; + } + } else { return -1; } @@ -994,7 +1020,7 @@ slap_tool_update_ctxcsn( if ( SLAP_SYNC_SUBENTRY( be )) { ctxcsn_e = slap_create_context_csn_entry( be, NULL ); for ( sid = 0; sid <= SLAP_SYNC_SID_MAX; sid++ ) { - if ( maxcsn[ sid ].bv_len ) { + if ( maxcsn[ sid ].bv_len && !sids_to_remove[sid] ) { attr_merge_one( ctxcsn_e, slap_schema.si_ad_contextCSN, &maxcsn[ sid ], NULL ); } @@ -1044,7 +1070,9 @@ slap_tool_update_ctxcsn( sid = (unsigned)rc_sid; - if ( maxcsn[ sid ].bv_len == 0 ) { + if ( sids_to_remove[sid] ) { + match = 1; + } else if ( maxcsn[ sid ].bv_len == 0 ) { match = -1; } else { diff --git a/servers/slapd/slapcommon.h b/servers/slapd/slapcommon.h index fa9049af9d..bddef9560d 100644 --- a/servers/slapd/slapcommon.h +++ b/servers/slapd/slapcommon.h @@ -54,6 +54,7 @@ typedef struct tool_vars { ber_len_t tv_ldif_wrap; char tv_maxcsnbuf[ LDAP_PVT_CSNSTR_BUFSIZE * ( SLAP_SYNC_SID_MAX + 1 ) ]; struct berval tv_maxcsn[ SLAP_SYNC_SID_MAX + 1 ]; + char tv_sids_to_remove[ SLAP_SYNC_SID_MAX + 1 ]; } tool_vars; extern tool_vars tool_globals; @@ -91,6 +92,7 @@ extern tool_vars tool_globals; #define ldif_wrap tool_globals.tv_ldif_wrap #define maxcsn tool_globals.tv_maxcsn #define maxcsnbuf tool_globals.tv_maxcsnbuf +#define sids_to_remove tool_globals.tv_sids_to_remove #define SLAP_TOOL_LDAPDN_PRETTY SLAP_LDAPDN_PRETTY #define SLAP_TOOL_LDAPDN_NORMAL (SLAP_LDAPDN_PRETTY << 1)