mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-13 14:27:59 +08:00
add support for ADD_IF_NOT_PRESENT and SOFTDEL internal modification types (ITS#6561)
This commit is contained in:
parent
8a8daa383e
commit
79d4e4cf6a
@ -1985,8 +1985,15 @@ acl_check_modlist(
|
||||
/* fall thru to check value to add */
|
||||
|
||||
case LDAP_MOD_ADD:
|
||||
case SLAP_MOD_ADD_IF_NOT_PRESENT:
|
||||
assert( mlist->sml_values != NULL );
|
||||
|
||||
if ( mlist->sml_op == SLAP_MOD_ADD_IF_NOT_PRESENT
|
||||
&& attr_find( e->e_attrs, mlist->sml_desc ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for ( bv = mlist->sml_nvalues
|
||||
? mlist->sml_nvalues : mlist->sml_values;
|
||||
bv->bv_val != NULL; bv++ )
|
||||
@ -2003,6 +2010,7 @@ acl_check_modlist(
|
||||
break;
|
||||
|
||||
case LDAP_MOD_DELETE:
|
||||
case SLAP_MOD_SOFTDEL:
|
||||
if ( mlist->sml_values == NULL ) {
|
||||
if ( ! access_allowed( op, e,
|
||||
mlist->sml_desc, NULL,
|
||||
|
@ -215,6 +215,56 @@ int bdb_modify_internal(
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_SOFTDEL:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"bdb_modify_internal: softdel %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val, 0, 0);
|
||||
/* Avoid problems in index_delete_mods()
|
||||
* We need to add index if necessary.
|
||||
*/
|
||||
mod->sm_op = LDAP_MOD_DELETE;
|
||||
|
||||
err = modify_delete_values( e, mod, get_permissiveModify(op),
|
||||
text, textbuf, textlen );
|
||||
|
||||
mod->sm_op = SLAP_MOD_SOFTDEL;
|
||||
|
||||
if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
|
||||
err = LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
if( err != LDAP_SUCCESS ) {
|
||||
Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
|
||||
err, *text, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_ADD_IF_NOT_PRESENT:
|
||||
if ( attr_find( e->e_attrs, mod->sm_desc ) != NULL ) {
|
||||
/* skip */
|
||||
err = LDAP_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"bdb_modify_internal: add_if_not_present %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val, 0, 0);
|
||||
/* Avoid problems in index_add_mods()
|
||||
* We need to add index if necessary.
|
||||
*/
|
||||
mod->sm_op = LDAP_MOD_ADD;
|
||||
|
||||
err = modify_add_values( e, mod, get_permissiveModify(op),
|
||||
text, textbuf, textlen );
|
||||
|
||||
mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;
|
||||
|
||||
if( err != LDAP_SUCCESS ) {
|
||||
Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
|
||||
err, *text, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug(LDAP_DEBUG_ANY, "bdb_modify_internal: invalid op %d\n",
|
||||
mod->sm_op, 0, 0);
|
||||
|
@ -1073,6 +1073,31 @@ apply_modify_to_entry(
|
||||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_SOFTDEL:
|
||||
mods->sm_op = LDAP_MOD_DELETE;
|
||||
rc = modify_delete_values(entry, mods,
|
||||
get_permissiveModify(op),
|
||||
&rs->sr_text, textbuf,
|
||||
sizeof( textbuf ) );
|
||||
mods->sm_op = SLAP_MOD_SOFTDEL;
|
||||
if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
|
||||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_ADD_IF_NOT_PRESENT:
|
||||
if ( attr_find( entry->e_attrs, mods->sm_desc ) ) {
|
||||
rc = LDAP_SUCCESS;
|
||||
break;
|
||||
}
|
||||
mods->sm_op = LDAP_MOD_ADD;
|
||||
rc = modify_add_values(entry, mods,
|
||||
get_permissiveModify(op),
|
||||
&rs->sr_text, textbuf,
|
||||
sizeof( textbuf ) );
|
||||
mods->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;
|
||||
break;
|
||||
}
|
||||
if(rc != LDAP_SUCCESS) break;
|
||||
}
|
||||
|
@ -300,6 +300,49 @@ int ndb_modify_internal(
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_SOFTDEL:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"ndb_modify_internal: softdel %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val, 0, 0);
|
||||
mod->sm_op = LDAP_MOD_DELETE;
|
||||
|
||||
rc = modify_delete_values( NA->e, mod, get_permissiveModify(op),
|
||||
text, textbuf, textlen );
|
||||
|
||||
mod->sm_op = SLAP_MOD_SOFTDEL;
|
||||
|
||||
if ( rc == LDAP_NO_SUCH_ATTRIBUTE) {
|
||||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
|
||||
rc, *text, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_ADD_IF_NOT_PRESENT:
|
||||
Debug(LDAP_DEBUG_ARGS,
|
||||
"ndb_modify_internal: add_if_not_present %s\n",
|
||||
mod->sm_desc->ad_cname.bv_val, 0, 0);
|
||||
if ( attr_find( NA->e->e_attrs, mod->sm_desc ) ) {
|
||||
rc = LDAP_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
mod->sm_op = LDAP_MOD_ADD;
|
||||
|
||||
rc = modify_add_values( NA->e, mod, get_permissiveModify(op),
|
||||
text, textbuf, textlen );
|
||||
|
||||
mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
|
||||
rc, *text, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug(LDAP_DEBUG_ANY, "ndb_modify_internal: invalid op %d\n",
|
||||
mod->sm_op, 0, 0);
|
||||
|
@ -389,6 +389,7 @@ del_all:
|
||||
*/
|
||||
case LDAP_MOD_ADD:
|
||||
/* case SLAP_MOD_SOFTADD: */
|
||||
/* case SLAP_MOD_ADD_IF_NOT_PRESENT: */
|
||||
add_only:;
|
||||
if ( at->bam_add_proc == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
@ -541,6 +542,7 @@ add_only:;
|
||||
break;
|
||||
|
||||
case LDAP_MOD_DELETE:
|
||||
/* case SLAP_MOD_SOFTDEL: */
|
||||
if ( at->bam_delete_proc == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
" backsql_modify_internal(): "
|
||||
|
@ -5562,7 +5562,9 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
|
||||
ct = config_find_table( colst, nocs, ml->sml_desc, ca );
|
||||
switch (ml->sml_op) {
|
||||
case LDAP_MOD_DELETE:
|
||||
case LDAP_MOD_REPLACE: {
|
||||
case LDAP_MOD_REPLACE:
|
||||
case SLAP_MOD_SOFTDEL:
|
||||
{
|
||||
BerVarray vals = NULL, nvals = NULL;
|
||||
int *idx = NULL;
|
||||
if ( ct && ( ct->arg_type & ARG_NO_DELETE )) {
|
||||
@ -5601,11 +5603,24 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
|
||||
ml->sml_values = vals;
|
||||
ml->sml_nvalues = nvals;
|
||||
}
|
||||
if ( rc == LDAP_NO_SUCH_ATTRIBUTE && ml->sml_op == SLAP_MOD_SOFTDEL )
|
||||
{
|
||||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
/* FIXME: check rc before fallthru? */
|
||||
if ( !vals )
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* FALLTHRU: LDAP_MOD_REPLACE && vals */
|
||||
|
||||
case SLAP_MOD_ADD_IF_NOT_PRESENT:
|
||||
if ( ml->sml_op == SLAP_MOD_ADD_IF_NOT_PRESENT
|
||||
&& attr_find( e->e_attrs, ml->sml_desc ) )
|
||||
{
|
||||
rc = LDAP_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case LDAP_MOD_ADD:
|
||||
case SLAP_MOD_SOFTADD: {
|
||||
int mop = ml->sml_op;
|
||||
|
@ -878,6 +878,7 @@ void slap_mods_opattrs(
|
||||
for ( modtail = modsp; *modtail; modtail = &(*modtail)->sml_next ) {
|
||||
if ( (*modtail)->sml_op != LDAP_MOD_ADD &&
|
||||
(*modtail)->sml_op != SLAP_MOD_SOFTADD &&
|
||||
(*modtail)->sml_op != SLAP_MOD_ADD_IF_NOT_PRESENT &&
|
||||
(*modtail)->sml_op != LDAP_MOD_REPLACE )
|
||||
{
|
||||
continue;
|
||||
|
@ -1027,6 +1027,29 @@ constraint_update( Operation *op, SlapReply *rs )
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_SOFTDEL:
|
||||
mod->sm_op = LDAP_MOD_ADD;
|
||||
err = modify_delete_values( target_entry_copy,
|
||||
mod, get_permissiveModify(op),
|
||||
&text, textbuf, textlen );
|
||||
mod->sm_op = SLAP_MOD_SOFTDEL;
|
||||
if ( err == LDAP_NO_SUCH_ATTRIBUTE ) {
|
||||
err = LDAP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_MOD_ADD_IF_NOT_PRESENT:
|
||||
if ( attr_find( target_entry_copy->e_attrs, mod->sm_desc ) ) {
|
||||
err = LDAP_SUCCESS;
|
||||
break;
|
||||
}
|
||||
mod->sm_op = LDAP_MOD_ADD;
|
||||
err = modify_add_values( target_entry_copy,
|
||||
mod, get_permissiveModify(op),
|
||||
&text, textbuf, textlen );
|
||||
mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = LDAP_OTHER;
|
||||
break;
|
||||
|
@ -587,6 +587,7 @@ dds_op_modify( Operation *op, SlapReply *rs )
|
||||
|
||||
switch ( mod->sml_op ) {
|
||||
case LDAP_MOD_DELETE:
|
||||
case SLAP_MOD_SOFTDEL: /* FIXME? */
|
||||
if ( mod->sml_values != NULL ) {
|
||||
if ( BER_BVISEMPTY( &bv_entryTtl )
|
||||
|| !bvmatch( &bv_entryTtl, &mod->sml_values[ 0 ] ) )
|
||||
@ -611,8 +612,9 @@ dds_op_modify( Operation *op, SlapReply *rs )
|
||||
entryTtl = -1;
|
||||
/* fallthru */
|
||||
|
||||
case SLAP_MOD_SOFTADD: /* FIXME? */
|
||||
case LDAP_MOD_ADD:
|
||||
case SLAP_MOD_SOFTADD: /* FIXME? */
|
||||
case SLAP_MOD_ADD_IF_NOT_PRESENT: /* FIXME? */
|
||||
assert( mod->sml_values != NULL );
|
||||
assert( BER_BVISNULL( &mod->sml_values[ 1 ] ) );
|
||||
|
||||
|
@ -111,12 +111,25 @@ LDAP_BEGIN_DECL
|
||||
# define SLAP_STRING_UNKNOWN "unknown"
|
||||
#endif /* ! TCP Wrappers */
|
||||
|
||||
/* LDAPMod.mod_op value ===> Must be kept in sync with ldap.h!
|
||||
* This is a value used internally by the backends. It is needed to allow
|
||||
* adding values that already exist without getting an error as required by
|
||||
* modrdn when the new rdn was already an attribute value itself.
|
||||
/* LDAPMod.mod_op value ===> Must be kept in sync with ldap.h! */
|
||||
/* These values are used internally by the backends. */
|
||||
/* SLAP_MOD_SOFTADD allows adding values that already exist without getting
|
||||
* an error as required by modrdn when the new rdn was already an attribute
|
||||
* value itself.
|
||||
*/
|
||||
#define SLAP_MOD_SOFTADD 0x1000
|
||||
/* SLAP_MOD_SOFTDEL allows deleting values if they exist without getting
|
||||
* an error otherwise.
|
||||
*/
|
||||
#define SLAP_MOD_SOFTDEL 0x1001
|
||||
/* SLAP_MOD_ADD_IF_NOT_PRESENT allows adding values unless the attribute
|
||||
* is already present without getting an error.
|
||||
*/
|
||||
#define SLAP_MOD_ADD_IF_NOT_PRESENT 0x1002
|
||||
/* SLAP_MOD_DEL_IF_PRESENT allows deleting values if the attribute
|
||||
* is present, without getting an error otherwise.
|
||||
* The semantics can be obtained using SLAP_MOD_SOFTDEL with NULL values.
|
||||
*/
|
||||
#define SLAP_MOD_SOFTADD 0x1000
|
||||
|
||||
#define MAXREMATCHES (100)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user