Blame SOURCES/0052-Ticket-47622-Automember-betxnpreoperation-transactio.patch

cc3dff
From e5cb97a16fa44e6944e234b9cf509ddb614559a3 Mon Sep 17 00:00:00 2001
cc3dff
From: Mark Reynolds <mreynolds@redhat.com>
cc3dff
Date: Mon, 9 Dec 2013 16:57:35 -0500
cc3dff
Subject: [PATCH 52/65] Ticket 47622 - Automember betxnpreoperation -
cc3dff
 transaction not aborted when group entry does not exist
cc3dff
cc3dff
Bug Description:  If the group defined in the automember plugin does not exist, than any add operation
cc3dff
                  that should trigger an update, succeeds even though the automember update failed.
cc3dff
cc3dff
Fix Description:  Return an error if a automember post operation update fails - previously we always
cc3dff
                  returned success.
cc3dff
cc3dff
                  Updated plugin_call_func() to check the result of betxn postop plugins.
cc3dff
cc3dff
                  Also added return text to the result message when a betxn plugin fails.  This is
cc3dff
                  useful for clients to explain why the operation failed.
cc3dff
cc3dff
https://fedorahosted.org/389/ticket/47622
cc3dff
cc3dff
Jenkins: passed
cc3dff
Valgrind: passed
cc3dff
Coverity: passed
cc3dff
cc3dff
Reviewed by: rmeggins(Thanks!)
cc3dff
(cherry picked from commit 1214168a222a35627b2bb9964600fad0246558cd)
cc3dff
(cherry picked from commit 6de4616f2506b4e093429cc1093e4ad21b22e6c9)
cc3dff
---
cc3dff
 ldap/servers/plugins/automember/automember.c | 151 ++++++++++++++++++++++-----
cc3dff
 ldap/servers/slapd/back-ldbm/ldbm_add.c      |   4 +-
cc3dff
 ldap/servers/slapd/back-ldbm/ldbm_delete.c   |   5 +
cc3dff
 ldap/servers/slapd/back-ldbm/ldbm_modify.c   |   2 +
cc3dff
 ldap/servers/slapd/back-ldbm/ldbm_modrdn.c   |   3 +
cc3dff
 ldap/servers/slapd/plugin.c                  |   3 +-
cc3dff
 6 files changed, 137 insertions(+), 31 deletions(-)
cc3dff
cc3dff
diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
cc3dff
index c7168cb..3214ea1 100644
cc3dff
--- a/ldap/servers/plugins/automember/automember.c
cc3dff
+++ b/ldap/servers/plugins/automember/automember.c
cc3dff
@@ -103,8 +103,8 @@ static struct automemberRegexRule *automember_parse_regex_rule(char *rule_string
cc3dff
 static void automember_free_regex_rule(struct automemberRegexRule *rule);
cc3dff
 static int automember_parse_grouping_attr(char *value, char **grouping_attr,
cc3dff
     char **grouping_value);
cc3dff
-static void automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd);
cc3dff
-static void automember_add_member_value(Slapi_Entry *member_e, const char *group_dn,
cc3dff
+static int automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd);
cc3dff
+static int automember_add_member_value(Slapi_Entry *member_e, const char *group_dn,
cc3dff
     char *grouping_attr, char *grouping_value, PRFileDesc *ldif_fd);
cc3dff
 const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
cc3dff
 
cc3dff
@@ -1401,7 +1401,7 @@ automember_parse_grouping_attr(char *value, char **grouping_attr, char **groupin
cc3dff
  * Determines which target groups need to be updated according to
cc3dff
  * the rules in config, then performs the updates.
cc3dff
  */
cc3dff
-static void
cc3dff
+static int
cc3dff
 automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd)
