]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9022 Introduce -o remove-sids= to slapadd
authorOndřej Kuzník <ondra@mistotebe.net>
Wed, 7 Jan 2026 15:04:47 +0000 (15:04 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Mon, 9 Feb 2026 18:41:47 +0000 (18:41 +0000)
doc/man/man8/slapadd.8
servers/slapd/slapadd.c
servers/slapd/slapcommon.c
servers/slapd/slapcommon.h

index 0840c4a84c68a22f5752fe3c7eaebfdb954b830c..884f3ced5fa60a254de04f30b85839c6d337378e 100644 (file)
@@ -147,13 +147,20 @@ Possible generic options/values are:
               syslog\-level=<level> (see `\-S' in slapd(8))
               syslog\-user=<user>   (see `\-l' in slapd(8))
 
-              schema-check={yes|no}
-              value-check={yes|no}
+              schema\-check={yes|no}
+              value\-check={yes|no}
+              remove\-sids={<sid>[,<sid>,...]}
 
 .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
index 88861078140b5f76e6c3010e3a4f3701d38ad39a..1f5a5b021add0be4ddce46648015f1d6ea1e9204 100644 (file)
@@ -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 ||
index b3ff1923eac8afa2653e889e1c9ba0b5dcada06a..f5f9f33d64e24c730da62dad2512c4cb88ad44a6 100644 (file)
@@ -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 {
index fa9049af9db892fd5b1f153eaa667ba80fb49645..bddef9560db0cfc29ee989141aae6c36849d9eba 100644 (file)
@@ -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)