Browse Source

Ticket #320 - allow most plugins to be betxn plugins

This allows plugins to run as betxn plugins instead of regular pre/post
op plugins.  For plugins that are not preoperation or postoperation in
the DSE, e.g. that are "object", I've introduced a boolean attribute
nsslapd-pluginbetxn.  If this is set to a true value, the internal
pre/post operation plugins registered will be made betxn plugins
instead.
Looks like cos cannot currently be made a betxn plugin - there is a deadlock
when deleting from the ldbm and DSE backends at the same time.
Everything else passes the acceptance tests.
Reviewed by: nhosoi (Thanks!)
Rich Megginson 14 years ago
parent
commit
836a31dcdf

+ 39 - 13
ldap/servers/plugins/cos/cos.c

@@ -170,17 +170,30 @@ int
 cos_postop_init ( Slapi_PBlock *pb )
 {
 	int rc = 0;
+	Slapi_Entry *plugin_entry = NULL;
+	char *plugin_type = NULL;
+	int postadd = SLAPI_PLUGIN_POST_ADD_FN;
+	int postmod = SLAPI_PLUGIN_POST_MODIFY_FN;
+	int postmdn = SLAPI_PLUGIN_POST_MODRDN_FN;
+	int postdel = SLAPI_PLUGIN_POST_DELETE_FN;
+
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry &&
+		(plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+		plugin_type && strstr(plugin_type, "betxn")) {
+		postadd = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
+		postmod = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
+		postmdn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
+		postdel = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
+	}
+	slapi_ch_free_string(&plugin_type);
 
 	if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, 
 							SLAPI_PLUGIN_VERSION_01 ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN,
-							(void *)cos_post_op ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN,
-							(void *)cos_post_op ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN,
-							(void *) cos_post_op ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN,
-							(void *) cos_post_op ) != 0 )
+		 slapi_pblock_set(pb, postmod, (void *)cos_post_op ) != 0 ||
+		 slapi_pblock_set(pb, postmdn, (void *)cos_post_op ) != 0 ||
+		 slapi_pblock_set(pb, postadd, (void *) cos_post_op ) != 0 ||
+		 slapi_pblock_set(pb, postdel, (void *) cos_post_op ) != 0 )
 	{
 		slapi_log_error( SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM,
 						 "cos_postop_init: failed to register plugin\n" );
@@ -221,9 +234,17 @@ int cos_init( Slapi_PBlock *pb )
 {
 	int ret = 0;
 	void * plugin_identity=NULL;
+	Slapi_Entry *plugin_entry = NULL;
+	int is_betxn = 0;
+	const char *plugintype = "postoperation";
 
 	LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_init\n",0,0,0);
 
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry) {
+		is_betxn = slapi_entry_attr_get_bool(plugin_entry, "nsslapd-pluginbetxn");
+	}
+
 	/*
 	** Store the plugin identity for later use.
 	** Used for internal operations
@@ -248,7 +269,10 @@ int cos_init( Slapi_PBlock *pb )
 		goto bailout;
 	}
 
-	ret = slapi_register_plugin("postoperation", 1 /* Enabled */,
+	if (is_betxn) {
+		plugintype = "betxnpostoperation";
+	}
+	ret = slapi_register_plugin(plugintype, 1 /* Enabled */,
 					"cos_postop_init", cos_postop_init,
 					"Class of Service postoperation plugin", NULL,
 					plugin_identity);
@@ -256,10 +280,12 @@ int cos_init( Slapi_PBlock *pb )
 		goto bailout;
 	}
 
-	ret = slapi_register_plugin("internalpostoperation", 1 /* Enabled */,
-					"cos_internalpostop_init", cos_internalpostop_init,
-					"Class of Service internalpostoperation plugin", NULL,
-					plugin_identity);
+	if (!is_betxn) {
+		ret = slapi_register_plugin("internalpostoperation", 1 /* Enabled */,
+									"cos_internalpostop_init", cos_internalpostop_init,
+									"Class of Service internalpostoperation plugin", NULL,
+									plugin_identity);
+	}
 
 bailout:
 	LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_init\n",0,0,0);

+ 39 - 9
ldap/servers/plugins/retrocl/retrocl.c