cc3dff
 {
cc3dff
     PRCList *rule = NULL;
cc3dff
@@ -1412,10 +1412,11 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
cc3dff
     Slapi_DN *last = NULL;
cc3dff
     PRCList *curr_exclusion = NULL;
cc3dff
     char **vals = NULL;
cc3dff
+    int rc = 0;
cc3dff
     int i = 0;
cc3dff
 
cc3dff
     if (!config || !e) {
cc3dff
-        return;
cc3dff
+        return -1;
cc3dff
     }
cc3dff
 
cc3dff
     slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
@@ -1555,15 +1556,23 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
cc3dff
     if (PR_CLIST_IS_EMPTY(&targets)) {
cc3dff
         /* Add to each default group. */
cc3dff
         for (i = 0; config->default_groups && config->default_groups[i]; i++) {
cc3dff
-            automember_add_member_value(e, config->default_groups[i],
cc3dff
-                                        config->grouping_attr, config->grouping_value, ldif_fd);
cc3dff
+            if(automember_add_member_value(e, config->default_groups[i], config->grouping_attr,
cc3dff
+                                           config->grouping_value, ldif_fd))
cc3dff
+            {
cc3dff
+                rc = SLAPI_PLUGIN_FAILURE;
cc3dff
+                goto out;
cc3dff
+            }
cc3dff
         }
cc3dff
     } else {
cc3dff
         /* Update the target groups. */
cc3dff
         dnitem = (struct automemberDNListItem *)PR_LIST_HEAD(&targets;;
cc3dff
         while ((PRCList *)dnitem != &targets) {
cc3dff
-            automember_add_member_value(e, slapi_sdn_get_dn(dnitem->dn),
cc3dff
-                                        config->grouping_attr, config->grouping_value, ldif_fd);
cc3dff
+            if(automember_add_member_value(e, slapi_sdn_get_dn(dnitem->dn),config->grouping_attr,
cc3dff
+                                           config->grouping_value, ldif_fd))
cc3dff
+            {
cc3dff
+                rc = SLAPI_PLUGIN_FAILURE;
cc3dff
+                goto out;
cc3dff
+            }
cc3dff
             dnitem = (struct automemberDNListItem *)PR_NEXT_LINK((PRCList *)dnitem);
cc3dff
         }
cc3dff
     }
cc3dff
@@ -1582,6 +1591,9 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
cc3dff
             slapi_ch_free((void**)&dnitem);
cc3dff
     }
cc3dff
 
cc3dff
+out:
cc3dff
+
cc3dff
+    return rc;
cc3dff
 }
cc3dff
 
cc3dff
 /*
cc3dff
@@ -1589,7 +1601,7 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
cc3dff
  *
cc3dff
  * Adds a member entry to a group.
cc3dff
  */
cc3dff
-static void
cc3dff
+static int
cc3dff
 automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *grouping_attr,
cc3dff
                             char *grouping_value, PRFileDesc *ldif_fd)
cc3dff
 {
cc3dff
@@ -1600,6 +1612,7 @@ automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *g
cc3dff
     char *vals[2];
cc3dff
     char *member_value = NULL;
cc3dff
     int freeit = 0;
cc3dff
+    int rc = 0;
cc3dff
 
cc3dff
     /* If grouping_value is dn, we need to fetch the dn instead. */
cc3dff
     if (slapi_attr_type_cmp(grouping_value, "dn", SLAPI_TYPE_CMP_EXACT) == 0) {
cc3dff
@@ -1649,6 +1662,7 @@ automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *g
cc3dff
                             "a \"%s\" value to group \"%s\" (%s).\n", 
cc3dff
                             member_value, grouping_attr, group_dn,
cc3dff
                             ldap_err2string(result));
cc3dff
+            rc = result;
cc3dff
         }
cc3dff
     } else {
cc3dff
         slapi_log_error(SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
@@ -1662,8 +1676,9 @@ out:
cc3dff
     if (freeit) {
cc3dff
         slapi_ch_free_string(&member_value);
cc3dff
     }
cc3dff
-
cc3dff
     slapi_pblock_destroy(mod_pb);
cc3dff
+
cc3dff
+    return rc;
cc3dff
 }
cc3dff
 
cc3dff
 
cc3dff
@@ -1833,6 +1848,7 @@ automember_add_post_op(Slapi_PBlock *pb)
cc3dff
     Slapi_DN *sdn = NULL;
cc3dff
     struct configEntry *config = NULL;
cc3dff
     PRCList *list = NULL;
cc3dff
+    int rc = SLAPI_PLUGIN_SUCCESS;
cc3dff
 
cc3dff
     slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
                     "--> automember_add_post_op\n");
