~ubuntu-branches/debian/jessie/389-ds-base/jessie

« back to all changes in this revision

Viewing changes to ldap/servers/slapd/back-ldbm/ldbm_add.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2014-07-08 15:50:11 UTC
  • mfrom: (0.2.2)
  • Revision ID: package-import@ubuntu.com-20140708155011-r66lvtioamqwaype
Tags: 1.3.2.19-1
* New upstream release.
* admin_scripts.diff: Updated to fix more bashisms.
* watch: Update the url.
* Install failedbinds.py and logregex.py scripts.
* init: Use status from init-functions.
* control: Update my email.

Show diffs side-by-side

added added

removed removed

Lines of Context:
94
94
        char *msg;
95
95
        int     managedsait;
96
96
        int     ldap_result_code = LDAP_SUCCESS;
97
 
        char *ldap_result_message= NULL;
98
 
        char *ldap_result_matcheddn= NULL;
 
97
        char *ldap_result_message = NULL;
 
98
        char *ldap_result_matcheddn = NULL;
99
99
        int     retry_count = 0;
100
100
        int     disk_full = 0;
101
101
        modify_context parent_modify_c = {0};
103
103
        int parent_found = 0;
104
104
        int ruv_c_init = 0;
105
105
        int rc = 0;
106
 
        int addingentry_id_assigned= 0;
107
 
        int addingentry_in_cache= 0;
108
 
        int tombstone_in_cache= 0;
 
106
        int addingentry_id_assigned = 0;
 
107
        int addingentry_in_cache = 0;
 
108
        int tombstone_in_cache = 0;
109
109
        Slapi_DN *sdn = NULL;
110
110
        Slapi_DN parentsdn;
111
111
        Slapi_Operation *operation;
117
117
        CSN *opcsn = NULL;
118
118
        entry_address addr = {0};
119
119
        int not_an_error = 0;
 
120
        int parent_switched = 0;
 
121
        int noabort = 1;
120
122
 
121
123
        slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
122
124
        slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e );
193
195
                goto error_return;
194
196
        }
195
197
 
196
 
 
197
198
        /*
198
199
         * Originally (in the U-M LDAP 3.3 code), there was a comment near this
199
200
         * code about a race condition.  The race was that a 2nd entry could be
213
214
                if (txn.back_txn_txn && (txn.back_txn_txn != parent_txn)) {
214
215
                        /* Don't release SERIAL LOCK */
215
216
                        dblayer_txn_abort_ext(li, &txn, PR_FALSE); 
 
217
                        noabort = 1;
216
218
                        slapi_pblock_set(pb, SLAPI_TXN, parent_txn);
217
219
 
218
220
                        if (addingentry_in_cache) {
219
221
                                /* addingentry is in cache.  Remove it once. */
220
 
                                CACHE_REMOVE(&inst->inst_cache, addingentry);
 
222
                                retval = CACHE_REMOVE(&inst->inst_cache, addingentry);
 
223
                                if (retval) {
 
224
                                        LDAPDebug1Arg(LDAP_DEBUG_CACHE, "ldbm_add: cache_remove %s failed.\n",
 
225
                                                      slapi_entry_get_dn_const(addingentry->ep_entry));
 
226
                                }
221
227
                                CACHE_RETURN(&inst->inst_cache, &addingentry);
222
228
                        } else {
223
229
                                backentry_free(&addingentry);
230
236
                        }
231
237
                        if (addingentry_in_cache) {
232
238
                                /* Adding the resetted addingentry to the cache. */
233
 
                                if (cache_add_tentative(&inst->inst_cache,
234
 
                                                        addingentry, NULL) != 0) {
235
 
                                        LDAPDebug0Args(LDAP_DEBUG_CACHE,
236
 
                                                      "cache_add_tentative concurrency detected\n");
 
239
                                if (cache_add_tentative(&inst->inst_cache, addingentry, NULL) != 0) {
 
240
                                        LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
 
241
                                                      slapi_entry_get_dn_const(addingentry->ep_entry));
237
242
                                        ldap_result_code = LDAP_ALREADY_EXISTS;
 
243
                                        addingentry_in_cache = 0;
238
244
                                        goto error_return;
239
245
                                }
240
246
                        }
259
265
                if (0 == retry_count) {
260
266
                        /* First time, hold SERIAL LOCK */
261
267
                        retval = dblayer_txn_begin(be, parent_txn, &txn);
 
268
                        noabort = 0;
262
269
 
263
270
                        if (!is_tombstone_operation) {
264
271
                                rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY);
305
312
                                                }
306
313
                                        }
307
314
 
 
315
                                        /* 
 
316
                                         * If the parent is conflict, slapi_sdn_get_backend_parent does not support it.
 
317
                                         * That is, adding children to a conflict entry is not allowed.
 
318
                                         */
308
319
                                        slapi_sdn_get_backend_parent(sdn, &parentsdn, pb->pb_backend);
309
320
                                        /* Check if an entry with the intended DN already exists. */
310
321
                                        done_with_pblock_entry(pb,SLAPI_ADD_EXISTING_DN_ENTRY); /* Could be through this multiple times */
