Debug( LDAP_DEBUG_TRACE, "do_modify\n", 0, 0, 0 );
#endif
-
/*
* Parse the modify request. It looks like this:
*
goto cleanup;
}
- if( ndn == '\0' ) {
+ if( *ndn == '\0' ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
"do_modify: attempt to modify root DSE.\n" ));
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "modify upon the root DSE not supported", NULL, NULL );
goto cleanup;
+
+#if defined( SLAPD_SCHEMA_DN )
+ } else if ( strcasecmp( ndn, SLAPD_SCHEMA_DN ) == 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
+ "do_modify: attempt to modify subschema subentry.\n" ));
+#else
+ Debug( LDAP_DEBUG_ANY, "do_modify: subschema subentry!\n", 0, 0, 0 );
+#endif
+
+ send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
+ NULL, "modification of subschema subentry not supported",
+ NULL, NULL );
+ goto cleanup;
+#endif
}
#ifdef LDAP_DEBUG
#ifdef NEW_LOGGING
LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
- "do_modify: modifications:\n" ));
+ "do_modify: modifications:\n" ));
#else
Debug( LDAP_DEBUG_ARGS, "modifications:\n", 0, 0, 0 );
#endif
"\t%s: %s\n", tmp->ml_op == LDAP_MOD_ADD ?
"add" : (tmp->ml_op == LDAP_MOD_DELETE ?
"delete" : "replace"), tmp->ml_type ));
+
+ if ( tmp->ml_bvalues == NULL ) {
+ LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
+ "\t\tno values" ));
+ } else if ( tmp->ml_bvalues[0] == NULL ) {
+ LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
+ "\t\tzero values" ));
+ } else if ( tmp->ml_bvalues[1] == NULL ) {
+ LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
+ "\t\tone value" ));
+ } else {
+ LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
+ "\t\tmultiple values" ));
+ }
+
#else
Debug( LDAP_DEBUG_ARGS, "\t%s: %s\n",
tmp->ml_op == LDAP_MOD_ADD
? "add" : (tmp->ml_op == LDAP_MOD_DELETE
? "delete" : "replace"), tmp->ml_type, 0 );
-#endif
+ if ( tmp->ml_bvalues == NULL ) {
+ Debug( LDAP_DEBUG_ARGS, "%s\n",
+ "\t\tno values", NULL, NULL );
+ } else if ( tmp->ml_bvalues[0] == NULL ) {
+ Debug( LDAP_DEBUG_ARGS, "%s\n",
+ "\t\tzero values", NULL, NULL );
+ } else if ( tmp->ml_bvalues[1] == NULL ) {
+ Debug( LDAP_DEBUG_ARGS, "%s, length %ld\n",
+ "\t\tone value", (long) tmp->ml_bvalues[0]->bv_len, NULL );
+ } else {
+ Debug( LDAP_DEBUG_ARGS, "%s\n",
+ "\t\tmultiple values", NULL, NULL );
+ }
+#endif
}
#endif
* if we don't hold it.
*/
if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+ struct berval **ref = referral_rewrite( default_referral,
+ NULL, dn, LDAP_SCOPE_DEFAULT );
+
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
- NULL, NULL, default_referral, NULL );
+ NULL, NULL, ref ? ref : default_referral, NULL );
+
+ ber_bvecfree( ref );
goto cleanup;
}
*/
if ( be->be_modify ) {
/* do the update here */
- int repl_user = (be->be_update_ndn != NULL &&
- strcmp( be->be_update_ndn, op->o_ndn ) == 0);
+ int repl_user = be_isupdate( be, op->o_ndn );
#ifndef SLAPD_MULTIMASTER
/* Multimaster slapd does not have to check for replicator dn
* because it accepts each modify request
#ifndef SLAPD_MULTIMASTER
/* send a referral */
} else {
+ struct berval **defref = be->be_update_refs
+ ? be->be_update_refs : default_referral;
+ struct berval **ref = referral_rewrite( defref,
+ NULL, dn, LDAP_SCOPE_DEFAULT );
+
send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
- be->be_update_refs ? be->be_update_refs : default_referral,
- NULL );
+ ref ? ref : defref, NULL );
+
+ ber_bvecfree( ref );
#endif
}
} else {
int update,
Modifications **mods,
const char **text,
- char *textbuf, size_t textlen )
+ char *textbuf,
+ size_t textlen )
{
int rc;
Modifications **modtail = mods;
if( rc != LDAP_SUCCESS ) {
slap_mods_free( mod );
- snprintf( textbuf, textlen, "%s: %s", ml->ml_type, text );
+ snprintf( textbuf, textlen, "%s: %s",
+ ml->ml_type, *text );
*text = textbuf;
return rc;
}
return LDAP_CONSTRAINT_VIOLATION;
}
+ if ( is_at_obsolete( ad->ad_type ) &&
+ ( mod->sml_op == LDAP_MOD_ADD || ml->ml_bvalues != NULL ) )
+ {
+ /*
+ * attribute is obsolete,
+ * only allow replace/delete with no values
+ */
+ slap_mods_free( mod );
+ snprintf( textbuf, textlen,
+ "%s: attribute is obsolete",
+ ml->ml_type );
+ *text = textbuf;
+ return LDAP_CONSTRAINT_VIOLATION;
+ }
+
/*
* check values
*/
ber_len_t nvals;
slap_syntax_validate_func *validate =
ad->ad_type->sat_syntax->ssyn_validate;
-
- if( !validate ) {
-#ifdef NEW_LOGGING
- LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
- "modlist2mods: Attribute %s, no validator for syntax %s\n",
- ml->ml_type, ad->ad_type->sat_syntax->ssyn_oid ));
-#else
- Debug( LDAP_DEBUG_TRACE,
- "modlist2mods: no validator for syntax %s\n",
- ad->ad_type->sat_syntax->ssyn_oid, 0, 0 );
-#endif
-
+ slap_syntax_transform_func *pretty =
+ ad->ad_type->sat_syntax->ssyn_pretty;
+
+ if( !pretty && !validate ) {
slap_mods_free( mod );
*text = "no validator for syntax";
snprintf( textbuf, textlen,
/*
* check that each value is valid per syntax
+ * and pretty if appropriate
*/
for( nvals = 0; ml->ml_bvalues[nvals]; nvals++ ) {
- rc = validate( ad->ad_type->sat_syntax, ml->ml_bvalues[nvals] );
+ struct berval *pval;
+ if( pretty ) {
+ rc = pretty( ad->ad_type->sat_syntax,
+ ml->ml_bvalues[nvals], &pval );
+ } else {
+ rc = validate( ad->ad_type->sat_syntax,
+ ml->ml_bvalues[nvals] );
+ }
if( rc != 0 ) {
slap_mods_free( mod );
snprintf( textbuf, textlen,
- "%s: value #%ld contains invalid data",
+ "%s: value #%ld invalid per syntax",
ml->ml_type, (long) nvals );
*text = textbuf;
return LDAP_INVALID_SYNTAX;
}
+
+ if( pretty ) {
+ ber_memfree( ml->ml_bvalues[nvals]->bv_val );
+ *ml->ml_bvalues[nvals] = *pval;
+ free( pval );
+ }
}
/*
"%s: multiple value provided",
ml->ml_type );
*text = textbuf;
- return LDAP_INVALID_SYNTAX;
+ return LDAP_CONSTRAINT_VIOLATION;
}
}
Modifications **modtail,
const char **text )
{
- struct berval name, timestamp;
+ struct berval name, timestamp, csn;
time_t now = slap_get_time();
char timebuf[22];
+ char csnbuf[64];
struct tm *ltm;
Modifications *mod;
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
ltm = gmtime( &now );
strftime( timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", ltm );
+
+ csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), 0, 0 );
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
+ csn.bv_val = csnbuf;
+
timestamp.bv_val = timebuf;
timestamp.bv_len = strlen(timebuf);
}
if( op->o_tag == LDAP_REQ_ADD ) {
+ struct berval uuid;
+ char uuidbuf[40];
+
+ uuid.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
+ uuid.bv_val = uuidbuf;
+
mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
mod->sml_op = mop;
- mod->sml_desc = ad_dup( slap_schema.si_ad_creatorsName );
+ mod->sml_desc = slap_schema.si_ad_entryUUID;
mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
- mod->sml_bvalues[0] = ber_bvdup( &name );
+ mod->sml_bvalues[0] = ber_bvdup( &uuid );
mod->sml_bvalues[1] = NULL;
+ assert( mod->sml_bvalues[0] );
+ *modtail = mod;
+ modtail = &mod->sml_next;
+ mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
+ mod->sml_op = mop;
+ mod->sml_desc = slap_schema.si_ad_creatorsName;
+ mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+ mod->sml_bvalues[0] = ber_bvdup( &name );
+ mod->sml_bvalues[1] = NULL;
+ assert( mod->sml_bvalues[0] );
*modtail = mod;
modtail = &mod->sml_next;
mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
mod->sml_op = mop;
- mod->sml_desc = ad_dup( slap_schema.si_ad_createTimestamp );
+ mod->sml_desc = slap_schema.si_ad_createTimestamp;
mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
mod->sml_bvalues[0] = ber_bvdup( ×tamp );
mod->sml_bvalues[1] = NULL;
+ assert( mod->sml_bvalues[0] );
*modtail = mod;
modtail = &mod->sml_next;
}
mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
mod->sml_op = mop;
- mod->sml_desc = ad_dup( slap_schema.si_ad_modifiersName );
- mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+ mod->sml_desc = slap_schema.si_ad_entryCSN;
+ mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof(struct berval *) );
+ mod->sml_bvalues[0] = ber_bvdup( &csn );
+ mod->sml_bvalues[1] = NULL;
+ assert( mod->sml_bvalues[0] );
+ *modtail = mod;
+ modtail = &mod->sml_next;
+
+ mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
+ mod->sml_op = mop;
+ mod->sml_desc = slap_schema.si_ad_modifiersName;
+ mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof(struct berval *) );
mod->sml_bvalues[0] = ber_bvdup( &name );
mod->sml_bvalues[1] = NULL;
+ assert( mod->sml_bvalues[0] );
*modtail = mod;
modtail = &mod->sml_next;
mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) );
mod->sml_op = mop;
- mod->sml_desc = ad_dup( slap_schema.si_ad_modifyTimestamp );
- mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) );
+ mod->sml_desc = slap_schema.si_ad_modifyTimestamp;
+ mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof(struct berval *) );
mod->sml_bvalues[0] = ber_bvdup( ×tamp );
mod->sml_bvalues[1] = NULL;
+ assert( mod->sml_bvalues[0] );
*modtail = mod;
modtail = &mod->sml_next;
return LDAP_SUCCESS;
}
-
-void
-slap_mod_free(
- Modification *mod,
- int freeit
-)
-{
- ad_free( mod->sm_desc, 1 );
-
- if ( mod->sm_bvalues != NULL )
- ber_bvecfree( mod->sm_bvalues );
-
- if( freeit )
- free( mod );
-}
-
-void
-slap_mods_free(
- Modifications *ml
-)
-{
- Modifications *next;
-
- for ( ; ml != NULL; ml = next ) {
- next = ml->sml_next;
-
- slap_mod_free( &ml->sml_mod, 0 );
- free( ml );
- }
-}
-
-void
-slap_modlist_free(
- LDAPModList *ml
-)
-{
- LDAPModList *next;
-
- for ( ; ml != NULL; ml = next ) {
- next = ml->ml_next;
-
- if (ml->ml_type)
- free( ml->ml_type );
-
- if ( ml->ml_bvalues != NULL )
- ber_bvecfree( ml->ml_bvalues );
-
- free( ml );
- }
-}