-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/21/2011 04:24 PM, Sumit Bose wrote:
> On Thu, Mar 17, 2011 at 05:25:55PM -0400, Stephen Gallagher wrote:
> On 03/16/2011 02:07 PM, Simo Sorce wrote:
>>>> On Wed, 16 Mar 2011 13:28:20 -0400
>>>> Stephen Gallagher <sgall...@redhat.com> wrote:
>>>>
>>>>> -----BEGIN PGP SIGNED MESSAGE-----
>>>>> Hash: SHA1
>>>>>
>>>>> Fixes https://fedorahosted.org/sssd/ticket/818
>>>>>
>>>>> Patch 0001: Create sysdb_get_rdn() function
>>>>> This function takes a DN formatted string and returns the RDN
>>>>> value from it.
>>>>
>>>> Nack, please return both the value and the attribute name
>>>>
>>>>> Patch 0002: Add sysdb_attrs_primary_name()
>>>>> This function will check a sysdb_attrs struct for the primary name
>>>>> of the entity it represents. If there are multiple entries, it
>>>>> will pick the one that matches the RDN. If none match, it will
>>>>> throw an error.
>>>>
>>>> Nack please the attribute used in the RDN matches before checking the
>>>> values.
>>>>
>>>>> Patch 0003: Handle multi-valued usernames correctly
>>>>> Users in ldap with multiple values for their username attribute
>>>>> will now be compared against the RDN of the entry to determine the
>>>>> "primary" username. 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 passwd altusername
>>>>> primaryuser:*:800014:800014:primaryuser:/home/primaryuser:/bin/sh
>>>>
>>>> Nack, turning SYSDB_NAME form a single valued attribute (as used
>>>> throughout the code) to a multivalued attribute is a very dangerous
>>>> proposition IMO.
>>>>
>>>> Although the current version of LDB always ends up returning values in
>>>> the same order, fill_pwent() and other functions seem to be working
>>>> only by accident now.
>>>>
>>>> I would rather use a different attribute name for aliases.
>>>> This assuming we really want to allow aliases, I am personally still
>>>> unconvinced it is a good idea. I would rather throw aliases away and
>>>> allow only the canonical name to be stored in our cache.
>>>>
>>>>> Patch 0004: 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
>>>>>
>>>>> Patch 0005: RFC2307bis: 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
>>>>>
>>>>>
>>>>> I tested with RFC2307, RFC2307bis and FreeIPA v2 data.
>>>>
>>>> I think the fact you are getting back the "right" name is happening by
>>>> accident.
>>>> Change the code to explicitly save the aliases first and add the
>>>> canonical name last, and I think you will see the code to fail
>>>> consistently to give you back the canonical name.
>>>>
>>>> Simo.
>>>>
> 
> 
> I have made the following changes to the patches.
> 
>  * sysdb_get_rdn() will return both the attribute name and value of the RDN.
> 
>  * sysdb_attrs_primary_name() will now validate that the attribute name
> matches the ldap_[user|group]_name value.
> 
>  * We will no longer attempt to save the aliases at all. Only the
> primary name will be stored in our database.
> 
> 
> There is a side-effect here that I think is probably okay, but I thought
> I should mention it all the same. A direct request for a user or group
> alias will always cause a cache refresh of the primary group. This is
> because a check of our cache will return no values for this alias, so we
> need to go to the backend to validate it.
> 
> This is not really an exploitable issue because we have the grouping
> optimization that ensures that we'd only have a single lookup for this
> alias going on at once (so the worst-case scenario is that a user could
> force us to keep running lookups after the previous one completed).
> 
> A potential future solution to this would be to store the alternate
> names in the cache with a different attribute name as a sort of
> secondary negative cache.
> 
>> Patch works good, but please put the reoccurring sequence of
>> sysdb_attrs_get_el()-sysdb_attrs_primary_name() calls into a call of its
>> onw.



