From 2fb9df3abd2bd63110cf2f9d829e8efbf47f7ef2 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Wed, 16 Mar 2011 09:09:28 -0400
Subject: [PATCH 4/5] RFC2307: Handle multi-valued group names correctly

Groups in ldap with multiple values for their groupname attribute
will now be compared against the RDN of the entry to determine the
"primary" group name. We will save all of the alternate names to the
ldb cache as well, so a lookup for any of them will return the
values for the primary name.

e.g.
getent group altgroup
primarygroup:*:800014:member1,member2
---
 src/providers/ldap/sdap_async_accounts.c |   64 +++++++++++++++++++++++------
 1 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 71c25c883fbaf03becbbe9804865ba0ac7cc7513..e7fc4001b9d1fa316e850fb2055c1f3e15c1875d 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -684,15 +684,37 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     gid_t gid;
     int ret;
     char *usn_value = NULL;
+    TALLOC_CTX *tmpctx = NULL;
+    size_t i;
+
+    tmpctx = talloc_new(memctx);
+    if (!tmpctx) {
+        ret = ENOMEM;
+        goto fail;
+    }
+
+    group_attrs = sysdb_new_attrs(tmpctx);
+    if (group_attrs == NULL) {
+        ret = ENOMEM;
+        goto fail;
+    }
 
     ret = sysdb_attrs_get_el(attrs,
-                          opts->group_map[SDAP_AT_GROUP_NAME].sys_name, &el);
-    if (ret) goto fail;
+                             opts->group_map[SDAP_AT_GROUP_NAME].sys_name,
+                             &el);
     if (el->num_values == 0) {
         ret = EINVAL;
         goto fail;
     }
-    name = (const char *)el->values[0].data;
+    if (ret) {
+        DEBUG(1, ("Failed to save the group - entry has no name attribute\n"));
+        goto fail;
+    }
+
+    ret = sysdb_attrs_primary_name(ctx, attrs, el, &name);
+    if (ret != EOK) {
+        goto fail;
+    }
 
     ret = sysdb_attrs_get_uint32_t(attrs,
                                    opts->group_map[SDAP_AT_GROUP_GID].sys_name,
@@ -712,12 +734,6 @@ static int sdap_save_group(TALLOC_CTX *memctx,
         goto fail;
     }
 
-    group_attrs = sysdb_new_attrs(memctx);
-    if (!group_attrs) {
-        ret = ENOMEM;
-        goto fail;
-    }
-
     ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
     if (ret) {
         goto fail;
@@ -728,12 +744,28 @@ static int sdap_save_group(TALLOC_CTX *memctx,
         DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
                   el->values[0].data, name));
         ret = sysdb_attrs_add_string(group_attrs, SYSDB_ORIG_DN,
-                                     (const char *)el->values[0].data);
+                                     (const char *) el->values[0].data);
         if (ret) {
             goto fail;
         }
     }
 
+    /* Save alternate names */
+    ret = sysdb_attrs_get_el(attrs, SYSDB_NAME, &el);
+    if (ret != EOK) {
+        goto fail;
+    }
+
+    for(i = 0; i < el->num_values; i++) {
+        DEBUG(7, ("Adding alternate name [%s] to attributes of [%s]\n",
+                  el->values[i].data, name));
+        ret = sysdb_attrs_add_string(group_attrs, SYSDB_NAME,
+                                     (const char *)el->values[i].data);
+        if (ret != EOK) {
+            goto fail;
+        }
+    }
+
     ret = sysdb_attrs_get_el(attrs,
                       opts->group_map[SDAP_AT_GROUP_MODSTAMP].sys_name, &el);
     if (ret) {
@@ -766,7 +798,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
         if (ret) {
             goto fail;
         }
-        usn_value = talloc_strdup(memctx, (const char*)el->values[0].data);
+        usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);
         if (!usn_value) {
             ret = ENOMEM;
             goto fail;
@@ -807,20 +839,24 @@ static int sdap_save_group(TALLOC_CTX *memctx,
 
     DEBUG(6, ("Storing info for group %s\n", name));
 
-    ret = sysdb_store_group(memctx, ctx, dom,
+    ret = sysdb_store_group(group_attrs, ctx, dom,
                             name, gid, group_attrs,
                             dp_opt_get_int(opts->basic,
                                            SDAP_ENTRY_CACHE_TIMEOUT));
     if (ret) goto fail;
 
     if (_usn_value) {
-        *_usn_value = usn_value;
+        *_usn_value = talloc_steal(memctx, usn_value);
     }
 
+    talloc_steal(memctx, group_attrs);
+    talloc_free(tmpctx);
     return EOK;
 
 fail:
-    DEBUG(2, ("Failed to save user %s\n", name));
+    DEBUG(2, ("Failed to save group [%s]\n",
+              name ? name : "Unknown"));
+    talloc_free(tmpctx);
     return ret;
 }
 
-- 
1.7.4

