andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
Blob Blame History Raw
From 39ccde6067bd72202cf11e956afe71ca5c92446c Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Mon, 2 Jun 2014 17:32:40 -0700
Subject: [PATCH 217/225] 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!!)

(cherry picked from commit 8d5410e2e08f2e6fdabe9ab1dc3e97b20842a34d)
(cherry picked from commit 945d113b968ef878f13848d1d7d83b70c9bc2e85)
(cherry picked from commit 2574dffa82490b2258226edf5b420abaf19a9c09)
(cherry picked from commit bdb5e35f608953ca1533365788ab12f56944156c)
---
 .../plugins/posix-winsync/posix-group-func.c       |  4 +-
 .../plugins/posix-winsync/posix-group-func.h       |  1 +
 .../plugins/posix-winsync/posix-group-task.c       | 72 ++++++++++++++++++----
 .../plugins/posix-winsync/posix-winsync-config.c   |  3 +-
 4 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/ldap/servers/plugins/posix-winsync/posix-group-func.c b/ldap/servers/plugins/posix-winsync/posix-group-func.c
index 6a7aa84..1f6be93 100644
--- a/ldap/servers/plugins/posix-winsync/posix-group-func.c
+++ b/ldap/servers/plugins/posix-winsync/posix-group-func.c
@@ -23,12 +23,12 @@
 #include <string.h>
 #include <nspr.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;
 
@@ -262,7 +262,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 0f0ae37..f6d53bf 100644
--- a/ldap/servers/plugins/posix-winsync/posix-group-func.h
+++ b/ldap/servers/plugins/posix-winsync/posix-group-func.h
@@ -19,5 +19,6 @@ void memberUidUnlock();
 int memberUidLockInit();
 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 05c43af..4ddbe52 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)) {
             const char *muid = 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 a7fd6e9..7973137 100644
--- a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
+++ b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
@@ -72,7 +72,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));
-- 
1.8.1.4