/* remove any attempts by the user to modify these attrs */
for ( m = modlist; *m != NULL; m = &(*m)->ml_next ) {
- if ( strcasecmp( (*m)->ml_type, "modifytimestamp" ) == 0 ||
- strcasecmp( (*m)->ml_type, "modifiersname" ) == 0 ||
- strcasecmp( (*m)->ml_type, "createtimestamp" ) == 0 ||
- strcasecmp( (*m)->ml_type, "creatorsname" ) == 0 ) {
-
+ if ( oc_check_no_usermod_attr( (*m)->ml_type ) ) {
Debug( LDAP_DEBUG_TRACE,
- "add_lastmods: found lastmod attr: %s\n",
+ "add_lastmods: found no user mod attr: %s\n",
(*m)->ml_type, 0, 0 );
tmp = *m;
*m = (*m)->ml_next;
int err;
LDAPMod *mod;
LDAPModList *ml;
+ Attribute *a;
if ( ((be->be_lastmod == ON)
|| ((be->be_lastmod == UNDEFINED)&&(global_lastmod == ON)))
if ( (err = acl_check_modlist( be, conn, op, e, modlist ))
- != LDAP_SUCCESS ) {
- send_ldap_result( conn, op, err, NULL, NULL );
+ != LDAP_SUCCESS )
+ {
+ send_ldap_result( conn, op, err,
+ NULL, NULL, NULL, NULL );
return -1;
}
break;
case LDAP_MOD_REPLACE:
+ /* Need to remove all values from indexes before they
+ * are lost.
+ */
+ if( e->e_attrs
+ && ((a = attr_find( e->e_attrs, mod->mod_type ))
+ != NULL) ) {
+
+ (void) index_change_values( be,
+ mod->mod_type,
+ a->a_vals,
+ e->e_id,
+ __INDEX_DELETE_OP);
+ }
+
err = replace_values( e, mod, op->o_ndn );
break;
+
+ case LDAP_MOD_SOFTADD:
+ /* Avoid problems in index_add_mods()
+ * We need to add index if necessary.
+ */
+ mod->mod_op = LDAP_MOD_ADD;
+ if ( (err = add_values( e, mod, op->o_ndn ))
+ == LDAP_TYPE_OR_VALUE_EXISTS ) {
+
+ err = LDAP_SUCCESS;
+ mod->mod_op = LDAP_MOD_SOFTADD;
+
+ }
+ break;
}
if ( err != LDAP_SUCCESS ) {
/* unlock entry, delete from cache */
- send_ldap_result( conn, op, err, NULL, NULL );
+ send_ldap_result( conn, op, err,
+ NULL, NULL, NULL, NULL );
return -1;
}
}
/* check that the entry still obeys the schema */
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
- send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION, NULL, NULL );
+ send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
+ NULL, NULL, NULL, NULL );
return -1;
}
/* modify indexes */
if ( index_add_mods( be, modlist, e->e_id ) != 0 ) {
- send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL );
+ send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+ NULL, NULL, NULL, NULL );
return -1;
}
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- char *matched;
+ Entry *matched;
Entry *e;
- int err;
+ int manageDSAit = get_manageDSAit( op );
Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
/* acquire and lock entry */
if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
- send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched,
- NULL );
+ char* matched_dn = NULL;
+ struct berval **refs = NULL;
+
if ( matched != NULL ) {
- free( matched );
+ matched_dn = ch_strdup( matched->e_dn );
+ refs = is_entry_referral( matched )
+ ? get_entry_referrals( be, conn, op, matched )
+ : NULL;
+ cache_return_entry_r( &li->li_cache, matched );
+ } else {
+ refs = default_referral;
}
+
+ send_ldap_result( conn, op, LDAP_REFERRAL,
+ matched_dn, NULL, refs, NULL );
+
+ if ( matched != NULL ) {
+ ber_bvecfree( refs );
+ free( matched_dn );
+ }
+
return( -1 );
}
- /* Modify the entry */
- if ( ldbm_modify_internal( be, conn, op, dn, modlist, e ) != 0 ) {
+ if ( !manageDSAit && is_entry_referral( e ) ) {
+ /* parent is a referral, don't allow add */
+ /* parent is an alias, don't allow add */
+ struct berval **refs = get_entry_referrals( be,
+ conn, op, e );
- goto error_return;
+ Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
+ 0, 0 );
- }
+ send_ldap_result( conn, op, LDAP_REFERRAL,
+ e->e_dn, NULL, refs, NULL );
+ ber_bvecfree( refs );
+ goto error_return;
+ }
+
+ /* Modify the entry */
+ if ( ldbm_modify_internal( be, conn, op, dn, modlist, e ) != 0 ) {
+ goto error_return;
+ }
/* change the entry itself */
if ( id2entry_add( be, e ) != 0 ) {
- send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL );
+ send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+ NULL, NULL, NULL, NULL );
goto error_return;
}
- send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
+ send_ldap_result( conn, op, LDAP_SUCCESS,
+ NULL, NULL, NULL, NULL );
cache_return_entry_w( &li->li_cache, e );
return( 0 );
a->a_vals[k - 1] = a->a_vals[k];
}
a->a_vals[k - 1] = NULL;
+
+ /* delete the entire attribute, if no values remain */
+ if ( a->a_vals[0] == NULL) {
+ Debug( LDAP_DEBUG_ARGS,
+ "removing entire attribute %s\n",
+ mod->mod_type, 0, 0 );
+ if ( attr_delete( &e->e_attrs, mod->mod_type ) ) {
+ return LDAP_NO_SUCH_ATTRIBUTE;
+ }
+ }
+
break;
}
char *dn
)
{
+
+ /* XXX: BEFORE YOU GET RID OF PREVIOUS VALUES REMOVE FROM INDEX
+ * FILES
+ */
+
(void) attr_delete( &e->e_attrs, mod->mod_type );
if ( attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 ) {