Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 309804 Details for
Bug 450989
memberOf: Make group and memberOf attributes configurable
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
CVS Diffs
diffs.txt (text/plain), 65.47 KB, created by
Nathan Kinder
on 2008-06-18 23:08:46 UTC
(
hide
)
Description:
CVS Diffs
Filename:
MIME Type:
Creator:
Nathan Kinder
Created:
2008-06-18 23:08:46 UTC
Size:
65.47 KB
patch
obsolete
>Index: Makefile.am >=================================================================== >RCS file: /cvs/dirsec/ldapserver/Makefile.am,v >retrieving revision 1.69 >diff -u -5 -t -r1.69 Makefile.am >--- Makefile.am 10 Jun 2008 20:24:01 -0000 1.69 >+++ Makefile.am 18 Jun 2008 22:57:02 -0000 >@@ -649,11 +649,12 @@ > libcollation_plugin_la_LINK = $(CXXLINK) > > #------------------------ > # libmemberof-plugin > #------------------------ >-libmemberof_plugin_la_SOURCES= ldap/servers/plugins/memberof/memberof.c >+libmemberof_plugin_la_SOURCES= ldap/servers/plugins/memberof/memberof.c \ >+ ldap/servers/plugins/memberof/memberof_config.c > > libmemberof_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) > libmemberof_plugin_la_LDFLAGS = -avoid-version > > #------------------------ >Index: ldap/ldif/template-dse.ldif.in >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/ldif/template-dse.ldif.in,v >retrieving revision 1.7 >diff -u -5 -t -r1.7 template-dse.ldif.in >--- ldap/ldif/template-dse.ldif.in 5 Jun 2008 19:11:50 -0000 1.7 >+++ ldap/ldif/template-dse.ldif.in 18 Jun 2008 22:57:06 -0000 >@@ -406,10 +406,12 @@ > nsslapd-pluginpath: libmemberof-plugin > nsslapd-plugininitfunc: memberof_postop_init > nsslapd-plugintype: postoperation > nsslapd-pluginenabled: off > nsslapd-plugin-depends-on-type: database >+memberOfGroupAttr: member >+memberOfAttr: memberOf > > dn: cn=Multimaster Replication Plugin,cn=plugins,cn=config > objectclass: top > objectclass: nsSlapdPlugin > objectclass: extensibleObject >Index: ldap/servers/plugins/memberof/memberof.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/memberof/memberof.c,v >retrieving revision 1.8 >diff -u -5 -t -r1.8 memberof.c >--- ldap/servers/plugins/memberof/memberof.c 9 Jun 2008 21:43:59 -0000 1.8 >+++ ldap/servers/plugins/memberof/memberof.c 18 Jun 2008 22:57:08 -0000 >@@ -70,22 +70,18 @@ > #include <dirlite_strings.h> /* PLUGIN_MAGIC_VENDOR_STR */ > > #include "string.h" > #include "nspr.h" > >-#define MEMBEROF_GROUP_ATTR "member" >-#define MEMBEROF_ATTR "memberof" >-#define MEMBEROF_GROUP_ATTR_IS_DN 1 >-#define MEMBEROF_GROUP_FILTER "(" MEMBEROF_GROUP_ATTR "=*)" >+#include "memberof.h" > >-#define MEMBEROF_PLUGIN_SUBSYSTEM "memberof-plugin" /* used for logging */ > static Slapi_PluginDesc pdesc = { "memberof", PLUGIN_MAGIC_VENDOR_STR, > PRODUCTTEXT, "memberof plugin" }; > > static void* _PluginID = NULL; >-static Slapi_Filter *memberof_group_filter = NULL; > static Slapi_Mutex *memberof_operation_lock = 0; >+MemberOfConfig *qsortConfig = 0; > > typedef struct _memberofstringll > { > const char *dn; > void *next; >@@ -105,59 +101,72 @@ > static int memberof_postop_close(Slapi_PBlock *pb); > > /* supporting cast */ > static int memberof_oktodo(Slapi_PBlock *pb); > static char *memberof_getdn(Slapi_PBlock *pb); >-static int memberof_modop_one(Slapi_PBlock *pb, int mod_op, char *op_this, char *op_to); >-static int memberof_modop_one_r(Slapi_PBlock *pb, int mod_op, char *group_dn, >- char *op_this, char *op_to, memberofstringll *stack); >-static int memberof_add_one(Slapi_PBlock *pb, char *addthis, char *addto); >-static int memberof_del_one(Slapi_PBlock *pb, char *delthis, char *delfrom); >-static int memberof_mod_smod_list(Slapi_PBlock *pb, int mod, char *groupdn, >- Slapi_Mod *smod); >-static int memberof_add_smod_list(Slapi_PBlock *pb, char *groupdn, Slapi_Mod *smod); >-static int memberof_del_smod_list(Slapi_PBlock *pb, char *groupdn, Slapi_Mod *smod); >-static int memberof_mod_attr_list(Slapi_PBlock *pb, int mod, char *groupdn, >- Slapi_Attr *attr); >-static int memberof_mod_attr_list_r(Slapi_PBlock *pb, int mod, char *group_dn, >- char *op_this, Slapi_Attr *attr, memberofstringll *stack); >-static int memberof_add_attr_list(Slapi_PBlock *pb, char *groupdn, Slapi_Attr *attr); >-static int memberof_del_attr_list(Slapi_PBlock *pb, char *groupdn, Slapi_Attr *attr); >-static int memberof_moddn_attr_list(Slapi_PBlock *pb, char *pre_dn, char *post_dn, >- Slapi_Attr *attr); >-static int memberof_replace_list(Slapi_PBlock *pb, char *group_dn); >+static int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, >+ char *op_this, char *op_to); >+static int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, >+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack); >+static int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, >+ char *addto); >+static int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, >+ char *delfrom); >+static int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod, >+ char *groupdn, Slapi_Mod *smod); >+static int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *groupdn, Slapi_Mod *smod); >+static int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *groupdn, Slapi_Mod *smod); >+static int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod, >+ char *groupdn, Slapi_Attr *attr); >+static int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, >+ int mod, char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack); >+static int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *groupdn, Slapi_Attr *attr); >+static int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *groupdn, Slapi_Attr *attr); >+static int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *pre_dn, char *post_dn, Slapi_Attr *attr); >+static int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn); > static void memberof_set_plugin_id(void * plugin_id); > static void *memberof_get_plugin_id(); >-static int memberof_compare(const void *a, const void *b); >+static int memberof_compare(MemberOfConfig *config, const void *a, const void *b); >+static int memberof_qsort_compare(const void *a, const void *b); > static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr); >-static Slapi_Filter *memberof_string2filter(char *strfilter); >-static int memberof_is_legit_member(Slapi_PBlock *pb, char *group_dn, >- char *op_this, char *op_to, memberofstringll *stack); >-static int memberof_del_dn_from_groups(Slapi_PBlock *pb, char *dn); >+static int memberof_is_legit_member(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack); >+static int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn); > static int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn, > char *type, plugin_search_entry_callback callback, void *callback_data); >-static int memberof_is_direct_member(Slapi_Value *groupdn, Slapi_Value *memberdn); >-static int memberof_is_member(Slapi_Value *groupdn, Slapi_Value *memberdn); >-static int memberof_test_membership(Slapi_PBlock *pb, char *group_dn); >+static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, >+ Slapi_Value *memberdn); >+static int memberof_is_member(MemberOfConfig *config, Slapi_Value *groupdn, >+ Slapi_Value *memberdn); >+static int memberof_is_member_r(MemberOfConfig *config, Slapi_Value *groupdn, >+ Slapi_Value *memberdn, memberofstringll *stack); >+static int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *group_dn); > static int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data); > static int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data); > static int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data); >-static int memberof_replace_dn_from_groups(Slapi_PBlock *pb, char *pre_dn, char *post_dn); >-static int memberof_modop_one_replace_r(Slapi_PBlock *pb, int mod_op, char *group_dn, >- char *op_this, char *replace_with, char *op_to, memberofstringll *stack); >-static void memberof_lock(); >-static void memberof_unlock(); >+static int memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *pre_dn, char *post_dn); >+static int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, >+ int mod_op, char *group_dn, char *op_this, char *replace_with, char *op_to, >+ memberofstringll *stack); > static int memberof_add_groups_search_callback(Slapi_Entry *e, void *callback_data); >-static int memberof_add_membership(Slapi_PBlock *pb, char *op_this, char *op_to); >+static int memberof_add_membership(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *op_this, char *op_to); > static int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, > void *arg); > static void memberof_task_destructor(Slapi_Task *task); > static const char *fetch_attr(Slapi_Entry *e, const char *attrname, > const char *default_val); > static void memberof_fixup_task_thread(void *arg); >-static int memberof_fix_memberof(char *dn, char *filter_str); >+static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str); > static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data); > > > /*** implementation ***/ > >@@ -221,24 +230,35 @@ > * > */ > int memberof_postop_start(Slapi_PBlock *pb) > { > int rc = 0; >+ Slapi_Entry *config_e = NULL; /* entry containing plugin config */ > > slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, > "--> memberof_postop_start\n" ); > >- memberof_group_filter = memberof_string2filter(MEMBEROF_GROUP_FILTER); >- > memberof_operation_lock = slapi_new_mutex(); >- >- if(0 == memberof_group_filter || 0 == memberof_operation_lock) >+ if(0 == memberof_operation_lock) > { > rc = -1; > goto bail; > } > >+ if ( slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &config_e ) != 0 ) { >+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, >+ "missing config entry\n" ); >+ rc = -1; >+ goto bail; >+ } >+ >+ if (( rc = memberof_config( config_e )) != LDAP_SUCCESS ) { >+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, >+ "configuration failed (%s)\n", ldap_err2string( rc )); >+ return( -1 ); >+ } >+ > rc = slapi_task_register_handler("memberof task", memberof_task_add); > if(rc) > { > goto bail; > } >@@ -290,36 +310,46 @@ > * really have those groups removed too) > */ > int memberof_postop_del(Slapi_PBlock *pb) > { > int ret = 0; >+ MemberOfConfig configCopy = {0, 0, 0, 0}; > char *dn; > > slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, > "--> memberof_postop_del\n" ); > > if(memberof_oktodo(pb) && (dn = memberof_getdn(pb))) > { > struct slapi_entry *e = NULL; > > slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e ); >- >- memberof_lock(); > >+ /* We need to get the config lock first. Trying to get the >+ * config lock after we already hold the op lock can cause >+ * a deadlock. */ >+ memberof_rlock_config(); >+ /* copy config so it doesn't change out from under us */ >+ memberof_copy_config(&configCopy, memberof_get_config()); >+ memberof_unlock_config(); >+ >+ /* get the memberOf operation lock */ >+ memberof_lock(); >+ > /* remove this group DN from the > * membership lists of groups > */ >- memberof_del_dn_from_groups(pb, dn); >+ memberof_del_dn_from_groups(pb, &configCopy, dn); > > /* is the entry of interest as a group? */ >- if(e && !slapi_filter_test_simple(e, memberof_group_filter)) >+ if(e && !slapi_filter_test_simple(e, configCopy.group_filter)) > { > Slapi_Attr *attr = 0; > >- if(0 == slapi_entry_attr_find(e, MEMBEROF_GROUP_ATTR, &attr)) >+ if(0 == slapi_entry_attr_find(e, configCopy.groupattr, &attr)) > { >- memberof_del_attr_list(pb, dn, attr); >+ memberof_del_attr_list(pb, &configCopy, dn, attr); > } > } > > memberof_unlock(); > } >@@ -333,16 +363,16 @@ > { > char *dn; > char *type; > } del_dn_data; > >-int memberof_del_dn_from_groups(Slapi_PBlock *pb, char *dn) >+int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn) > { >- del_dn_data data = {dn, MEMBEROF_GROUP_ATTR}; >+ del_dn_data data = {dn, config->groupattr}; > > return memberof_call_foreach_dn(pb, dn, >- MEMBEROF_GROUP_ATTR, memberof_del_dn_type_callback, &data); >+ config->groupattr, memberof_del_dn_type_callback, &data); > } > > int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data) > { > int rc = 0; >@@ -406,16 +436,11 @@ > base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0); > } > > if(base_sdn) > { >- int filter_size = >- (strlen(type) + >- strlen(dn) + 4); /* 4 for (=) + null */ >- filter_str = (char*)slapi_ch_malloc(filter_size); >- >- sprintf(filter_str, "(%s=%s)", type, dn); >+ filter_str = slapi_ch_smprintf("(%s=%s)", type, dn); > } > > if(filter_str) > { > slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn), >@@ -449,14 +474,17 @@ > slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, > "--> memberof_postop_modrdn\n" ); > > if(memberof_oktodo(pb)) > { >+ MemberOfConfig *mainConfig = 0; >+ MemberOfConfig configCopy = {0, 0, 0, 0}; > struct slapi_entry *pre_e = NULL; > struct slapi_entry *post_e = NULL; > char *pre_dn = 0; > char *post_dn = 0; >+ int interested = 0; > > slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e ); > slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e ); > > if(pre_e && post_e) >@@ -464,52 +492,62 @@ > pre_dn = slapi_entry_get_ndn(pre_e); > post_dn = slapi_entry_get_ndn(post_e); > } > > /* is the entry of interest? */ >- if(pre_dn && post_dn && >- !slapi_filter_test_simple(post_e, memberof_group_filter)) >+ memberof_rlock_config(); >+ mainConfig = memberof_get_config(); >+ if(pre_dn && post_dn && >+ !slapi_filter_test_simple(post_e, mainConfig->group_filter)) >+ { >+ interested = 1; >+ /* copy config so it doesn't change out from under us */ >+ memberof_copy_config(&configCopy, mainConfig); >+ } >+ memberof_unlock_config(); >+ >+ if(interested) > { > Slapi_Attr *attr = 0; > > memberof_lock(); > > /* get a list of member attributes present in the group > * entry that is being renamed. */ >- if(0 == slapi_entry_attr_find(post_e, MEMBEROF_GROUP_ATTR, &attr)) >+ if(0 == slapi_entry_attr_find(post_e, configCopy.groupattr, &attr)) > { >- memberof_moddn_attr_list(pb, pre_dn, post_dn, attr); >+ memberof_moddn_attr_list(pb, &configCopy, pre_dn, post_dn, attr); > } > > /* modrdn must change the dns in groups that have > * this group as a member. > */ >- memberof_replace_dn_from_groups(pb, pre_dn, post_dn); >+ memberof_replace_dn_from_groups(pb, &configCopy, pre_dn, post_dn); > > memberof_unlock(); > } > } > > > slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, > "<-- memberof_postop_modrdn\n" ); >- return ret;slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, >- "--> memberof_postop_modify\n" ); >+ return ret; > } > > typedef struct _replace_dn_data > { > char *pre_dn; > char *post_dn; > char *type; > } replace_dn_data; > >-int memberof_replace_dn_from_groups(Slapi_PBlock *pb, char *pre_dn, char *post_dn) >+int memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *pre_dn, char *post_dn) > { >- replace_dn_data data = {pre_dn, post_dn, MEMBEROF_GROUP_ATTR}; >+ replace_dn_data data = {pre_dn, post_dn, config->groupattr}; > >- return memberof_call_foreach_dn(pb, pre_dn, MEMBEROF_GROUP_ATTR, >+ return memberof_call_foreach_dn(pb, pre_dn, config->groupattr, > memberof_replace_dn_type_callback, &data); > } > > > int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data) >@@ -586,23 +624,53 @@ > "--> memberof_postop_modify\n" ); > > if(memberof_oktodo(pb) && > (dn = memberof_getdn(pb))) > { >+ int config_copied = 0; >+ MemberOfConfig *mainConfig = 0; >+ MemberOfConfig configCopy = {0, 0, 0, 0}; >+ > /* get the mod set */ > slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); > smods = slapi_mods_new(); > slapi_mods_init_byref(smods, mods); > > next_mod = slapi_mod_new(); > smod = slapi_mods_get_first_smod(smods, next_mod); > while(smod) > { >+ int interested = 0; > char *type = (char *)slapi_mod_get_type(smod); > >- /* we only care about the group attribute */ >- if(slapi_attr_types_equivalent(type,MEMBEROF_GROUP_ATTR)) >+ /* We only want to copy the config if we encounter an >+ * operation that we need to act on. We also want to >+ * only copy the config the first time it's needed so >+ * it remains the same for all mods in the operation, >+ * despite any config changes that may be made. */ >+ if (!config_copied) >+ { >+ memberof_rlock_config(); >+ mainConfig = memberof_get_config(); >+ >+ if(slapi_attr_types_equivalent(type, mainConfig->groupattr)) >+ { >+ interested = 1; >+ /* copy config so it doesn't change out from under us */ >+ memberof_copy_config(&configCopy, mainConfig); >+ config_copied = 1; >+ } >+ >+ memberof_unlock_config(); >+ } else { >+ if(slapi_attr_types_equivalent(type, configCopy.groupattr)) >+ { >+ interested = 1; >+ } >+ } >+ >+ if(interested) > { > int op = slapi_mod_get_operation(smod); > > memberof_lock(); > >@@ -610,11 +678,11 @@ > switch(op & ~LDAP_MOD_BVALUES) > { > case LDAP_MOD_ADD: > { > /* add group DN to targets */ >- memberof_add_smod_list(pb, dn, smod); >+ memberof_add_smod_list(pb, &configCopy, dn, smod); > break; > } > > case LDAP_MOD_DELETE: > { >@@ -622,24 +690,24 @@ > * just do a replace instead. The user is just > * trying to delete all members from this group > * entry, which the replace code deals with. */ > if (slapi_mod_get_num_values(smod) == 0) > { >- memberof_replace_list(pb, dn); >+ memberof_replace_list(pb, &configCopy, dn); > } > else > { > /* remove group DN from target values in smod*/ >- memberof_del_smod_list(pb, dn, smod); >+ memberof_del_smod_list(pb, &configCopy, dn, smod); > } > break; > } > > case LDAP_MOD_REPLACE: > { > /* replace current values */ >- memberof_replace_list(pb, dn); >+ memberof_replace_list(pb, &configCopy, dn); > break; > } > > default: > { >@@ -675,31 +743,45 @@ > * and have the group DN added to their memberOf attribute > */ > int memberof_postop_add(Slapi_PBlock *pb) > { > int ret = 0; >+ int interested = 0; > char *dn = 0; > > slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, > "--> memberof_postop_add\n" ); > > if(memberof_oktodo(pb) && (dn = memberof_getdn(pb))) > { >+ MemberOfConfig *mainConfig = 0; >+ MemberOfConfig configCopy = {0, 0, 0, 0}; > struct slapi_entry *e = NULL; > > slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e ); > >+ > /* is the entry of interest? */ >- if(e && !slapi_filter_test_simple(e, memberof_group_filter)) >+ memberof_rlock_config(); >+ mainConfig = memberof_get_config(); >+ if(e && !slapi_filter_test_simple(e, mainConfig->group_filter)) >+ { >+ interested = 1; >+ /* copy config so it doesn't change out from under us */ >+ memberof_copy_config(&configCopy, mainConfig); >+ } >+ memberof_unlock_config(); >+ >+ if(interested) > { > Slapi_Attr *attr = 0; > > memberof_lock(); > >- if(0 == slapi_entry_attr_find(e, MEMBEROF_GROUP_ATTR, &attr)) >+ if(0 == slapi_entry_attr_find(e, configCopy.groupattr, &attr)) > { >- memberof_add_attr_list(pb, dn, attr); >+ memberof_add_attr_list(pb, &configCopy, dn, attr); > } > > memberof_unlock(); > } > } >@@ -772,50 +854,51 @@ > * members to have the mod performed on them instead, and we must take > * care to not recurse when we have visted a group before > * > * Also, we must not delete entries that are a member of the group > */ >-int memberof_modop_one(Slapi_PBlock *pb, int mod_op, char *op_this, char *op_to) >+int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, >+ char *op_this, char *op_to) > { >- return memberof_modop_one_r(pb, mod_op, op_this, op_this, op_to, 0); >+ return memberof_modop_one_r(pb, config, mod_op, op_this, op_this, op_to, 0); > } > > /* memberof_modop_one_r() > * > * recursive function to perform above (most things don't need the replace arg) > */ > >-int memberof_modop_one_r(Slapi_PBlock *pb, int mod_op, char *group_dn, >- char *op_this, char *op_to, memberofstringll *stack) >+int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, >+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack) > { > return memberof_modop_one_replace_r( >- pb, mod_op, group_dn, op_this, 0, op_to, stack); >+ pb, config, mod_op, group_dn, op_this, 0, op_to, stack); > } > > /* memberof_modop_one_replace_r() > * > * recursive function to perform above (with added replace arg) > */ >-int memberof_modop_one_replace_r(Slapi_PBlock *pb, int mod_op, char *group_dn, >- char *op_this, char *replace_with, char *op_to, memberofstringll *stack) >+int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, >+ int mod_op, char *group_dn, char *op_this, char *replace_with, >+ char *op_to, memberofstringll *stack) > { > int rc = 0; > LDAPMod mod; > LDAPMod replace_mod; > LDAPMod *mods[3]; > char *val[2]; > char *replace_val[2]; > Slapi_PBlock *mod_pb = 0; >- char *attrlist[2] = {MEMBEROF_GROUP_ATTR,0}; >+ char *attrlist[2] = {config->groupattr,0}; > Slapi_DN *op_to_sdn = 0; > Slapi_Entry *e = 0; > memberofstringll *ll = 0; > char *op_str = 0; > Slapi_Value *to_dn_val = slapi_value_new_string(op_to); > Slapi_Value *this_dn_val = slapi_value_new_string(op_this); > >- > /* determine if this is a group op or single entry */ > op_to_sdn = slapi_sdn_new_dn_byref(op_to); > slapi_search_internal_get_entry( op_to_sdn, attrlist, > &e, memberof_get_plugin_id()); > slapi_sdn_free(&op_to_sdn); >@@ -829,11 +912,11 @@ > * and we must fall back to testing all members > * of the (potentially deleted group) for valid > * membership given the delete operation that > * triggered this operation > */ >- memberof_test_membership(pb, group_dn); >+ memberof_test_membership(pb, config, group_dn); > } > > goto bail; > } > >@@ -853,14 +936,14 @@ > { > op_str = "UNKNOWN"; > } > > slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, >- "memberof_modop_one_r: %s %s in %s\n" >+ "memberof_modop_one_replace_r: %s %s in %s\n" > ,op_str, op_this, op_to); > >- if(!slapi_filter_test_simple(e, memberof_group_filter)) >+ if(!slapi_filter_test_simple(e, config->group_filter)) > { > /* group */ > Slapi_Value *ll_dn_val = 0; > Slapi_Attr *members = 0; > >@@ -869,19 +952,19 @@ > /* have we been here before? */ > while(ll) > { > ll_dn_val = slapi_value_new_string(ll->dn); > >- if(0 == memberof_compare(&ll_dn_val, &to_dn_val)) >+ if(0 == memberof_compare(config, &ll_dn_val, &to_dn_val)) > { > slapi_value_free(&ll_dn_val); > > /* someone set up infinitely > recursive groups - bail out */ > slapi_log_error( SLAPI_LOG_FATAL, > MEMBEROF_PLUGIN_SUBSYSTEM, >- "memberof_modop_one_r: group recursion" >+ "memberof_modop_one_replace_r: group recursion" > " detected in %s\n" > ,op_to); > goto bail; > } > >@@ -890,21 +973,21 @@ > } > > /* do op on group */ > slapi_log_error( SLAPI_LOG_PLUGIN, > MEMBEROF_PLUGIN_SUBSYSTEM, >- "memberof_modop_one_r: descending into group %s\n", >+ "memberof_modop_one_replace_r: descending into group %s\n", > op_to); > /* Add the nested group's DN to the stack so we can detect loops later. */ > ll = (memberofstringll*)slapi_ch_malloc(sizeof(memberofstringll)); > ll->dn = op_to; > ll->next = stack; > >- slapi_entry_attr_find( e, MEMBEROF_GROUP_ATTR, &members ); >+ slapi_entry_attr_find( e, config->groupattr, &members ); > if(members) > { >- memberof_mod_attr_list_r(pb, mod_op, group_dn, op_this, members, ll); >+ memberof_mod_attr_list_r(pb, config, mod_op, group_dn, op_this, members, ll); > } > > { > /* crazyness follows: > * strict-aliasing doesn't like the required cast >@@ -919,46 +1002,47 @@ > /* continue with operation */ > { > /* We want to avoid listing a group as a memberOf itself > * in case someone set up a circular grouping. > */ >- if (0 == memberof_compare(&this_dn_val, &to_dn_val)) >+ if (0 == memberof_compare(config, &this_dn_val, &to_dn_val)) > { > slapi_log_error( SLAPI_LOG_PLUGIN, > MEMBEROF_PLUGIN_SUBSYSTEM, >- "memberof_modop_one_r: not processing memberOf " >+ "memberof_modop_one_replace_r: not processing memberOf " > "operations on self entry: %s\n", this_dn_val); > goto bail; > } > > /* We need to deal with delete cases separately. We may not > * want to remove a memberof attribute from an entry since > * it could still be a member in some other indirect manner. */ > if(stack && LDAP_MOD_DELETE == mod_op) > { >- if(memberof_is_legit_member(pb, group_dn, >+ if(memberof_is_legit_member(pb, config, group_dn, > op_this, op_to, stack)) > { > /* entry is member some other way too */ > slapi_log_error( SLAPI_LOG_PLUGIN, > MEMBEROF_PLUGIN_SUBSYSTEM, >- "memberof_modop_one_r: not deleting %s\n" >+ "memberof_modop_one_replace_r: not deleting %s\n" > ,op_to); > goto bail; > } > } > > /* Check if the entry is still an indirect member. If it is, we > * don't want to remove the memberOf value. */ >- if((LDAP_MOD_DELETE != mod_op) || (0 == memberof_is_member(this_dn_val, to_dn_val))) { >+ if((LDAP_MOD_DELETE != mod_op) || >+ (0 == memberof_is_member(config, this_dn_val, to_dn_val))) { > /* If we're about to add a memberOf value to an entry, we should first check > * if the value already exists. */ > if((LDAP_MOD_ADD == mod_op) && (slapi_entry_attr_has_syntax_value(e, >- MEMBEROF_ATTR, this_dn_val))) >+ config->memberof_attr, this_dn_val))) > { > slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, >- "memberof_modop_one_r: memberOf value %s already exists in " >+ "memberof_modop_one_replace_r: memberOf value %s already exists in " > "entry %s\n", op_this, op_to); > goto bail; > } > > /* single entry - do mod */ >@@ -977,20 +1061,20 @@ > > val[0] = op_this; > val[1] = 0; > > mod.mod_op = LDAP_MOD_REPLACE == mod_op?LDAP_MOD_DELETE:mod_op; >- mod.mod_type = MEMBEROF_ATTR; >+ mod.mod_type = config->memberof_attr; > mod.mod_values = val; > > if(LDAP_MOD_REPLACE == mod_op) > { > replace_val[0] = replace_with; > replace_val[1] = 0; > > replace_mod.mod_op = LDAP_MOD_ADD; >- replace_mod.mod_type = MEMBEROF_ATTR; >+ replace_mod.mod_type = config->memberof_attr; > replace_mod.mod_values = replace_val; > } > > slapi_modify_internal_set_pb( > mod_pb, op_to, >@@ -1007,20 +1091,20 @@ > } > > if(LDAP_MOD_DELETE == mod_op) > { > /* fix up membership for groups that have been orphaned */ >- memberof_test_membership_callback(e, 0); >+ memberof_test_membership_callback(e, config); > } > > if(LDAP_MOD_ADD == mod_op) > { > /* If we failed to update memberOf for op_to, we shouldn't > * try to fix up membership for parent groups. */ > if (rc == 0) { > /* fix up membership for groups that are now in scope */ >- memberof_add_membership(pb, op_this, op_to); >+ memberof_add_membership(pb, config, op_this, op_to); > } > } > } > > bail: >@@ -1035,33 +1119,34 @@ > * memberof_add_one() > * > * Add addthis DN to the memberof attribute of addto > * > */ >-int memberof_add_one(Slapi_PBlock *pb, char *addthis, char *addto) >+int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, char *addto) > { >- return memberof_modop_one(pb, LDAP_MOD_ADD, addthis, addto); >+ return memberof_modop_one(pb, config, LDAP_MOD_ADD, addthis, addto); > } > > /* > * memberof_del_one() > * > * Delete delthis DN from the memberof attribute of delfrom > * > */ >-int memberof_del_one(Slapi_PBlock *pb, char *delthis, char *delfrom) >+int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, char *delfrom) > { >- return memberof_modop_one(pb, LDAP_MOD_DELETE, delthis, delfrom); >+ return memberof_modop_one(pb, config, LDAP_MOD_DELETE, delthis, delfrom); > } > > /* > * memberof_mod_smod_list() > * > * Perform mod for group DN to the memberof attribute of the list of targets > * > */ >-int memberof_mod_smod_list(Slapi_PBlock *pb, int mod, char *group_dn, Slapi_Mod *smod) >+int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod, >+ char *group_dn, Slapi_Mod *smod) > { > int rc = 0; > struct berval *bv = slapi_mod_get_first_value(smod); > int last_size = 0; > char *last_str = 0; >@@ -1089,11 +1174,11 @@ > > memset(dn_str, 0, last_size); > > strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len); > >- memberof_modop_one(pb, mod, group_dn, dn_str); >+ memberof_modop_one(pb, config, mod, group_dn, dn_str); > > bv = slapi_mod_get_next_value(smod); > } > > if(last_str) >@@ -1106,25 +1191,27 @@ > * memberof_add_smod_list() > * > * Add group DN to the memberof attribute of the list of targets > * > */ >-int memberof_add_smod_list(Slapi_PBlock *pb, char *groupdn, Slapi_Mod *smod) >+int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *groupdn, Slapi_Mod *smod) > { >- return memberof_mod_smod_list(pb, LDAP_MOD_ADD, groupdn, smod); >+ return memberof_mod_smod_list(pb, config, LDAP_MOD_ADD, groupdn, smod); > } > > > /* > * memberof_del_smod_list() > * > * Remove group DN from the memberof attribute of the list of targets > * > */ >-int memberof_del_smod_list(Slapi_PBlock *pb, char *groupdn, Slapi_Mod *smod) >+int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *groupdn, Slapi_Mod *smod) > { >- return memberof_mod_smod_list(pb, LDAP_MOD_DELETE, groupdn, smod); >+ return memberof_mod_smod_list(pb, config, LDAP_MOD_DELETE, groupdn, smod); > } > > /** > * Plugin identity mgmt > */ >@@ -1143,17 +1230,18 @@ > * memberof_mod_attr_list() > * > * Perform mod for group DN to the memberof attribute of the list of targets > * > */ >-int memberof_mod_attr_list(Slapi_PBlock *pb, int mod, char *group_dn, Slapi_Attr *attr) >+int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod, >+ char *group_dn, Slapi_Attr *attr) > { >- return memberof_mod_attr_list_r(pb, mod, group_dn, group_dn, attr, 0); >+ return memberof_mod_attr_list_r(pb, config, mod, group_dn, group_dn, attr, 0); > } > >-int memberof_mod_attr_list_r(Slapi_PBlock *pb, int mod, char *group_dn, char *op_this, >- Slapi_Attr *attr, memberofstringll *stack) >+int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod, >+ char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack) > { > int rc = 0; > Slapi_Value *val = 0; > int last_size = 0; > char *last_str = 0; >@@ -1187,16 +1275,16 @@ > > /* If we're doing a replace (as we would in the MODRDN case), we need > * to specify the new group DN value */ > if(mod == LDAP_MOD_REPLACE) > { >- memberof_modop_one_replace_r(pb, mod, group_dn, op_this, group_dn, >+ memberof_modop_one_replace_r(pb, config, mod, group_dn, op_this, group_dn, > dn_str, stack); > } > else > { >- memberof_modop_one_r(pb, mod, group_dn, op_this, dn_str, stack); >+ memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack); > } > > hint = slapi_attr_next_value(attr, hint, &val); > } > >@@ -1210,33 +1298,36 @@ > * memberof_add_attr_list() > * > * Add group DN to the memberof attribute of the list of targets > * > */ >-int memberof_add_attr_list(Slapi_PBlock *pb, char *groupdn, Slapi_Attr *attr) >+int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn, >+ Slapi_Attr *attr) > { >- return memberof_mod_attr_list(pb, LDAP_MOD_ADD, groupdn, attr); >+ return memberof_mod_attr_list(pb, config, LDAP_MOD_ADD, groupdn, attr); > } > > /* > * memberof_del_attr_list() > * > * Remove group DN from the memberof attribute of the list of targets > * > */ >-int memberof_del_attr_list(Slapi_PBlock *pb, char *groupdn, Slapi_Attr *attr) >+int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn, >+ Slapi_Attr *attr) > { >- return memberof_mod_attr_list(pb, LDAP_MOD_DELETE, groupdn, attr); >+ return memberof_mod_attr_list(pb, config, LDAP_MOD_DELETE, groupdn, attr); > } > > /* > * memberof_moddn_attr_list() > * > * Perform mod for group DN to the memberof attribute of the list of targets > * > */ >-int memberof_moddn_attr_list(Slapi_PBlock *pb, char *pre_dn, char *post_dn, Slapi_Attr *attr) >+int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *pre_dn, char *post_dn, Slapi_Attr *attr) > { > int rc = 0; > Slapi_Value *val = 0; > int last_size = 0; > char *last_str = 0; >@@ -1266,11 +1357,11 @@ > > memset(dn_str, 0, last_size); > > strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len); > >- memberof_modop_one_replace_r(pb, LDAP_MOD_REPLACE, >+ memberof_modop_one_replace_r(pb, config, LDAP_MOD_REPLACE, > post_dn, pre_dn, post_dn, dn_str, 0); > > hint = slapi_attr_next_value(attr, hint, &val); > } > >@@ -1280,49 +1371,52 @@ > return rc; > } > > typedef struct _memberof_add_groups > { >+ MemberOfConfig *config; > char *target_dn; > char *group_dn; > } memberof_add_groups; > >-int memberof_add_membership(Slapi_PBlock *pb, char *op_this, char *op_to) >+int memberof_add_membership(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *op_this, char *op_to) > { >- memberof_add_groups data = {op_to, op_this}; >+ memberof_add_groups data = {config, op_to, op_this}; > >- return memberof_call_foreach_dn(pb, op_this, MEMBEROF_GROUP_ATTR, >+ return memberof_call_foreach_dn(pb, op_this, config->groupattr, > memberof_add_groups_search_callback, &data); > } > > int memberof_add_groups_search_callback(Slapi_Entry *e, void *callback_data) > { >- return memberof_add_one(0, slapi_entry_get_dn(e), >+ return memberof_add_one(0, ((memberof_add_groups*)callback_data)->config, slapi_entry_get_dn(e), > ((memberof_add_groups*)callback_data)->target_dn); > } > > /* memberof_is_direct_member() > * > * tests for direct membership of memberdn in group groupdn > * returns non-zero when true, zero otherwise > */ >-int memberof_is_direct_member(Slapi_Value *groupdn, Slapi_Value *memberdn) >+int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, >+ Slapi_Value *memberdn) > { > int rc = 0; > Slapi_DN *sdn = 0; >- char *attrlist[2] = {MEMBEROF_GROUP_ATTR,0}; >+ char *attrlist[2] = {config->groupattr,0}; > Slapi_Entry *group_e = 0; > Slapi_Attr *attr = 0; > > sdn = slapi_sdn_new_dn_byref(slapi_value_get_string(groupdn)); > > slapi_search_internal_get_entry(sdn, attrlist, > &group_e, memberof_get_plugin_id()); > > if(group_e) > { >- slapi_entry_attr_find(group_e, MEMBEROF_GROUP_ATTR, &attr ); >+ slapi_entry_attr_find(group_e, config->groupattr, &attr ); > if(attr) > { > rc = 0 == slapi_attr_value_find( > attr, slapi_value_get_berval(memberdn)); > } >@@ -1337,23 +1431,24 @@ > * > * tests for membership of memberdn in group groupdn. This > * will check for both direct and indirect membership. > * returns non-zero when true, zero otherwise > */ >-int memberof_is_member(Slapi_Value *groupdn, Slapi_Value *memberdn) >+int memberof_is_member(MemberOfConfig *config, Slapi_Value *groupdn, >+ Slapi_Value *memberdn) > { > memberofstringll *stack = 0; > > /* Do a quick check to see if the entry is a direct > * member before tracing through nested groups. */ >- if(memberof_is_direct_member(groupdn, memberdn)) >+ if(memberof_is_direct_member(config, groupdn, memberdn)) > { > /* entry is a direct member */ > return 1; > } > >- return memberof_is_member_r(groupdn, memberdn, stack); >+ return memberof_is_member_r(config, groupdn, memberdn, stack); > } > > /* memberof_is_member_r() > * > * Recursive function to do the work for the memberof_is_member() >@@ -1362,11 +1457,12 @@ > * values will be used to make this determination, not "memberOf" > * attribute values. > * > * returns non-zero when true, zero otherwise > */ >-int memberof_is_member_r(Slapi_Value *groupdn, Slapi_Value *memberdn, memberofstringll *stack) >+int memberof_is_member_r(MemberOfConfig *config, Slapi_Value *groupdn, >+ Slapi_Value *memberdn, memberofstringll *stack) > { > Slapi_DN *member_sdn = 0; > Slapi_DN *base_sdn = 0; > Slapi_PBlock *search_pb = slapi_pblock_new(); > Slapi_Backend *be = 0; >@@ -1380,21 +1476,26 @@ > * unecessary processing. */ > while(ll) > { > ll_dn_val = slapi_value_new_string(ll->dn); > >- if(0 == memberof_compare(&ll_dn_val, &memberdn)) >+ if(0 == memberof_compare(config, &ll_dn_val, &memberdn)) > { > slapi_value_free(&ll_dn_val); > > /* someone set up infinitely > * recursive groups - bail out */ > slapi_log_error( SLAPI_LOG_FATAL, > MEMBEROF_PLUGIN_SUBSYSTEM, > "memberof_is_member_r: group recursion" > " detected in %s\n" > ,slapi_value_get_string(memberdn)); >+ /* We set this to null to avoid freeing it twice. >+ * If we don't do this, we'd free ll in the bail section >+ * and the caller (ourselves since we're using recursion) >+ * would free it as well. */ >+ ll = 0; > goto bail; > } > > slapi_value_free(&ll_dn_val); > ll = ll->next; >@@ -1417,15 +1518,12 @@ > /* Do a search for "member=<memberdn>". Go through matches to > * see if it is our group. If not, search for "member=<matchdn>" > * and keep looping until we've exhausted it. */ > if(base_sdn) > { >- int filter_size = >- (strlen(MEMBEROF_GROUP_ATTR) + >- strlen(slapi_value_get_string(memberdn)) + 4); /* 4 for (=) + null */ >- filter_str = (char*)slapi_ch_malloc(filter_size); >- sprintf(filter_str, "(%s=%s)", MEMBEROF_GROUP_ATTR, slapi_value_get_string(memberdn)); >+ filter_str = slapi_ch_smprintf("(%s=%s)", config->groupattr, >+ slapi_value_get_string(memberdn)); > } > > if(filter_str) > { > slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn), >@@ -1463,11 +1561,11 @@ > /* This is not the group you're looking for... > * Find all of the groups that this group is a member of to > * see if any of them are the group we are trying to find. > * We do this by doing a recursive call on this function. */ > Slapi_Value *entrydn = slapi_value_new_string(slapi_entry_get_ndn(entries[i])); >- rc = memberof_is_member_r(groupdn, entrydn, ll); >+ rc = memberof_is_member_r(config, groupdn, entrydn, ll); > slapi_value_free(&entrydn); > } > } > } > } >@@ -1496,14 +1594,14 @@ > * move groups entry is memberof to member group > * test remaining groups for membership in member groups > * iterate until a pass fails to move a group over to member groups > * remaining groups should be deleted > */ >-int memberof_test_membership(Slapi_PBlock *pb, char *group_dn) >+int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn) > { >- return memberof_call_foreach_dn(pb, group_dn, MEMBEROF_ATTR, >- memberof_test_membership_callback ,0); >+ return memberof_call_foreach_dn(pb, group_dn, config->memberof_attr, >+ memberof_test_membership_callback , config); > } > > /* > * memberof_test_membership_callback() > * >@@ -1517,20 +1615,21 @@ > Slapi_Attr *attr = 0; > int total = 0; > Slapi_Value **member_array = 0; > Slapi_Value **candidate_array = 0; > Slapi_Value *entry_dn = 0; >+ MemberOfConfig *config = (MemberOfConfig *)callback_data; > > entry_dn = slapi_value_new_string(slapi_entry_get_dn(e)); > > if(0 == entry_dn) > { > goto bail; > } > > /* divide groups into member and non-member lists */ >- slapi_entry_attr_find(e, MEMBEROF_ATTR, &attr ); >+ slapi_entry_attr_find(e, config->memberof_attr, &attr ); > if(attr) > { > slapi_attr_get_numvalues( attr, &total); > if(total) > { >@@ -1553,11 +1652,11 @@ > hint = slapi_attr_first_value(attr, &val); > > while(val) > { > /* test for direct membership */ >- if(memberof_is_direct_member(val, entry_dn)) >+ if(memberof_is_direct_member(config, val, entry_dn)) > { > /* it is a member */ > member_array[m_index] = val; > m_index++; > } >@@ -1600,10 +1699,11 @@ > inner_index++; > continue; > } > > if(memberof_is_direct_member( >+ config, > candidate_array[inner_index], > member_array[outer_index])) > { > member_array[m_index] = > candidate_array >@@ -1638,11 +1738,11 @@ > outer_index++; > continue; > } > > memberof_del_one( >- 0, >+ 0, config, > (char*)slapi_value_get_string( > candidate_array[outer_index]), > (char*)slapi_value_get_string(entry_dn)); > > outer_index++; >@@ -1673,11 +1773,11 @@ > * memberof_replace_list() > * > * Perform replace the group DN list in the memberof attribute of the list of targets > * > */ >-int memberof_replace_list(Slapi_PBlock *pb, char *group_dn) >+int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn) > { > struct slapi_entry *pre_e = NULL; > struct slapi_entry *post_e = NULL; > Slapi_Attr *pre_attr = 0; > Slapi_Attr *post_attr = 0; >@@ -1685,12 +1785,12 @@ > slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e ); > slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e ); > > if(pre_e && post_e) > { >- slapi_entry_attr_find( pre_e, MEMBEROF_GROUP_ATTR, &pre_attr ); >- slapi_entry_attr_find( post_e, MEMBEROF_GROUP_ATTR, &post_attr ); >+ slapi_entry_attr_find( pre_e, config->groupattr, &pre_attr ); >+ slapi_entry_attr_find( post_e, config->groupattr, &post_attr ); > } > > if(pre_attr || post_attr) > { > int pre_total = 0; >@@ -1709,21 +1809,29 @@ > if(post_attr) > { > slapi_attr_get_numvalues( post_attr, &post_total); > } > >+ /* Stash a plugin global pointer here and have memberof_qsort_compare >+ * use it. We have to do this because we use memberof_qsort_compare >+ * as the comparator function for qsort, which requires the function >+ * to only take two void* args. This is thread-safe since we only >+ * store and use the pointer while holding the memberOf operation >+ * lock. */ >+ qsortConfig = config; >+ > if(pre_total) > { > pre_array = > (Slapi_Value**) > slapi_ch_malloc(sizeof(Slapi_Value*)*pre_total); > memberof_load_array(pre_array, pre_attr); > qsort( > pre_array, > pre_total, > sizeof(Slapi_Value*), >- memberof_compare); >+ memberof_qsort_compare); > } > > if(post_total) > { > post_array = >@@ -1732,13 +1840,15 @@ > memberof_load_array(post_array, post_attr); > qsort( > post_array, > post_total, > sizeof(Slapi_Value*), >- memberof_compare); >+ memberof_qsort_compare); > } > >+ qsortConfig = 0; >+ > > /* work through arrays, following these rules: > in pre, in post, do nothing > in pre, not in post, delete from entry > not in pre, in post, add to entry >@@ -1747,51 +1857,52 @@ > { > if(pre_index == pre_total) > { > /* add the rest of post */ > memberof_add_one( >- pb, >+ pb, config, > group_dn, > (char*)slapi_value_get_string( > post_array[post_index])); > > post_index++; > } > else if(post_index == post_total) > { > /* delete the rest of pre */ > memberof_del_one( >- pb, >+ pb, config, > group_dn, > (char*)slapi_value_get_string( > pre_array[pre_index])); > > pre_index++; > } > else > { > /* decide what to do */ > int cmp = memberof_compare( >+ config, > &(pre_array[pre_index]), > &(post_array[post_index])); > > if(cmp < 0) > { > /* delete pre array */ > memberof_del_one( >- pb, >+ pb, config, > group_dn, > (char*)slapi_value_get_string( > pre_array[pre_index])); > > pre_index++; > } > else if(cmp > 0) > { > /* add post array */ > memberof_add_one( >- pb, >+ pb, config, > group_dn, > (char*)slapi_value_get_string( > post_array[post_index])); > > post_index++; >@@ -1830,46 +1941,39 @@ > > /* memberof_compare() > * > * compare two attr values > */ >-int memberof_compare(const void *a, const void *b) >+int memberof_compare(MemberOfConfig *config, const void *a, const void *b) > { >- static Slapi_Attr *attr = 0; >- static int first_time = 1; > Slapi_Value *val1 = *((Slapi_Value **)a); > Slapi_Value *val2 = *((Slapi_Value **)b); > >- if(first_time) >- { >- first_time = 0; >- attr = slapi_attr_new(); >- slapi_attr_init(attr, MEMBEROF_GROUP_ATTR); >- } >- > return slapi_attr_value_cmp( >- attr, >- slapi_value_get_berval(val1), >+ config->group_slapiattr, >+ slapi_value_get_berval(val1), > slapi_value_get_berval(val2)); > } > >-/* memberof_string2filter() >+/* memberof_qsort_compare() > * >- * For some reason slapi_str2filter writes to its input >- * which means you cannot pass in a string constant >- * so this is a fix up function for that >+ * This is a version of memberof_compare that uses a plugin >+ * global copy of the config. We'd prefer to pass in a copy >+ * of config that is local to the running thread, but we can't >+ * do this since qsort is using us as a comparator function. >+ * We should only use this function when using qsort, and only >+ * when the memberOf lock is acquired. > */ >-Slapi_Filter *memberof_string2filter(char *strfilter) >+int memberof_qsort_compare(const void *a, const void *b) > { >- Slapi_Filter *ret = 0; >- char *idontbelieveit = slapi_ch_strdup(strfilter); >- >- ret = slapi_str2filter( idontbelieveit ); >- >- slapi_ch_free_string(&idontbelieveit); >+ Slapi_Value *val1 = *((Slapi_Value **)a); >+ Slapi_Value *val2 = *((Slapi_Value **)b); > >- return ret; >+ return slapi_attr_value_cmp( >+ qsortConfig->group_slapiattr, >+ slapi_value_get_berval(val1), >+ slapi_value_get_berval(val2)); > } > > /* memberof_is_legit_member() > * > * before we rush to remove this group from the entry >@@ -1878,24 +1982,23 @@ > * that it is not itself a direct member of the group, > * and that all groups in its memberof attribute except > * the second from bottom one of our stack do not appear > * in the membership attribute of the group > */ >-int memberof_is_legit_member(Slapi_PBlock *pb, char *group_dn, >- char *op_this, char *op_to, memberofstringll *stack) >+int memberof_is_legit_member(Slapi_PBlock *pb, MemberOfConfig *config, >+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack) > { > int rc = 0; > Slapi_DN *group_sdn = 0; > Slapi_Entry *group_e = 0; > Slapi_DN *opto_sdn = 0; > Slapi_Entry *opto_e = 0; > char *filter_str = 0; > Slapi_Filter *filter = 0; >- int filter_size = 0; > memberofstringll *ll = 0; >- char *attrlist[2] = {MEMBEROF_GROUP_ATTR,0}; >- char *optolist[2] = {MEMBEROF_ATTR,0}; >+ char *attrlist[2] = {config->groupattr,0}; >+ char *optolist[2] = {config->memberof_attr,0}; > Slapi_Attr *memberof = 0; > Slapi_Value *memberdn = 0; > int hint = 0; > const char *delete_group_dn = 0; > >@@ -1911,18 +2014,12 @@ > if(!group_e) > { > goto bail; > } > >- filter_size = 2 * >- (strlen(MEMBEROF_GROUP_ATTR) + >- strlen(op_to) + 4); /* 4 for (=) + null */ >- filter_str = (char*)slapi_ch_malloc(filter_size); >- >- sprintf(filter_str, "(%s=%s)", MEMBEROF_GROUP_ATTR, op_to); >- >- filter = memberof_string2filter(filter_str); >+ filter_str = slapi_ch_smprintf("(%s=%s)", config->groupattr, op_to); >+ filter = slapi_str2filter(filter_str); > > if(!slapi_filter_test_simple(group_e, filter)) > { > /* entry is direct member */ > slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, >@@ -1964,11 +2061,11 @@ > &opto_e, memberof_get_plugin_id()); > slapi_sdn_free(&opto_sdn); > > if(opto_e) > { >- slapi_entry_attr_find(opto_e, MEMBEROF_ATTR, &memberof); >+ slapi_entry_attr_find(opto_e, config->memberof_attr, &memberof); > } > > if(0 == memberof) > { > goto bail; >@@ -1979,29 +2076,28 @@ > > while(memberdn) > { > char *dn = (char*)slapi_value_get_string(memberdn); > int current_size = >- (strlen(MEMBEROF_GROUP_ATTR) + >+ (strlen(config->groupattr) + > strlen(dn) + 4); /* 4 for (=) + null */ > > /* disregard the group being removed */ > if(0 == strcmp(dn, delete_group_dn)) > { > hint = slapi_attr_next_value(memberof, hint, &memberdn); > continue; > } > >- if(current_size > filter_size) >+ if (current_size > strlen(filter_str)) > { >- filter_size = 2 * current_size; >- filter_str = slapi_ch_realloc( >- filter_str, filter_size); >+ int filter_size = 2 * current_size; >+ filter_str = slapi_ch_realloc(filter_str, filter_size); > } > >- sprintf(filter_str, "(%s=%s)", MEMBEROF_GROUP_ATTR, dn); >- filter = memberof_string2filter(filter_str); >+ sprintf(filter_str, "(%s=%s)", config->groupattr, dn); >+ filter = slapi_str2filter(filter_str); > > if(!slapi_filter_test_simple(group_e, filter)) > { > /* another group allows entry */ > slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, >@@ -2044,10 +2140,11 @@ > char *filter_str; > } task_data; > > void memberof_fixup_task_thread(void *arg) > { >+ MemberOfConfig configCopy = {0, 0, 0, 0}; > Slapi_Task *task = (Slapi_Task *)arg; > task_data *td = NULL; > int rc = 0; > > /* Fetch our task data from the task */ >@@ -2055,12 +2152,26 @@ > > slapi_task_begin(task, 1); > slapi_task_log_notice(task, "Memberof task starts (arg: %s) ...\n", > td->filter_str); > >+ /* We need to get the config lock first. Trying to get the >+ * config lock after we already hold the op lock can cause >+ * a deadlock. */ >+ memberof_rlock_config(); >+ /* copy config so it doesn't change out from under us */ >+ memberof_copy_config(&configCopy, memberof_get_config()); >+ memberof_unlock_config(); >+ >+ /* get the memberOf operation lock */ >+ memberof_lock(); >+ > /* do real work */ >- rc = memberof_fix_memberof(td->dn, td->filter_str); >+ rc = memberof_fix_memberof(&configCopy, td->dn, td->filter_str); >+ >+ /* release the memberOf operation lock */ >+ memberof_unlock(); > > slapi_task_log_notice(task, "Memberof task finished."); > slapi_task_log_status(task, "Memberof task finished."); > slapi_task_inc_progress(task); > >@@ -2162,11 +2273,11 @@ > slapi_ch_free((void **)&mydata); > } > } > } > >-int memberof_fix_memberof(char *dn, char *filter_str) >+int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str) > { > int rc = 0; > Slapi_PBlock *search_pb = slapi_pblock_new(); > > slapi_search_internal_set_pb(search_pb, dn, >@@ -2174,11 +2285,11 @@ > 0, 0, > memberof_get_plugin_id(), > 0); > > rc = slapi_search_internal_callback_pb(search_pb, >- 0, >+ config, > 0, memberof_fix_memberof_callback, > 0); > > slapi_pblock_destroy(search_pb); > >@@ -2194,17 +2305,18 @@ > */ > int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) > { > int rc = 0; > char *dn = slapi_entry_get_dn(e); >- memberof_add_groups data = {dn, dn}; >+ MemberOfConfig *config = (MemberOfConfig *)callback_data; >+ memberof_add_groups data = {config, dn, dn}; > > /* step 1 */ >- slapi_entry_attr_delete(e, MEMBEROF_ATTR); >+ slapi_entry_attr_delete(e, config->memberof_attr); > > /* step 2 and 3 */ >- rc = memberof_call_foreach_dn(0, dn, MEMBEROF_GROUP_ATTR, >+ rc = memberof_call_foreach_dn(0, dn, config->groupattr, > memberof_add_groups_search_callback, &data); > > return rc; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 450989
:
309023
|
309024
|
309025
|
309681
|
309682
|
309683
|
309753
|
309754
|
309755
| 309804 |
309805
|
309806