]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldbm/modrdn.c
use slab memory for proxyauthz
[openldap] / servers / slapd / back-ldbm / modrdn.c
index c8ef1e5446379e24ead8ebfcf2f54773354fcc16..668939f9b81e39094cd253f2bd4a8cb95931e049 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,9 +47,6 @@ ldbm_back_modrdn(
        Entry           *e, *p = NULL;
        Entry           *matched;
        /* LDAP v2 supporting correct attribute handling. */
-       LDAPRDN         new_rdn = NULL;
-       LDAPRDN         old_rdn = NULL;
-       int             isroot = -1;
        int             rc_id = 0;
        ID              id = NOID;
        char            textbuf[SLAP_TEXT_BUFLEN];
@@ -59,7 +56,6 @@ ldbm_back_modrdn(
        struct berval   *np_ndn = NULL; /* newSuperior ndn */
        struct berval   *new_parent_dn = NULL;  /* np_dn, p_dn, or NULL */
        /* Used to interface with ldbm_modify_internal() */
-       Modifications   *mod = NULL;            /* Used to delete old/add new rdn */
        int             manageDSAit = get_manageDSAit( op );
 
        Debug( LDAP_DEBUG_TRACE,
@@ -68,6 +64,9 @@ ldbm_back_modrdn(
                ( op->oq_modrdn.rs_newSup && op->oq_modrdn.rs_newSup->bv_len )
                        ? op->oq_modrdn.rs_newSup->bv_val : "NULL", 0 );
 
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_mods_opattrs( op, &op->orr_modlist, 1 );
+
        /* grab giant lock for writing */
        ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
 
@@ -159,79 +158,42 @@ ldbm_back_modrdn(
 
                        goto return_results;
                }
+       } else {
+               p = (Entry *)&slap_entry_root;
+       }
 
-               /* check parent for "children" acl */
-               if ( ! access_allowed( op, p, children, NULL,
-                               op->oq_modrdn.rs_newSup != NULL ?
-                                       ACL_WDEL : ACL_WRITE,
-                               NULL ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
-                               0, 0 );
-
-                       send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
-                               NULL );
-                       goto return_results;
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: wr to children of entry %s OK\n",
-                      p_ndn.bv_val, 0, 0 );
-
-               if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
-                       p_dn = slap_empty_bv;
-               } else {
-                       dnParent( &e->e_name, &p_dn );
-               }
-
-               Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n",
-                      p_dn.bv_val, 0, 0 );
+       /* check parent for "children" acl */
+       rs->sr_err = access_allowed( op, p, children, NULL,
+                       op->oq_modrdn.rs_newSup != NULL ?
+                               ACL_WDEL : ACL_WRITE,
+                       NULL );
 
-       } else {
-               /* no parent, must be root to modify rdn */
-               isroot = be_isroot( op );
-               if ( ! isroot ) {
-                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                               || be_shadow_update( op ) ) {
-                               int     can_access;
-                               p = (Entry *)&slap_entry_root;
-                               
-                               can_access = access_allowed( op, p,
-                                               children, NULL,
-                                               op->oq_modrdn.rs_newSup ?
-                                                       ACL_WDEL : ACL_WRITE,
-                                               NULL );
-                               p = NULL;
-                                                               
-                               /* check parent for "children" acl */
-                               if ( ! can_access ) {
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "<=- ldbm_back_modrdn: no "
-                                               "access to parent\n", 0, 0, 0 );
+       if ( BER_BVISEMPTY( &p_ndn ))
+               p = NULL;
 
-                                       send_ldap_error( op, rs,
-                                               LDAP_INSUFFICIENT_ACCESS,
-                                               NULL );
-                                       goto return_results;
-                               }
+       if ( !rs->sr_err )
+       {
+               Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
+                       0, 0 );
 
-                       } else {
-                               Debug( LDAP_DEBUG_TRACE,
-                                       "<=- ldbm_back_modrdn: no parent & "
-                                       "not root\n", 0, 0, 0);
+               send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
+                       NULL );
+               goto return_results;
+       }
 
-                               send_ldap_error( op, rs,
-                                       LDAP_INSUFFICIENT_ACCESS,
-                                       NULL );
-                               goto return_results;
-                       }
-               }
+       Debug( LDAP_DEBUG_TRACE,
+                  "ldbm_back_modrdn: wr to children of entry %s OK\n",
+                  p_ndn.bv_val, 0, 0 );
 
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: no parent, locked root\n",
-                      0, 0, 0 );
+       if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
+               p_dn = slap_empty_bv;
+       } else {
+               dnParent( &e->e_name, &p_dn );
        }
 
+       Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n",
+                  p_dn.bv_val, 0, 0 );
+
        new_parent_dn = &p_dn;  /* New Parent unless newSuperior given */
 
        if ( op->oq_modrdn.rs_newSup != NULL ) {
@@ -262,7 +224,7 @@ ldbm_back_modrdn(
                                    "ldbm_back_modrdn: newSup(ndn=%s) not here!\n",
                                    np_ndn->bv_val, 0, 0);
 
-                               send_ldap_error( op, rs, LDAP_OTHER,
+                               send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT,
                                        "newSuperior not found" );
                                goto return_results;
                        }