@@ -118,14 +118,31 @@ int retrocl_postop_modrdn (Slapi_PBlock *pb) { return retrocl_postob(pb,OP_MODRD
 int
 retrocl_postop_init( Slapi_PBlock *pb )
 {
-    int rc= 0; /* OK */
+	int rc= 0; /* OK */
+	Slapi_Entry *plugin_entry = NULL;
+	char *plugin_type = NULL;
+	int postadd = SLAPI_PLUGIN_POST_ADD_FN;
+	int postmod = SLAPI_PLUGIN_POST_MODIFY_FN;
+	int postmdn = SLAPI_PLUGIN_POST_MODRDN_FN;
+	int postdel = SLAPI_PLUGIN_POST_DELETE_FN;
+
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry &&
+		(plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+		plugin_type && strstr(plugin_type, "betxn")) {
+		postadd = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
+		postmod = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
+		postmdn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
+		postdel = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
+	}
+	slapi_ch_free_string(&plugin_type);
 
 	if( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,	SLAPI_PLUGIN_VERSION_01 ) != 0 || 
-	    slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retroclpostopdesc ) != 0 ||
-	    slapi_pblock_set( pb, SLAPI_PLUGIN_POST_ADD_FN, (void *) retrocl_postop_add ) != 0 ||
-	    slapi_pblock_set( pb, SLAPI_PLUGIN_POST_DELETE_FN, (void *) retrocl_postop_delete ) != 0 ||
-		slapi_pblock_set( pb, SLAPI_PLUGIN_POST_MODIFY_FN, (void *) retrocl_postop_modify ) != 0 ||
-	    slapi_pblock_set( pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *) retrocl_postop_modrdn ) != 0 )
+		slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retroclpostopdesc ) != 0 ||
+		slapi_pblock_set( pb, postadd, (void *) retrocl_postop_add ) != 0 ||
+		slapi_pblock_set( pb, postdel, (void *) retrocl_postop_delete ) != 0 ||
+		slapi_pblock_set( pb, postmod, (void *) retrocl_postop_modify ) != 0 ||
+		slapi_pblock_set( pb, postmdn, (void *) retrocl_postop_modrdn ) != 0 )
 	{
 		slapi_log_error( SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_postop_init failed\n" );
 		rc= -1;
@@ -417,9 +434,12 @@ int
 retrocl_plugin_init(Slapi_PBlock *pb)
 {
   	static int legacy_initialised= 0;
-    	int rc = 0;
+	int rc = 0;
 	int precedence = 0;
 	void *identity = NULL;
+	Slapi_Entry *plugin_entry = NULL;
+	int is_betxn = 0;
+	const char *plugintype = "postoperation";
 
 	slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
 	PR_ASSERT (identity);
@@ -427,14 +447,24 @@ retrocl_plugin_init(Slapi_PBlock *pb)
 
 	slapi_pblock_get( pb, SLAPI_PLUGIN_PRECEDENCE, &precedence );
     
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+	  plugin_entry) {
+	  is_betxn = slapi_entry_attr_get_bool(plugin_entry, "nsslapd-pluginbetxn");
+	}
+
 	if (!legacy_initialised) {
 	  rc= slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 );
 	  rc= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&retrocldesc );
 	  rc= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, (void *) retrocl_start );
 	  rc= slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, (void *) retrocl_stop );
 
-	  rc= slapi_register_plugin_ext("postoperation", 1 /* Enabled */, "retrocl_postop_init", retrocl_postop_init, "Retrocl postoperation plugin", NULL, identity, precedence);
-	  rc= slapi_register_plugin_ext("internalpostoperation", 1 /* Enabled */, "retrocl_internalpostop_init", retrocl_internalpostop_init, "Retrocl internal postoperation plugin", NULL, identity, precedence);
+	  if (is_betxn) {
+	    plugintype = "betxnpostoperation";
+	  }
+	  rc= slapi_register_plugin_ext(plugintype, 1 /* Enabled */, "retrocl_postop_init", retrocl_postop_init, "Retrocl postoperation plugin", NULL, identity, precedence);
+	  if (!is_betxn) {
+	    rc= slapi_register_plugin_ext("internalpostoperation", 1 /* Enabled */, "retrocl_internalpostop_init", retrocl_internalpostop_init, "Retrocl internal postoperation plugin", NULL, identity, precedence);
+	  }
 
 	  retrocl_internal_lock = PR_NewLock();
 	  if (retrocl_internal_lock == NULL) return -1;

