]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ndb/modrdn.cpp
Merge remote-tracking branch 'origin/mdb.master'
[openldap] / servers / slapd / back-ndb / modrdn.cpp
index c9ac0d89e7ac084702d4d9c8b1c45c8a6da8c0c5..e87d285770a7d6305533c51c0b81e14568a47213 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2008 The OpenLDAP Foundation.
+ * Copyright 2008-2012 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -88,12 +88,16 @@ retry:      /* transaction retry */
                        rs->sr_err = SLAPD_ABANDON;
                        goto return_results;
                }
+               if ( NA2.ocs ) {
+                       ber_bvarray_free_x( NA2.ocs, op->o_tmpmemctx );
+               }
                if ( NA.ocs ) {
-                       ber_bvarray_free( NA.ocs );
+                       ber_bvarray_free_x( NA.ocs, op->o_tmpmemctx );
                }
                ndb_trans_backoff( ++num_retries );
        }
        NA.ocs = NULL;
+       NA2.ocs = NULL;
 
        /* begin transaction */
        NA.txn = NA.ndb->startTransaction();
@@ -109,7 +113,7 @@ retry:      /* transaction retry */
        NA2.txn = NA.txn;
 
        /* get entry */
-       rs->sr_err = ndb_entry_get_info( op->o_bd, &NA, 1, &matched );
+       rs->sr_err = ndb_entry_get_info( op, &NA, 1, &matched );
        switch( rs->sr_err ) {
        case 0:
                break;
@@ -118,6 +122,8 @@ retry:      /* transaction retry */
                        "<=- ndb_back_modrdn: no such object %s\n",
                        op->o_req_dn.bv_val, 0, 0 );
                rs->sr_matched = matched.bv_val;
+               if ( NA.ocs )
+                       ndb_check_referral( op, rs, &NA );
                goto return_results;
 #if 0
        case DB_LOCK_DEADLOCK:
@@ -134,8 +140,15 @@ retry:     /* transaction retry */
        }
 
        /* acquire and lock entry */
-       rs->sr_err = ndb_entry_get_data( op->o_bd, &NA, 1 );
+       rs->sr_err = ndb_entry_get_data( op, &NA, 1 );
+       if ( rs->sr_err )
+               goto return_results;
 
+       if ( !manageDSAit && is_entry_glue( &e )) {
+               rs->sr_err = LDAP_NO_SUCH_OBJECT;
+               goto return_results;
+       }
+       
        if ( get_assert( op ) &&
                ( test_filter( op, &e, (Filter *)get_assertion( op )) != LDAP_COMPARE_TRUE ))
        {
@@ -248,8 +261,7 @@ retry:      /* transaction retry */
 
                        e2.e_name = *np_dn;
                        e2.e_nname = *np_ndn;
-                       NA2.ocs = &matched;
-                       rs->sr_err = ndb_entry_get_info( op->o_bd, &NA2, 1, NULL );
+                       rs->sr_err = ndb_entry_get_info( op, &NA2, 1, NULL );
                        switch( rs->sr_err ) {
                        case 0:
                                break;
@@ -273,6 +285,40 @@ retry:     /* transaction retry */
                                rs->sr_text = "internal error";
                                goto return_results;
                        }
+                       if ( NA2.ocs ) {
+                               Attribute a;
+                               int i;
+
+                               for ( i=0; !BER_BVISNULL( &NA2.ocs[i] ); i++);
+                               a.a_numvals = i;
+                               a.a_desc = slap_schema.si_ad_objectClass;
+                               a.a_vals = NA2.ocs;
+                               a.a_nvals = NA2.ocs;
+                               a.a_next = NULL;
+                               e2.e_attrs = &a;
+
+                               if ( is_entry_alias( &e2 )) {
+                                       /* parent is an alias, don't allow move */
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               LDAP_XSTRING(ndb_back_modrdn)
+                                               ": entry is alias\n",
+                                               0, 0, 0 );
+                                       rs->sr_text = "new superior is an alias";
+                                       rs->sr_err = LDAP_ALIAS_PROBLEM;
+                                       goto return_results;
+                               }
+
+                               if ( is_entry_referral( &e2 ) ) {
+                                       /* parent is a referral, don't allow move */
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               LDAP_XSTRING(ndb_back_modrdn)
+                                               ": entry is referral\n",
+                                               0, 0, 0 );
+                                       rs->sr_text = "new superior is a referral";
+                                       rs->sr_err = LDAP_OTHER;
+                                       goto return_results;
+                               }
+                       }
                }
 
                /* check newSuperior for "children" acl */
@@ -312,7 +358,8 @@ retry:      /* transaction retry */
                e2.e_name = new_dn;
                e2.e_nname = new_ndn;
                NA2.ocs = &matched;
-               rs->sr_err = ndb_entry_get_info( op->o_bd, &NA2, 1, NULL );
+               rs->sr_err = ndb_entry_get_info( op, &NA2, 1, NULL );
+               NA2.ocs = NULL;
                switch( rs->sr_err ) {
 #if 0
                case DB_LOCK_DEADLOCK:
@@ -434,13 +481,15 @@ retry:    /* transaction retry */
        }
 
        if( op->o_noop ) {
-               if(( rs->sr_err = NA.txn->execute( Rollback )) != 0 ) {
+               if (( rs->sr_err=NA.txn->execute( NdbTransaction::Rollback,
+                       NdbOperation::AbortOnError, 1 )) != 0 ) {
                        rs->sr_text = "txn_abort (no-op) failed";
                } else {
                        rs->sr_err = LDAP_X_NO_OPERATION;
                }
        } else {
-               if(( rs->sr_err = NA.txn->execute( Commit )) != 0 ) {
+               if (( rs->sr_err=NA.txn->execute( NdbTransaction::Commit,
+                       NdbOperation::AbortOnError, 1 )) != 0 ) {
                        rs->sr_text = "txn_commit failed";
                } else {
                        rs->sr_err = LDAP_SUCCESS;
@@ -469,8 +518,13 @@ retry:     /* transaction retry */
        if( num_ctrls ) rs->sr_ctrls = ctrls;
 
 return_results:
+       if ( NA2.ocs ) {
+               ber_bvarray_free_x( NA2.ocs, op->o_tmpmemctx );
+               NA2.ocs = NULL;
+       }
+
        if ( NA.ocs ) {
-               ber_bvarray_free( NA.ocs );
+               ber_bvarray_free_x( NA.ocs, op->o_tmpmemctx );
                NA.ocs = NULL;
        }