浏览代码

Bug 697961 - memberOf needs to be triggered by internal operations

The memberOf plug-in is not currently triggered by internal modify,
add, delete, or rename operations.  This patch makes it work with
internal operations so it can play nicely with other plug-ins that
make membership changes, such as the new Auto Membership plug-in.

The precedence for the referential integrity plug-in needed to be
lowered to ensure consistency of membership attributes when both
memberOf and referential integrity plug-ins are in use.
Nathan Kinder 14 年之前
父节点
当前提交
7eec674514

+ 1 - 0
Makefile.am

@@ -467,6 +467,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
 	ldap/admin/src/scripts/50linkedattrsplugin.ldif \
 	ldap/admin/src/scripts/50usnplugin.ldif \
 	ldap/admin/src/scripts/50smd5pwdstorageplugin.ldif \
+	ldap/admin/src/scripts/50refintprecedence.ldif \
 	ldap/admin/src/scripts/50retroclprecedence.ldif \
 	ldap/admin/src/scripts/60upgradeschemafiles.pl \
 	ldap/admin/src/scripts/90subtreerename.pl \

+ 1 - 0
Makefile.in

@@ -1656,6 +1656,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
 	ldap/admin/src/scripts/50linkedattrsplugin.ldif \
 	ldap/admin/src/scripts/50usnplugin.ldif \
 	ldap/admin/src/scripts/50smd5pwdstorageplugin.ldif \
+	ldap/admin/src/scripts/50refintprecedence.ldif \
 	ldap/admin/src/scripts/50retroclprecedence.ldif \
 	ldap/admin/src/scripts/60upgradeschemafiles.pl \
 	ldap/admin/src/scripts/90subtreerename.pl \

+ 4 - 0
ldap/admin/src/scripts/50refintprecedence.ldif

@@ -0,0 +1,4 @@
+dn: cn=referential integrity postoperation,cn=plugins,cn=config
+changetype: modify
+replace: nsslapd-pluginPrecedence
+nsslapd-pluginPrecedence: 40

+ 1 - 0
ldap/ldif/template-dse.ldif.in

@@ -581,6 +581,7 @@ nsslapd-pluginpath: libreferint-plugin
 nsslapd-plugininitfunc: referint_postop_init
 nsslapd-plugintype: postoperation
 nsslapd-pluginenabled: off
+nsslapd-pluginprecedence: 40
 nsslapd-pluginArg0: 0
 nsslapd-pluginArg1: %log_dir%/referint
 nsslapd-pluginArg2: 0

+ 85 - 2
ldap/servers/plugins/memberof/memberof.c

@@ -79,6 +79,7 @@ static Slapi_PluginDesc pdesc = { "memberof", VENDOR,
 static void* _PluginID = NULL;
 static Slapi_Mutex *memberof_operation_lock = 0;
 MemberOfConfig *qsortConfig = 0;
+static int g_plugin_started = 0;
 
 typedef struct _memberofstringll
 {
@@ -97,6 +98,7 @@ typedef struct _memberof_get_groups_data
 
 /* exported functions */
 int memberof_postop_init(Slapi_PBlock *pb );
+static int memberof_internal_postop_init(Slapi_PBlock *pb);
 
 /* plugin callbacks */ 
 static int memberof_postop_del(Slapi_PBlock *pb ); 
@@ -213,7 +215,14 @@ memberof_postop_init(Slapi_PBlock *pb)
 		slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
 			(void *) memberof_postop_start ) != 0 ||
 		slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
-			(void *) memberof_postop_close ) != 0)
+			(void *) memberof_postop_close ) != 0 ||
+		slapi_register_plugin("internalpostoperation",  /* op type */
+			1,        /* Enabled */
+			"memberof_postop_init",   /* this function desc */
+			memberof_internal_postop_init,  /* init func */
+			MEMBEROF_INT_PREOP_DESC,      /* plugin desc */
+			NULL,     /* ? */
+			memberof_plugin_identity   /* access control */))
 	{
 		slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
 			"memberof_postop_init failed\n" );
@@ -225,6 +234,31 @@ memberof_postop_init(Slapi_PBlock *pb)
 	return ret;
 }
 