Thanks for the review. New patches attached makes the requested change.
I also switched to having the sysdb_attrs_get_el() use SYSDB_NAME
always, as that was the net effect anyway (since
user_map[LDAP_USER_NAME].sys_name always maps to this anyway).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAk2I5dYACgkQeiVVYja6o6N8SACghAtbU3ItnVT/ZqutVyBKeMcl
v8UAn1N27FyURQvTtxMqWtCloiQ33LuT
=d2TA
-----END PGP SIGNATURE-----
From b87f0e823a8efe453f1d32cd2a19caf891080a6e Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Wed, 16 Mar 2011 12:34:26 -0400
Subject: [PATCH 1/5] Create sysdb_get_rdn() function

This function takes a DN formatted string and returns the RDN
value from it.
---
 src/db/sysdb.c |   61 ++++++++++++++++++++++++++++++++++++++++++++------------
 src/db/sysdb.h |    2 +
 2 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 521ae9d2ae2b49bd3c8ecec8a3e0eaf172a2583c..34c65dfabf7fd3be88f4f20fe2854469ef38dee3 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -204,33 +204,68 @@ struct ldb_dn *sysdb_netgroup_base_dn(struct sysdb_ctx *ctx, void *memctx,
     return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_NETGROUP_BASE, domain);
 }
 