+ 39 - 13
ldap/servers/plugins/roles/roles_plugin.c

@@ -81,17 +81,30 @@ int
 roles_postop_init ( Slapi_PBlock *pb )
 {
 	int rc = 0;
+	Slapi_Entry *plugin_entry = NULL;
+	char *plugin_type = NULL;
+	int postadd = SLAPI_PLUGIN_POST_ADD_FN;
+	int postmod = SLAPI_PLUGIN_POST_MODIFY_FN;
+	int postmdn = SLAPI_PLUGIN_POST_MODRDN_FN;
+	int postdel = SLAPI_PLUGIN_POST_DELETE_FN;
+
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry &&
+		(plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+		plugin_type && strstr(plugin_type, "betxn")) {
+		postadd = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
+		postmod = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
+		postmdn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
+		postdel = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
+	}
+	slapi_ch_free_string(&plugin_type);
 
 	if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, 
 							SLAPI_PLUGIN_VERSION_01 ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN,
-							(void *)roles_post_op ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN,
-							(void *)roles_post_op ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN,
-							(void *) roles_post_op ) != 0 ||
-		 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN,
-							(void *) roles_post_op ) != 0 )
+		 slapi_pblock_set(pb, postmod, (void *)roles_post_op ) != 0 ||
+		 slapi_pblock_set(pb, postmdn, (void *)roles_post_op ) != 0 ||
+		 slapi_pblock_set(pb, postadd, (void *) roles_post_op ) != 0 ||
+		 slapi_pblock_set(pb, postdel, (void *) roles_post_op ) != 0 )
 	{
 		slapi_log_error( SLAPI_LOG_FATAL, ROLES_PLUGIN_SUBSYSTEM,
 						 "roles_postop_init: failed to register plugin\n" );
@@ -131,6 +144,9 @@ int roles_init( Slapi_PBlock *pb )
 {
 	int rc = 0;
 	void *plugin_identity = NULL; 
+	Slapi_Entry *plugin_entry = NULL;
+	int is_betxn = 0;
+	const char *plugintype = "postoperation";
 
 	slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM,
 						"=> roles_init\n" );
@@ -139,6 +155,11 @@ int roles_init( Slapi_PBlock *pb )
 	PR_ASSERT (plugin_identity);
 	roles_set_plugin_identity(plugin_identity);
 
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry) {
+		is_betxn = slapi_entry_attr_get_bool(plugin_entry, "nsslapd-pluginbetxn");
+	}
+
 	if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
 							(void *)SLAPI_PLUGIN_VERSION_01 ) != 0 ||
 		 slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
@@ -154,7 +175,10 @@ int roles_init( Slapi_PBlock *pb )
 		goto bailout;
 	}
 
-	rc = slapi_register_plugin("postoperation", 1 /* Enabled */,
+	if (is_betxn) {
+		plugintype = "betxnpostoperation";
+	}
+	rc = slapi_register_plugin(plugintype, 1 /* Enabled */,
 					"roles_postop_init", roles_postop_init,
 					"Roles postoperation plugin", NULL,
 					plugin_identity);
@@ -162,10 +186,12 @@ int roles_init( Slapi_PBlock *pb )
 		goto bailout;
 	}
 
-	rc = slapi_register_plugin("internalpostoperation", 1 /* Enabled */,
-					"roles_internalpostop_init", roles_internalpostop_init,
-					"Roles internalpostoperation plugin", NULL,
-					plugin_identity);
+	if (!is_betxn) {
+		rc = slapi_register_plugin("internalpostoperation", 1 /* Enabled */,
+								   "roles_internalpostop_init", roles_internalpostop_init,
+								   "Roles internalpostoperation plugin", NULL,
+								   plugin_identity);
+	}
 bailout:
 	slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM,
 							"<= roles_init %d\n", rc );

+ 21 - 8
ldap/servers/plugins/statechange/statechange.c

