From 8d5410e2e08f2e6fdabe9ab1dc3e97b20842a34d Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Jun 03 2014 00:26:33 +0000 Subject: Ticket #47770 - #481 breaks possibility to reassemble memberuid list Description: Patch to implement #481 "expand nested posix groups" wiped out the code in posix_group_fix_memberuid_callback (posix- group-task.c) to add memberuid if the entry is a posix group. This patch adds the code back. Plus fixed a couple of memory leaks and renamed a posix winsync local function plugin_op_all_finished to posix_winsync_plugin_op_ all_finished not to confuse valgrind. https://fedorahosted.org/389/ticket/47770 Reviewed by rmeggins@redhat.com (Thank you, Rich!!) --- diff --git a/ldap/servers/plugins/posix-winsync/posix-group-func.c b/ldap/servers/plugins/posix-winsync/posix-group-func.c index 11e9a7f..5f841e5 100644 --- a/ldap/servers/plugins/posix-winsync/posix-group-func.c +++ b/ldap/servers/plugins/posix-winsync/posix-group-func.c @@ -21,12 +21,12 @@ #include #include "slapi-plugin.h" #include "posix-wsp-ident.h" +#include "posix-group-func.h" #define MAX_RECURSION_DEPTH (5) Slapi_Value ** valueset_get_valuearray(const Slapi_ValueSet *vs); /* stolen from proto-slap.h */ -static int hasObjectClass(Slapi_Entry *entry, const char *objectClass); static PRMonitor *memberuid_operation_lock = 0; @@ -257,7 +257,7 @@ smods_has_mod(Slapi_Mods *smods, int modtype, const char *type, const char *val) return rc; } -static int +int hasObjectClass(Slapi_Entry *entry, const char *objectClass) { int rc = 0; diff --git a/ldap/servers/plugins/posix-winsync/posix-group-func.h b/ldap/servers/plugins/posix-winsync/posix-group-func.h index e9db3a2..c37740c 100644 --- a/ldap/servers/plugins/posix-winsync/posix-group-func.h +++ b/ldap/servers/plugins/posix-winsync/posix-group-func.h @@ -20,5 +20,6 @@ int memberUidLockInit(); void memberUidLockDestroy(); int addUserToGroupMembership(Slapi_Entry *entry); void propogateDeletionsUpward(Slapi_Entry *, const Slapi_DN *, Slapi_ValueSet*, Slapi_ValueSet *, int); +int hasObjectClass(Slapi_Entry *entry, const char *objectClass); #endif diff --git a/ldap/servers/plugins/posix-winsync/posix-group-task.c b/ldap/servers/plugins/posix-winsync/posix-group-task.c index 9f558bf..c5ea729 100644 --- a/ldap/servers/plugins/posix-winsync/posix-group-task.c +++ b/ldap/servers/plugins/posix-winsync/posix-group-task.c @@ -89,7 +89,7 @@ posix_group_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "posix_group_task_add: retrieved basedn: %s\n", dn); - if ((filter = fetch_attr(e, "filter", "(objectclass=ntGroup)")) == NULL) { + if ((filter = fetch_attr(e, "filter", "(&(objectclass=ntGroup)(|(uniquemember=*)(memberuid=*)))")) == NULL) { *returncode = LDAP_OBJECT_CLASS_VIOLATION; rv = SLAPI_DSE_CALLBACK_ERROR; goto out; @@ -240,6 +240,7 @@ posix_group_fix_memberuid(char *dn, char *filter_str, void *txn) static int posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) { + int i; slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "_fix_memberuid ==>\n"); cb_data *the_cb_data = (cb_data *) callback_data; @@ -253,7 +254,11 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) char *dn = slapi_entry_get_dn(e); Slapi_DN *sdn = slapi_entry_get_sdn(e); LDAPMod **mods = NULL; + int is_posix_group = 0; + if (hasObjectClass(e, "posixGroup")) { + is_posix_group = 1; + } /* Clean out memberuids and dsonlymemberuids without a valid referant */ rc = slapi_entry_attr_find(e, "memberuid", &muid_attr); if (rc == 0 && muid_attr) { @@ -272,7 +277,6 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "_fix_memberuid scan for orphaned memberuids\n"); - int i; for (i = slapi_attr_first_value(muid_attr, &v); i != -1; i = slapi_attr_next_value(muid_attr, i, &v)) { char *muid = (char *)slapi_value_get_string(v); @@ -337,10 +341,8 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) if (rc == 0 && obj_attr) { int fixMembership = 0; Slapi_ValueSet *bad_ums = NULL; - - int i; - Slapi_Value * uniqval = NULL; /* uniquemeber Attribute values */ - + Slapi_Value *uniqval = NULL; /* uniquemeber Attribute values */ + Slapi_ValueSet *uids = NULL; slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "_fix_memberuid scan uniquemember, group %s\n", dn); for (i = slapi_attr_first_value(obj_attr, &uniqval); i != -1; @@ -350,11 +352,14 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) char *attrs[] = { "uid", "objectclass", NULL }; Slapi_Entry *child = getEntry(member, attrs); - if (!child) { + if (child) { + slapi_entry_free(child); + } else { slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "_fix_memberuid orphaned uniquemember found: %s\n", member); - if (strncasecmp(member, "cn=", 3) == 0) { + if ((strncasecmp(member, "cn=", 3) == 0) || + (strncasecmp(member, "uid=", 4) == 0)) { fixMembership = 1; } if (!bad_ums) { @@ -362,12 +367,51 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) } slapi_valueset_add_value(bad_ums, uniqval); } + + if (is_posix_group) { + char *uid = NULL; + /* search uid for member (DN) */ + slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "search %s\n", member); + if ((uid = searchUid(member)) != NULL) { + Slapi_Value *value = slapi_value_new(); + /* Search an entry having "member" as DN and get uid value from it. */ + slapi_value_set_string_passin(value, uid); + /* add uids ValueSet */ + if (NULL == uids) { + uids = slapi_valueset_new(); + } + slapi_valueset_add_value(uids, value); + slapi_value_free(&value); + } + } + } + /* If we found some posix members, replace the existing memberuid attribute + * with the found values. */ + if (uids && slapi_valueset_count(uids)) { + Slapi_Value *val = 0; + Slapi_Mod *smod = slapi_mod_new(); + int hint = 0; + + slapi_mod_init(smod, 0); + slapi_mod_set_operation(smod, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES); + slapi_mod_set_type(smod, "memberuid"); + + /* Loop through all of our values and add them to smod */ + hint = slapi_valueset_first_value(uids, &val); + while (val) { + /* this makes a copy of the berval */ + slapi_mod_add_value(smod, slapi_value_get_berval(val)); + hint = slapi_valueset_next_value(uids, hint, &val); + } + slapi_mods_add_ldapmod(smods, slapi_mod_get_ldapmod_passout(smod)); + slapi_mod_free(&smod); } + slapi_valueset_free(uids); slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "_fix_memberuid Finishing...\n"); - if (fixMembership && posix_winsync_config_get_mapNestedGrouping()) { + if (fixMembership && posix_winsync_config_get_mapNestedGrouping()) { Slapi_ValueSet *del_nested_vs = slapi_valueset_new(); slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, @@ -383,7 +427,7 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) } } - mods = slapi_mods_get_ldapmods_passout(smods); + mods = slapi_mods_get_ldapmods_byref(smods); if (mods) { Slapi_PBlock *mod_pb = NULL; mod_pb = slapi_pblock_new(); @@ -400,7 +444,13 @@ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data) slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "_fix_memberuid <==\n"); - return rc; + /* + * Since Ticket #481 "expand nested posix groups", + * there's a possibility the found entry does not contain + * uniqueMember attribute. But "not found" error shoud not + * be returned, which stops the further fixup task. + */ + return 0; } static void diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c index 1f025a6..81f2b6d 100644 --- a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c +++ b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c @@ -78,7 +78,8 @@ posix_winsync_agmt_init(const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree) sdn = slapi_get_first_suffix(&node, 0); while (sdn) { - if (slapi_sdn_isparent(sdn, ds_subtree) == 0) { + /* if sdn is a parent of ds_subtree or sdn is the WinSync Subtree itself */ + if (slapi_sdn_isparent(sdn, ds_subtree) || !slapi_sdn_compare(sdn, ds_subtree)) { theConfig.rep_suffix = sdn; slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "Found suffix's '%s'\n", slapi_sdn_get_dn(sdn)); diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c b/ldap/servers/plugins/posix-winsync/posix-winsync.c index bd8553d..58b6cd8 100644 --- a/ldap/servers/plugins/posix-winsync/posix-winsync.c +++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c @@ -1980,7 +1980,7 @@ posix_winsync_plugin_close(Slapi_PBlock *pb) "--> posix_winsync_plugin_close -- begin\n"); g_plugin_started = 0; - plugin_op_all_finished(); + posix_winsync_plugin_op_all_finished(); slapi_apib_unregister(WINSYNC_v1_0_GUID); posix_winsync_config_free(); @@ -2051,7 +2051,7 @@ plugin_op_finished() } void -plugin_op_all_finished() +posix_winsync_plugin_op_all_finished() { while(slapi_counter_get_value(op_counter) > 0){ PR_Sleep(PR_MillisecondsToInterval(100)); diff --git a/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h b/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h index 24b4052..7691e56 100644 --- a/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h +++ b/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h @@ -53,6 +53,6 @@ int posix_group_task_add(Slapi_PBlock *pb, Slapi_Entry *e, PRUint64 get_plugin_started(); void plugin_op_started(); void plugin_op_finished(); -void plugin_op_all_finished(); +void posix_winsync_plugin_op_all_finished(); #endif