+static int
+memberof_internal_postop_init(Slapi_PBlock *pb)
+{
+	int status = 0;
+
+	if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
+			SLAPI_PLUGIN_VERSION_01) != 0 ||
+		slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
+			(void *) &pdesc) != 0 ||
+		slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,
+			(void *) memberof_postop_del) != 0 ||
+		slapi_pblock_set( pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,
+			(void *) memberof_postop_modrdn ) != 0 ||
+		slapi_pblock_set( pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,
+			(void *) memberof_postop_modify ) != 0 ||
+		slapi_pblock_set( pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,
+			(void *) memberof_postop_add ) != 0) {
+		slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+			"memberof_internal_postop_init: failed to register plugin\n");
+		status = -1;
+	}
+
+	return status;
+}
+
 /*
  * memberof_postop_start()
  *
@@ -239,6 +273,11 @@ int memberof_postop_start(Slapi_PBlock *pb)
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		"--> memberof_postop_start\n" );
 
+	/* Check if we're already started */
+	if (g_plugin_started) {
+		goto bail;
+	}
+
 	memberof_operation_lock = slapi_new_mutex();
 	if(0 == memberof_operation_lock)
 	{
@@ -265,6 +304,8 @@ int memberof_postop_start(Slapi_PBlock *pb)
 		goto bail;
 	}
 
+	g_plugin_started = 1;
+
 	/*
 	 * TODO: start up operation actor thread
 	 * need to get to a point where server failure
@@ -293,7 +334,7 @@ int memberof_postop_close(Slapi_PBlock *pb)
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_close\n" );
 
-
+	g_plugin_started = 0;
 
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "<-- memberof_postop_close\n" );
@@ -316,10 +357,19 @@ int memberof_postop_del(Slapi_PBlock *pb)
 	int ret = 0;
 	MemberOfConfig configCopy = {0, 0, 0, 0};
 	char *dn;
+	void *caller_id = NULL;
 
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_del\n" );
 
+	/* We don't want to process internal modify
+	 * operations that originate from this plugin. */
+	slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &caller_id);
+	if (caller_id == memberof_get_plugin_id()) {
+		/* Just return without processing */
+		return 0;
+	}
+
 	if(memberof_oktodo(pb) && (dn = memberof_getdn(pb)))
 	{
 		struct slapi_entry *e = NULL;
@@ -532,10 +582,19 @@ int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn,
 int memberof_postop_modrdn(Slapi_PBlock *pb)
 {
 	int ret = 0;
+	void *caller_id = NULL;
 
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_modrdn\n" );
 
+	/* We don't want to process internal modify
+	 * operations that originate from this plugin. */
+	slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &caller_id);
+	if (caller_id == memberof_get_plugin_id()) {
+		/* Just return without processing */
+		return 0;
+	}
+
 	if(memberof_oktodo(pb))
 	{
 		MemberOfConfig *mainConfig = 0;
@@ -698,10 +757,19 @@ int memberof_postop_modify(Slapi_PBlock *pb)
 	Slapi_Mod *smod = 0;
 	LDAPMod **mods;
 	Slapi_Mod *next_mod = 0;
+	void *caller_id = NULL;
 
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_modify\n" );
 
+	/* We don't want to process internal modify
+	 * operations that originate from this plugin. */
+	slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &caller_id);
+	if (caller_id == memberof_get_plugin_id()) {
+		/* Just return without processing */
+		return 0;
+	}
+
 	if(memberof_oktodo(pb) &&
 		(dn = memberof_getdn(pb)))
 	{
@@ -831,10 +899,19 @@ int memberof_postop_add(Slapi_PBlock *pb)
 	int ret = 0;
 	int interested = 0;
 	char *dn = 0;
+	void *caller_id = NULL;
 
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_add\n" );
 
+	/* We don't want to process internal modify
+	 * operations that originate from this plugin. */
+	slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &caller_id);
+	if (caller_id == memberof_get_plugin_id()) {
+		/* Just return without processing */
+		return 0;
+	}
+
 	if(memberof_oktodo(pb) && (dn = memberof_getdn(pb)))
 	{
 		MemberOfConfig *mainConfig = 0;
@@ -902,6 +979,11 @@ int memberof_oktodo(Slapi_PBlock *pb)
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_oktodo\n" );
 
+	if (!g_plugin_started) {
+		ret = 0;
+		goto bail;
+	}
+
 	if(slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0) 
         {
 		slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
@@ -919,6 +1001,7 @@ int memberof_oktodo(Slapi_PBlock *pb)
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "<-- memberof_postop_oktodo\n" );
 
+bail:
 	return ret;
 }
 

+ 1 - 0
ldap/servers/plugins/memberof/memberof.h

@@ -62,6 +62,7 @@
  * macros
  */
 #define MEMBEROF_PLUGIN_SUBSYSTEM   "memberof-plugin"   /* used for logging */
+#define MEMBEROF_INT_PREOP_DESC "memberOf internal postop plugin"
 #define MEMBEROF_GROUP_ATTR "memberOfGroupAttr"
 #define MEMBEROF_ATTR "memberOfAttr"
 #define DN_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.12"