From 7fa8b66caf952fc1b1f2e33adaebac7d72e3d3f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 29 Oct 2013 15:03:02 +0100
Subject: [PATCH 1/2] sdap_save_user: try to determine domain by SID

GC contains objects from both parent domain and subdomain.

Lets say we have user with UID 5000 that belongs to a subdomain and
overlapping search bases dc=ad,dc=pb and dc=sub,dc=ad,dc=pb. Now
we call 'getent passwd 5000' and this request goes through data
provider, searching in parent domain first. Even though this
user does not belong to this domain it is found and stored as
ad.pb user.

With this patch we look at user's SID and put it into correct domain.
---
 src/providers/ldap/sdap_async_users.c | 54 +++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 22 deletions(-)

diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 2807b072887962162b1c8bf1a4f64c136679d936..9cfe217482580d4a11ad4ace2f688f42ca55d7b3 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -139,6 +139,38 @@ int sdap_save_user(TALLOC_CTX *memctx,
         goto done;
     }
 
+    /* Always store SID string if available */
+    ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs,
+                                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
+                                &sid_str);
+    if (ret == EOK) {
+        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not add SID string: [%s]\n",
+                                         strerror(ret)));
+            goto done;
+        }
+    } else if (ret == ENOENT) {
+        DEBUG(SSSDBG_TRACE_ALL, ("objectSID: not available for group [%s].\n",
+                                 user_name));
+        sid_str = NULL;
+    } else {
+        DEBUG(SSSDBG_MINOR_FAILURE, ("Could not identify objectSID: [%s]\n",
+                                     strerror(ret)));
+        sid_str = NULL;
+    }
+
+    /* If this object has a SID available, we will determine the correct
+     * domain by its SID. */
+    if (sid_str != NULL) {
+        dom = find_subdomain_by_sid(get_domains_head(dom), sid_str);
+        if (dom == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE, ("SID %s does not belong to any known "
+                                      "domain\n", sid_str));
+            return ERR_DOMAIN_NOT_FOUND;
+        }
+    }
+
     ret = sdap_get_user_primary_name(memctx, opts, attrs, dom, &user_name);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, ("Failed to get user name\n"));
@@ -192,28 +224,6 @@ int sdap_save_user(TALLOC_CTX *memctx,
     if (el->num_values == 0) shell = NULL;
     else shell = (const char *)el->values[0].data;
 
-    /* Always store SID string if available */
-    ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs,
-                                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
-                                &sid_str);
-    if (ret == EOK) {
-        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
-        if (ret != EOK) {
-            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not add SID string: [%s]\n",
-                                         strerror(ret)));
-            goto done;
-        }
-    } else if (ret == ENOENT) {
-        DEBUG(SSSDBG_TRACE_ALL, ("objectSID: not available for group [%s].\n",
-                                 user_name));
-        sid_str = NULL;
-    } else {
-        DEBUG(SSSDBG_MINOR_FAILURE, ("Could not identify objectSID: [%s]\n",
-                                     strerror(ret)));
-        sid_str = NULL;
-    }
-
-
     use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
                                                                dom->name,
                                                                sid_str);
-- 
1.7.11.7