@@ -111,23 +111,36 @@ void plugin_init_debug_level(int *level_ptr)
 int statechange_init( Slapi_PBlock *pb )
 {
 	int ret = 0;
+	Slapi_Entry *plugin_entry = NULL;
+	char *plugin_type = NULL;
+	int postadd = SLAPI_PLUGIN_POST_ADD_FN;
+	int postmod = SLAPI_PLUGIN_POST_MODIFY_FN;
+	int postmdn = SLAPI_PLUGIN_POST_MODRDN_FN;
+	int postdel = SLAPI_PLUGIN_POST_DELETE_FN;
 
 	slapi_log_error( SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "--> statechange_init\n");
 
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry &&
+		(plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+		plugin_type && strstr(plugin_type, "betxn")) {
+		postadd = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
+		postmod = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
+		postmdn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
+		postdel = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
+	}
+	slapi_ch_free_string(&plugin_type);
+
 	head = 0;
 
 	if (	slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
 	    			SLAPI_PLUGIN_VERSION_01 ) != 0 ||
 	        slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
         	         (void *) statechange_start ) != 0 ||
-	        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN,
-        	         (void *) statechange_mod_post_op ) != 0 ||
-	        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN,
-        	         (void *) statechange_modrdn_post_op ) != 0 ||
-	        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN,
-        	         (void *) statechange_add_post_op ) != 0 ||
-	        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN,
-        	         (void *) statechange_delete_post_op ) != 0 ||
+	        slapi_pblock_set(pb, postmod, (void *) statechange_mod_post_op ) != 0 ||
+	        slapi_pblock_set(pb, postmdn, (void *) statechange_modrdn_post_op ) != 0 ||
+	        slapi_pblock_set(pb, postadd, (void *) statechange_add_post_op ) != 0 ||
+	        slapi_pblock_set(pb, postdel, (void *) statechange_delete_post_op ) != 0 ||
 	        slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
         	         (void *) statechange_close ) != 0 ||
 			slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,

+ 18 - 6
ldap/servers/plugins/uiduniq/7bit.c

@@ -692,6 +692,11 @@ int
 NS7bitAttr_Init(Slapi_PBlock *pb)
 {
   int err = 0;
+  Slapi_Entry *plugin_entry = NULL;
+  char *plugin_type = NULL;
+  int preadd = SLAPI_PLUGIN_PRE_ADD_FN;
+  int premod = SLAPI_PLUGIN_PRE_MODIFY_FN;
+  int premdn = SLAPI_PLUGIN_PRE_MODRDN_FN;
 
   BEGIN
     int argc;
@@ -703,6 +708,16 @@ NS7bitAttr_Init(Slapi_PBlock *pb)
             SLAPI_PLUGIN_VERSION_01);
     if (err) break;
 
+    if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+        plugin_entry &&
+        (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+        plugin_type && strstr(plugin_type, "betxn")) {
+        preadd = SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN;
+        premod = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN;
+        premdn = SLAPI_PLUGIN_BE_TXN_PRE_MODRDN_FN;
+    }
+    slapi_ch_free_string(&plugin_type);
+
     /*
      * Get and normalize arguments
      */
@@ -734,16 +749,13 @@ NS7bitAttr_Init(Slapi_PBlock *pb)
     if (err) break;
 
     /* Register functions */
-    err = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN,
-            (void*)preop_add);
+    err = slapi_pblock_set(pb, preadd, (void*)preop_add);
     if (err) break;
 
-    err = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODIFY_FN,
-            (void*)preop_modify);
+    err = slapi_pblock_set(pb, premod, (void*)preop_modify);
     if (err) break;
 
-    err = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODRDN_FN,
-            (void*)preop_modrdn);
+    err = slapi_pblock_set(pb, premdn, (void*)preop_modrdn);
     if (err) break;
 
   END

+ 18 - 6
ldap/servers/plugins/uiduniq/uid.c

