>From a78584542ad6e093180adc586ad07f37b625818a Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
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

