~ubuntu-branches/ubuntu/oneiric/likewise-open/oneiric

« back to all changes in this revision

Viewing changes to openldap/servers/slapd/back-ndb/modrdn.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Salley
  • Date: 2010-11-22 12:06:00 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122120600-8lba1fpceot71wlb
Tags: 6.0.0.53010-1
Likewise Open 6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* modrdn.cpp - ndb backend modrdn routine */
 
2
/* $OpenLDAP: pkg/ldap/servers/slapd/back-ndb/modrdn.cpp,v 1.3.2.2 2009/01/22 00:01:09 kurt Exp $ */
 
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 
4
 *
 
5
 * Copyright 2008-2009 The OpenLDAP Foundation.
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted only as authorized by the OpenLDAP
 
10
 * Public License.
 
11
 *
 
12
 * A copy of this license is available in the file LICENSE in the
 
13
 * top-level directory of the distribution or, alternatively, at
 
14
 * <http://www.OpenLDAP.org/license.html>.
 
15
 */
 
16
/* ACKNOWLEDGEMENTS:
 
17
 * This work was initially developed by Howard Chu for inclusion
 
18
 * in OpenLDAP Software. This work was sponsored by MySQL.
 
19
 */
 
20
 
 
21
#include "portable.h"
 
22
 
 
23
#include <stdio.h>
 
24
#include <ac/string.h>
 
25
 
 
26
#include "back-ndb.h"
 
27
 
 
28
int
 
29
ndb_back_modrdn( Operation *op, SlapReply *rs )
 
