Commit 15f1e7bd authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

move ctxcsn and schema check code in helpers; also apply to slapmodify (ITS#6737)

parent dc156d7f
......@@ -41,7 +41,6 @@
#include "slapcommon.h"
static char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
static char maxcsnbuf[ LDAP_PVT_CSNSTR_BUFSIZE * ( SLAP_SYNC_SID_MAX + 1 ) ];
int
slapadd( int argc, char **argv )
......@@ -53,21 +52,16 @@ slapadd( int argc, char **argv )
const char *progname = "slapadd";
struct berval csn;
struct berval maxcsn[ SLAP_SYNC_SID_MAX + 1 ];
unsigned long sid;
unsigned long sid = SLAP_SYNC_SID_MAX + 1;
struct berval bvtext;
Attribute *attr;
Entry *ctxcsn_e;
ID ctxcsn_id, id;
ID id;
OperationBuffer opbuf;
Operation *op;
int match;
int checkvals;
int lineno, nextline, ldifrc;
int lmax;
int rc = EXIT_SUCCESS;
int manage = 0;
int enable_meter = 0;
lutil_meter_t meter;
......@@ -125,13 +119,7 @@ slapadd( int argc, char **argv )
exit( EXIT_FAILURE );
}
if ( update_ctxcsn ) {
maxcsn[ 0 ].bv_val = maxcsnbuf;
for ( sid = 1; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
maxcsn[ sid ].bv_val = maxcsn[ sid - 1 ].bv_val + LDAP_PVT_CSNSTR_BUFSIZE;
maxcsn[ sid ].bv_len = 0;
}
}
(void)slap_tool_update_ctxcsn_init();
if ( enable_meter
#ifdef LDAP_DEBUG
......@@ -244,65 +232,12 @@ slapadd( int argc, char **argv )
break;
}
{
Attribute *oc = attr_find( e->e_attrs,
slap_schema.si_ad_objectClass );
if( oc == NULL ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
progname, e->e_dn, lineno,
"no objectClass attribute");
rc = EXIT_FAILURE;
entry_free( e );
if( continuemode ) continue;
break;
}
/* check schema */
op->o_bd = be;
if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
rc = entry_schema_check( op, e, NULL, manage, 1, NULL,
&text, textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
progname, e->e_dn, lineno, rc, text );
rc = EXIT_FAILURE;
entry_free( e );
if( continuemode ) continue;
break;
}
textbuf[ 0 ] = '\0';
}
if ( (slapMode & SLAP_TOOL_VALUE_CHECK) != 0) {
Modifications *ml = NULL;
if ( slap_entry2mods( e, &ml, &text, textbuf, textlen )
!= LDAP_SUCCESS )
{
fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
progname, e->e_dn, lineno, rc, text );
rc = EXIT_FAILURE;
entry_free( e );
if( continuemode ) continue;
break;
}
textbuf[ 0 ] = '\0';
rc = slap_mods_check( op, ml, &text, textbuf, textlen, NULL );
slap_mods_free( ml, 1 );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
progname, e->e_dn, lineno, rc, text );
rc = EXIT_FAILURE;
entry_free( e );
if( continuemode ) continue;
break;
}
textbuf[ 0 ] = '\0';
}
rc = slap_tool_entry_check( progname, op, e, lineno, &text, textbuf, textlen );
if ( rc != LDAP_SUCCESS ) {
rc = EXIT_FAILURE;
entry_free( e );
if( continuemode ) continue;
break;
}
if ( SLAP_LASTMOD(be) ) {
......@@ -405,37 +340,7 @@ slapadd( int argc, char **argv )
progname, buf, e->e_name.bv_val );
}
if ( update_ctxcsn ) {
int rc_sid;
attr = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN );
assert( attr != NULL );
rc_sid = slap_parse_csn_sid( &attr->a_nvals[ 0 ] );
if ( rc_sid < 0 ) {
Debug( LDAP_DEBUG_ANY, "%s: could not "
"extract SID from entryCSN=%s, entry dn=\"%s\"\n",
progname, attr->a_nvals[ 0 ].bv_val, e->e_name.bv_val );
} else {
assert( rc_sid <= SLAP_SYNC_SID_MAX );
sid = (unsigned)rc_sid;
if ( maxcsn[ sid ].bv_len != 0 ) {
match = 0;
value_match( &match, slap_schema.si_ad_entryCSN,
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
&maxcsn[ sid ], &attr->a_nvals[0], &text );
} else {
match = -1;
}
if ( match < 0 ) {
strcpy( maxcsn[ sid ].bv_val, attr->a_nvals[0].bv_val );
maxcsn[ sid ].bv_len = attr->a_nvals[0].bv_len;
}
}
}
sid = slap_tool_update_ctxcsn_check( progname, e );
}
if ( !dryrun ) {
......@@ -473,116 +378,8 @@ slapadd( int argc, char **argv )
lutil_meter_close( &meter );
}
if ( rc == EXIT_SUCCESS && update_ctxcsn && !dryrun && sid != SLAP_SYNC_SID_MAX + 1 ) {
struct berval ctxdn;
if ( SLAP_SYNC_SUBENTRY( be )) {
build_new_dn( &ctxdn, &be->be_nsuffix[0],
(struct berval *)&slap_ldapsync_cn_bv, NULL );
} else {
ctxdn = be->be_nsuffix[0];
}
ctxcsn_id = be->be_dn2id_get( be, &ctxdn );
if ( ctxcsn_id == NOID ) {
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 ) {
attr_merge_one( ctxcsn_e, slap_schema.si_ad_contextCSN,
&maxcsn[ sid ], NULL );
}
}
ctxcsn_id = be->be_entry_put( be, ctxcsn_e, &bvtext );
if ( ctxcsn_id == NOID ) {
fprintf( stderr, "%s: couldn't create context entry\n", progname );
rc = EXIT_FAILURE;
}
} else {
fprintf( stderr, "%s: context entry is missing\n", progname );
rc = EXIT_FAILURE;
}
} else {
ctxcsn_e = be->be_entry_get( be, ctxcsn_id );
if ( ctxcsn_e != NULL ) {
Entry *e = entry_dup( ctxcsn_e );
int change;
attr = attr_find( e->e_attrs, slap_schema.si_ad_contextCSN );
if ( attr ) {
int i;
change = 0;
for ( i = 0; !BER_BVISNULL( &attr->a_nvals[ i ] ); i++ ) {
int rc_sid;
rc_sid = slap_parse_csn_sid( &attr->a_nvals[ i ] );
if ( rc_sid < 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: unable to extract SID "
"from #%d contextCSN=%s\n",
progname, i,
attr->a_nvals[ i ].bv_val );
continue;
}
assert( rc_sid <= SLAP_SYNC_SID_MAX );
sid = (unsigned)rc_sid;
if ( maxcsn[ sid ].bv_len == 0 ) {
match = -1;
} else {
value_match( &match, slap_schema.si_ad_entryCSN,
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
&maxcsn[ sid ], &attr->a_nvals[i], &text );
}
if ( match > 0 ) {
change = 1;
} else {
AC_MEMCPY( maxcsn[ sid ].bv_val,
attr->a_nvals[ i ].bv_val,
attr->a_nvals[ i ].bv_len );
maxcsn[ sid ].bv_val[ attr->a_nvals[ i ].bv_len ] = '\0';
maxcsn[ sid ].bv_len = attr->a_nvals[ i ].bv_len;
}
}
if ( change ) {
if ( attr->a_nvals != attr->a_vals ) {
ber_bvarray_free( attr->a_nvals );
}
attr->a_nvals = NULL;
ber_bvarray_free( attr->a_vals );
attr->a_vals = NULL;
attr->a_numvals = 0;
}
} else {
change = 1;
}
if ( change ) {
for ( sid = 0; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
if ( maxcsn[ sid ].bv_len ) {
attr_merge_one( e, slap_schema.si_ad_contextCSN,
&maxcsn[ sid], NULL );
}
}
ctxcsn_id = be->be_entry_modify( be, e, &bvtext );
if( ctxcsn_id == NOID ) {
fprintf( stderr, "%s: could not modify ctxcsn\n",
progname);
rc = EXIT_FAILURE;
} else if ( verbose ) {
fprintf( stderr, "modified: \"%s\" (%08lx)\n",
e->e_dn, (long) ctxcsn_id );
}
}
entry_free( e );
}
}
if ( rc == EXIT_SUCCESS ) {
rc = slap_tool_update_ctxcsn( progname, sid, &bvtext );
}
ch_free( buf );
......
......@@ -963,4 +963,261 @@ int slap_tool_destroy( void )
return rc;
}
int
slap_tool_update_ctxcsn(
const char *progname,
unsigned long sid,
struct berval *bvtext )
{
struct berval ctxdn;
ID ctxcsn_id;
Entry *ctxcsn_e;
int rc = EXIT_SUCCESS;
if ( !(update_ctxcsn && !dryrun && sid != SLAP_SYNC_SID_MAX + 1) ) {
return rc;
}
if ( SLAP_SYNC_SUBENTRY( be )) {
build_new_dn( &ctxdn, &be->be_nsuffix[0],
(struct berval *)&slap_ldapsync_cn_bv, NULL );
} else {
ctxdn = be->be_nsuffix[0];
}
ctxcsn_id = be->be_dn2id_get( be, &ctxdn );
if ( ctxcsn_id == NOID ) {
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 ) {
attr_merge_one( ctxcsn_e, slap_schema.si_ad_contextCSN,
&maxcsn[ sid ], NULL );
}
}
ctxcsn_id = be->be_entry_put( be, ctxcsn_e, bvtext );
if ( ctxcsn_id == NOID ) {
fprintf( stderr, "%s: couldn't create context entry\n", progname );
rc = EXIT_FAILURE;
}
} else {
fprintf( stderr, "%s: context entry is missing\n", progname );
rc = EXIT_FAILURE;
}
} else {
ctxcsn_e = be->be_entry_get( be, ctxcsn_id );
if ( ctxcsn_e != NULL ) {
Entry *e = entry_dup( ctxcsn_e );
int change;
Attribute *attr = attr_find( e->e_attrs, slap_schema.si_ad_contextCSN );
if ( attr ) {
int i;
change = 0;
for ( i = 0; !BER_BVISNULL( &attr->a_nvals[ i ] ); i++ ) {
int rc_sid;
int match;
const char *text = NULL;
rc_sid = slap_parse_csn_sid( &attr->a_nvals[ i ] );
if ( rc_sid < 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: unable to extract SID "
"from #%d contextCSN=%s\n",
progname, i,
attr->a_nvals[ i ].bv_val );
continue;
}
assert( rc_sid <= SLAP_SYNC_SID_MAX );
sid = (unsigned)rc_sid;
if ( maxcsn[ sid ].bv_len == 0 ) {
match = -1;
} else {
value_match( &match, slap_schema.si_ad_entryCSN,
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
&maxcsn[ sid ], &attr->a_nvals[i], &text );
}
if ( match > 0 ) {
change = 1;
} else {
AC_MEMCPY( maxcsn[ sid ].bv_val,
attr->a_nvals[ i ].bv_val,
attr->a_nvals[ i ].bv_len );
maxcsn[ sid ].bv_val[ attr->a_nvals[ i ].bv_len ] = '\0';
maxcsn[ sid ].bv_len = attr->a_nvals[ i ].bv_len;
}
}
if ( change ) {
if ( attr->a_nvals != attr->a_vals ) {
ber_bvarray_free( attr->a_nvals );
}
attr->a_nvals = NULL;
ber_bvarray_free( attr->a_vals );
attr->a_vals = NULL;
attr->a_numvals = 0;
}
} else {
change = 1;
}
if ( change ) {
for ( sid = 0; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
if ( maxcsn[ sid ].bv_len ) {
attr_merge_one( e, slap_schema.si_ad_contextCSN,
&maxcsn[ sid], NULL );
}
}
ctxcsn_id = be->be_entry_modify( be, e, bvtext );
if( ctxcsn_id == NOID ) {
fprintf( stderr, "%s: could not modify ctxcsn (%s)\n",
progname, bvtext->bv_val ? bvtext->bv_val : "" );
rc = EXIT_FAILURE;
} else if ( verbose ) {
fprintf( stderr, "modified: \"%s\" (%08lx)\n",
e->e_dn, (long) ctxcsn_id );
}
}
entry_free( e );
}
}
return rc;
}
/*
* return value:
* -1: update_ctxcsn == 0
* SLAP_SYNC_SID_MAX + 1: unable to extract SID
* 0 <= SLAP_SYNC_SID_MAX: the SID
*/
unsigned long
slap_tool_update_ctxcsn_check(
const char *progname,
Entry *e )
{
if ( update_ctxcsn ) {
unsigned long sid = SLAP_SYNC_SID_MAX + 1;
int rc_sid;
Attribute *attr;
attr = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN );
assert( attr != NULL );
rc_sid = slap_parse_csn_sid( &attr->a_nvals[ 0 ] );
if ( rc_sid < 0 ) {
Debug( LDAP_DEBUG_ANY, "%s: could not "
"extract SID from entryCSN=%s, entry dn=\"%s\"\n",
progname, attr->a_nvals[ 0 ].bv_val, e->e_name.bv_val );
return (unsigned long)(-1);
} else {
int match;
const char *text = NULL;
assert( rc_sid <= SLAP_SYNC_SID_MAX );
sid = (unsigned)rc_sid;
if ( maxcsn[ sid ].bv_len != 0 ) {
match = 0;
value_match( &match, slap_schema.si_ad_entryCSN,
slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
&maxcsn[ sid ], &attr->a_nvals[0], &text );
} else {
match = -1;
}
if ( match < 0 ) {
strcpy( maxcsn[ sid ].bv_val, attr->a_nvals[0].bv_val );
maxcsn[ sid ].bv_len = attr->a_nvals[0].bv_len;
}
}
}
return (unsigned long)(-1);
}
int
slap_tool_update_ctxcsn_init(void)
{
if ( update_ctxcsn ) {
unsigned long sid;
maxcsn[ 0 ].bv_val = maxcsnbuf;
for ( sid = 1; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
maxcsn[ sid ].bv_val = maxcsn[ sid - 1 ].bv_val + LDAP_PVT_CSNSTR_BUFSIZE;
maxcsn[ sid ].bv_len = 0;
}
}
return 0;
}
int
slap_tool_entry_check(
const char *progname,
Operation *op,
Entry *e,
int lineno,
const char **text,
char *textbuf,
size_t textlen )
{
/* NOTE: we may want to conditionally enable manage */
int manage = 0;
Attribute *oc = attr_find( e->e_attrs,
slap_schema.si_ad_objectClass );
if( oc == NULL ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
progname, e->e_dn, lineno,
"no objectClass attribute");
return LDAP_NO_SUCH_ATTRIBUTE;
}
/* check schema */
op->o_bd = be;
if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
int rc = entry_schema_check( op, e, NULL, manage, 1, NULL,
text, textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
progname, e->e_dn, lineno, rc, *text );
return rc;
}
textbuf[ 0 ] = '\0';
}
if ( (slapMode & SLAP_TOOL_VALUE_CHECK) != 0) {
Modifications *ml = NULL;
int rc = slap_entry2mods( e, &ml, text, textbuf, textlen );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
progname, e->e_dn, lineno, rc, *text );
return rc;
}
textbuf[ 0 ] = '\0';
rc = slap_mods_check( op, ml, text, textbuf, textlen, NULL );
slap_mods_free( ml, 1 );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
progname, e->e_dn, lineno, rc, *text );
return rc;
}
textbuf[ 0 ] = '\0';
}
return LDAP_SUCCESS;
}
......@@ -66,6 +66,8 @@ typedef struct tool_vars {
unsigned tv_dn_mode;
unsigned int tv_csnsid;
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 ];
} tool_vars;
extern tool_vars tool_globals;
......@@ -101,6 +103,8 @@ extern tool_vars tool_globals;
#define dn_mode tool_globals.tv_dn_mode
#define csnsid tool_globals.tv_csnsid
#define ldif_wrap tool_globals.tv_ldif_wrap
#define maxcsn tool_globals.tv_maxcsn
#define maxcsnbuf tool_globals.tv_maxcsnbuf
#define SLAP_TOOL_LDAPDN_PRETTY SLAP_LDAPDN_PRETTY
#define SLAP_TOOL_LDAPDN_NORMAL (SLAP_LDAPDN_PRETTY << 1)
......@@ -112,4 +116,24 @@ void slap_tool_init LDAP_P((
int slap_tool_destroy LDAP_P((void));
int slap_tool_update_ctxcsn LDAP_P((
const char *progname,
unsigned long sid,
struct berval *bvtext ));
unsigned long slap_tool_update_ctxcsn_check LDAP_P((
const char *progname,
Entry *e ));
int slap_tool_update_ctxcsn_init LDAP_P((void));
int slap_tool_entry_check LDAP_P((
const char *progname,
Operation *op,
Entry *e,
int lineno,
const char **text,
char *textbuf,
size_t textlen ));
#endif /* SLAPCOMMON_H_ */
......@@ -39,7 +39,6 @@
#include "slapcommon.h"
static char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
static char maxcsnbuf[ LDAP_PVT_CSNSTR_BUFSIZE * ( SLAP_SYNC_SID_MAX + 1 ) ];
int
slapmodify( int argc, char **argv )
......@@ -51,20 +50,16 @@ slapmodify( int argc, char **argv )
const char *progname = "slapmodify";
struct berval csn;
struct berval maxcsn[ SLAP_SYNC_SID_MAX + 1 ];
unsigned long sid;
struct berval bvtext;
Entry *ctxcsn_e;
ID ctxcsn_id, id;
ID id;
OperationBuffer opbuf;
Operation *op;
int match;
int checkvals;
int lineno, nextline, ldifrc;
int lmax;
int rc = EXIT_SUCCESS;
int manage = 0;
int enable_meter = 0;
lutil_meter_t meter;
......@@ -113,6 +108,8 @@ slapmodify( int argc, char **argv )
exit( EXIT_FAILURE );