@@ -1013,6 +1013,11 @@ int
 NSUniqueAttr_Init(Slapi_PBlock *pb)
 {
   int err = 0;
+  Slapi_Entry *plugin_entry = NULL;
+  char *plugin_type = NULL;
+  int preadd = SLAPI_PLUGIN_PRE_ADD_FN;
+  int premod = SLAPI_PLUGIN_PRE_MODIFY_FN;
+  int premdn = SLAPI_PLUGIN_PRE_MODRDN_FN;
 
   BEGIN
     int argc;
@@ -1031,6 +1036,16 @@ NSUniqueAttr_Init(Slapi_PBlock *pb)
     slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
     /* PR_ASSERT (plugin_identity); */
 
+    if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+        plugin_entry &&
+        (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+        plugin_type && strstr(plugin_type, "betxn")) {
+        preadd = SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN;
+        premod = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN;
+        premdn = SLAPI_PLUGIN_BE_TXN_PRE_MODRDN_FN;
+    }
+    slapi_ch_free_string(&plugin_type);
+
     /*
      * Get and normalize arguments
      */
@@ -1056,16 +1071,13 @@ NSUniqueAttr_Init(Slapi_PBlock *pb)
     if (err) break;
 
     /* Register functions */
-    err = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN,
-            (void*)preop_add);
+    err = slapi_pblock_set(pb, preadd, (void*)preop_add);
     if (err) break;
 
-    err = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODIFY_FN,
-            (void*)preop_modify);
+    err = slapi_pblock_set(pb, premod, (void*)preop_modify);
     if (err) break;
 
-    err = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODRDN_FN,
-            (void*)preop_modrdn);
+    err = slapi_pblock_set(pb, premdn, (void*)preop_modrdn);
     if (err) break;
 
   END

+ 81 - 25
ldap/servers/plugins/usn/usn.c

@@ -78,12 +78,20 @@ usn_init(Slapi_PBlock *pb)
 {
     int rc = 0;
     void *identity = NULL;
+	Slapi_Entry *plugin_entry = NULL;
+	int is_betxn = 0;
+    const char *plugintype;
 
     slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
                     "--> usn_init\n");
 
     slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &identity);
 
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry) {
+		is_betxn = slapi_entry_attr_get_bool(plugin_entry, "nsslapd-pluginbetxn");
+	}
+
     /* slapi_register_plugin always returns SUCCESS (0) */
     if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
                          SLAPI_PLUGIN_VERSION_01) != 0 ||
@@ -104,13 +112,25 @@ usn_init(Slapi_PBlock *pb)
         goto bail;
     }
 