30
{
 
31
        struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private;
 
32
        AttributeDescription *children = slap_schema.si_ad_children;
 
33
        AttributeDescription *entry = slap_schema.si_ad_entry;
 
34
        struct berval   new_dn = BER_BVNULL, new_ndn = BER_BVNULL;
 
35
        Entry           e = {0};
 
36
        Entry           e2 = {0};
 
37
        char textbuf[SLAP_TEXT_BUFLEN];
 
38
        size_t textlen = sizeof textbuf;
 
39
 
 
40
        struct berval   *np_dn = NULL;                  /* newSuperior dn */
 
41
        struct berval   *np_ndn = NULL;                 /* newSuperior ndn */
 
42
 
 
43
        int             manageDSAit = get_manageDSAit( op );
 
44
        int             num_retries = 0;
 
45
 
 
46
        NdbArgs NA, NA2;
 
47
        NdbRdns rdns, rdn2;
 
48
        struct berval matched;
 
49
 
 
50
        LDAPControl **preread_ctrl = NULL;
 
51
        LDAPControl **postread_ctrl = NULL;
 
52
        LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
 
53
        int num_ctrls = 0;
 
54
 
 
55
        int     rc;
 
56
 
 
57
        Debug( LDAP_DEBUG_ARGS, "==>" LDAP_XSTRING(ndb_back_modrdn) "(%s,%s,%s)\n",
 
58
                op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
 
59
                op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" );
 
60
 
 
61
        ctrls[num_ctrls] = NULL;
 
62
 
 
63
        slap_mods_opattrs( op, &op->orr_modlist, 1 );
 
64
 
 
65
        e.e_name = op->o_req_dn;
 
66
        e.e_nname = op->o_req_ndn;
 
67
 
 
68
        /* Get our NDB handle */
 
69
        rs->sr_err = ndb_thread_handle( op, &NA.ndb );
 
70
        rdns.nr_num = 0;
 
71
        NA.rdns = &rdns;
 
72
        NA.e = &e;
 
73
        NA2.ndb = NA.ndb;
 
74
        NA2.e = &e2;
 
75
        NA2.rdns = &rdn2;
 
76
 
 
77
        if( 0 ) {
 
78
retry:  /* transaction retry */
 
79
                NA.txn->close();
 
80
                NA.txn = NULL;
 
81
                if ( e.e_attrs ) {
 
82
                        attrs_free( e.e_attrs );
 
83
                        e.e_attrs = NULL;
 
84
                }
 
85
                Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(ndb_back_modrdn)
 
86
                                ": retrying...\n", 0, 0, 0 );
 
87
                if ( op->o_abandon ) {
 
88
                        rs->sr_err = SLAPD_ABANDON;
 
89
                        goto return_results;
 
90
                }
 
91
                if ( NA2.ocs ) {
 
92
                        ber_bvarray_free_x( NA2.ocs, op->o_tmpmemctx );
 
93
                }
 
94
                if ( NA.ocs ) {
 
95
                        ber_bvarray_free_x( NA.ocs, op->o_tmpmemctx );
 
96
                }
 
97
                ndb_trans_backoff( ++num_retries );
 
98
        }
 
99
        NA.ocs = NULL;
 
100
        NA2.ocs = NULL;
 
101
 
 
102
        /* begin transaction */
 
103
        NA.txn = NA.ndb->startTransaction();
 
104
        rs->sr_text = NULL;
 
105
        if( !NA.txn ) {
 
106
                Debug( LDAP_DEBUG_TRACE,
 
107
                        LDAP_XSTRING(ndb_back_modrdn) ": startTransaction failed: %s (%d)\n",
 
108
                        NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 );
 
109
                rs->sr_err = LDAP_OTHER;
 
110
                rs->sr_text = "internal error";
 
111
                goto return_results;
 
112
        }
 
113
        NA2.txn = NA.txn;
 
114
 
 
115
        /* get entry */
 
116
        rs->sr_err = ndb_entry_get_info( op, &NA, 1, &matched );
 
117
        switch( rs->sr_err ) {
 
118
        case 0:
 
119
                break;
 
120
        case LDAP_NO_SUCH_OBJECT:
 
121
                Debug( LDAP_DEBUG_ARGS,
 
122
                        "<=- ndb_back_modrdn: no such object %s\n",
 
123
                        op->o_req_dn.bv_val, 0, 0 );
 
124
                rs->sr_matched = matched.bv_val;
 
125
                if ( NA.ocs )
 
126
                        ndb_check_referral( op, rs, &NA );
 
127
                goto return_results;
 
128
#if 0
 
129
        case DB_LOCK_DEADLOCK:
 
130
        case DB_LOCK_NOTGRANTED:
 
131
                goto retry;
 
132
#endif
 
133
        case LDAP_BUSY:
 
134
                rs->sr_text = "ldap server busy";
 
135
                goto return_results;
 
136
        default:
 
137
                rs->sr_err = LDAP_OTHER;
 
138
                rs->sr_text = "internal error";
 
139
                goto return_results;
 
140
        }
 
141
 
 
142
        /* acquire and lock entry */
 
143
        rs->sr_err = ndb_entry_get_data( op, &NA, 1 );
 
144
        if ( rs->sr_err )
 
145
                goto return_results;
 
146
 
 
147
        if ( !manageDSAit && is_entry_glue( &e )) {
 
148
                rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
149
                goto return_results;
 
150
        }
 
151
 
 
152
        if ( get_assert( op ) &&
 
153
                ( test_filter( op, &e, (Filter *)get_assertion( op )) != LDAP_COMPARE_TRUE ))
 
154
        {
 
155
                rs->sr_err = LDAP_ASSERTION_FAILED;
 
156
                goto return_results;
 
157
        }
 
158
 
 
159
        /* check write on old entry */
 
160
        rs->sr_err = access_allowed( op, &e, entry, NULL, ACL_WRITE, NULL );
 
161
        if ( ! rs->sr_err ) {
 
162
                Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0,
 
163
                        0, 0 );
 
164
                rs->sr_text = "no write access to old entry";
 
165
                rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 
166
                goto return_results;
 
167
        }
 
168
 
 
169
        /* Can't do it if we have kids */
 
170
        rs->sr_err = ndb_has_children( &NA, &rc );
 
171
        if ( rs->sr_err ) {
 
172
                Debug(LDAP_DEBUG_ARGS,
 
173
                        "<=- " LDAP_XSTRING(ndb_back_modrdn)
 
174
                        ": has_children failed: %s (%d)\n",
 
175
                        NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 );
 
176
                rs->sr_err = LDAP_OTHER;
 
177
                rs->sr_text = "internal error";
 
178
                goto return_results;
 
179
        }
 
180
        if ( rc == LDAP_COMPARE_TRUE ) {
 
181
                Debug(LDAP_DEBUG_ARGS,
 
182
                        "<=- " LDAP_XSTRING(ndb_back_modrdn)
 
183
                        ": non-leaf %s\n",
 
184
                        op->o_req_dn.bv_val, 0, 0);
 
185
                rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
 
186
                rs->sr_text = "subtree rename not supported";
 
187
                goto return_results;
 
188
        }
 
