From fc833faa88f6068362c1f803027a966dfb2b33bc Mon Sep 17 00:00:00 2001
From: Thierry Bordaz <tbordaz@redhat.com>
Date: Thu, 9 Jun 2016 16:09:12 +0200
Subject: [PATCH] Ticket 48880 - RFE: adding pre/post extop ability

Bug Description:
    In some cases it is useful to allow a plugin to change the target_dn before processing the extop.
    The extop does not support PRE/POST operation.

Fix Description:
    extended operation would call SLAPI_PLUGIN_PRE_EXTOP_FN/SLAPI_PLUGIN_POST_EXTOP_FN callbacks.
    The plugins register those callbacks as SLAPI_PLUGIN_PRE_EXTOP_FN/SLAPI_PLUGIN_PRE_EXTOP_FN in their
    init function. The callbacks are then store into dedicated plugins lists SLAPI_PLUGIN_PREEXTOPERATION and
    SLAPI_PLUGIN_POSTEXTOPERATION

http://fedorahosted.org/389/ticket/48880ticket URL>

Reviewed by: ?

Platforms tested: F23

Flag Day: no

Doc impact: no
---
 ldap/servers/slapd/extendop.c     |  9 +++++++++
 ldap/servers/slapd/pblock.c       | 25 ++++++++++++++++++++++++-
 ldap/servers/slapd/plugin.c       | 14 +++++++++++++-
 ldap/servers/slapd/slap.h         |  8 +++++++-
 ldap/servers/slapd/slapi-plugin.h |  8 ++++++--
 5 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c
index 0a6a739..5459f9e 100644
--- a/ldap/servers/slapd/extendop.c
+++ b/ldap/servers/slapd/extendop.c
@@ -337,6 +337,11 @@ do_extended( Slapi_PBlock *pb )
 
     rc = plugin_determine_exop_plugins( extoid, &p );
     slapi_log_error(SLAPI_LOG_TRACE, NULL, "exendop.c plugin_determine_exop_plugins rc %d\n", rc);
+
+    if (plugin_call_plugins(pb, SLAPI_PLUGIN_PRE_EXTOP_FN) != SLAPI_PLUGIN_SUCCESS) {
+        goto free_and_return;
+    }
+
     if (rc == SLAPI_PLUGIN_EXTENDEDOP && p != NULL) {
         slapi_log_error(SLAPI_LOG_TRACE, NULL, "extendop.c calling plugin ... \n");
         rc = plugin_call_exop_plugins( pb, p);
@@ -385,6 +390,10 @@ do_extended( Slapi_PBlock *pb )
         } /* if be */
     }
 
+    if (plugin_call_plugins(pb, SLAPI_PLUGIN_POST_EXTOP_FN) != SLAPI_PLUGIN_SUCCESS) {
+        goto free_and_return;
+    }
+
     if ( SLAPI_PLUGIN_EXTENDED_SENT_RESULT != rc ) {
         if ( SLAPI_PLUGIN_EXTENDED_NOT_HANDLED == rc ) {
             lderr = LDAP_PROTOCOL_ERROR;    /* no plugin handled the op */
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index f6d3af0..7205337 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -828,6 +828,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
 		}
 		(*(IFP *)value) = pblock->pb_plugin->plg_preresult;
 		break;
+	case SLAPI_PLUGIN_PRE_EXTOP_FN:
+		if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_PREEXTOPERATION) {
+			return( -1 );
+		}
+		(*(IFP *)value) = pblock->pb_plugin->plg_preextop;
+		break;
 
 	/* postoperation plugin functions */
 	case SLAPI_PLUGIN_POST_BIND_FN:
@@ -908,7 +914,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
 		}
 		(*(IFP *)value) = pblock->pb_plugin->plg_postresult;
 		break;
-
+	case SLAPI_PLUGIN_POST_EXTOP_FN:
+		if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_POSTEXTOPERATION) {
+			return( -1 );
+		}
+		(*(IFP *)value) = pblock->pb_plugin->plg_postextop;
+		break;
 	case SLAPI_ENTRY_PRE_OP:
 		(*(Slapi_Entry **)value) = pblock->pb_pre_op_entry;
 		break;
@@ -2474,6 +2485,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
 		}
 		pblock->pb_plugin->plg_preresult = (IFP) value;
 		break;
+        case SLAPI_PLUGIN_PRE_EXTOP_FN:
+		if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_PREEXTOPERATION) {
+			return( -1 );
+		}
+		pblock->pb_plugin->plg_preextop  = (IFP) value;
+		break;
 
 	/* postoperation plugin functions */
 	case SLAPI_PLUGIN_POST_BIND_FN:
@@ -2554,6 +2571,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
 		}
 		pblock->pb_plugin->plg_postresult = (IFP) value;
 		break;
+        case SLAPI_PLUGIN_POST_EXTOP_FN:
+		if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_POSTEXTOPERATION) {
+			return( -1 );
+		}
+		pblock->pb_plugin->plg_postextop  = (IFP) value;
+		break;
 
 	/* backend preoperation plugin */
 	case SLAPI_PLUGIN_BE_PRE_MODIFY_FN:
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 39bfcef..2ab6890 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -421,6 +421,12 @@ plugin_call_plugins( Slapi_PBlock *pb, int whichfunction )
         plugin_list_number= PLUGIN_LIST_BETXNPOSTOPERATION;
 		do_op = 1; /* always allow backend callbacks (even during startup) */
 		break;
