mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-24 08:39:37 -05:00
Call slap_mods2entry() in do_add(), so that global overlays (including
global SLAPI plugins) have access to op->ora_e. Note that slap_mods2entry() is still called in fe_op_add() in order to add any operational attributes.
This commit is contained in:
parent
014393dfa2
commit
6f0edd6c22
8 changed files with 103 additions and 74 deletions
|
|
@ -166,6 +166,14 @@ do_add( Operation *op, SlapReply *rs )
|
|||
/* temporary; remove if not invoking backend function */
|
||||
op->ora_modlist = modlist;
|
||||
|
||||
/* call this so global overlays/SLAPI have access to ora_e */
|
||||
rs->sr_err = slap_mods2entry( op->ora_modlist, &op->ora_e,
|
||||
1, 0, &rs->sr_text, textbuf, textlen );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
|
||||
op->o_bd = frontendDB;
|
||||
rc = frontendDB->be_add( op, rs );
|
||||
if ( rc == 0 ) {
|
||||
|
|
@ -302,6 +310,7 @@ fe_op_add( Operation *op, SlapReply *rs )
|
|||
assert( (*modtail)->sml_desc != NULL );
|
||||
}
|
||||
|
||||
|
||||
rs->sr_err = slap_mods_opattrs( op, modlist,
|
||||
modtail, &rs->sr_text,
|
||||
textbuf, textlen, 1 );
|
||||
|
|
@ -309,13 +318,21 @@ fe_op_add( Operation *op, SlapReply *rs )
|
|||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
rs->sr_err = slap_mods2entry( modlist, &op->ora_e,
|
||||
repl_user, 0, &rs->sr_text, textbuf, textlen );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
/* check for duplicate values */
|
||||
rs->sr_err = slap_mods_no_repl_user_mod_check( op,
|
||||
modlist, &rs->sr_text, textbuf, textlen );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rs->sr_err = slap_mods2entry( *modtail, &op->ora_e,
|
||||
0, 0, &rs->sr_text, textbuf, textlen );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SLAPD_MULTIMASTER
|
||||
|
|
@ -373,22 +390,22 @@ int
|
|||
slap_mods2entry(
|
||||
Modifications *mods,
|
||||
Entry **e,
|
||||
int repl_user,
|
||||
int initial,
|
||||
int dup,
|
||||
const char **text,
|
||||
char *textbuf, size_t textlen )
|
||||
{
|
||||
Attribute **tail = &(*e)->e_attrs;
|
||||
assert( *tail == NULL );
|
||||
|
||||
if ( initial ) {
|
||||
assert( *tail == NULL );
|
||||
}
|
||||
|
||||
*text = textbuf;
|
||||
|
||||
for( ; mods != NULL; mods = mods->sml_next ) {
|
||||
Attribute *attr;
|
||||
|
||||
if ( !repl_user ) {
|
||||
assert( mods->sml_op == LDAP_MOD_ADD );
|
||||
}
|
||||
assert( mods->sml_desc != NULL );
|
||||
|
||||
attr = attr_find( (*e)->e_attrs, mods->sml_desc );
|
||||
|
|
@ -398,13 +415,6 @@ slap_mods2entry(
|
|||
#ifdef SLURPD_FRIENDLY
|
||||
ber_len_t i,j;
|
||||
|
||||
if( !repl_user ) {
|
||||
snprintf( textbuf, textlen,
|
||||
"attribute '%s' provided more than once",
|
||||
mods->sml_desc->ad_cname.bv_val );
|
||||
return LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
}
|
||||
|
||||
for( i=0; attr->a_vals[i].bv_val; i++ ) {
|
||||
/* count them */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -441,43 +441,10 @@ ldap_chain_response( Operation *op, SlapReply *rs )
|
|||
}
|
||||
break;
|
||||
case LDAP_REQ_ADD:
|
||||
{
|
||||
int cleanup_attrs = 0;
|
||||
|
||||
if ( op->ora_e->e_attrs == NULL ) {
|
||||
char textbuf[ SLAP_TEXT_BUFLEN ];
|
||||
size_t textlen = sizeof( textbuf );
|
||||
|
||||
#if 0
|
||||
/* FIXME: op->o_bd is still set to the BackendDB
|
||||
* structure of the database that tried to handle
|
||||
* the operation and actually returned a referral
|
||||
* ... */
|
||||
assert( SLAP_DBFLAGS( op->o_bd ) & SLAP_DBFLAG_GLOBAL_OVERLAY );
|
||||
#endif
|
||||
|
||||
/* global overlay: create entry */
|
||||
/* NOTE: this is a hack to use the chain overlay
|
||||
* as global. I expect to be able to remove this
|
||||
* soon by using slap_mods2entry() earlier in
|
||||
* do_add(), adding the operational attrs later
|
||||
* if required. */
|
||||
rs->sr_err = slap_mods2entry( op->ora_modlist,
|
||||
&op->ora_e, 0, 1,
|
||||
&rs->sr_text, textbuf, textlen );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* slap_mods2entry () should be called in do_add() */
|
||||
assert( op->ora_e->e_attrs != NULL );
|
||||
rc = ldap_chain_op( op, rs, lback->bi_op_add, ref );
|
||||
if ( cleanup_attrs ) {
|
||||
attrs_free( op->ora_e->e_attrs );
|
||||
op->ora_e->e_attrs = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LDAP_REQ_DELETE:
|
||||
rc = ldap_chain_op( op, rs, lback->bi_op_delete, ref );
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -525,6 +525,34 @@ slap_mods_no_user_mod_check(
|
|||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
slap_mods_no_repl_user_mod_check(
|
||||
Operation *op,
|
||||
Modifications *ml,
|
||||
const char **text,
|
||||
char *textbuf,
|
||||
size_t textlen )
|
||||
{
|
||||
Modifications *mods;
|
||||
Modifications *modp;
|
||||
|
||||
for ( mods = ml; mods != NULL; mods = mods->sml_next ) {
|
||||
assert( mods->sml_op == LDAP_MOD_ADD );
|
||||
|
||||
/* check doesn't already appear */
|
||||
for ( modp = ml; modp != NULL; modp = modp->sml_next ) {
|
||||
if ( mods->sml_desc == modp->sml_desc ) {
|
||||
snprintf( textbuf, textlen,
|
||||
"attribute '%s' provided more than once",
|
||||
mods->sml_desc->ad_cname.bv_val );
|
||||
return LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do basic attribute type checking and syntax validation.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ LDAP_SLAPD_V( AttributeName * ) slap_anlist_all_attributes;
|
|||
* add.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) slap_mods2entry LDAP_P(( Modifications *mods, Entry **e,
|
||||
int repl_user, int dup, const char **text, char *textbuf, size_t textlen ));
|
||||
int initial, int dup, const char **text, char *textbuf, size_t textlen ));
|
||||
|
||||
LDAP_SLAPD_F (int) slap_entry2mods LDAP_P(( Entry *e,
|
||||
Modifications **mods, const char **text,
|
||||
|
|
@ -957,6 +957,13 @@ LDAP_SLAPD_F( int ) slap_mods_no_user_mod_check(
|
|||
const char **text,
|
||||
char *textbuf, size_t textlen );
|
||||
|
||||
LDAP_SLAPD_F ( int ) slap_mods_no_repl_user_mod_check(
|
||||
Operation *op,
|
||||
Modifications *ml,
|
||||
const char **text,
|
||||
char *textbuf,
|
||||
size_t textlen );
|
||||
|
||||
LDAP_SLAPD_F( int ) slap_mods_check(
|
||||
Modifications *ml,
|
||||
const char **text,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ LDAP_BEGIN_DECL
|
|||
|
||||
/* slapi_utils.c */
|
||||
LDAP_SLAPI_F (LDAPMod **) slapi_int_modifications2ldapmods LDAP_P(( Modifications **, void *ctx ));
|
||||
LDAP_SLAPI_F (Modifications *) slapi_int_ldapmods2modifications LDAP_P(( LDAPMod **, void *ctx ));
|
||||
LDAP_SLAPI_F (Modifications *) slapi_int_ldapmods2modifications LDAP_P(( LDAPMod **, int dup, void *ctx ));
|
||||
LDAP_SLAPI_F (void) slapi_int_free_ldapmods LDAP_P(( LDAPMod ** ));
|
||||
LDAP_SLAPI_F (int) slapi_int_count_controls LDAP_P(( LDAPControl **ctrls ));
|
||||
LDAP_SLAPI_F (char **) slapi_get_supported_extended_ops LDAP_P((void));
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ slapi_int_set_operation_dn( Slapi_PBlock *pb )
|
|||
|
||||
if ( BER_BVISNULL( &op->o_ndn ) ) {
|
||||
/* set to root DN */
|
||||
be = select_backend( &op->o_req_ndn, 0, 0 );
|
||||
be = select_backend( &op->o_req_ndn, get_manageDSAit( op ), 1 );
|
||||
if ( be != NULL ) {
|
||||
ber_dupbv( &op->o_dn, &be->be_rootdn );
|
||||
ber_dupbv( &op->o_ndn, &be->be_rootndn );
|
||||
|
|
@ -344,10 +344,10 @@ slapi_int_connection_done_pb( Slapi_PBlock *pb )
|
|||
}
|
||||
break;
|
||||
case LDAP_REQ_ADD:
|
||||
slapi_int_mods_free( op->ora_modlist );
|
||||
slap_mods_free( op->ora_modlist );
|
||||
break;
|
||||
case LDAP_REQ_MODIFY:
|
||||
slapi_int_mods_free( op->orm_modlist );
|
||||
slap_mods_free( op->orm_modlist );
|
||||
break;
|
||||
case LDAP_REQ_SEARCH:
|
||||
if ( op->ors_attrs != NULL ) {
|
||||
|
|
@ -429,6 +429,10 @@ slapi_add_internal_pb( Slapi_PBlock *pb )
|
|||
entry_orig = pb->pb_op->ora_e;
|
||||
pb->pb_op->ora_e = NULL;
|
||||
|
||||
/*
|
||||
* The caller can specify a new entry, or a target DN and set
|
||||
* of modifications, but not both.
|
||||
*/
|
||||
if ( entry_orig != NULL ) {
|
||||
if ( pb->pb_op->ora_modlist != NULL || !BER_BVISNULL( &pb->pb_op->o_req_ndn )) {
|
||||
rs->sr_err = LDAP_PARAM_ERROR;
|
||||
|
|
@ -443,10 +447,6 @@ slapi_add_internal_pb( Slapi_PBlock *pb )
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller can specify a new entry, or a target DN and set
|
||||
* of modifications, but not both.
|
||||
*/
|
||||
pb->pb_op->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) );
|
||||
ber_dupbv( &pb->pb_op->ora_e->e_name, &pb->pb_op->o_req_dn );
|
||||
ber_dupbv( &pb->pb_op->ora_e->e_nname, &pb->pb_op->o_req_ndn );
|
||||
|
|
@ -469,11 +469,17 @@ slapi_add_internal_pb( Slapi_PBlock *pb )
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Duplicate the values, because we may call slapi_entry_free() */
|
||||
rs->sr_err = slap_mods2entry( pb->pb_op->ora_modlist, &pb->pb_op->ora_e,
|
||||
1, 1, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ( slapi_int_func_internal_pb( pb, op_add ) == 0 ) {
|
||||
if ( pb->pb_op->ora_e != NULL && pb->pb_op->o_private != NULL ) {
|
||||
BackendDB *bd = pb->pb_op->o_bd;
|
||||
|
||||
/* could we use SLAPI_BACKEND instead? */
|
||||
pb->pb_op->o_bd = (BackendDB *)pb->pb_op->o_private;
|
||||
pb->pb_op->o_private = NULL;
|
||||
be_entry_release_w( pb->pb_op, pb->pb_op->ora_e );
|
||||
|
|
@ -492,7 +498,7 @@ cleanup:
|
|||
}
|
||||
if ( entry_orig != NULL ) {
|
||||
pb->pb_op->ora_e = entry_orig;
|
||||
slapi_int_mods_free( pb->pb_op->ora_modlist );
|
||||
slap_mods_free( pb->pb_op->ora_modlist );
|
||||
pb->pb_op->ora_modlist = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -889,11 +889,10 @@ pblock_set( Slapi_PBlock *pb, int param, void *value )
|
|||
break;
|
||||
case SLAPI_ADD_ENTRY:
|
||||
PBLOCK_ASSERT_OP( pb, 0 );
|
||||
if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
|
||||
if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
|
||||
pb->pb_op->ora_e = (Slapi_Entry *)value;
|
||||
} else {
|
||||
else
|
||||
rc = PBLOCK_ERROR;
|
||||
}
|
||||
break;
|
||||
case SLAPI_MODIFY_MODS: {
|
||||
Modifications **mlp;
|
||||
|
|
@ -916,7 +915,14 @@ pblock_set( Slapi_PBlock *pb, int param, void *value )
|
|||
slapi_int_mods_free( *mlp );
|
||||
*mlp = NULL;
|
||||
}
|
||||
*mlp = slapi_int_ldapmods2modifications( (LDAPMod **)value, NULL );
|
||||
/*
|
||||
* Note: for internal operations, the modifications need to be
|
||||
* duplicated because slap_mods_check() will free values before
|
||||
* prettying, and we have no idea how the values were
|
||||
* allocated. For frontend operations, slap_mods_check() will
|
||||
* have already been called.
|
||||
*/
|
||||
*mlp = slapi_int_ldapmods2modifications( (LDAPMod **)value, pb->pb_intop, NULL );
|
||||
break;
|
||||
}
|
||||
case SLAPI_MODRDN_NEWRDN:
|
||||
|
|
|
|||
|
|
@ -2657,7 +2657,7 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
|
|||
if ( pb == NULL || pb->pb_op == NULL )
|
||||
return LDAP_PARAM_ERROR;
|
||||
|
||||
ml = slapi_int_ldapmods2modifications( mods, NULL );
|
||||
ml = slapi_int_ldapmods2modifications( mods, 0, NULL );
|
||||
if ( ml == NULL ) {
|
||||
return LDAP_OTHER;
|
||||
}
|
||||
|
|
@ -2741,7 +2741,7 @@ LDAPMod **slapi_int_modifications2ldapmods(
|
|||
* LDAPMods array; the latter MUST be freed with
|
||||
* slapi_int_free_ldapmods() (see below).
|
||||
*/
|
||||
Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
|
||||
Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, int dup, void *memctx )
|
||||
{
|
||||
Modifications *modlist = NULL, **modtail;
|
||||
LDAPMod **modp;
|
||||
|
|
@ -2791,12 +2791,17 @@ Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
|
|||
/* NB: This implicitly trusts a plugin to return valid modifications. */
|
||||
if ( lmod->mod_op & LDAP_MOD_BVALUES ) {
|
||||
for ( i = 0; lmod->mod_bvalues[i] != NULL; i++ ) {
|
||||
mod->sml_values[i].bv_val = lmod->mod_bvalues[i]->bv_val;
|
||||
mod->sml_values[i].bv_len = lmod->mod_bvalues[i]->bv_len;
|
||||
if ( dup ) {
|
||||
ber_dupbv( &mod->sml_values[i], lmod->mod_bvalues[i] );
|
||||
} else {
|
||||
mod->sml_values[i].bv_val = lmod->mod_bvalues[i]->bv_val;
|
||||
mod->sml_values[i].bv_len = lmod->mod_bvalues[i]->bv_len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( i = 0; lmod->mod_values[i] != NULL; i++ ) {
|
||||
mod->sml_values[i].bv_val = lmod->mod_values[i];
|
||||
mod->sml_values[i].bv_val = dup ? slapi_ch_strdup( lmod->mod_values[i] ) :
|
||||
lmod->mod_values[i];
|
||||
mod->sml_values[i].bv_len = strlen( lmod->mod_values[i] );
|
||||
}
|
||||
}
|
||||
|
|
@ -2837,7 +2842,7 @@ slapi_int_mods_free( Modifications *ml )
|
|||
/*
|
||||
* This function only frees the parts of the mods array that
|
||||
* are not shared with the Modification list that was created
|
||||
* by slapi_int_ldapmods2modifications().
|
||||
* by slapi_int_ldapmods2modifications() (if dup == 0).
|
||||
*/
|
||||
void
|
||||
slapi_int_free_ldapmods ( LDAPMod **mods )
|
||||
|
|
|
|||
Loading…
Reference in a new issue