189
 
 
190
        if (!manageDSAit && is_entry_referral( &e ) ) {
 
191
                /* entry is a referral, don't allow modrdn */
 
192
                rs->sr_ref = get_entry_referrals( op, &e );
 
193
 
 
194
                Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(ndb_back_modrdn)
 
195
                        ": entry %s is referral\n", e.e_dn, 0, 0 );
 
196
 
 
197
                rs->sr_err = LDAP_REFERRAL,
 
198
                rs->sr_matched = op->o_req_dn.bv_val;
 
199
                rs->sr_flags = REP_REF_MUSTBEFREED;
 
200
                goto return_results;
 
201
        }
 
202
 
 
203
        if ( be_issuffix( op->o_bd, &e.e_nname ) ) {
 
204
                /* There can only be one suffix entry */
 
205
                rs->sr_err = LDAP_NAMING_VIOLATION;
 
206
                rs->sr_text = "cannot rename suffix entry";
 
207
                goto return_results;
 
208
        } else {
 
209
                dnParent( &e.e_nname, &e2.e_nname );
 
210
                dnParent( &e.e_name, &e2.e_name );
 
211
        }
 
212
 
 
213
        /* check parent for "children" acl */
 
214
        rs->sr_err = access_allowed( op, &e2,
 
215
                children, NULL,
 
216
                op->oq_modrdn.rs_newSup == NULL ?
 
217
                        ACL_WRITE : ACL_WDEL,
 
218
                NULL );
 
219
 
 
220
        if ( ! rs->sr_err ) {
 
221
                rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 
222
                Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
 
223
                        0, 0 );
 
224
                rs->sr_text = "no write access to old parent's children";
 
225
                goto return_results;
 
226
        }
 
227
 
 
228
        Debug( LDAP_DEBUG_TRACE,
 
229
                LDAP_XSTRING(ndb_back_modrdn) ": wr to children "
 
230
                "of entry %s OK\n", e2.e_name.bv_val, 0, 0 );
 
231
 
 
232
        if ( op->oq_modrdn.rs_newSup != NULL ) {
 
233
                Debug( LDAP_DEBUG_TRACE,
 
234
                        LDAP_XSTRING(ndb_back_modrdn)
 
235
                        ": new parent \"%s\" requested...\n",
 
236
                        op->oq_modrdn.rs_newSup->bv_val, 0, 0 );
 
237
 
 
238
                /*  newSuperior == oldParent? */
 
239
                if( dn_match( &e2.e_nname, op->oq_modrdn.rs_nnewSup ) ) {
 
240
                        Debug( LDAP_DEBUG_TRACE, "bdb_back_modrdn: "
 
241
                                "new parent \"%s\" same as the old parent \"%s\"\n",
 
242
                                op->oq_modrdn.rs_newSup->bv_val, e2.e_name.bv_val, 0 );
 
243
                        op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */
 
244
                }
 
245
        }
 
