Ver código fonte

Ticket 47526 - Allow memberof suffixes to be configurable

Bug Description:  Request to apply referential memberof operations
			to specific subtrees only

Fix Description:  The fix adds a configuration parameters to the
	memberof plugin:
	nsslapd-memberofScope: <dn>

	The logic implemented is:
		If a member is added top group only if member and group
		are in the defined memberof scope the memberof attribute
		is updated.
		If an entry is deleted and it is inside the scope, its
		member references will be purged (like befoer, only apply scope)
		If an entry is renamed and moved out of scope it will be handled
		like a deletie and in addition its memberof attribute is removed.

https://fedorahosted.org/389/ticket/47526

Reviewed by:  Thierry,Rich,Noriko -Thanks
Ludwig Krispenz 12 anos atrás
pai
commit
11898c30ca

+ 28 - 1
ldap/servers/plugins/memberof/memberof.c

@@ -666,6 +666,7 @@ int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
 	char *filter_str = NULL;
 	char *cookie = NULL;
 	int all_backends = memberof_config_get_all_backends();
+	Slapi_DN *entry_scope = memberof_config_get_entry_scope();
 	int types_name_len = 0;
 	int num_types = 0;
 	int dn_len = slapi_sdn_get_ndn_len(sdn);
@@ -673,6 +674,10 @@ int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
 	int rc = 0;
 	int i = 0;
 
+	if (entry_scope && !slapi_sdn_issuffix(sdn, entry_scope)) {
+		return (rc);
+	}
+
 	/* Count the number of types. */
 	for (num_types = 0; types && types[num_types]; num_types++)
 	{
@@ -741,6 +746,21 @@ int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
 				continue;
 			}
 		}
+		if (entry_scope) {
+			if (slapi_sdn_issuffix(base_sdn, entry_scope)) {
+				/* do nothing, entry scope is spanning 
+				 * multiple suffixes, start at suffix */
+			} else if (slapi_sdn_issuffix(entry_scope, base_sdn)) {
+				/* scope is below suffix, set search base */
+				base_sdn = entry_scope;
+			} else if(!all_backends){
+				break;
+			} else {
+				/* its ok, goto the next backend */
+				be = slapi_get_next_backend(cookie);
+				continue;
+			}
+		}
 
 		slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
 			LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0, memberof_get_plugin_id(), 0);
@@ -770,6 +790,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
 {
 	int ret = SLAPI_PLUGIN_SUCCESS;
 	void *caller_id = NULL;
+	Slapi_DN *entry_scope = memberof_config_get_entry_scope();
 
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_modrdn\n" );
@@ -833,7 +854,13 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
 		 * of other group entries.  We need to update any member
 		 * attributes to refer to the new name. */
 		if (pre_sdn && post_sdn) {
-			memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn);
+			if (entry_scope && !slapi_sdn_issuffix(post_sdn, entry_scope)) {
+				memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
+				memberof_del_dn_from_groups(pb, &configCopy, pre_sdn);
+				memberof_del_dn_type_callback(post_e, &del_data);
+			} else {
+				memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn);
+			}
 		}
 
 		memberof_unlock();

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

@@ -67,6 +67,7 @@
 #define MEMBEROF_GROUP_ATTR "memberOfGroupAttr"
 #define MEMBEROF_ATTR "memberOfAttr"
 #define MEMBEROF_BACKEND_ATTR "memberOfAllBackends"
+#define MEMBEROF_ENTRY_SCOPE_ATTR "memberOfEntryScope"
 #define DN_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.12"
 #define NAME_OPT_UID_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.34"
 
@@ -78,6 +79,7 @@ typedef struct memberofconfig {
 	char **groupattrs;
 	char *memberof_attr;
 	int allBackends;
+	Slapi_DN *entryScope;
 	Slapi_Filter *group_filter;
 	Slapi_Attr **group_slapiattrs;
 } MemberOfConfig;
@@ -96,6 +98,7 @@ void memberof_rlock_config();
 void memberof_wlock_config();
 void memberof_unlock_config();
 int memberof_config_get_all_backends();
+Slapi_DN * memberof_config_get_entry_scope();
 void memberof_set_config_area(Slapi_DN *sdn);
 Slapi_DN * memberof_get_config_area();
 void memberof_set_plugin_area(Slapi_DN *sdn);

+ 31 - 1
ldap/servers/plugins/memberof/memberof_config.c

@@ -77,7 +77,7 @@ static int memberof_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_En
 /* This is the main configuration which is updated from dse.ldif.  The
  * config will be copied when it is used by the plug-in to prevent it
  * being changed out from under a running memberOf operation. */
-static MemberOfConfig theConfig;
+static MemberOfConfig theConfig = {NULL, NULL,0, NULL, NULL, NULL};
 static Slapi_RWLock *memberof_config_lock = 0;
 static int inited = 0;
 
@@ -310,6 +310,7 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
 	int num_groupattrs = 0;
 	int groupattr_name_len = 0;
 	char *allBackends = NULL;
+	char *entryScope = NULL;
 	char *sharedcfg = NULL;
 
 	*returncode = LDAP_SUCCESS;
@@ -360,6 +361,7 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
 	groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR);
 	memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR);
 	allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR);
+	entryScope = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_ATTR);
 
 	/* We want to be sure we don't change the config in the middle of
 	 * a memberOf operation, so we obtain an exclusive lock here */
@@ -469,6 +471,22 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
 		theConfig.allBackends = 0;
 	}
 
+	slapi_sdn_free(&theConfig.entryScope);
+	if (entryScope)
+	{
+        	if (slapi_dn_syntax_check(NULL, entryScope, 1) == 1) {
+            		slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+                		"Error: Ignoring invalid DN used as plugin entry scope: [%s]\n",
+                		entryScope);
+			theConfig.entryScope = NULL;
+			slapi_ch_free_string(&entryScope);
+		} else {
+			theConfig.entryScope = slapi_sdn_new_dn_passin(entryScope);
+		}
+	} else {
+		theConfig.entryScope = NULL;
+	}
+
 	/* release the lock */
 	memberof_unlock_config();
 
@@ -648,6 +666,18 @@ memberof_config_get_all_backends()
 	return all_backends;
 }
 
+Slapi_DN *
+memberof_config_get_entry_scope()
+{
+	Slapi_DN *entry_scope;
+
+	slapi_rwlock_rdlock(memberof_config_lock);
+	entry_scope = theConfig.entryScope;
+	slapi_rwlock_unlock(memberof_config_lock);
+
+	return entry_scope;
+}
+
 /*
  * Check if we are modifying the config, or changing the shared config entry
  */