cc3dff
@@ -1848,8 +1864,9 @@ automember_add_post_op(Slapi_PBlock *pb)
cc3dff
         }
cc3dff
     } else {
cc3dff
         slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
-                        "automember_add_post_op: Error "
cc3dff
-                        "retrieving dn\n");
cc3dff
+                        "automember_add_post_op: Error retrieving dn\n");
cc3dff
+
cc3dff
+        rc = SLAPI_PLUGIN_FAILURE;
cc3dff
         goto bail;
cc3dff
     }
cc3dff
 
cc3dff
@@ -1863,12 +1880,11 @@ automember_add_post_op(Slapi_PBlock *pb)
cc3dff
 
cc3dff
     if (e) {
cc3dff
         /* If the entry is a tombstone, just bail. */
cc3dff
-        Slapi_Value *tombstone =
cc3dff
-                        slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
cc3dff
-        int rc = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS,
cc3dff
-                                                   tombstone);
cc3dff
+        Slapi_Value *tombstone = slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
cc3dff
+        int is_tombstone = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS,
cc3dff
+                                                             tombstone);
cc3dff
         slapi_value_free(&tombstone);
cc3dff
-        if (rc) {
cc3dff
+        if (is_tombstone) {
cc3dff
             return SLAPI_PLUGIN_SUCCESS;
cc3dff
         }
cc3dff
 
cc3dff
@@ -1891,7 +1907,10 @@ automember_add_post_op(Slapi_PBlock *pb)
cc3dff
                 if (slapi_dn_issuffix(slapi_sdn_get_dn(sdn), config->scope) &&
cc3dff
                     (slapi_filter_test_simple(e, config->filter) == 0)) {
cc3dff
                     /* Find out what membership changes are needed and make them. */
cc3dff
-                    automember_update_membership(config, e, NULL);
cc3dff
+                    if(automember_update_membership(config, e, NULL)){
cc3dff
+                        rc = SLAPI_PLUGIN_FAILURE;
cc3dff
+                        break;
cc3dff
+                    }
cc3dff
                 }
cc3dff
 
cc3dff
                 list = PR_NEXT_LINK(list);
cc3dff
@@ -1904,11 +1923,21 @@ automember_add_post_op(Slapi_PBlock *pb)
cc3dff
                         "automember_add_post_op: Error "
cc3dff
                         "retrieving post-op entry %s\n", slapi_sdn_get_dn(sdn));
cc3dff
     }
cc3dff
+
cc3dff
 bail:
cc3dff
     slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
-                    "<-- automember_add_post_op\n");
cc3dff
+                    "<-- automember_add_post_op (%d)\n", rc);
cc3dff
 
cc3dff
-    return SLAPI_PLUGIN_SUCCESS;
cc3dff
+    if(rc){
cc3dff
+        char errtxt[SLAPI_DSE_RETURNTEXT_SIZE];
cc3dff
+        int result = LDAP_UNWILLING_TO_PERFORM;
cc3dff
+
cc3dff
+        PR_snprintf(errtxt, SLAPI_DSE_RETURNTEXT_SIZE, "Automember Plugin update unexpectedly failed.\n");
cc3dff
+        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &result);
cc3dff
+        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, &errtxt);
cc3dff
+    }
cc3dff
+
cc3dff
+    return rc;
cc3dff
 }
cc3dff
 
cc3dff
 /*
cc3dff
@@ -2216,7 +2245,11 @@ void automember_rebuild_task_thread(void *arg){
cc3dff
                 if (slapi_dn_issuffix(slapi_entry_get_dn(entries[i]), config->scope) &&
cc3dff
                     (slapi_filter_test_simple(entries[i], config->filter) == 0))
cc3dff
                 {
cc3dff
-                    automember_update_membership(config, entries[i], NULL);
cc3dff
+                    if(automember_update_membership(config, entries[i], NULL)){
cc3dff
+                        result = SLAPI_PLUGIN_FAILURE;
cc3dff
+                        automember_config_unlock();
cc3dff
+                        goto out;
cc3dff
+                    }
cc3dff
                 }
cc3dff
                 list = PR_NEXT_LINK(list);
cc3dff
             }
cc3dff
@@ -2416,7 +2449,7 @@ void automember_export_task_thread(void *arg){
cc3dff
         /* make sure the plugin is still up, as this loop could run for awhile */