@@ -306,27 +268,20 @@ ldbm_back_modrdn(
                        }
 
                } else {
-
-                       /* no parent, must be root to modify newSuperior */
-                       if ( isroot == -1 ) {
-                               isroot = be_isroot( op );
-                       }
-
-                       if ( ! isroot ) {
-                               if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                                       || be_shadow_update( op ) ) {
-                                       int     can_access;
-                                       np = (Entry *)&slap_entry_root;
-                               
-                                       can_access = access_allowed( op, np,
-                                                       children, NULL, ACL_WADD, NULL );
-                                       np = NULL;
-                                                               
-                                       /* check parent for "children" acl */
-                                       if ( ! can_access ) {
-                                               Debug( LDAP_DEBUG_TRACE,
-                                                       "<=- ldbm_back_modrdn: no "
-                                                       "access to new superior\n", 0, 0, 0 );
+                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
+                               || be_shadow_update( op ) ) {
+                               int     can_access;
+                               np = (Entry *)&slap_entry_root;
+                       
+                               can_access = access_allowed( op, np,
+                                               children, NULL, ACL_WADD, NULL );
+                               np = NULL;
+                                                       
+                               /* check parent for "children" acl */
+                               if ( ! can_access ) {
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               "<=- ldbm_back_modrdn: no "
+                                               "access to new superior\n", 0, 0, 0 );
 
                                                send_ldap_error( op, rs,
                                                        LDAP_INSUFFICIENT_ACCESS,
@@ -334,17 +289,16 @@ ldbm_back_modrdn(
                                                goto return_results;
                                        }
 
-                               } else {
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "<=- ldbm_back_modrdn: \"\" "
-                                               "not allowed as new superior\n", 
-                                               0, 0, 0);
-
-                                       send_ldap_error( op, rs,
-                                               LDAP_INSUFFICIENT_ACCESS,
-                                               NULL );
-                                       goto return_results;
-                               }
+                       } else {
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "<=- ldbm_back_modrdn: \"\" "
+                                       "not allowed as new superior\n", 
+                                       0, 0, 0);
+
+                               send_ldap_error( op, rs,
+                                       LDAP_INSUFFICIENT_ACCESS,
+                                       NULL );
+                               goto return_results;
                        }
                }
 
@@ -379,48 +333,10 @@ ldbm_back_modrdn(
            "ldbm_back_modrdn: new ndn=%s does not exist\n",
            new_ndn.bv_val, 0, 0 );
 
-       /* Get attribute type and attribute value of our new rdn, we will
-        * need to add that to our new entry
-        */
-       if ( ldap_bv2rdn( &op->oq_modrdn.rs_newrdn, &new_rdn, (char **)&rs->sr_text,
-               LDAP_DN_FORMAT_LDAP ) )
-       {
-               Debug( LDAP_DEBUG_TRACE,
-                       "ldbm_back_modrdn: can't figure out "
-                       "type(s)/values(s) of newrdn\n", 
-                       0, 0, 0 );
-               send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX,
-                                   "unknown type(s) used in RDN" );
-               goto return_results;            
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-               "ldbm_back_modrdn: new_rdn_type=\"%s\", "
-               "new_rdn_val=\"%s\"\n",
-               new_rdn[ 0 ]->la_attr.bv_val,
-               new_rdn[ 0 ]->la_value.bv_val, 0 );
-
-       if ( op->oq_modrdn.rs_deleteoldrdn ) {
-               if ( ldap_bv2rdn( &op->o_req_dn, &old_rdn, (char **)&rs->sr_text,
-                       LDAP_DN_FORMAT_LDAP ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "ldbm_back_modrdn: can't figure out "
-                               "the old_rdn type(s)/value(s)\n", 
-                               0, 0, 0 );
-                       send_ldap_error( op, rs, LDAP_OTHER,
-                                   "cannot parse RDN from old DN" );
-                       goto return_results;            
-               }
-       }
-
        Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n",
               0, 0, 0 );
        
-       if ( slap_modrdn2mods( op, rs, e, old_rdn, new_rdn, &mod ) != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               goto return_results;
-       }
+       assert( op->orr_modlist != NULL );
 
        /* check for abandon */
        if ( op->o_abandon ) {
@@ -442,7 +358,7 @@ ldbm_back_modrdn(
         */
 
        /* modify memory copy of entry */
-       rs->sr_err = ldbm_modify_internal( op, &mod[0], e,
+       rs->sr_err = ldbm_modify_internal( op, op->orr_modlist, e,
                &rs->sr_text, textbuf, textlen );
        switch ( rs->sr_err ) {
        case LDAP_SUCCESS:
@@ -510,28 +426,6 @@ return_results:
        if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val );
        if( old_ndn.bv_val != NULL ) free( old_ndn.bv_val );
 
-       /* LDAP v2 supporting correct attribute handling. */
-       if ( new_rdn != NULL ) {
-               ldap_rdnfree( new_rdn );
-       }
-       if ( old_rdn != NULL ) {
-               ldap_rdnfree( old_rdn );
-       }
-       if ( mod != NULL ) {
-               Modifications *tmp;
-               for (; mod; mod = tmp ) {
-                       /* slap_modrdn2mods does things one way,
-                        * slap_mods_opattrs does it differently
-                        */
-                       if ( mod->sml_op != SLAP_MOD_SOFTADD &&
-                               mod->sml_op != LDAP_MOD_DELETE ) break;
-                       if ( mod->sml_nvalues ) free( mod->sml_nvalues[0].bv_val );
-                       tmp = mod->sml_next;
-                       free( mod );
-               }
-               slap_mods_free( mod, 1 );
-       }
-
        /* LDAP v3 Support */
        if( np != NULL ) {
                /* free new parent and writer lock */