312
323
                                        addr.udn = NULL;
313
324
                                        addr.uniqueid = NULL;
314
325
                                        ldap_result_code= get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_EXISTING_DN_ENTRY, !is_replicated_operation);
315
 
                                        if(ldap_result_code==LDAP_OPERATIONS_ERROR ||
316
 
                                           ldap_result_code==LDAP_INVALID_DN_SYNTAX)
317
 
                                        {
 
326
                                        if(ldap_result_code==LDAP_OPERATIONS_ERROR || ldap_result_code==LDAP_INVALID_DN_SYNTAX) {
318
327
                                            goto error_return;
319
328
                                        }
320
329
                                }
321
330
                                /* if we can find the parent by dn or uniqueid, and the operation has requested the parent
322
331
                                   then get it */
323
 
                                if(have_parent_address(&parentsdn, operation->o_params.p.p_add.parentuniqueid) &&
324
 
                                   slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY))
325
 
                                {
 
332
                                if (have_parent_address(&parentsdn, operation->o_params.p.p_add.parentuniqueid) &&
 
333
                                    slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY)) {
326
334
                                        done_with_pblock_entry(pb,SLAPI_ADD_PARENT_ENTRY); /* Could be through this multiple times */
327
335
                                        addr.sdn = &parentsdn;
328
336
                                        addr.udn = NULL;
329
337
                                        addr.uniqueid = operation->o_params.p.p_add.parentuniqueid;
330
 
                                        ldap_result_code= get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_PARENT_ENTRY, !is_replicated_operation);
331
 
                                        /* need to set parentsdn or parentuniqueid if either is not set? */
 
338
                                        ldap_result_code = get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_PARENT_ENTRY, !is_replicated_operation);
332
339
                                }
333
340
 
334
341
                                /* Call the Backend Pre Add plugins */
 
342
                                ldap_result_code = LDAP_SUCCESS;
335
343
                                slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
336
 
                                rc= plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_ADD_FN);
 
344
                                rc = plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_ADD_FN);
337
345
                                if (rc < 0) {
338
346
                                        int opreturn = 0;
339
347
                                        if (SLAPI_PLUGIN_NOOP == rc) {
379
387
                        ldap_result_code= LDAP_OPERATIONS_ERROR;
380
388
                        goto error_return; 
381
389
                }
 
390
                noabort = 0;
382
391
 
383
392
                /* stash the transaction for plugins */
384
393
                slapi_pblock_set(pb, SLAPI_TXN, txn.back_txn_txn);
401
410
                                                operation->o_params.p.p_add.parentuniqueid = 
402
411
                                                    slapi_ch_strdup(slapi_entry_get_uniqueid(parententry->ep_entry));
403
412
                                        }
404
 
                                        if (slapi_sdn_isempty(&parentsdn)) {
 
413
                                        if (slapi_sdn_isempty(&parentsdn) || 
 
414
                                            slapi_sdn_compare(&parentsdn, slapi_entry_get_sdn(parententry->ep_entry))) {
405
415
                                                /* Set the parentsdn now */
406
416
                                                slapi_sdn_set_dn_byval(&parentsdn, slapi_entry_get_dn_const(parententry->ep_entry));
407
417
                                        }
 
418
                                } else {
 
419
                                        LDAPDebug(LDAP_DEBUG_BACKLDBM, "find_entry2modify_only returned NULL parententry pdn: %s, uniqueid: %s\n",
 
420
                                                  slapi_sdn_get_dn(&parentsdn), slapi_sdn_get_dn(&parentsdn), addr.uniqueid?addr.uniqueid:"none");
408
421
                                }
409
422
                                modify_init(&parent_modify_c,parententry);
410
423
                        }
412
425
                        /* Check if the entry we have been asked to add already exists */
