From bea556cd9c267b5b985b42e7017ecbde73ee81e1 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Sun, 22 Apr 2012 14:05:30 -0400
Subject: [PATCH 07/20] LDAP: Enable looking up ID-mapped users by name

---
 src/db/sysdb.h                        |    1 +
 src/providers/ldap/ldap_common.h      |    1 +
 src/providers/ldap/sdap_async_users.c |   63 ++++++++++++++++++++++++++++-----
 3 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index eb7cfd7812d21799b94a26812a5034b371022f71..98255bede9e03899f80901f58ba5c9fc9ded16a5 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -108,6 +108,7 @@
 
 #define SYSDB_UUID "uniqueID"
 #define SYSDB_SID "objectSID"
+#define SYSDB_SID_STR "objectSIDString"
 #define SYSDB_UPN "userPrincipalName"
 #define SYSDB_CCACHE_FILE "ccacheFile"
 
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 58054afe60f99e17634fefaafaceff4dd610ce19..44c53ed9445465419bd78c5261d40be61c947a00 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -27,6 +27,7 @@
 #include "providers/ldap/sdap_id_op.h"
 #include "providers/fail_over.h"
 #include "providers/krb5/krb5_common.h"
+#include "lib/idmap/sss_idmap.h"
 
 #define PWD_POL_OPT_NONE "none"
 #define PWD_POL_OPT_SHADOW "shadow"
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 200670404d29cd1d0e7750b801ed154fc02ca853..5f8875a58c5adcd35e8f022894a2ca3c283347d5 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -25,6 +25,7 @@
 #include "db/sysdb.h"
 #include "providers/ldap/sdap_async_private.h"
 #include "providers/ldap/ldap_common.h"
+#include "providers/ldap/sdap_idmap.h"
 
 /* ==Save-User-Entry====================================================== */
 
@@ -54,6 +55,10 @@ int sdap_save_user(TALLOC_CTX *memctx,
     char *usn_value = NULL;
     char **missing = NULL;
     TALLOC_CTX *tmpctx = NULL;
+    bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
+    struct dom_sid *dom_sid;
+    char *sid_str;
+    enum idmap_error_code err;
 
     DEBUG(9, ("Save user\n"));
 
@@ -110,16 +115,56 @@ int sdap_save_user(TALLOC_CTX *memctx,
     if (el->num_values == 0) shell = NULL;
     else shell = (const char *)el->values[0].data;
 
-    ret = sysdb_attrs_get_uint32_t(attrs,
-                                   opts->user_map[SDAP_AT_USER_UID].sys_name,
-                                   &uid);
-    if (ret != EOK) {
-        DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
-                  name, dom->name));
-        ret = EINVAL;
-        goto fail;
+    /* Retrieve or map the UID as appropriate */
+    if (use_id_mapping) {
+        ret = sysdb_attrs_get_el(attrs,
+                                 opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
+                                 &el);
+        if (ret != EOK || el->num_values != 1) {
+            DEBUG(SSSDBG_MINOR_FAILURE,
+                  ("No [%s] attribute for user [%s] while id-mapping\n",
+                   opts->user_map[SDAP_AT_USER_OBJECTSID].name,
+                   name));
+            goto fail;
+        }
+
+        ret = binary_to_dom_sid(tmpctx,
+                                el->values[0].data,
+                                el->values[0].length,
+                                &dom_sid);
+        if (ret != EOK) goto fail;
+
+        ret = dom_sid_to_string(tmpctx, dom_sid, &sid_str);
+        talloc_zfree(dom_sid);
+        if (ret != EOK) goto fail;
+
+        /* Add string representation to the cache for easier
+         * debugging
+         */
+        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
+        if (ret != EOK) goto fail;
+
+        /* Convert the SID into a UNIX user ID */
+        err = sss_idmap_sid_to_unix(
+                opts->idmap_ctx->map,
+                                    sid_str,
+                                    (uint32_t *)&uid);
+        if (err != IDMAP_SUCCESS) {
+            ret = EIO;
+            goto fail;
+        }
+
+    } else {
+        ret = sysdb_attrs_get_uint32_t(attrs,
+                                       opts->user_map[SDAP_AT_USER_UID].sys_name,
+                                       &uid);
+        if (ret != EOK) {
+            DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
+                      name, dom->name));
+            ret = EINVAL;
+            goto fail;
+        }
     }
-
     /* check that the uid is valid for this domain */
     if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
             DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
-- 
1.7.10