cc3dff
         if (!g_plugin_started) {
cc3dff
             automember_config_unlock();
cc3dff
-            result = -1;
cc3dff
+            result = SLAPI_DSE_CALLBACK_ERROR;
cc3dff
             goto out;
cc3dff
         }
cc3dff
         if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
cc3dff
@@ -2426,7 +2459,11 @@ void automember_export_task_thread(void *arg){
cc3dff
                 if (slapi_dn_issuffix(slapi_sdn_get_dn(td->base_dn), config->scope) &&
cc3dff
                     (slapi_filter_test_simple(entries[i], config->filter) == 0))
cc3dff
                 { 
cc3dff
-                    automember_update_membership(config, entries[i], ldif_fd);
cc3dff
+                    if(automember_update_membership(config, entries[i], ldif_fd)){
cc3dff
+                        result = SLAPI_DSE_CALLBACK_ERROR;
cc3dff
+                        automember_config_unlock();
cc3dff
+                        goto out;
cc3dff
+                    }
cc3dff
                 }
cc3dff
                 list = PR_NEXT_LINK(list);
cc3dff
             }
cc3dff
@@ -2624,7 +2661,13 @@ void automember_map_task_thread(void *arg){
cc3dff
                     if (slapi_dn_issuffix(slapi_entry_get_dn_const(e), config->scope) &&
cc3dff
                         (slapi_filter_test_simple(e, config->filter) == 0))
cc3dff
                     {
cc3dff
-                        automember_update_membership(config, e, ldif_fd_out);
cc3dff
+                        if(automember_update_membership(config, e, ldif_fd_out)){
cc3dff
+                            result = SLAPI_DSE_CALLBACK_ERROR;
cc3dff
+                            slapi_entry_free(e);
cc3dff
+                            slapi_ch_free_string(&entrystr);
cc3dff
+                            automember_config_unlock();
cc3dff
+                            goto out;
cc3dff
+                        }
cc3dff
                     }
cc3dff
                     list = PR_NEXT_LINK(list);
cc3dff
                 }
cc3dff
@@ -2635,7 +2678,7 @@ void automember_map_task_thread(void *arg){
cc3dff
             slapi_task_log_notice(task, "Automember map task, skipping invalid entry.");
cc3dff
             slapi_task_log_status(task, "Automember map task, skipping invalid entry.");
cc3dff
         }
cc3dff
-        slapi_ch_free((void **)&entrystr);
cc3dff
+        slapi_ch_free_string(&entrystr);
cc3dff
     }
cc3dff
     automember_config_unlock();
cc3dff
 
cc3dff
@@ -2666,6 +2709,9 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
cc3dff
     Slapi_DN *old_sdn = NULL;
cc3dff
     Slapi_DN *new_sdn = NULL;
cc3dff
     Slapi_Entry *post_e = NULL;
cc3dff
+    struct configEntry *config = NULL;
cc3dff
+    PRCList *list = NULL;
cc3dff
+    int rc = SLAPI_PLUGIN_SUCCESS;
cc3dff
 
cc3dff
     slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
                     "--> automember_modrdn_post_op\n");
cc3dff
@@ -2684,7 +2730,7 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
cc3dff
         slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
                         "automember_modrdn_post_op: Error "
cc3dff
                         "retrieving post-op entry\n");
cc3dff
-        return 0;
cc3dff
+        return SLAPI_PLUGIN_FAILURE;
cc3dff
     }
cc3dff
 
cc3dff
     if ((old_sdn = automember_get_sdn(pb))) {
cc3dff
@@ -2694,11 +2740,58 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
cc3dff
         slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
                         "automember_modrdn_post_op: Error "
cc3dff
                         "retrieving dn\n");