-    rc = slapi_register_plugin("preoperation", 1 /* Enabled */,
+    plugintype = "preoperation";
+    if (is_betxn) {
+        plugintype = "betxnpreoperation";
+    }
+    rc = slapi_register_plugin(plugintype, 1 /* Enabled */,
                                "usn_preop_init", usn_preop_init,
                                "USN preoperation plugin", NULL, identity);
-    rc |= slapi_register_plugin("bepreoperation", 1 /* Enabled */,
+    plugintype = "bepreoperation";
+    if (is_betxn) {
+        plugintype = "betxnpreoperation";
+    }
+    rc |= slapi_register_plugin(plugintype, 1 /* Enabled */,
                                "usn_bepreop_init", usn_bepreop_init,
                                "USN bepreoperation plugin", NULL, identity);
-    rc |= slapi_register_plugin("bepostoperation", 1 /* Enabled */,
+    plugintype = "bepostoperation";
+    if (is_betxn) {
+        plugintype = "betxnpostoperation";
+    }
+    rc |= slapi_register_plugin(plugintype, 1 /* Enabled */,
                                "usn_bepostop_init", usn_bepostop_init,
                                "USN bepostoperation plugin", NULL, identity);
     usn_set_identity(identity);
@@ -124,6 +144,17 @@ static int
 usn_preop_init(Slapi_PBlock *pb)
 {
     int rc = 0;
+    Slapi_Entry *plugin_entry = NULL;
+    char *plugin_type = NULL;
+    int predel = SLAPI_PLUGIN_PRE_DELETE_FN;
+
+	if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+		plugin_entry &&
+		(plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+		plugin_type && strstr(plugin_type, "betxn")) {
+        predel = SLAPI_PLUGIN_BE_TXN_PRE_DELETE_FN;
+	}
+	slapi_ch_free_string(&plugin_type);
 
     /* set up csn generator for tombstone */
     _usn_csngen = csngen_new(USN_CSNGEN_ID, NULL);
@@ -133,8 +164,7 @@ usn_preop_init(Slapi_PBlock *pb)
         rc = -1;
     }
 
-    if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_DELETE_FN,
-                                 (void *)usn_preop_delete) != 0) {
+    if (slapi_pblock_set(pb, predel, (void *)usn_preop_delete) != 0) {
         slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
                         "usn_preop_init: failed to register preop plugin\n");
         rc = -1;
@@ -147,17 +177,30 @@ static int
 usn_bepreop_init(Slapi_PBlock *pb)
 {
     int rc = 0;
-
-    if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_ADD_FN,
-                                 (void *)usn_bepreop_add) != 0 ||
-        slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN,
-                                 (void *)usn_bepreop_delete) != 0 ||
-        slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_MODIFY_FN,
-                                 (void *)usn_bepreop_modify) != 0 ||
-        slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_MODRDN_FN,
-                                 (void *)usn_bepreop_modify) != 0) {
+    Slapi_Entry *plugin_entry = NULL;
+    char *plugin_type = NULL;
+    int preadd = SLAPI_PLUGIN_BE_PRE_ADD_FN;
+    int premod = SLAPI_PLUGIN_BE_PRE_MODIFY_FN;
+    int premdn = SLAPI_PLUGIN_BE_PRE_MODRDN_FN;
+    int predel = SLAPI_PLUGIN_BE_PRE_DELETE_FN;
+
+    if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+        plugin_entry &&
+        (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+        plugin_type && strstr(plugin_type, "betxn")) {
+        preadd = SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN;
+        premod = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN;
+        premdn = SLAPI_PLUGIN_BE_TXN_PRE_MODRDN_FN;
+        predel = SLAPI_PLUGIN_BE_TXN_PRE_DELETE_FN;
+    }
+    slapi_ch_free_string(&plugin_type);
+
+    if (slapi_pblock_set(pb, preadd, (void *)usn_bepreop_add) != 0 ||
+        slapi_pblock_set(pb, predel, (void *)usn_bepreop_delete) != 0 ||
+        slapi_pblock_set(pb, premod, (void *)usn_bepreop_modify) != 0 ||
+        slapi_pblock_set(pb, premdn, (void *)usn_bepreop_modify) != 0) {
         slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
-                    "usn_bepreop_init: failed to register bepreop plugin\n");
+                        "usn_bepreop_init: failed to register bepreop plugin\n");
         rc = -1;
     }
 
@@ -168,17 +211,30 @@ static int
 usn_bepostop_init(Slapi_PBlock *pb)
 {
     int rc = 0;
-
-    if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_ADD_FN,
-                                 (void *)usn_bepostop) != 0 ||
-        slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_DELETE_FN,
-                                 (void *)usn_bepostop_delete) != 0 ||
-        slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_MODIFY_FN,
-                                 (void *)usn_bepostop_modify) != 0 ||
-        slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_MODRDN_FN,
-                                 (void *)usn_bepostop) != 0) {
+    Slapi_Entry *plugin_entry = NULL;
+    char *plugin_type = NULL;
+    int postadd = SLAPI_PLUGIN_BE_POST_ADD_FN;
+    int postmod = SLAPI_PLUGIN_BE_POST_MODIFY_FN;
+    int postmdn = SLAPI_PLUGIN_BE_POST_MODRDN_FN;
+    int postdel = SLAPI_PLUGIN_BE_POST_DELETE_FN;
+
+    if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
+        plugin_entry &&
+        (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
+        plugin_type && strstr(plugin_type, "betxn")) {
+        postadd = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
+        postmod = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
+        postmdn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
+        postdel = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
+    }
+    slapi_ch_free_string(&plugin_type);
+
+    if (slapi_pblock_set(pb, postadd, (void *)usn_bepostop) != 0 ||
+        slapi_pblock_set(pb, postdel, (void *)usn_bepostop_delete) != 0 ||
+        slapi_pblock_set(pb, postmod, (void *)usn_bepostop_modify) != 0 ||
+        slapi_pblock_set(pb, postmdn, (void *)usn_bepostop) != 0) {
         slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
-                    "usn_bepostop_init: failed to register bepostop plugin\n");
+                        "usn_bepostop_init: failed to register bepostop plugin\n");
         rc = -1;
     }