Hello, 

please see attached patches.

I have briefly discussed with Jakub how to handle saving users with uid
0 whether to resurrect sysdb_add_fake_user or modify existing fuctions
for storing users. I decided to add wrapper function around existing
ones to minimize changes in code which calls them. 

Thanks, 

Pavel Reichl 
>From a78584542ad6e093180adc586ad07f37b625818a Mon Sep 17 00:00:00 2001
From: Pavel Reichl <[email protected]>
Date: Thu, 22 May 2014 10:37:57 +0100
Subject: [PATCH 1/2] SYSDB: enable storing urers with uid 0

Store users with uid 0 if explicitly asked to.

Resolves:
https://fedorahosted.org/sssd/ticket/2117
---
 src/db/sysdb.h     |  13 +++++++
 src/db/sysdb_ops.c | 109 ++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 95 insertions(+), 27 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 6710400182f3d74994c7313d3ae0f897778c0bd4..8e55a007e709c51eb40fcc3eb0d02240cd710d16 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -649,6 +649,19 @@ int sysdb_store_user(struct sss_domain_info *domain,
                      uint64_t cache_timeout,
                      time_t now);
 
+int sysdb_store_user_tolerate_uid_zero(struct sss_domain_info *domain,
+                                       const char *name,
+                                       const char *pwd,
+                                       uid_t uid, gid_t gid,
+                                       const char *gecos,
+                                       const char *homedir,
+                                       const char *shell,
+                                       const char *orig_dn,
+                                       struct sysdb_attrs *attrs,
+                                       char **remove_attrs,
+                                       uint64_t cache_timeout,
+                                       time_t now);
+
 int sysdb_store_group(struct sss_domain_info *domain,
                       const char *name,
                       gid_t gid,
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 1f51b9682f11b04f1e40677eb26982c300a1687f..d2557c3ca85f9f31ae2513318988cdd2346a0b23 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -1175,16 +1175,17 @@ done:
 
 /* =Add-User-Function===================================================== */
 
-int sysdb_add_user(struct sss_domain_info *domain,
-                   const char *name,
-                   uid_t uid, gid_t gid,
-                   const char *gecos,
-                   const char *homedir,
-                   const char *shell,
-                   const char *orig_dn,
-                   struct sysdb_attrs *attrs,
-                   int cache_timeout,
-                   time_t now)
+static int sysdb_add_user_impl(struct sss_domain_info *domain,
+                               const char *name,
+                               uid_t uid, gid_t gid,
+                               const char *gecos,
+                               const char *homedir,
+                               const char *shell,
+                               const char *orig_dn,
+                               struct sysdb_attrs *attrs,
+                               int cache_timeout,
+                               time_t now,
+                               bool tolererate_uid_zero)
 {
     TALLOC_CTX *tmp_ctx;
     struct ldb_message *msg;
@@ -1255,7 +1256,7 @@ int sysdb_add_user(struct sss_domain_info *domain,
     ret = sysdb_add_basic_user(domain, name, uid, gid, gecos, homedir, shell);
     if (ret) goto done;
 
-    if (uid == 0) {
+    if (uid == 0 && !tolererate_uid_zero) {
         ret = sysdb_get_new_id(domain, &id);
         if (ret) goto done;
 
@@ -1323,6 +1324,21 @@ done:
     return ret;
 }
 
+int sysdb_add_user(struct sss_domain_info *domain,
+                   const char *name,
+                   uid_t uid, gid_t gid,
+                   const char *gecos,
+                   const char *homedir,
+                   const char *shell,
+                   const char *orig_dn,
+                   struct sysdb_attrs *attrs,
+                   int cache_timeout,
+                   time_t now)
+{
+    return sysdb_add_user_impl(domain, name, uid, gid, gecos, homedir, shell,
+                               orig_dn, attrs,  cache_timeout, now, false);
+}
+
 /* =Add-Basic-Group-NO-CHECKS============================================= */
 
 int sysdb_add_basic_group(struct sss_domain_info *domain,
@@ -1719,18 +1735,19 @@ done:
 /* if one of the basic attributes is empty ("") as opposed to NULL,
  * this will just remove it */
 
-int sysdb_store_user(struct sss_domain_info *domain,
-                     const char *name,
-                     const char *pwd,
-                     uid_t uid, gid_t gid,
-                     const char *gecos,
-                     const char *homedir,
-                     const char *shell,
-                     const char *orig_dn,
-                     struct sysdb_attrs *attrs,
-                     char **remove_attrs,
-                     uint64_t cache_timeout,
-                     time_t now)
+static int sysdb_store_user_impl(struct sss_domain_info *domain,
+                                 const char *name,
+                                 const char *pwd,
+                                 uid_t uid, gid_t gid,
+                                 const char *gecos,
+                                 const char *homedir,
+                                 const char *shell,
+                                 const char *orig_dn,
+                                 struct sysdb_attrs *attrs,
+                                 char **remove_attrs,
+                                 uint64_t cache_timeout,
+                                 time_t now,
+                                 bool tolererate_uid_zero)
 {
     TALLOC_CTX *tmp_ctx;
     struct ldb_message *msg;
@@ -1776,8 +1793,9 @@ int sysdb_store_user(struct sss_domain_info *domain,
 
     if (ret == ENOENT) {
         /* users doesn't exist, turn into adding a user */
-        ret = sysdb_add_user(domain, name, uid, gid, gecos, homedir,
-                             shell, orig_dn, attrs, cache_timeout, now);
+        ret = sysdb_add_user_impl(domain, name, uid, gid, gecos, homedir,
+                                  shell, orig_dn, attrs, cache_timeout, now,
+                                  tolererate_uid_zero);
         if (ret == EEXIST) {
             /* This may be a user rename. If there is a user with the
              * same UID, remove it and try to add the basic user again
@@ -1795,8 +1813,9 @@ int sysdb_store_user(struct sss_domain_info *domain,
             DEBUG(SSSDBG_MINOR_FAILURE,
                   "A user with the same UID [%llu] was removed from the "
                    "cache\n", (unsigned long long) uid);
-            ret = sysdb_add_user(domain, name, uid, gid, gecos, homedir,
-                                 shell, orig_dn, attrs, cache_timeout, now);
+            ret = sysdb_add_user_impl(domain, name, uid, gid, gecos, homedir,
+                                      shell, orig_dn, attrs, cache_timeout,
+                                      now, tolererate_uid_zero);
         }
 
         /* Handle the result of sysdb_add_user */
@@ -1884,6 +1903,42 @@ fail:
     return ret;
 }
 
+int sysdb_store_user(struct sss_domain_info *domain,
+                     const char *name,
+                     const char *pwd,
+                     uid_t uid, gid_t gid,
+                     const char *gecos,
+                     const char *homedir,
+                     const char *shell,
+                     const char *orig_dn,
+                     struct sysdb_attrs *attrs,
+                     char **remove_attrs,
+                     uint64_t cache_timeout,
+                     time_t now)
+{
+    return  sysdb_store_user_impl(domain, name, pwd, uid, gid, gecos, homedir,
+                                  shell, orig_dn, attrs, remove_attrs,
+                                  cache_timeout, now, false);
+}
+
+int sysdb_store_user_tolerate_uid_zero(struct sss_domain_info *domain,
+                                       const char *name,
+                                       const char *pwd,
+                                       uid_t uid, gid_t gid,
+                                       const char *gecos,
+                                       const char *homedir,
+                                       const char *shell,
+                                       const char *orig_dn,
+                                       struct sysdb_attrs *attrs,
+                                       char **remove_attrs,
+                                       uint64_t cache_timeout,
+                                       time_t now)
+{
+    return  sysdb_store_user_impl(domain, name, pwd, uid, gid, gecos, homedir,
+                                  shell, orig_dn, attrs, remove_attrs,
+                                  cache_timeout, now, true);
+}
+
 /* =Store-Group-(Native/Legacy)-(replaces-existing-data)================== */
 
 /* this function does not check that all user members are actually present */
-- 
1.8.4.2

>From a8ea7fca48ea6add57b8732943e7c0c9ff2db3e5 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <[email protected]>
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 | 42 ++++++++++++++++++++++++++---------
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 297d6016ee0a64478a57036cd8efc04629a7e701..2d400a59eb3c1c96a4f90f4a3af3e75c1046c0f9 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..4833d0cf633c5f45cd722d6d86274b48a03391ea 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -111,6 +111,7 @@ done:
     return ret;
 }
 
+// todo
 /* FIXME: support storing additional attributes */
 int sdap_save_user(TALLOC_CTX *memctx,
                    struct sdap_options *opts,
@@ -142,6 +143,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 +284,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 +333,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 +349,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 +470,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 +495,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

_______________________________________________
sssd-devel mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to