>From 21d66ed6b303837c050fb5f185686abe74265af9 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Thu, 22 May 2014 10:53:15 +0100
Subject: [PATCH 2/2] LDAP: save non-posix users with ID-mapping off

Save such users into sysdb with UID and GID set to 0.
Also set isPosix attribute to FALSE.

Resolves:
https://fedorahosted.org/sssd/ticket/2117
---
 src/providers/ldap/ldap_id.c          | 10 ++++-----
 src/providers/ldap/sdap_async_users.c | 41 +++++++++++++++++++++++++----------
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index c788b6bdd6235f5b940d99382b115a2534dbb1d9..10b7a491472aa56540dba34d0ef6303f5cab910b 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -197,14 +197,14 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
                                         ctx->opts->user_map[SDAP_AT_USER_NAME].name,
                                         ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name);
     } else {
-        /* When not ID-mapping, make sure there is a non-NULL UID */
+        /* When not ID-mapping, do not require UID attribute to be present and
+         * if present do not constrain allowed value
+         */
         state->filter = talloc_asprintf(state,
-                                        "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
+                                        "(&(%s=%s)(objectclass=%s)(%s=*))",
                                         attr_name, clean_name,
                                         ctx->opts->user_map[SDAP_OC_USER].name,
-                                        ctx->opts->user_map[SDAP_AT_USER_NAME].name,
-                                        ctx->opts->user_map[SDAP_AT_USER_UID].name,
-                                        ctx->opts->user_map[SDAP_AT_USER_UID].name);
+                                        ctx->opts->user_map[SDAP_AT_USER_NAME].name);
     }
 
     talloc_zfree(clean_name);
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index be0536ef3c3ffaf398c4f2d3e85094d4deb7bd81..ccc4fca06e1bf3cc12fb579935022c3fa7a65b10 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -142,6 +142,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
     char *sid_str;
     char *dom_sid_str = NULL;
     struct sss_domain_info *subdomain;
+    bool is_fake_user = false;
 
     DEBUG(SSSDBG_TRACE_FUNC, "Save user\n");
 
@@ -282,15 +283,15 @@ int sdap_save_user(TALLOC_CTX *memctx,
                                        opts->user_map[SDAP_AT_USER_UID].sys_name,
                                        &uid);
         if (ret != EOK) {
-            DEBUG(SSSDBG_CRIT_FAILURE,
-                  "no uid provided for [%s] in domain [%s].\n",
-                   user_name, dom->name);
-            ret = EINVAL;
-            goto done;
+            /* posix user */
+            DEBUG(SSSDBG_TRACE_FUNC,
+                  "no uid provided for [%s] in domain [%s] - fake user.\n",
+                  user_name, dom->name);
+            is_fake_user = true;
         }
     }
     /* check that the uid is valid for this domain */
-    if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
+    if (!is_fake_user && OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
             DEBUG(SSSDBG_OP_FAILURE,
                   "User [%s] filtered out! (uid out of range)\n",
                       user_name);
@@ -331,6 +332,8 @@ int sdap_save_user(TALLOC_CTX *memctx,
         */
         ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
         if (ret != EOK) goto done;
+    } else if (is_fake_user) {
+        gid = 0;
     } else {
         ret = sysdb_attrs_get_uint32_t(attrs,
                                        opts->user_map[SDAP_AT_USER_GID].sys_name,
@@ -345,8 +348,8 @@ int sdap_save_user(TALLOC_CTX *memctx,
     }
 
     /* check that the gid is valid for this domain */
-    if (IS_SUBDOMAIN(dom) == false &&
-            OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
+    if (!is_fake_user && IS_SUBDOMAIN(dom) == false &&
+        OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "User [%s] filtered out! (primary gid out of range)\n",
                user_name);
@@ -466,6 +469,14 @@ int sdap_save_user(TALLOC_CTX *memctx,
         }
     }
 
+    if (is_fake_user) {
+        ret = sysdb_attrs_add_bool(user_attrs, SYSDB_POSIX, false);
+
+        if (ret) {
+            goto done;
+        }
+    }
+
     ret = sdap_save_all_names(user_name, attrs, dom, user_attrs);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save user names\n");
@@ -483,9 +494,17 @@ int sdap_save_user(TALLOC_CTX *memctx,
 
     DEBUG(SSSDBG_TRACE_FUNC, "Storing info for user %s\n", user_name);
 
-    ret = sysdb_store_user(dom, user_name, pwd, uid, gid,
-                           gecos, homedir, shell, orig_dn,
-                           user_attrs, missing, cache_timeout, now);
+    if (is_fake_user) {
+        ret = sysdb_store_user_tolerate_uid_zero(dom, user_name, pwd, uid, gid,
+                                                 gecos, homedir, shell,
+                                                 orig_dn, user_attrs, missing,
+                                                 cache_timeout, now);
+    } else {
+        ret = sysdb_store_user(dom, user_name, pwd, uid, gid,
+                               gecos, homedir, shell, orig_dn,
+                               user_attrs, missing, cache_timeout,
+                               now);
+    }
     if (ret) goto done;
 
     if (_usn_value) {
-- 
1.8.4.2

