Blob Blame History Raw
From c4379aa97754b4c4cfc02663315b7c6319e3fa61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Wed, 10 Aug 2016 15:41:34 +0200
Subject: [PATCH 115/115] sdap: Skip exact duplicates when extending maps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When extending map with entry that already
exists in the map in the exacty same form,
then there is no need to fail.

We should only fail if we try to
change purpose of already used sysdb
attribute.

Resolves:
https://fedorahosted.org/sssd/ticket/3120

Signed-off-by: Lukas Slebodnik <lslebodn@redhat.com>

Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
 src/providers/ldap/sdap.c | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index 97b8f126d4ed6bc59c510d5763789a458bd4863a..dc7d5e0caf223c3ee3c43054aa44e796f1b37766 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -122,19 +122,30 @@ static errno_t split_extra_attr(TALLOC_CTX *mem_ctx,
     return EOK;
 }
 
-static bool is_sysdb_duplicate(struct sdap_attr_map *map,
-                               int num_entries,
-                               const char *sysdb_attr)
+enum duplicate_t {
+    NOT_FOUND = 0,
+    ALREADY_IN_MAP, /* nothing to add */
+    CONFLICT_WITH_MAP /* attempt to redefine attribute */
+};
+
+static enum duplicate_t check_duplicate(struct sdap_attr_map *map,
+                                        int num_entries,
+                                        const char *sysdb_attr,
+                                        const char *ldap_attr)
 {
     int i;
 
     for (i = 0; i < num_entries; i++) {
         if (strcmp(map[i].sys_name, sysdb_attr) == 0) {
-            return true;
+            if (strcmp(map[i].name, ldap_attr) == 0) {
+                return ALREADY_IN_MAP;
+            } else {
+                return CONFLICT_WITH_MAP;
+            }
         }
     }
 
-    return false;
+    return NOT_FOUND;
 }
 
 int sdap_extend_map(TALLOC_CTX *memctx,
@@ -167,14 +178,20 @@ int sdap_extend_map(TALLOC_CTX *memctx,
         return ENOMEM;
     }
 
-    for (i = 0; extra_attrs[i]; i++) {
-        ret = split_extra_attr(map, extra_attrs[i], &sysdb_attr, &ldap_attr);
+    for (i = 0; *extra_attrs != NULL; extra_attrs++) {
+        ret = split_extra_attr(map, *extra_attrs, &sysdb_attr, &ldap_attr);
         if (ret != EOK) {
-            DEBUG(SSSDBG_MINOR_FAILURE, "Cannot split %s\n", extra_attrs[i]);
+            DEBUG(SSSDBG_MINOR_FAILURE, "Cannot split %s\n", *extra_attrs);
             continue;
         }
 
-        if (is_sysdb_duplicate(map, num_entries, sysdb_attr)) {
+        ret = check_duplicate(map, num_entries, sysdb_attr, ldap_attr);
+        if (ret == ALREADY_IN_MAP) {
+            DEBUG(SSSDBG_TRACE_FUNC,
+                  "Attribute %s (%s in LDAP) is already in map.\n",
+                  sysdb_attr, ldap_attr);
+            continue;
+        } else if (ret == CONFLICT_WITH_MAP) {
             DEBUG(SSSDBG_FATAL_FAILURE,
                   "Attribute %s (%s in LDAP) is already used by SSSD, please "
                   "choose a different cache name\n", sysdb_attr, ldap_attr);
@@ -193,9 +210,14 @@ int sdap_extend_map(TALLOC_CTX *memctx,
             map[num_entries+i].def_name == NULL) {
             return ENOMEM;
         }
-        DEBUG(SSSDBG_TRACE_FUNC, "Extending map with %s\n", extra_attrs[i]);
+        DEBUG(SSSDBG_TRACE_FUNC, "Extending map with %s\n", *extra_attrs);
+
+        /* index must be incremented only for appended entry. */
+        i++;
     }
 
+    nextra = i;
+
     /* Sentinel */
     memset(&map[num_entries+nextra], 0, sizeof(struct sdap_attr_map));
 
-- 
2.4.11