cc3dff
+        return SLAPI_PLUGIN_FAILURE;
cc3dff
     }
cc3dff
 
cc3dff
-    slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
-                    "<-- automember_modrdn_post_op\n");
cc3dff
+    /* If replication, just bail. */
cc3dff
+    if (automember_isrepl(pb)) {
cc3dff
+        return SLAPI_PLUGIN_SUCCESS;
cc3dff
+    }
cc3dff
 
cc3dff
-    return 0;
cc3dff
+    /*
cc3dff
+     * Check if a config entry applies to the entry(post modrdn)
cc3dff
+     */
cc3dff
+    automember_config_read_lock();
cc3dff
+
cc3dff
+    /* Bail out if the plug-in close function was just called. */
cc3dff
+    if (!g_plugin_started) {
cc3dff
+        automember_config_unlock();
cc3dff
+        return SLAPI_PLUGIN_SUCCESS;
cc3dff
+    }
cc3dff
+
cc3dff
+    if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
cc3dff
+        list = PR_LIST_HEAD(g_automember_config);
cc3dff
+        while (list != g_automember_config) {
cc3dff
+            config = (struct configEntry *)list;
cc3dff
+
cc3dff
+            /* Does the entry meet scope and filter requirements? */
cc3dff
+            if (slapi_dn_issuffix(slapi_sdn_get_dn(new_sdn), config->scope) &&
cc3dff
+                (slapi_filter_test_simple(post_e, config->filter) == 0)) {
cc3dff
+                /* Find out what membership changes are needed and make them. */
cc3dff
+                if(automember_update_membership(config, post_e, NULL)){
cc3dff
+                    rc = SLAPI_PLUGIN_FAILURE;
cc3dff
+                    break;
cc3dff
+                }
cc3dff
+            }
cc3dff
+
cc3dff
+            list = PR_NEXT_LINK(list);
cc3dff
+        }
cc3dff
+    }
cc3dff
+
cc3dff
+    automember_config_unlock();
cc3dff
+
cc3dff
+    if(rc){
cc3dff
+        char errtxt[SLAPI_DSE_RETURNTEXT_SIZE];
cc3dff
+        int result = LDAP_UNWILLING_TO_PERFORM;
cc3dff
+
cc3dff
+        PR_snprintf(errtxt, SLAPI_DSE_RETURNTEXT_SIZE, "Automember Plugin update unexpectedly failed.  "
cc3dff
+                    "Please see the server errors log for more information.\n");
cc3dff
+        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &result);
cc3dff
+        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, &errtxt);
cc3dff
+    }
cc3dff
+
cc3dff
+    slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
cc3dff
+                    "<-- automember_modrdn_post_op (%d)\n", rc);
cc3dff
+    return rc;
cc3dff
 }
cc3dff
 
cc3dff
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
cc3dff
index fa1e9bc..e5b9eeb 100644
cc3dff
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
cc3dff
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
cc3dff
@@ -357,7 +357,7 @@ ldbm_back_add( Slapi_PBlock *pb )
cc3dff
 						/* make sure opreturn is set for the postop plugins */
cc3dff
 						slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &rc);
cc3dff
 					}
cc3dff
-
cc3dff
+					slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 					goto error_return;
cc3dff
 				}
cc3dff
 				/*
cc3dff
@@ -795,6 +795,7 @@ ldbm_back_add( Slapi_PBlock *pb )
cc3dff
 			if (!opreturn) {
cc3dff
 				slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
cc3dff
 			}
cc3dff
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 			goto error_return;
cc3dff
 		}
cc3dff
 
cc3dff
@@ -1046,6 +1047,7 @@ ldbm_back_add( Slapi_PBlock *pb )
cc3dff
 		if (!opreturn) {
cc3dff
 			slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
cc3dff
 		}
cc3dff
+		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 		goto error_return;
cc3dff
 	}
cc3dff
 
cc3dff
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
cc3dff
index 6725123..367ab99 100644
cc3dff
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
cc3dff
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
cc3dff
@@ -325,6 +325,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
cc3dff
 					if (!opreturn) {
cc3dff
 						slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &rc );
cc3dff
 					}
cc3dff
+					slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 					goto error_return;
cc3dff
 				}
cc3dff
 				/* the flag could be set in a preop plugin (e.g., USN) */