246
 
 
247
        if ( op->oq_modrdn.rs_newSup != NULL ) {
 
248
                if ( op->oq_modrdn.rs_newSup->bv_len ) {
 
249
                        rdn2.nr_num = 0;
 
250
                        np_dn = op->oq_modrdn.rs_newSup;
 
251
                        np_ndn = op->oq_modrdn.rs_nnewSup;
 
252
 
 
253
                        /* newSuperior == oldParent? - checked above */
 
254
                        /* newSuperior == entry being moved?, if so ==> ERROR */
 
255
                        if ( dnIsSuffix( np_ndn, &e.e_nname )) {
 
256
                                rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
257
                                rs->sr_text = "new superior not found";
 
258
                                goto return_results;
 
259
                        }
 
260
                        /* Get Entry with dn=newSuperior. Does newSuperior exist? */
 
261
 
 
262
                        e2.e_name = *np_dn;
 
263
                        e2.e_nname = *np_ndn;
 
264
                        rs->sr_err = ndb_entry_get_info( op, &NA2, 1, NULL );
 
265
                        switch( rs->sr_err ) {
 
266
                        case 0:
 
267
                                break;
 
268
                        case LDAP_NO_SUCH_OBJECT:
 
269
                                Debug( LDAP_DEBUG_TRACE,
 
270
                                        LDAP_XSTRING(ndb_back_modrdn)
 
271
                                        ": newSup(ndn=%s) not here!\n",
 
272
                                        np_ndn->bv_val, 0, 0);
 
273
                                rs->sr_text = "new superior not found";
 
274
                                goto return_results;
 
275
#if 0
 
276
                        case DB_LOCK_DEADLOCK:
 
277
                        case DB_LOCK_NOTGRANTED:
 
278
                                goto retry;
 
279
#endif
 
280
                        case LDAP_BUSY:
 
281
                                rs->sr_text = "ldap server busy";
 
282
                                goto return_results;
 
283
                        default:
 
284
                                rs->sr_err = LDAP_OTHER;
 
285
                                rs->sr_text = "internal error";
 
286
                                goto return_results;
 
287
                        }
 
288
                        if ( NA2.ocs ) {
 
289
                                Attribute a;
 
290
                                int i;
 
291
 
 
292
                                for ( i=0; !BER_BVISNULL( &NA2.ocs[i] ); i++);
 
293
                                a.a_numvals = i;
 
294
                                a.a_desc = slap_schema.si_ad_objectClass;
 
295
                                a.a_vals = NA2.ocs;
 
296
                                a.a_nvals = NA2.ocs;
 
297
                                a.a_next = NULL;
 
298
                                e2.e_attrs = &a;
 
299
 
 
300
                                if ( is_entry_alias( &e2 )) {
 
301
                                        /* parent is an alias, don't allow move */
 
302
                                        Debug( LDAP_DEBUG_TRACE,
 
303
                                                LDAP_XSTRING(ndb_back_modrdn)
 
304
                                                ": entry is alias\n",
 
305
                                                0, 0, 0 );
 
306
                                        rs->sr_text = "new superior is an alias";
 
307
                                        rs->sr_err = LDAP_ALIAS_PROBLEM;
 
308
                                        goto return_results;
 
309
                                }
 
310
 
 
311
                                if ( is_entry_referral( &e2 ) ) {
 
312
                                        /* parent is a referral, don't allow move */
 
313
                                        Debug( LDAP_DEBUG_TRACE,
 
314
                                                LDAP_XSTRING(ndb_back_modrdn)
 
315
                                                ": entry is referral\n",
 
316
                                                0, 0, 0 );
 
317
                                        rs->sr_text = "new superior is a referral";
 
318
                                        rs->sr_err = LDAP_OTHER;
 
319
                                        goto return_results;
 
320
                                }
 
321
                        }
 
322
                }
 
323
 
 
324
                /* check newSuperior for "children" acl */
 
325
                rs->sr_err = access_allowed( op, &e2, children,
 
326
                        NULL, ACL_WADD, NULL );
 
327
                if( ! rs->sr_err ) {
 
328
                        Debug( LDAP_DEBUG_TRACE,
 
329
                                LDAP_XSTRING(ndb_back_modrdn)
 
330
                                ": no wr to newSup children\n",
 
331
                                0, 0, 0 );
 
332
                        rs->sr_text = "no write access to new superior's children";
 
333
                        rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 
334
                        goto return_results;
 
335
                }
 
336
 
 
337
                Debug( LDAP_DEBUG_TRACE,
 
338
                        LDAP_XSTRING(ndb_back_modrdn)
 
339
                        ": wr to new parent OK id=%ld\n",
 
340
                        (long) e2.e_id, 0, 0 );
 
341
        }
 
342
 
 
343
        /* Build target dn and make sure target entry doesn't exist already. */
 
344
        if (!new_dn.bv_val) {
 
345
                build_new_dn( &new_dn, &e2.e_name, &op->oq_modrdn.rs_newrdn, NULL );
 
346
        }
 
347
 
 
348
        if (!new_ndn.bv_val) {
 
349
                build_new_dn( &new_ndn, &e2.e_nname, &op->oq_modrdn.rs_nnewrdn, NULL );
 
350
        }
 
351
 
 
352
        Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(ndb_back_modrdn) ": new ndn=%s\n",
 
353
                new_ndn.bv_val, 0, 0 );
 
354
 
 
355
        /* Allow rename to same DN */
 