+        case SLAPI_PLUGIN_PRE_EXTOP_FN:
+            plugin_list_number= PLUGIN_LIST_PREEXTENDED_OPERATION;
+            break;
+	case SLAPI_PLUGIN_POST_EXTOP_FN:
+            plugin_list_number= PLUGIN_LIST_POSTEXTENDED_OPERATION;
+            break;
 	}
 
 	if(plugin_list_number!=-1 && do_op)
@@ -2302,7 +2308,13 @@ plugin_get_type_and_list(
 	} else if ( strcasecmp( plugintype, "betxnextendedop" ) == 0 ) {
 		*type = SLAPI_PLUGIN_BETXNEXTENDEDOP;
     	plugin_list_index= PLUGIN_LIST_BE_TXN_EXTENDED_OPERATION;
-	} else {
+	} else if ( strcasecmp( plugintype, "preextendedop" ) == 0 ) {
+		*type = SLAPI_PLUGIN_PREEXTOPERATION;
+		plugin_list_index= PLUGIN_LIST_PREEXTENDED_OPERATION;
+        } else if ( strcasecmp( plugintype, "postextendedop" ) == 0 ) {
+		*type = SLAPI_PLUGIN_POSTEXTOPERATION;
+		plugin_list_index= PLUGIN_LIST_POSTEXTENDED_OPERATION;
+        } else {
         return( 1 ); /* unknown plugin type - pass to backend */
 	}
 
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index a594a29..b792da4 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -684,7 +684,9 @@ struct matchingRuleList {
 #define PLUGIN_LIST_INTERNAL_POSTOPERATION 6
 #define PLUGIN_LIST_EXTENDED_OPERATION 7
 #define PLUGIN_LIST_BE_TXN_EXTENDED_OPERATION 8
-#define PLUGIN_LIST_BACKEND_MAX 9
+#define PLUGIN_LIST_PREEXTENDED_OPERATION 9
+#define PLUGIN_LIST_POSTEXTENDED_OPERATION 10
+#define PLUGIN_LIST_BACKEND_MAX 11
 
 /* Global Plugins */
 #define PLUGIN_LIST_ACL 10
@@ -904,11 +906,15 @@ struct slapdplugin {
 			char	**plg_un_pe_exoids;	  /* exop oids */
 			char	**plg_un_pe_exnames;  /* exop names (may be NULL) */
 			IFP	plg_un_pe_exhandler;	  /* handler */
+                        IFP	plg_un_pe_pre_exhandler;  /* pre extop */
+                        IFP	plg_un_pe_post_exhandler; /* post extop */
 			IFP	plg_un_pe_be_exhandler;	  /* handler to retrieve the be name for the operation */
 		} plg_un_pe;
 #define plg_exoids		plg_un.plg_un_pe.plg_un_pe_exoids
 #define plg_exnames		plg_un.plg_un_pe.plg_un_pe_exnames
 #define plg_exhandler		plg_un.plg_un_pe.plg_un_pe_exhandler
+#define plg_preextop		plg_un.plg_un_pe.plg_un_pe_pre_exhandler
+#define plg_postextop		plg_un.plg_un_pe.plg_un_pe_post_exhandler
 #define plg_be_exhandler		plg_un.plg_un_pe.plg_un_pe_be_exhandler
 
 
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 294f2c3..c3d8ca9 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6760,7 +6760,9 @@ time_t slapi_current_time( void );
 #define SLAPI_PLUGIN_INDEX			18
 #define	SLAPI_PLUGIN_BETXNPREOPERATION		19
 #define SLAPI_PLUGIN_BETXNPOSTOPERATION		20
-#define SLAPI_PLUGIN_BETXNEXTENDEDOP			21
+#define SLAPI_PLUGIN_BETXNEXTENDEDOP		21
+#define SLAPI_PLUGIN_PREEXTOPERATION		22
+#define SLAPI_PLUGIN_POSTEXTOPERATION		23
 
 /*
  * special return values for extended operation plugins (zero or positive
@@ -6908,6 +6910,7 @@ typedef struct slapi_plugindesc {
 #define SLAPI_PLUGIN_PRE_ENTRY_FN		410
 #define SLAPI_PLUGIN_PRE_REFERRAL_FN		411
 #define SLAPI_PLUGIN_PRE_RESULT_FN		412
+#define SLAPI_PLUGIN_PRE_EXTOP_FN		413
 
 /* internal preoperation plugin functions */
 #define SLAPI_PLUGIN_INTERNAL_PRE_ADD_FN    	420
@@ -6944,7 +6947,8 @@ typedef struct slapi_plugindesc {
 #define SLAPI_PLUGIN_POST_ENTRY_FN		510
 #define SLAPI_PLUGIN_POST_REFERRAL_FN		511
 #define SLAPI_PLUGIN_POST_RESULT_FN		512
-#define SLAPI_PLUGIN_POST_SEARCH_FAIL_FN		513
+#define SLAPI_PLUGIN_POST_SEARCH_FAIL_FN	513
+#define SLAPI_PLUGIN_POST_EXTOP_FN		514
 
 /* internal preoperation plugin functions */
 #define SLAPI_PLUGIN_INTERNAL_POST_ADD_FN   	520
-- 
2.5.0

