]> git.sur5r.net Git - openldap/commitdiff
Call slap_mods2entry() in do_add(), so that global overlays (including
authorLuke Howard <lukeh@openldap.org>
Sun, 31 Jul 2005 04:56:27 +0000 (04:56 +0000)
committerLuke Howard <lukeh@openldap.org>
Sun, 31 Jul 2005 04:56:27 +0000 (04:56 +0000)
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.

servers/slapd/add.c
servers/slapd/back-ldap/chain.c
servers/slapd/modify.c
servers/slapd/proto-slap.h
servers/slapd/slapi/proto-slapi.h
servers/slapd/slapi/slapi_ops.c
servers/slapd/slapi/slapi_pblock.c
servers/slapd/slapi/slapi_utils.c

index b877169f4989794d121ac9bed0d4b5cf6265e7a0..30af7693dda1ae7be0983c4cebd17cd6a9b513ce 100644 (file)
@@ -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 */
                        }
index 4b1bc2433b1c1f1cae9d0c86ce52e52fc7c5a5df..2cba84c833adb8002556bd4ebf184bf32dcebb93 100644 (file)
@@ -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;
index e943b22db10217fe9f348b01be8d0a870ec8211e..efa03812d9e9ee1c93f50fe36bd93ac8a4f78a98 100644 (file)
@@ -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.
  */
index 29c6d8f15ce322d588a8b7dfc4b52f26fcb52c49..77eea618ac519b3684efc01a6ee7141bafb8a877 100644 (file)
@@ -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,
index 4a7d6b0ddee70dab3fe7b8d9ee7d84d70991fc99..b39873745dfa45e48ebdc3a713b013e6506a318f 100644 (file)
@@ -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));
index c224d7a667bbf7fabe94050cd6ed742a4ebddb5b..d57f3fc65121ee2267ee4ab3cb52d841ed6a7cd7 100644 (file)
@@ -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;
        }
 
index cc1b653e76c7f1ad9a4534af4daee43f0a2209b0..791a3101d10451449c76552bfa9e2ecad758b7c1 100644 (file)
@@ -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:
index fea5e7d02eb09bf1a93c6a2538927eddd43b119a..e12d8ab90029d7e2c8354368e39b6f0cf492891a 100644 (file)
@@ -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 )