cc3dff
@@ -354,6 +355,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
cc3dff
 									  ldap_result_code ?
cc3dff
 									  &ldap_result_code : &retval );
cc3dff
 				}
cc3dff
+				slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 				goto error_return;
cc3dff
 			}
cc3dff
 
cc3dff
@@ -603,6 +605,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
cc3dff
 					                  ldap_result_code ?
cc3dff
 					                  &ldap_result_code : &retval );
cc3dff
 				}
cc3dff
+				slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 				goto error_return;
cc3dff
 			}
cc3dff
 		}
cc3dff
@@ -633,6 +636,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
cc3dff
 					                  &ldap_result_code : &rc );
cc3dff
 				}
cc3dff
 				/* retval is -1 */
cc3dff
+				slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 				goto error_return;
cc3dff
 			}
cc3dff
 			slapi_pblock_set( pb, SLAPI_DELETE_BEPREOP_ENTRY, orig_entry );
cc3dff
@@ -1105,6 +1109,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
cc3dff
 		if (!opreturn) {
cc3dff
 			slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &retval );
cc3dff
 		}
cc3dff
+		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 		goto error_return;
cc3dff
 	}
cc3dff
 
cc3dff
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
cc3dff
index b5bdb41..f3b099d 100644
cc3dff
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
cc3dff
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
cc3dff
@@ -582,6 +582,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
cc3dff
 			if (!opreturn) {
cc3dff
 				slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
cc3dff
 			}
cc3dff
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 			goto error_return;
cc3dff
 		}
cc3dff
 
cc3dff
@@ -752,6 +753,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
cc3dff
 		if (!opreturn) {
cc3dff
 			slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
cc3dff
 		}
cc3dff
+		slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
 		goto error_return;
cc3dff
 	}
cc3dff
 
cc3dff
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
cc3dff
index 4908751..1162fdb 100644
cc3dff
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
cc3dff
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
cc3dff
@@ -466,6 +466,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
cc3dff
                     if (!opreturn) {
cc3dff
                         slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &rc );
cc3dff
                     }
cc3dff
+                    slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
                     goto error_return;
cc3dff
                 }
cc3dff
                 /*
cc3dff
@@ -890,6 +891,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
cc3dff
             if (!opreturn) {
cc3dff
                 slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval );
cc3dff
             }
cc3dff
+            slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
             goto error_return;
cc3dff
         }
cc3dff
 
cc3dff
@@ -1130,6 +1132,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
cc3dff
         if (!opreturn) {
cc3dff
             slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval );
cc3dff
         }
cc3dff
+        slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
cc3dff
         goto error_return;
cc3dff
     }
cc3dff
 
cc3dff
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
cc3dff
index 5f66ab2..1ca4dc5 100644
cc3dff
--- a/ldap/servers/slapd/plugin.c
cc3dff
+++ b/ldap/servers/slapd/plugin.c
cc3dff
@@ -1467,7 +1467,8 @@ plugin_call_func (struct slapdplugin *list, int operation, Slapi_PBlock *pb, int
cc3dff
 				}
cc3dff
 				else if (SLAPI_PLUGIN_BEPREOPERATION == list->plg_type ||
cc3dff
 				         SLAPI_PLUGIN_BETXNPREOPERATION == list->plg_type ||
cc3dff
-				         SLAPI_PLUGIN_BEPOSTOPERATION == list->plg_type)
cc3dff
+				         SLAPI_PLUGIN_BEPOSTOPERATION == list->plg_type ||
cc3dff
+				         SLAPI_PLUGIN_BETXNPOSTOPERATION == list->plg_type )
cc3dff
 				{
cc3dff
 					/* 
cc3dff
 					 * respect fatal error SLAPI_PLUGIN_FAILURE (-1);
cc3dff
-- 
cc3dff
1.8.1.4
cc3dff