413
426
                        {
414
427
                                Slapi_Entry *entry;
415
 
                                slapi_pblock_get( pb, SLAPI_ADD_EXISTING_DN_ENTRY, &entry);
416
 
                                if ( entry != NULL )
417
 
                                {
418
 
                                        /* The entry already exists */ 
419
 
                                        ldap_result_code= LDAP_ALREADY_EXISTS;
 
428
                                slapi_pblock_get(pb, SLAPI_ADD_EXISTING_DN_ENTRY, &entry);
 
429
                                if (entry) {
 
430
                                        if (is_resurect_operation) {
 
431
                                                Slapi_Entry *uniqentry;
 
432
                                                slapi_pblock_get(pb, SLAPI_ADD_EXISTING_UNIQUEID_ENTRY, &uniqentry);
 
433
                                                if (uniqentry == entry) { 
 
434
                                                        /* 
 
435
                                                         * adding entry having the uniqueid exists.
 
436
                                                         * No need to resurrect.
 
437
                                                         */ 
 
438
                                                        ldap_result_code = LDAP_SUCCESS;
 
439
                                                } else {
 
440
                                                        /* The entry having the DN already exists */
 
441
                                                        if (uniqentry) {
 
442
                                                                if (PL_strcmp(slapi_entry_get_uniqueid(entry),
 
443
                                                                              slapi_entry_get_uniqueid(uniqentry))) {
 
444
                                                                        /* Not match; conflict. */
 
445
                                                                        ldap_result_code = LDAP_ALREADY_EXISTS;
 
446
                                                                } else {
 
447
                                                                        /* Same entry; no need to resurrect. */
 
448
                                                                        ldap_result_code = LDAP_SUCCESS;
 
449
                                                                }
 
450
                                                        } else {
 
451
                                                                ldap_result_code = LDAP_ALREADY_EXISTS;
 
452
                                                        }
 
453
                                                }
 
454
                                        } else {
 
455
                                                /* The entry already exists */ 
 
456
                                                ldap_result_code = LDAP_ALREADY_EXISTS;
 
457
                                        }
420
458
                                        goto error_return;
421
459
                                } 
422
460
                                else 
427
465
                                         * entry we did match has a referral we should return
428
466
                                         * instead. we do this only if managedsait is not on.
429
467
                                         */
430
 
                                        if ( !managedsait && !is_tombstone_operation )
 
468
                                        if (!managedsait && !is_tombstone_operation && !is_resurect_operation)
431
469
                                        {
432
470
                                                int err= 0;
433
471
                                                Slapi_DN ancestorsdn;
437
475
                                                slapi_sdn_done(&ancestorsdn);
438
476
                                                if ( ancestorentry != NULL )
439
477
                                                {
440
 
                                                        int sentreferral = 
441
 
                                                            check_entry_for_referral(pb, ancestorentry->ep_entry,
442
 
                                                                                     backentry_get_ndn(ancestorentry), "ldbm_back_add");
 
478
                                                        int sentreferral= check_entry_for_referral(pb, ancestorentry->ep_entry, backentry_get_ndn(ancestorentry), "ldbm_back_add");
443
479
                                                        CACHE_RETURN( &inst->inst_cache, &ancestorentry );
444
480
                                                        if(sentreferral)
445
481
                                                        {
452
488
                        }
453
489
 
454
490
                        /* no need to check the schema as this is a replication add */
455
 
                        if(!is_replicated_operation){
 
491
                        if (!is_replicated_operation) {
456
492
                                if ((operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK))
457
493
                                     && (slapi_entry_schema_check(pb, e) != 0))
458
 
                        {
459
 
                                LDAPDebug(LDAP_DEBUG_TRACE, "entry failed schema check\n", 0, 0, 0);
460
 
                                ldap_result_code = LDAP_OBJECT_CLASS_VIOLATION;
461
 
                                slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
462
 
                                goto error_return;
463
 
                        }
 
494
                                {
 
495
                                        LDAPDebug(LDAP_DEBUG_TRACE, "entry failed schema check\n", 0, 0, 0);
 
496
                                        ldap_result_code = LDAP_OBJECT_CLASS_VIOLATION;
 
497
                                        slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
 
498
                                        goto error_return;
 
499
                                }
464
500
 
465
 
                        /* Check attribute syntax */
466
 
                        if (slapi_entry_syntax_check(pb, e, 0) != 0)
467
 
                        {
468
 
                                LDAPDebug(LDAP_DEBUG_TRACE, "entry failed syntax check\n", 0, 0, 0);
469
 
                                ldap_result_code = LDAP_INVALID_SYNTAX;
470
 
                                slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
471
 
                                goto error_return;
 
501
                                /* Check attribute syntax */
 
502
                                if (slapi_entry_syntax_check(pb, e, 0) != 0)
 
503
                                {
 
504
                                        LDAPDebug(LDAP_DEBUG_TRACE, "entry failed syntax check\n", 0, 0, 0);
 
505
                                        ldap_result_code = LDAP_INVALID_SYNTAX;
 
506
                                        slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
 
507
                                        goto error_return;
 
508
                                }
472
509
                        }
473
 
                }
474
510
 
475
511
                        opcsn = operation_get_csn (operation);
476
512
                        if(is_resurect_operation)
487
523
                                if ( tombstoneentry==NULL )
488
524
                                {
489
525
                                        ldap_result_code= -1;
490
 
                                        goto error_return;        /* error result sent by find_entry2modify() */
 
526
                                        goto error_return;  /* error result sent by find_entry2modify() */
491
527
                                }
492
528
                                tombstone_in_cache = 1;
493
529
 
506
542
                                 */
507
543
                                if (NULL == sdn) {
508
544
                                        LDAPDebug0Args(LDAP_DEBUG_ANY, "ldbm_back_add: Null target dn\n");
 
545
                                        ldap_result_code = LDAP_OPERATIONS_ERROR;
509
546
                                        goto error_return;
510
547
                                }
511
548
                                dn = slapi_sdn_get_dn(sdn);
512
549
                                slapi_entry_set_sdn(addingentry->ep_entry, sdn); /* The DN is passed into the entry. */
 
550
                                /* not just e_sdn, e_rsdn needs to be updated. */
 
551
                                slapi_rdn_set_all_dn(slapi_entry_get_srdn(addingentry->ep_entry),
 
552
                                slapi_entry_get_dn_const(addingentry->ep_entry));
513
553
                                /* LPREPL: the DN is normalized...Somehow who should get a not normalized one */
514
554
                                addingentry->ep_id = slapi_entry_attr_get_ulong(addingentry->ep_entry,"entryid");
515
555
                                slapi_entry_attr_delete(addingentry->ep_entry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID);
673
713
                                        Slapi_DN ancestorsdn;
674
714
                                        struct backentry *ancestorentry;
675
715
 
676
 
                                        LDAPDebug( LDAP_DEBUG_TRACE,
677
 
                                                "parent does not exist, pdn = %s\n",
678
 
                                                slapi_sdn_get_dn(&parentsdn), 0, 0 );
679
 
 
 
716
                                        LDAPDebug1Arg(LDAP_DEBUG_BACKLDBM, "ldbm_add: Parent \"%s\" does not exist. "
 
717
                                                      "It might be a conflict entry.\n", slapi_sdn_get_dn(&parentsdn));
680
718
                                        slapi_sdn_init(&ancestorsdn);
681
719
                                        ancestorentry = dn2ancestor(be, &parentsdn, &ancestorsdn, &txn, &err );
682
720
                                        CACHE_RETURN( &inst->inst_cache, &ancestorentry );
687
725
                                        slapi_sdn_done(&ancestorsdn);
688
726
                                        goto error_return;
689
727
                                }
690
 
                                ldap_result_code = plugin_call_acl_plugin (pb, e, NULL, NULL, SLAPI_ACL_ADD, 
691
 
                                                                ACLPLUGIN_ACCESS_DEFAULT, &errbuf );
 
728
                                ldap_result_code = plugin_call_acl_plugin(pb, e, NULL, NULL, SLAPI_ACL_ADD, 
 
729
                                                                          ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
692
730
                                if ( ldap_result_code != LDAP_SUCCESS )
693
731
                                {
694
 
                                        LDAPDebug( LDAP_DEBUG_TRACE, "no access to parent\n", 0, 0, 0 );
 
732
                                        LDAPDebug1Arg(LDAP_DEBUG_TRACE, "no access to parent, pdn = %s\n",
 
733
                                                      slapi_sdn_get_dn(&parentsdn));
695
734
                                        ldap_result_message= errbuf;
696
735
                                        goto error_return;
697
736
                                }
698
737
                                pid = parententry->ep_id;
 
738
 
 
739
                                /* We may need to adjust the DN since parent could be a resrected conflict entry... */
 
740
                                if (!slapi_sdn_isparent(slapi_entry_get_sdn_const(parententry->ep_entry),
 
741
                                                        slapi_entry_get_sdn_const(addingentry->ep_entry))) {
 
742
                                        Slapi_DN adjustedsdn = {0};
 
743
                                        char *adjusteddn = slapi_ch_smprintf("%s,%s", 
 
744
                                                                             slapi_entry_get_rdn_const(addingentry->ep_entry),
 
745
                                                                             slapi_entry_get_dn_const(parententry->ep_entry));
 
746
                                        LDAPDebug2Args(LDAP_DEBUG_BACKLDBM, "ldbm_add: adjusting dn: %s --> %s\n",
 
747
                                                       slapi_entry_get_dn(addingentry->ep_entry), adjusteddn);
 
748
                                        slapi_sdn_set_normdn_passin(&adjustedsdn, adjusteddn);
 
749
                                        slapi_entry_set_sdn(addingentry->ep_entry, &adjustedsdn);
 
750
                                        /* not just e_sdn, e_rsdn needs to be updated. */
 
751
                                        slapi_rdn_set_all_dn(slapi_entry_get_srdn(addingentry->ep_entry), adjusteddn);
 
752
                                        slapi_sdn_done(&adjustedsdn);
 
753
                                }
699
754
                        }
700
755
                        else
701
756
                        {       /* no parent */
702
 
                                if ( !isroot && !is_replicated_operation)
703
 
                                {
704
 
                                        LDAPDebug( LDAP_DEBUG_TRACE, "no parent & not root\n",
705
 
                                                0, 0, 0 );
 
757
                                if (!isroot && !is_replicated_operation) {
 
758
                                        LDAPDebug0Args(LDAP_DEBUG_TRACE, "no parent & not root\n");
706
759
                                        ldap_result_code= LDAP_INSUFFICIENT_ACCESS;
707
760
                                        goto error_return;
708
761
                                }
731
784
                         * operational attributes to ensure that the cache is sized correctly. */
732
785
                        if ( cache_add_tentative( &inst->inst_cache, addingentry, NULL )!= 0 )
733
786
                        {
734
 
                                LDAPDebug( LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected\n", 0, 0, 0 );
 
787
                                LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
 
788
                                              slapi_entry_get_dn_const(addingentry->ep_entry));
735
789
                                ldap_result_code= LDAP_ALREADY_EXISTS;
736
790
                                goto error_return;
737
791
                        }
738
 
                        addingentry_in_cache= 1;
 
792
                        addingentry_in_cache = 1;
739
793
 
740
794
                        /*
741
795
                         * Before we add the entry, find out if the syntax of the aci
743
797
                         * the entry if the syntax is incorrect.
744
798
                         */
745
799
                        if ( plugin_call_acl_verify_syntax (pb, addingentry->ep_entry, &errbuf) != 0 ) {
746
 
                                LDAPDebug( LDAP_DEBUG_TRACE, "ACL syntax error\n", 0,0,0);
 
800
                                LDAPDebug1Arg(LDAP_DEBUG_TRACE, "ACL syntax error: %s\n",
 
801
                                              slapi_entry_get_dn_const(addingentry->ep_entry));
747
802
                                ldap_result_code= LDAP_INVALID_SYNTAX;
748
803
                                ldap_result_message= errbuf;
749
804
                                goto error_return;
752
807
                        /* Having decided that we're really going to do the operation, let's modify 
753
808
                           the in-memory state of the parent to reflect the new child (update
754
809
                           subordinate count specifically */
755
 
                        if (NULL != parententry)
756
 
                        {
 
810
                        if (parententry) {
757
811
                                retval = parent_update_on_childchange(&parent_modify_c,
758
 
                                                                      PARENTUPDATE_ADD, NULL);
 
812
                                                                      is_resurect_operation?PARENTUPDATE_RESURECT:PARENTUPDATE_ADD,
 
813
                                                                      NULL);
759
814
                                /* The modify context now contains info needed later */
760
 
                                if (0 != retval) {
 
815
                                if (retval) {
 
816
                                        LDAPDebug2Args(LDAP_DEBUG_BACKLDBM, "parent_update_on_childchange: %s, rc=%d\n",
 
817
                                                       slapi_entry_get_dn_const(addingentry->ep_entry), retval);
761
818
                                        ldap_result_code= LDAP_OPERATIONS_ERROR;
762
819
                                        goto error_return;
763
820
                                }
780
837
                                not_an_error = 1;
781
838
                                rc = retval = LDAP_SUCCESS;
782
839
                        }
783
 
                        LDAPDebug1Arg( LDAP_DEBUG_TRACE, "SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN plugin "
784
 
                                       "returned error code %d\n", retval );
 
840
                        LDAPDebug1Arg(LDAP_DEBUG_TRACE, "SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN plugin "
 
841
                                      "returned error code %d\n", retval );
785
842
                        if (!ldap_result_code) {
786
843
                                slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code);
787
844
                        }
788
845
                        if (!ldap_result_code) {
789
 
                                LDAPDebug0Args( LDAP_DEBUG_ANY, "SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN plugin "
790
 
                                                "returned error but did not setSLAPI_RESULT_CODE \n" );
791
846
                                ldap_result_code = LDAP_OPERATIONS_ERROR;
792
847
                                slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
793
848
                        }
796
851
                                slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
797
852
                        }
798
853
                        slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
 
854
                        LDAPDebug1Arg(LDAP_DEBUG_ANY, "SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN plugin failed: %d\n",
 
855
                                      ldap_result_code ? ldap_result_code : retval);
799
856
                        goto error_return;
800
857
                }
801
858
 
806
863
                        /* Retry txn */
807
864
                        continue;
808
865
                }
809
 
                if (retval != 0) {
810
 
                        LDAPDebug( LDAP_DEBUG_TRACE, "id2entry_add failed, err=%d %s\n",
811
 
                                   retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
 
866
                if (retval) {
 
867
                        LDAPDebug(LDAP_DEBUG_TRACE, "id2entry_add(%s) failed, err=%d %s\n",
 
868
                                  slapi_entry_get_dn_const(addingentry->ep_entry),
 
869
                                  retval, (msg = dblayer_strerror( retval )) ? msg : "");
812
870
                        ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
813
871
                        if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
814
872
                                disk_full = 1;
816
874
                        }
817
875
                        goto error_return; 
818
876
                }
819
 
                if(is_resurect_operation)
820
 
                {
 
877
                if (is_resurect_operation) {
821
878
                        retval = index_addordel_string(be,SLAPI_ATTR_OBJECTCLASS,SLAPI_ATTR_VALUE_TOMBSTONE,addingentry->ep_id,BE_INDEX_DEL|BE_INDEX_EQUALITY,&txn);
822
879
                        if (DB_LOCK_DEADLOCK == retval) {
823
880
                                LDAPDebug( LDAP_DEBUG_ARGS, "add 2 DB_LOCK_DEADLOCK\n", 0, 0, 0 );
824
881
                                /* Retry txn */
825
882
                                continue;
826
883
                        }
827
 
                        if (0 != retval) {
828
 
                                LDAPDebug( LDAP_DEBUG_TRACE, "add 1 BAD, err=%d %s\n",
829
 
                                           retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
830
 
                                ADD_SET_ERROR(ldap_result_code, 
831
 
                                                          LDAP_OPERATIONS_ERROR, retry_count);
 
884
                        if (retval) {
 
885
                                LDAPDebug(LDAP_DEBUG_TRACE, "index_addordel_string TOMBSTONE (%s), err=%d %s\n",
 
886
                                          slapi_entry_get_dn_const(addingentry->ep_entry),
 
887
                                          retval, (msg = dblayer_strerror( retval )) ? msg : "");
 
888
                                ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
832
889
                                if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
833
890
                                        disk_full = 1;
834
891
                                        goto diskfull_return;
842
899
                                continue;
843
900
                        }
844
901
                        if (0 != retval) {
845
 
                                LDAPDebug( LDAP_DEBUG_TRACE, "add 2 BAD, err=%d %s\n",
846
 
                                           retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
847
 
                                ADD_SET_ERROR(ldap_result_code, 
848
 
                                                          LDAP_OPERATIONS_ERROR, retry_count);
 
902
                                LDAPDebug(LDAP_DEBUG_TRACE, "index_addordel_string UNIQUEID (%s), err=%d %s\n",
 
903
                                          slapi_entry_get_dn_const(addingentry->ep_entry),
 
904
                                          retval, (msg = dblayer_strerror( retval )) ? msg : "");
 
905
                                ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
849
906
                                if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
850
907
                                        disk_full = 1;
851
908
                                        goto diskfull_return;
863
920
                                continue;
864
921
                        }
865
922
                        if (0 != retval) {
866
 
                                LDAPDebug( LDAP_DEBUG_TRACE, "add 3 BAD, err=%d %s\n",
867
 
                                           retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
868
 
                                ADD_SET_ERROR(ldap_result_code, 
869
 
                                                          LDAP_OPERATIONS_ERROR, retry_count);
 
923
                                LDAPDebug(LDAP_DEBUG_TRACE, "index_addordel_string ENTRYDN (%s), err=%d %s\n",
 
924
                                          slapi_entry_get_dn_const(addingentry->ep_entry),
 
925
                                          retval, (msg = dblayer_strerror( retval )) ? msg : "");
 
926
                                ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
870
927
                                if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
871
928
                                        disk_full = 1;
872
929
                                        goto diskfull_return;
873
930
                                }
874
931
                                goto error_return; 
875
932
                        }
876
 
                } 
 
933
                        /* Need to delete the entryrdn index of the resurrected tombstone... */
 
934
                        if (entryrdn_get_switch()) { /* subtree-rename: on */
 
935
                                if (tombstoneentry) {
 
936
                                        retval = entryrdn_index_entry(be, tombstoneentry, BE_INDEX_DEL, &txn);
 
937
                                        if (retval) {
 
938
                                                LDAPDebug(LDAP_DEBUG_ANY, "Resurrecting %s: failed to remove entryrdn index, err=%d %s\n",
 
939
                                                          slapi_entry_get_dn_const(tombstoneentry->ep_entry),
 
940
                                                          retval, (msg = dblayer_strerror( retval )) ? msg : "");
 
941
                                                goto error_return; 
 
942
                                        }
 
943
                                }
 
944
                        }
 
945
                }
877
946
                if (is_tombstone_operation)
878
947
                {
879
948
                        retval = index_addordel_entry( be, addingentry, BE_INDEX_ADD | BE_INDEX_TOMBSTONE, &txn );
888
957
                        /* retry txn */
889
958
                        continue;
890
959
                }
891
 
                if (retval != 0) {
892
 
                        LDAPDebug2Args(LDAP_DEBUG_ANY,
893
 
                                       "add: attempt to index %lu failed (rc=%d)\n",
 
960
                if (retval) {
 
961
                        LDAPDebug2Args(LDAP_DEBUG_ANY, "add: attempt to index %lu failed; rc=%d\n",
894
962
                                       (u_long)addingentry->ep_id, retval);
895
963
                        ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
896
964
                        if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
908
976
                                /* Retry txn */
909
977
                                continue;
910
978
                        }
911
 
                        if (0 != retval) {
912
 
                                LDAPDebug( LDAP_DEBUG_TRACE, "add 1 BAD, err=%d %s\n",
913
 
                                           retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
914
 
                                ADD_SET_ERROR(ldap_result_code, 
915
 
                                                          LDAP_OPERATIONS_ERROR, retry_count);
 
979
                        if (retval) {
 
980
                                LDAPDebug(LDAP_DEBUG_BACKLDBM, "modify_update_all: %s (%lu) failed; rc=%d\n",
 
981
                                          slapi_entry_get_dn(addingentry->ep_entry), (u_long)addingentry->ep_id, retval);
 
982
                                ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
916
983
                                if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
917
984
                                        disk_full = 1;
918
985
                                        goto diskfull_return;
927
994
                {
928
995
                        retval= vlv_update_all_indexes(&txn, be, pb, NULL, addingentry);
929
996
                        if (DB_LOCK_DEADLOCK == retval) {
930
 
                                LDAPDebug( LDAP_DEBUG_ARGS,
931
 
                                                                "add DEADLOCK vlv_update_index\n", 0, 0, 0 );
 
997
                                LDAPDebug(LDAP_DEBUG_ARGS,
 
998
                                          "add DEADLOCK vlv_update_index\n", 0, 0, 0 );
932
999
                                /* Retry txn */
933
1000
                                continue;
934
1001
                        }
935
 
                        if (0 != retval) {
936
 
                                LDAPDebug( LDAP_DEBUG_TRACE,
937
 
                                        "vlv_update_index failed, err=%d %s\n",
938
 
                                        retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
939
 
                                ADD_SET_ERROR(ldap_result_code, 
940
 
                                                          LDAP_OPERATIONS_ERROR, retry_count);
 
1002
                        if (retval) {
 
1003
                                LDAPDebug2Args(LDAP_DEBUG_TRACE,
 
1004
                                               "vlv_update_index failed, err=%d %s\n",
 
1005
                                               retval, (msg = dblayer_strerror( retval )) ? msg : "");
 
1006
                                ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
941
1007
                                if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
942
1008
                                        disk_full = 1;
943
1009
                                        goto diskfull_return;
983
1049
        if (retry_count == RETRY_TIMES) {
984
1050
                /* Failed */
985
1051
                LDAPDebug( LDAP_DEBUG_ANY, "Retry count exceeded in add\n", 0, 0, 0 );
986
 
                ldap_result_code= LDAP_BUSY;
 
1052
                ldap_result_code= LDAP_BUSY;
987
1053
                goto error_return;
988
1054
        }
989
1055
 
994
1060
        slapi_pblock_set( pb, SLAPI_ENTRY_PRE_OP, NULL );
995
1061
        slapi_pblock_set( pb, SLAPI_ENTRY_POST_OP, slapi_entry_dup( addingentry->ep_entry ));
996
1062
 
997
 
        if(is_resurect_operation)
998
 
        {
 
1063
        if (is_resurect_operation) {
999
1064
                /*
1000
1065
                 * We can now switch the tombstone entry with the real entry.
1001
1066
                 */
1002
 
                if (cache_replace( &inst->inst_cache, tombstoneentry, addingentry ) != 0 )
1003
 
                {
 
1067
                retval = cache_replace(&inst->inst_cache, tombstoneentry, addingentry);
 
1068
                if (retval) {
1004
1069
                        /* This happens if the dn of addingentry already exists */
1005
 
                        cache_unlock_entry( &inst->inst_cache, tombstoneentry );
1006
1070
                        ADD_SET_ERROR(ldap_result_code, LDAP_ALREADY_EXISTS, retry_count);
 
1071
                        LDAPDebug2Args(LDAP_DEBUG_CACHE, "ldap_add: cache_replace concurrency detected: %s (rc: %d)\n",
 
1072
                                       slapi_entry_get_dn_const(addingentry->ep_entry), retval);
 
1073
                        retval = -1;
1007
1074
                        goto error_return;
1008
1075
                }
 
1076
                if (addingentry_in_cache) { /* decrease the refcnt added by tentative */
 
1077
                        CACHE_RETURN( &inst->inst_cache, &addingentry );
 
1078
                }
 
1079
                addingentry_in_cache = 1; /* reset it to make it sure... */
1009
1080
                /*
1010
1081
                 * The tombstone was locked down in the cache... we can
1011
1082
                 * get rid of the entry in the cache now.
 
1083
                 * We cannot expect tombstoneentry exists from now on.
1012
1084
                 */
1013
 
                cache_unlock_entry( &inst->inst_cache, tombstoneentry );
1014
 
                CACHE_RETURN( &inst->inst_cache, &tombstoneentry );
1015
 
                tombstone_in_cache = 0; /* deleted */
 
1085
                if (entryrdn_get_switch()) { /* subtree-rename: on */
 
1086
                        /* since the op was successful, delete the tombstone dn from the dn cache */
 
1087
                        struct backdn *bdn = dncache_find_id(&inst->inst_dncache,
 
1088
                                                             tombstoneentry->ep_id);
 
1089
                        if (bdn) { /* in the dncache, remove it. */
 
1090
                                CACHE_REMOVE(&inst->inst_dncache, bdn);
 
1091
                                CACHE_RETURN(&inst->inst_dncache, &bdn);
 
1092
                        }
 
1093
                }
 
1094
                cache_unlock_entry(&inst->inst_cache, tombstoneentry);
 
1095
                CACHE_RETURN(&inst->inst_cache, &tombstoneentry);
 
1096
                tombstone_in_cache = 0;
1016
1097
        }
1017
1098
        if (parent_found)
1018
1099
        {
1019
1100
                /* switch the parent entry copy into play */
1020
 
                modify_switch_entries( &parent_modify_c,be);
 
1101
                modify_switch_entries(&parent_modify_c,be);
 
1102
                parent_switched = 1;
1021
1103
        }
1022
1104
 
1023
1105
        if (ruv_c_init) {
1024
1106
                if (modify_switch_entries(&ruv_c, be) != 0 ) {
1025
1107
                        ldap_result_code= LDAP_OPERATIONS_ERROR;
1026
 
                        LDAPDebug( LDAP_DEBUG_ANY,
1027
 
                                "ldbm_back_add: modify_switch_entries failed\n", 0, 0, 0);
 
1108
                        LDAPDebug0Args(LDAP_DEBUG_ANY,
 
1109
                                       "ldbm_back_add: modify_switch_entries failed\n");
1028
1110
                        goto error_return;
1029
1111
                }
1030
1112
        }
1038
1120
                        slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code);
1039
1121
                }
1040
1122
                if (!ldap_result_code) {
1041
 
                        LDAPDebug0Args( LDAP_DEBUG_ANY, "SLAPI_PLUGIN_BE_TXN_POST_ADD_FN plugin "
1042
 
                                        "returned error but did not set SLAPI_RESULT_CODE\n" );
1043
1123
                        ldap_result_code = LDAP_OPERATIONS_ERROR;
1044
1124
                        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
1045
1125
                }
1064
1144
                }
1065
1145
                goto error_return; 
1066
1146
        }
 
1147
        noabort = 1;
1067
1148
 
1068
1149
        rc= 0;
1069
1150
        goto common_return;
1073
1154
        {
1074
1155
                next_id_return( be, addingentry->ep_id );
1075
1156
        }
1076
 
        if ( NULL != addingentry )
 
1157
        if ( addingentry )
1077
1158
        {
1078
1159
                if ( addingentry_in_cache )
1079
1160
                {
1080
1161
                        if (inst) {
1081
1162
                                CACHE_REMOVE(&inst->inst_cache, addingentry);
1082
 
                        }
1083
 
                        addingentry_in_cache = 0;
1084
 
                }
1085
 
                backentry_clear_entry(addingentry); /* e is released in the frontend */
1086
 
                backentry_free( &addingentry ); /* release the backend wrapper, here */
1087
 
        }
1088
 
        if(tombstone_in_cache && inst)
1089
 
        {
1090
 
                CACHE_RETURN(&inst->inst_cache, &tombstoneentry);
1091
 
        }
1092
 
 
 
1163
                                /* tell frontend not to free this entry */
 
1164
                                slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
 
1165
                        }
 
1166
                }
 
1167
                else
 
1168
                {
 
1169
                        if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */
 
1170
                                backentry_clear_entry(addingentry); /* e is released in the frontend */
 
1171
                        }
 
1172
                        backentry_free( &addingentry ); /* release the backend wrapper, here */
 
1173
                }
 
1174
        }
1093
1175
        if (rc == DB_RUNRECOVERY) {
1094
1176
                dblayer_remember_disk_filled(li);
1095
1177
                ldbm_nasty("Add",80,rc);
1097
1179
        } else if (0 == rc) {
1098
1180
                rc = SLAPI_FAIL_GENERAL;
1099
1181
        }
 
1182
        if (parent_switched){
 
1183
                /*
 
1184
                 * Restore the old parent entry, switch the new with the original.
 
1185
                 * Otherwise the numsubordinate count will be off, and could later
 
1186
                 * be written to disk.
 
1187
                 */
 
1188
                modify_unswitch_entries( &parent_modify_c,be);
 
1189
        }
1100
1190
diskfull_return:
1101
1191
        if (disk_full) {
1102
 
                rc= return_on_disk_full(li);
 
1192
                rc = return_on_disk_full(li);
1103
1193
        } else {
1104
1194
                /* It is safer not to abort when the transaction is not started. */
1105
1195
                if (txn.back_txn_txn && (txn.back_txn_txn != parent_txn)) {
1130
1220
                                        opreturn = -1;
1131
1221
                                        slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &opreturn);
1132
1222
                                }
 
1223
                                if (addingentry_in_cache && addingentry && inst) {
 
1224
                                        CACHE_REMOVE(&inst->inst_cache, addingentry);
 
1225
                                        /* tell frontend not to free this entry */
 
1226
                                        slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
 
1227
                                }
 
1228
 
 
1229
                                slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
1133
1230
                        }
1134
1231
 
1135
1232
                        /* Release SERIAL LOCK */
1136
 
                        dblayer_txn_abort(be, &txn); /* abort crashes in case disk full */
 
1233
                        if (!noabort) {
 
1234
                                dblayer_txn_abort(be, &txn); /* abort crashes in case disk full */
 
1235
                        }
1137
1236
                        /* txn is no longer valid - reset the txn pointer to the parent */
1138
1237
                        slapi_pblock_set(pb, SLAPI_TXN, parent_txn);
1139
1238
                }
1144
1243
        
1145
1244
common_return:
1146
1245
        if (inst) {
 
1246
                if(tombstone_in_cache && tombstoneentry) {
 
1247
                        cache_unlock_entry(&inst->inst_cache, tombstoneentry);
 
1248
                        CACHE_RETURN(&inst->inst_cache, &tombstoneentry);
 
1249
                }
1147
1250
                if (addingentry_in_cache && addingentry) {
1148
 
                        if (entryrdn_get_switch()) { /* subtree-rename: on */
 
1251
                        if ((0 == retval) && entryrdn_get_switch()) { /* subtree-rename: on */
1149
1252
                                /* since adding the entry to the entry cache was successful,
1150
1253
                                 * let's add the dn to dncache, if not yet done. */
1151
1254
                                struct backdn *bdn = dncache_find_id(&inst->inst_dncache,