356
        if ( !bvmatch ( &new_ndn, &e.e_nname )) {
 
357
                rdn2.nr_num = 0;
 
358
                e2.e_name = new_dn;
 
359
                e2.e_nname = new_ndn;
 
360
                NA2.ocs = &matched;
 
361
                rs->sr_err = ndb_entry_get_info( op, &NA2, 1, NULL );
 
362
                NA2.ocs = NULL;
 
363
                switch( rs->sr_err ) {
 
364
#if 0
 
365
                case DB_LOCK_DEADLOCK:
 
366
                case DB_LOCK_NOTGRANTED:
 
367
                        goto retry;
 
368
#endif
 
369
                case LDAP_NO_SUCH_OBJECT:
 
370
                        break;
 
371
                case 0:
 
372
                        rs->sr_err = LDAP_ALREADY_EXISTS;
 
373
                        goto return_results;
 
374
                default:
 
375
                        rs->sr_err = LDAP_OTHER;
 
376
                        rs->sr_text = "internal error";
 
377
                        goto return_results;
 
378
                }
 
379
        }
 
380
 
 
381
        assert( op->orr_modlist != NULL );
 
382
 
 
383
        if( op->o_preread ) {
 
384
                if( preread_ctrl == NULL ) {
 
385
                        preread_ctrl = &ctrls[num_ctrls++];
 
386
                        ctrls[num_ctrls] = NULL;
 
387
                }
 
388
                if( slap_read_controls( op, rs, &e,
 
389
                        &slap_pre_read_bv, preread_ctrl ) )
 
390
                {
 
391
                        Debug( LDAP_DEBUG_TRACE,
 
392
                                "<=- " LDAP_XSTRING(ndb_back_modrdn)
 
393
                                ": pre-read failed!\n", 0, 0, 0 );
 
394
                        if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
 
395
                                /* FIXME: is it correct to abort
 
396
                                 * operation if control fails? */
 
397
                                goto return_results;
 
398
                        }
 
399
                }
 
400
        }
 
401
 
 
402
        /* delete old DN */
 
403
        rs->sr_err = ndb_entry_del_info( op->o_bd, &NA );
 
404
        if ( rs->sr_err != 0 ) {
 
405
                Debug(LDAP_DEBUG_TRACE,
 
406
                        "<=- " LDAP_XSTRING(ndb_back_modrdn)
 
407
                        ": dn2id del failed: %s (%d)\n",
 
408
                        NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 );
 
409
#if 0
 
410
                switch( rs->sr_err ) {
 
411
                case DB_LOCK_DEADLOCK:
 
412
                case DB_LOCK_NOTGRANTED:
 
413
                        goto retry;
 
414
                }
 
415
#endif
 
416
                rs->sr_err = LDAP_OTHER;
 
417
                rs->sr_text = "DN index delete fail";
 
418
                goto return_results;
 
419
        }
 
420
 
 
421
        /* copy entry fields */
 
422
        e2.e_attrs = e.e_attrs;
 
423
        e2.e_id = e.e_id;
 
424
 
 
425
        /* add new DN */
 
426
        rs->sr_err = ndb_entry_put_info( op->o_bd, &NA2, 0 );
 
427
        if ( rs->sr_err != 0 ) {
 
428
                Debug(LDAP_DEBUG_TRACE,
 
429
                        "<=- " LDAP_XSTRING(ndb_back_modrdn)
 
430
                        ": dn2id add failed: %s (%d)\n",
 
431
                        NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 );
 
432
#if 0
 
433
                switch( rs->sr_err ) {
 
434
                case DB_LOCK_DEADLOCK:
 
435
                case DB_LOCK_NOTGRANTED:
 
436
                        goto retry;
 
437
                }
 
438
#endif
 
439
                rs->sr_err = LDAP_OTHER;
 
440
                rs->sr_text = "DN index add failed";
 
441
                goto return_results;
 
442
        }
 
443
 
 
444
        /* modify entry */
 
445
        rs->sr_err = ndb_modify_internal( op, &NA2,
 
446
                &rs->sr_text, textbuf, textlen );
 
447
        if( rs->sr_err != LDAP_SUCCESS ) {
 
448
                Debug(LDAP_DEBUG_TRACE,
 
449
                        "<=- " LDAP_XSTRING(ndb_back_modrdn)
 
450
                        ": modify failed: %s (%d)\n",
 
451
                        NA.txn->getNdbError().message, NA.txn->getNdbError().code, 0 );
 
452
#if 0
 
453
                switch( rs->sr_err ) {
 
454
                case DB_LOCK_DEADLOCK:
 
455
                case DB_LOCK_NOTGRANTED:
 
456
                        goto retry;
 
457
                }
 
458
#endif
 
459
                goto return_results;
 
460
        }
 