-errno_t sysdb_group_dn_name(struct sysdb_ctx *ctx, void *memctx,
-                            const char *_dn, char **_name)
+errno_t sysdb_get_rdn(struct sysdb_ctx *ctx, void *memctx,
+                      const char *_dn, char **_name, char **_val)
 {
+    errno_t ret;
     struct ldb_dn *dn;
+    const char *attr_name = NULL;
     const struct ldb_val *val;
-    *_name = NULL;
+    TALLOC_CTX *tmpctx;
 
-    dn = ldb_dn_new_fmt(memctx, ctx->ldb, "%s", _dn);
+    /* We have to create a tmpctx here because
+     * ldb_dn_new_fmt() fails if memctx is NULL
+     */
+    tmpctx = talloc_new(NULL);
+    if (!tmpctx) {
+        return ENOMEM;
+    }
+
+    dn = ldb_dn_new_fmt(tmpctx, ctx->ldb, "%s", _dn);
     if (dn == NULL) {
-        return ENOMEM;
+        ret = ENOMEM;
+        goto done;
+    }
+
+    if (_name) {
+        attr_name = ldb_dn_get_rdn_name(dn);
+        if (attr_name == NULL) {
+            ret = EINVAL;
+            goto done;
+        }
+
+        *_name = talloc_strdup(memctx, attr_name);
+        if (!_name) {
+            ret = ENOMEM;
+            goto done;
+        }
     }
 
     val = ldb_dn_get_rdn_val(dn);
     if (val == NULL) {
-        talloc_zfree(dn);
-        return EINVAL;
+        ret = EINVAL;
+        talloc_free(*_name);
+        goto done;
     }
 
-    *_name = talloc_strndup(memctx, (char *) val->data, val->length);
-    if (!*_name) {
-        talloc_zfree(dn);
-        return ENOMEM;
+    *_val = talloc_strndup(memctx, (char *) val->data, val->length);
+    if (!*_val) {
+        ret = ENOMEM;
+        talloc_free(*_name);
+        goto done;
     }
 
-    talloc_zfree(dn);
+    ret = EOK;
 
-    return EOK;
+done:
+    talloc_zfree(tmpctx);
+    return ret;
+}
+
+errno_t sysdb_group_dn_name(struct sysdb_ctx *ctx, void *memctx,
+                            const char *_dn, char **_name)
+{
+    return sysdb_get_rdn(ctx, memctx, _dn, NULL, _name);
 }
 
 struct ldb_dn *sysdb_domain_dn(struct sysdb_ctx *ctx, void *memctx,
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index ae0b33ce1efcec4a895bd89633d27d4cc3c19182..caef6163e8712bb39d574ec090a423e5af3f8874 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -220,6 +220,8 @@ int sysdb_attrs_users_from_ldb_vals(struct sysdb_attrs *attrs,
 int sysdb_error_to_errno(int ldberr);
 
 /* DNs related helper functions */
+errno_t sysdb_get_rdn(struct sysdb_ctx *ctx, void *memctx,
+                      const char *_dn, char **_name, char **_val);
 struct ldb_dn *sysdb_user_dn(struct sysdb_ctx *ctx, void *memctx,
                              const char *domain, const char *name);
 struct ldb_dn *sysdb_group_dn(struct sysdb_ctx *ctx, void *memctx,
-- 
1.7.4

From f7849223cb12a6e2e794e06ca6383f07ba733c8a Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Wed, 16 Mar 2011 12:29:37 -0400
Subject: [PATCH 2/5] Add sysdb_attrs_primary_name()

This function will check a sysdb_attrs struct for the primary name
of the entity it represents. If there are multiple entries, it
will pick the one that matches the RDN. If none match, it will
throw an error.
---
 src/db/sysdb.c |  102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/db/sysdb.h |    4 ++
 2 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 34c65dfabf7fd3be88f4f20fe2854469ef38dee3..ef9d0a237645f8b52e9a64eedd54d7d9f3762f05 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -2154,3 +2154,105 @@ done:
     talloc_free(tmp_ctx);
     return ret;
 }
+
+errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb,
+                                 struct sysdb_attrs *attrs,
+                                 const char *ldap_attr,
+                                 const char **_primary)
+{
+    errno_t ret;
+    char *rdn_attr = NULL;
+    char *rdn_val = NULL;
+    struct ldb_message_element *sysdb_name_el;
+    struct ldb_message_element *orig_dn_el;
+    size_t i;
+    TALLOC_CTX *tmpctx = NULL;
+
+    tmpctx = talloc_new(NULL);
+    if (!tmpctx) {
+        return ENOMEM;
+    }
+
+    ret = sysdb_attrs_get_el(attrs,
+                             SYSDB_NAME,
+                             &sysdb_name_el);
+    if (sysdb_name_el->num_values == 0) {
+        ret = EINVAL;
+        goto done;
+    }
+
+    if (sysdb_name_el->num_values == 1) {
+        /* Entry contains only one name. Just return that */
+        *_primary = (const char *)sysdb_name_el->values[0].data;
+        ret = EOK;
+        goto done;
+    }
+
+    /* Multiple values for name. Check whether one matches the RDN */
+
+    ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &orig_dn_el);
+    if (ret) {
+        goto done;
+    }
+    if (orig_dn_el->num_values == 0) {
+        DEBUG(7, ("Original DN is not available.\n"));
+    } else if (orig_dn_el->num_values == 1) {
+        ret = sysdb_get_rdn(sysdb, tmpctx,
+                            (const char *) orig_dn_el->values[0].data,
+                            &rdn_attr,
+                            &rdn_val);
+        if (ret != EOK) {
+            DEBUG(1, ("Could not get rdn from [%s]\n",
+                      (const char *) orig_dn_el->values[0].data));
+            goto done;
+        }
+    } else {
+        DEBUG(1, ("Should not have more than one origDN\n"));
+        ret = EINVAL;
+        goto done;
+    }
+
+    /* First check whether the attribute name matches */
+    DEBUG(8, ("Comparing attribute names [%s] and [%s]\n",
+              rdn_attr, ldap_attr));
+    if (strcasecmp(rdn_attr, ldap_attr) != 0) {
+        /* Multiple entries, and the RDN attribute doesn't match.
+         * We have no way of resolving this deterministically,
+         * so we'll punt.
+         */
+        DEBUG(1, ("Cannot save entry. It has multiple names and the RDN "
+                  "attribute does not match\n"));
+        ret = EINVAL;
+        goto done;
+    }
+
+    for (i = 0; i < sysdb_name_el->num_values; i++) {
+        if (strcasecmp(rdn_val,
+                       (const char *)sysdb_name_el->values[i].data) == 0) {
+            /* This name matches the RDN. Use it */
+            break;
+        }
+    }
+    if (i < sysdb_name_el->num_values) {
+        /* Match was found */
+        *_primary = (const char *)sysdb_name_el->values[i].data;
+    } else {
+        /* If we can't match the name to the RDN, we just have to
+         * throw up our hands. There's no deterministic way to
+         * decide which name is correct.
+         */
+        DEBUG(1, ("Cannot save entry. Unable to determine groupname\n"));
+        ret = EINVAL;
+        goto done;
+    }
+
+    ret = EOK;
+
+done:
+    if (ret != EOK) {
+        DEBUG(1, ("Could not determine primary name: [%d][%s]\n",
+                  ret, strerror(ret)));
+    }
+    talloc_free(tmpctx);
+    return ret;
+}
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index caef6163e8712bb39d574ec090a423e5af3f8874..e98426551d594ca7e53b7a056d314d80d096f2fe 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -215,6 +215,10 @@ int sysdb_attrs_users_from_ldb_vals(struct sysdb_attrs *attrs,
                                     const char *domain,
                                     struct ldb_val *values,
                                     int num_values);
+errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb,
+                                 struct sysdb_attrs *attrs,
+                                 const char *ldap_attr,
+                                 const char **_primary);
 
 /* convert an ldb error into an errno error */
 int sysdb_error_to_errno(int ldberr);
