From 3aa53a7e4b705d4da951c6946d5b59cbb9983051 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 24 Nov 2014 16:58:57 -0500 Subject: [PATCH] Ticket 47963 - RFE - memberOf - add option to skip nested group lookups during delete operations Bug Description: The recursive nested group lookups performed during a group delete operation can take a very long time to complete if there are very large static groups(groups with with over 10K members). If there are no nested groups, then it would be nice to have an option to skip the nested group check, which would significantly improve delete performance. Fix Description: Added a new memberOf plugin configuration attribute: memberOfSkipNested: on|off https://fedorahosted.org/389/ticket/47963 Reviewed by: ? --- ldap/servers/plugins/memberof/memberof.c | 6 +++-- ldap/servers/plugins/memberof/memberof.h | 2 ++ ldap/servers/plugins/memberof/memberof_config.c | 31 +++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c index b1c51a1..118d232 100644 --- a/ldap/servers/plugins/memberof/memberof.c +++ b/ldap/servers/plugins/memberof/memberof.c @@ -2816,8 +2816,10 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) memberof_del_dn_data del_data = {0, config->memberof_attr}; Slapi_ValueSet *groups = 0; - /* get a list of all of the groups this user belongs to */ - groups = memberof_get_groups(config, sdn); + if(!config->skip_nested){ + /* get a list of all of the groups this user belongs to */ + groups = memberof_get_groups(config, sdn); + } /* If we found some groups, replace the existing memberOf attribute * with the found values. */ diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h index 6d56081..93f031b 100644 --- a/ldap/servers/plugins/memberof/memberof.h +++ b/ldap/servers/plugins/memberof/memberof.h @@ -69,6 +69,7 @@ #define MEMBEROF_BACKEND_ATTR "memberOfAllBackends" #define MEMBEROF_ENTRY_SCOPE_ATTR "memberOfEntryScope" #define MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE "memberOfEntryScopeExcludeSubtree" +#define MEMBEROF_SKIP_NESTED_ATTR "memberOfSkipNested" #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" @@ -84,6 +85,7 @@ typedef struct memberofconfig { Slapi_DN *entryScopeExcludeSubtree; Slapi_Filter *group_filter; Slapi_Attr **group_slapiattrs; + int skip_nested; } MemberOfConfig; diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c index df8ddcb..8efbe2f 100644 --- a/ldap/servers/plugins/memberof/memberof_config.c +++ b/ldap/servers/plugins/memberof/memberof_config.c @@ -193,6 +193,7 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr Slapi_DN *config_sdn = NULL; char *syntaxoid = NULL; char *config_dn = NULL; + char *skip_nested = NULL; int not_dn_syntax = 0; *returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */ @@ -272,6 +273,16 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr goto done; } + if ((skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR))){ + if(strcasecmp(skip_nested, "on") != 0 && strcasecmp(skip_nested, "off") != 0){ + PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, + "The %s configuration attribute must be set to " + "\"on\" or \"off\". (illegal value: %s)", + MEMBEROF_SKIP_NESTED_ATTR, skip_nested); + goto done; + } + } + if ((config_dn = slapi_entry_attr_get_charptr(e, SLAPI_PLUGIN_SHARED_CONFIG_AREA))){ /* Now check the shared config attribute, validate it now */ @@ -305,6 +316,7 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr done: slapi_sdn_free(&config_sdn); slapi_ch_free_string(&config_dn); + slapi_ch_free_string(&skip_nested); if (*returncode != LDAP_SUCCESS) { @@ -336,8 +348,9 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* int groupattr_name_len = 0; char *allBackends = NULL; char *entryScope = NULL; - char *entryScopeExcludeSubtree = NULL; + char *entryScopeExcludeSubtree = NULL; char *sharedcfg = NULL; + char *skip_nested = NULL; *returncode = LDAP_SUCCESS; @@ -388,7 +401,8 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* 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); - entryScopeExcludeSubtree = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE); + entryScopeExcludeSubtree = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE); + skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_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 */ @@ -487,6 +501,14 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* memberof_attr = NULL; /* config now owns memory */ } + if (skip_nested){ + if(strcasecmp(skip_nested,"on") == 0){ + theConfig.skip_nested = 1; + } else { + theConfig.skip_nested = 0; + } + } + if (allBackends) { if(strcasecmp(allBackends,"on")==0){ @@ -556,6 +578,7 @@ done: slapi_ch_array_free(groupattrs); slapi_ch_free_string(&memberof_attr); slapi_ch_free_string(&allBackends); + slapi_ch_free_string(&skip_nested); if (*returncode != LDAP_SUCCESS) { @@ -628,6 +651,10 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) dest->memberof_attr = slapi_ch_strdup(src->memberof_attr); } + if(src->skip_nested){ + dest->skip_nested = src->skip_nested; + } + if(src->allBackends) { dest->allBackends = src->allBackends; -- 1.9.3