461
 
 
462
        e.e_attrs = e2.e_attrs;
 
463
 
 
464
        if( op->o_postread ) {
 
465
                if( postread_ctrl == NULL ) {
 
466
                        postread_ctrl = &ctrls[num_ctrls++];
 
467
                        ctrls[num_ctrls] = NULL;
 
468
                }
 
469
                if( slap_read_controls( op, rs, &e2,
 
470
                        &slap_post_read_bv, postread_ctrl ) )
 
471
                {
 
472
                        Debug( LDAP_DEBUG_TRACE,
 
473
                                "<=- " LDAP_XSTRING(ndb_back_modrdn)
 
474
                                ": post-read failed!\n", 0, 0, 0 );
 
475
                        if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
 
476
                                /* FIXME: is it correct to abort
 
477
                                 * operation if control fails? */
 
478
                                goto return_results;
 
479
                        }
 
480
                }
 
481
        }
 
482
 
 
483
        if( op->o_noop ) {
 
484
                if (( rs->sr_err=NA.txn->execute( NdbTransaction::Rollback,
 
485
                        NdbOperation::AbortOnError, 1 )) != 0 ) {
 
486
                        rs->sr_text = "txn_abort (no-op) failed";
 
487
                } else {
 
488
                        rs->sr_err = LDAP_X_NO_OPERATION;
 
489
                }
 
490
        } else {
 
491
                if (( rs->sr_err=NA.txn->execute( NdbTransaction::Commit,
 
492
                        NdbOperation::AbortOnError, 1 )) != 0 ) {
 
493
                        rs->sr_text = "txn_commit failed";
 
494
                } else {
 
495
                        rs->sr_err = LDAP_SUCCESS;
 
496
                }
 
497
        }
 
498
 
 
499
        if( rs->sr_err != LDAP_SUCCESS && rs->sr_err != LDAP_X_NO_OPERATION ) {
 
500
                Debug( LDAP_DEBUG_TRACE,
 
501
                        LDAP_XSTRING(ndb_back_modrdn) ": txn_%s failed: %s (%d)\n",
 
502
                        op->o_noop ? "abort (no-op)" : "commit",
 
503
                        NA.txn->getNdbError().message, NA.txn->getNdbError().code );
 
504
                rs->sr_err = LDAP_OTHER;
 
505
                goto return_results;
 
506
        }
 
507
        NA.txn->close();
 
508
        NA.txn = NULL;
 
509
 
 
510
        Debug(LDAP_DEBUG_TRACE,
 
511
                LDAP_XSTRING(ndb_back_modrdn)
 
512
                ": rdn modified%s id=%08lx dn=\"%s\"\n",
 
513
                op->o_noop ? " (no-op)" : "",
 
514
                e.e_id, op->o_req_dn.bv_val );
 
515
 
 
516
        rs->sr_err = LDAP_SUCCESS;
 
517
        rs->sr_text = NULL;
 
518
        if( num_ctrls ) rs->sr_ctrls = ctrls;
 
519
 
 
520
return_results:
 
521
        if ( NA2.ocs ) {
 
522
                ber_bvarray_free_x( NA2.ocs, op->o_tmpmemctx );
 
523
                NA2.ocs = NULL;
 
524
        }
 
525
 
 
526
        if ( NA.ocs ) {
 
527
                ber_bvarray_free_x( NA.ocs, op->o_tmpmemctx );
 
528
                NA.ocs = NULL;
 
529
        }
 
530
 
 
531
        if ( e.e_attrs ) {
 
532
                attrs_free( e.e_attrs );
 
533
                e.e_attrs = NULL;
 
534
        }
 
535
 
 
536
        if( NA.txn != NULL ) {
 
537
                NA.txn->execute( Rollback );
 
538
                NA.txn->close();
 
539
        }
 
540
 
 
541
        send_ldap_result( op, rs );
 
542
        slap_graduate_commit_csn( op );
 
543
 
 
544
        if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
 
545
        if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val );
 
546
 
 
547
        if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
 
548
                slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
 
549
                slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
 
550
        }
 
551
        if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
 
552
                slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
 
553
                slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
 
554
        }
 
555
 
 
556
        rs->sr_text = NULL;
 
557
        return rs->sr_err;
 
558
}