-- 
1.7.4

From 5d4efefd74530201728457c2ca1488892a8c5d29 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Wed, 16 Mar 2011 12:35:27 -0400
Subject: [PATCH 3/5] Ignore aliases for users

Users in ldap with multiple values for their username attribute
will now be compared against the RDN of the entry to determine the
"primary" username. We will save only this primary name to the ldb
cache.
---
 src/providers/ldap/sdap_async_accounts.c |   46 +++++++++++++++++-------------
 1 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 3fedf07da7fbdc9409f5360ba8301158a65014cd..e7304bd4be9af54f13ed43a293582784456671d4 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -40,7 +40,7 @@ static int sdap_save_user(TALLOC_CTX *memctx,
 {
     struct ldb_message_element *el;
     int ret;
-    const char *name;
+    const char *name = NULL;
     const char *pwd;
     const char *gecos;
     const char *homedir;
@@ -49,25 +49,35 @@ static int sdap_save_user(TALLOC_CTX *memctx,
     gid_t gid;
     struct sysdb_attrs *user_attrs;
     char *upn = NULL;
-    int i;
+    size_t i;
     char *val = NULL;
     int cache_timeout;
     char *usn_value = NULL;
     size_t c;
     char **missing = NULL;
+    TALLOC_CTX *tmpctx = NULL;
 
     DEBUG(9, ("Save user\n"));
 
-    ret = sysdb_attrs_get_el(attrs,
-                             opts->user_map[SDAP_AT_USER_NAME].sys_name, &el);
-    if (el->num_values == 0) {
-        ret = EINVAL;
+    tmpctx = talloc_new(memctx);
+    if (!tmpctx) {
+        ret = ENOMEM;
+        goto fail;
     }
-    if (ret) {
+
+    user_attrs = sysdb_new_attrs(tmpctx);
+    if (user_attrs == NULL) {
+        ret = ENOMEM;
+        goto fail;
+    }
+
+    ret = sysdb_attrs_primary_name(ctx, attrs,
+                                   opts->user_map[SDAP_AT_USER_NAME].name,
+                                   &name);
+    if (ret != EOK) {
         DEBUG(1, ("Failed to save the user - entry has no name attribute\n"));
-        return ret;
+        goto fail;
     }
-    name = (const char *)el->values[0].data;
 
     ret = sysdb_attrs_get_el(attrs,
                              opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
@@ -129,12 +139,6 @@ static int sdap_save_user(TALLOC_CTX *memctx,
         goto fail;
     }
 
-    user_attrs = sysdb_new_attrs(memctx);
-    if (user_attrs == NULL) {
-        ret = ENOMEM;
-        goto fail;
-    }
-
     ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
     if (ret) {
         goto fail;
@@ -271,7 +275,7 @@ static int sdap_save_user(TALLOC_CTX *memctx,
     /* Make sure that any attributes we requested from LDAP that we
      * did not receive are also removed from the sysdb
      */
-    ret = list_missing_attrs(NULL, opts->user_map, SDAP_OPTS_USER,
+    ret = list_missing_attrs(user_attrs, opts->user_map, SDAP_OPTS_USER,
                              ldap_attrs, attrs, &missing);
     if (ret != EOK) {
         goto fail;
@@ -285,21 +289,23 @@ static int sdap_save_user(TALLOC_CTX *memctx,
 
     DEBUG(6, ("Storing info for user %s\n", name));
 
-    ret = sysdb_store_user(memctx, ctx, dom,
+    ret = sysdb_store_user(user_attrs, ctx, dom,
                            name, pwd, uid, gid, gecos, homedir, shell,
                            user_attrs, missing, cache_timeout);
     if (ret) goto fail;
-    talloc_zfree(missing);
 
     if (_usn_value) {
         *_usn_value = usn_value;
     }
 
+    talloc_steal(memctx, user_attrs);
+    talloc_free(tmpctx);
     return EOK;
 
 fail:
-    DEBUG(2, ("Failed to save user %s\n", name));
-    talloc_free(missing);
+    DEBUG(2, ("Failed to save user [%s]\n",
+              name ? name : "Unknown"));
+    talloc_free(tmpctx);
     return ret;
 }
 
-- 
1.7.4

From 47ac2d3ee4ce724629f2675e4d413d4ff88c2049 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Wed, 16 Mar 2011 09:09:28 -0400
Subject: [PATCH 4/5] RFC2307: Ignore aliases for groups

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 only this primary group name
to the ldb cache.
---
 src/providers/ldap/sdap_async_accounts.c |   58 ++++++++++++++++++------------
 1 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index e7304bd4be9af54f13ed43a293582784456671d4..a46c7dd1830b4c9e9dbd2473c56e178e02778f98 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -661,15 +661,27 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     gid_t gid;
     int ret;
     char *usn_value = NULL;
+    TALLOC_CTX *tmpctx = NULL;
 
-    ret = sysdb_attrs_get_el(attrs,
-                          opts->group_map[SDAP_AT_GROUP_NAME].sys_name, &el);
-    if (ret) goto fail;
-    if (el->num_values == 0) {
-        ret = EINVAL;
+    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_primary_name(ctx, attrs,
+                                   opts->group_map[SDAP_AT_GROUP_NAME].name,
+                                   &name);
+    if (ret != EOK) {
+        DEBUG(1, ("Failed to save the group - entry has no name attribute\n"));
         goto fail;
     }
-    name = (const char *)el->values[0].data;
 
     ret = sysdb_attrs_get_uint32_t(attrs,
                                    opts->group_map[SDAP_AT_GROUP_GID].sys_name,
@@ -689,12 +701,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;
@@ -705,7 +711,7 @@ 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;
         }
@@ -743,7 +749,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;
@@ -784,20 +790,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;
 }
 
@@ -1840,6 +1850,7 @@ static void sdap_nested_done(struct tevent_req *subreq)
 
 /* ==Save-fake-group-list=====================================*/
 static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
+                                          struct sdap_options *opts,
                                           struct sss_domain_info *dom,
                                           char **groupnames,
                                           struct sysdb_attrs **ldap_groups,
@@ -1903,10 +1914,10 @@ static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
     for (i=0; missing[i]; i++) {
         /* The group is not in sysdb, need to add a fake entry */
         for (ai=0; ai < ldap_groups_count; ai++) {
-            ret = sysdb_attrs_get_string(ldap_groups[ai],
-                                         SYSDB_NAME,
-                                         &name);
-            if (ret) {
+            ret = sysdb_attrs_primary_name(sysdb, ldap_groups[ai],
+                                           opts->group_map[SDAP_AT_GROUP_NAME].name,
+                                           &name);
+            if (ret != EOK) {
                 DEBUG(1, ("The group has no name attribute\n"));
                 goto fail;
             }
@@ -2132,8 +2143,9 @@ static void sdap_initgr_rfc2307_process(struct tevent_req *subreq)
      * member of but that are not cached in sysdb
      */
     if (add_groups && add_groups[0]) {
-        ret = sdap_add_incomplete_groups(state->sysdb, state->dom,
-                                         add_groups, ldap_groups, count);
+        ret = sdap_add_incomplete_groups(state->sysdb, state->opts,
+                                         state->dom, add_groups,
+                                         ldap_groups, count);
         if (ret != EOK) {
             tevent_req_error(req, ret);
             return;
-- 
1.7.4

From 2b574f9c4c00d7b9001a2ec4a1b807d99944503c Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Wed, 16 Mar 2011 12:59:33 -0400
Subject: [PATCH 5/5] RFC2307bis: Ignore aliases for groups

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 only this primary group name to
the ldb cache.
---
 src/providers/ldap/sdap_async_accounts.c |   40 +++++++++++++++++++----------
 1 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index a46c7dd1830b4c9e9dbd2473c56e178e02778f98..27165a827e0c98c5488779e2da5733423e0ae6bc 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -828,9 +828,9 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
     const char *name;
     int ret;
 
-    ret = sysdb_attrs_get_string(attrs,
-                                opts->group_map[SDAP_AT_GROUP_NAME].sys_name,
-                                &name);
+    ret = sysdb_attrs_primary_name(ctx, attrs,
+                                   opts->group_map[SDAP_AT_GROUP_NAME].name,
+                                   &name);
     if (ret != EOK) {
         goto fail;
     }
@@ -2224,7 +2224,9 @@ static struct tevent_req *sdap_initgr_nested_send(TALLOC_CTX *memctx,
     state->grp_attrs = grp_attrs;
     state->op = NULL;
 
-    ret = sysdb_attrs_get_string(user, SYSDB_NAME, &state->username);
+    ret = sysdb_attrs_primary_name(sysdb, user,
+                                   opts->user_map[SDAP_AT_USER_NAME].name,
+                                   &state->username);
     if (ret != EOK) {
         DEBUG(1, ("User entry had no username\n"));
         talloc_free(req);
@@ -2826,11 +2828,12 @@ static struct tevent_req *sdap_nested_group_process_send(
      */
     key.type = HASH_KEY_STRING;
 
-    ret = sysdb_attrs_get_string(
-            group,
-            opts->group_map[SDAP_AT_GROUP_NAME].sys_name,
-            &groupname);
-    if (ret != EOK) goto immediate;
+    ret = sysdb_attrs_primary_name(sysdb, group,
+                                   opts->group_map[SDAP_AT_GROUP_NAME].name,
+                                   &groupname);
+    if (ret != EOK) {
+        goto immediate;
+    }
 
     key.str = talloc_strdup(state, groupname);
     if (!key.str) {
@@ -3794,8 +3797,11 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
         goto error;
     }
 
-    ret = sysdb_attrs_get_string(state->groups[state->group_iter],
-                                 SYSDB_NAME, &name);
+    ret = sysdb_attrs_primary_name(
+            state->sysdb,
+            state->groups[state->group_iter],
+            state->opts->group_map[SDAP_AT_GROUP_NAME].name,
+            &name);
     if (ret != EOK) {
         goto error;
     }
@@ -3834,7 +3840,8 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
 
     DEBUG(6, ("Saving incomplete group [%s] to the sysdb\n",
               groupnamelist[0]));
-    ret = sdap_add_incomplete_groups(state->sysdb, state->dom, groupnamelist,
+    ret = sdap_add_incomplete_groups(state->sysdb, state->opts,
+                                     state->dom, groupnamelist,
                                      grouplist, 1);
     if (ret != EOK) {
         goto error;
@@ -4043,12 +4050,17 @@ static errno_t rfc2307bis_nested_groups_update_sysdb(
     }
     in_transaction = true;
 
-    ret = sysdb_attrs_get_string(state->groups[state->group_iter],
-                                 SYSDB_NAME, &name);
+    ret = sysdb_attrs_primary_name(
+            state->sysdb,
+            state->groups[state->group_iter],
+            state->opts->group_map[SDAP_AT_GROUP_NAME].name,
+            &name);
     if (ret != EOK) {
         goto error;
     }
 
+    DEBUG(6, ("Processing group [%s]\n", name));
+
     attrs = talloc_array(tmp_ctx, const char *, 2);
     if (!attrs) {
         ret = ENOMEM;
-- 
1.7.4

Attachment: 0001-Create-sysdb_get_rdn-function.patch.sig
Description: PGP signature

Attachment: 0002-Add-sysdb_attrs_primary_name.patch.sig
Description: PGP signature

Attachment: 0003-Ignore-aliases-for-users.patch.sig
Description: PGP signature

Attachment: 0004-RFC2307-Ignore-aliases-for-groups.patch.sig
Description: PGP signature

Attachment: 0005-RFC2307bis-Ignore-aliases-for-groups.patch.sig
Description: PGP signature

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to