From b40a0e4d5a05e78adce3c2eff0e981333a1a6e40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 18 Oct 2012 12:42:50 +0200
Subject: [PATCH] do not default fullname to gecos when schema = ad

https://fedorahosted.org/sssd/ticket/1482
---
 src/db/sysdb.h                        |    3 +++
 src/db/sysdb_ops.c                    |   29 ++++++++++++++++++++---------
 src/db/sysdb_subdomains.c             |    5 +++--
 src/providers/ldap/sdap_async_users.c |   21 +++++++++++++++++++--
 src/providers/proxy/proxy_id.c        |    1 +
 src/responder/pac/pacsrv_cmd.c        |    2 +-
 src/tests/sysdb-tests.c               |   18 +++++++++++-------
 src/tools/sss_seed.c                  |    2 +-
 src/tools/sss_sync_ops.c              |    2 +-
 9 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 0ce6beaa361bcb5930e64c31fc3763a230881e9a..6b36db0fa3567ed1d6b3d0deb6313154b57265b1 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -609,6 +609,7 @@ int sysdb_get_new_id(struct sysdb_ctx *sysdb,
 /* Add user (only basic attrs and w/o checks) */
 int sysdb_add_basic_user(struct sysdb_ctx *sysdb,
                          const char *name,
+                         const char *fullname,
                          uid_t uid, gid_t gid,
                          const char *gecos,
                          const char *homedir,
@@ -617,6 +618,7 @@ int sysdb_add_basic_user(struct sysdb_ctx *sysdb,
 /* Add user (all checks) */
 int sysdb_add_user(struct sysdb_ctx *sysdb,
                    const char *name,
+                   const char *fullname,
                    uid_t uid, gid_t gid,
                    const char *gecos,
                    const char *homedir,
@@ -662,6 +664,7 @@ int sysdb_mod_group_member(struct sysdb_ctx *sysdb,
 
 int sysdb_store_user(struct sysdb_ctx *sysdb,
                      const char *name,
+                     const char *fullname,
                      const char *pwd,
                      uid_t uid, gid_t gid,
                      const char *gecos,
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 52f0cef54b9819b1f5d754dcbd56abd1d7cb0e96..859d1d58b9959da778fac08b6f5cf426d2433d25 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -776,6 +776,7 @@ done:
 
 int sysdb_add_basic_user(struct sysdb_ctx *sysdb,
                          const char *name,
+                         const char *fullname,
                          uid_t uid, gid_t gid,
                          const char *gecos,
                          const char *homedir,
@@ -796,6 +797,14 @@ int sysdb_add_basic_user(struct sysdb_ctx *sysdb,
         goto done;
     }
 
+    /* If fullname is not provided, we set gecos to be the same as fullname
+     * on user creation, but we will not enforce coherency after that,
+     * it's up to admins to decide if they want to keep it in sync if they
+     * change one of the 2 */
+    if (fullname == NULL) {
+        fullname = gecos;
+    }
+
     /* user dn */
     msg->dn = sysdb_user_dn(sysdb, msg, name);
     if (!msg->dn) {
@@ -814,13 +823,12 @@ int sysdb_add_basic_user(struct sysdb_ctx *sysdb,
     ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_GIDNUM, (unsigned long)gid);
     if (ret) goto done;
 
-    /* We set gecos to be the same as fullname on user creation,
-     * But we will not enforce coherency after that, it's up to
-     * admins to decide if they want to keep it in sync if they change
-     * one of the 2 */
+    if (fullname && *fullname) {
+        ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_FULLNAME, fullname);
+        if (ret) goto done;
+    }
+
     if (gecos && *gecos) {
-        ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_FULLNAME, gecos);
-        if (ret) goto done;
         ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_GECOS, gecos);
         if (ret) goto done;
     }
@@ -856,6 +864,7 @@ done:
 
 int sysdb_add_user(struct sysdb_ctx *sysdb,
                    const char *name,
+                   const char *fullname,
                    uid_t uid, gid_t gid,
                    const char *gecos,
                    const char *homedir,
@@ -938,7 +947,8 @@ int sysdb_add_user(struct sysdb_ctx *sysdb,
     }
 
     /* try to add the user */
-    ret = sysdb_add_basic_user(sysdb, name, uid, gid, gecos, homedir, shell);
+    ret = sysdb_add_basic_user(sysdb, name, fullname, uid, gid, gecos,
+                               homedir, shell);
     if (ret) goto done;
 
     if (uid == 0) {
@@ -1491,6 +1501,7 @@ done:
 
 int sysdb_store_user(struct sysdb_ctx *sysdb,
                      const char *name,
+                     const char *fullname,
                      const char *pwd,
                      uid_t uid, gid_t gid,
                      const char *gecos,
@@ -1546,7 +1557,7 @@ int sysdb_store_user(struct sysdb_ctx *sysdb,
 
     if (ret == ENOENT) {
         /* users doesn't exist, turn into adding a user */
-        ret = sysdb_add_user(sysdb, name, uid, gid,
+        ret = sysdb_add_user(sysdb, name, fullname, uid, gid,
                              gecos, homedir, shell, attrs, cache_timeout, now);
         if (ret == EEXIST) {
             /* This may be a user rename. If there is a user with the
@@ -1565,7 +1576,7 @@ int sysdb_store_user(struct sysdb_ctx *sysdb,
             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(sysdb, name, uid, gid, gecos,
+            ret = sysdb_add_user(sysdb, name, fullname, uid, gid, gecos,
                                  homedir, shell, attrs, cache_timeout, now);
         }
 
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 2e0170f4d37f04468e9a56dbca9b8176c017c9ff..401f1ec3b32a644723bea40ef7e63684670c45af 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -613,8 +613,9 @@ errno_t sysdb_store_domuser(struct sss_domain_info *domain,
 {
     CHECK_DOMAIN_INFO(domain);
 
-    return sysdb_store_user(domain->sysdb, name, pwd, uid, gid, gecos, homedir,
-                            shell, attrs, remove_attrs, cache_timeout, now);
+    return sysdb_store_user(domain->sysdb, name, NULL, pwd, uid, gid,
+                            gecos, homedir, shell, attrs, remove_attrs,
+                            cache_timeout, now);
 }
 
 errno_t sysdb_delete_domuser(struct sss_domain_info *domain,
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 8974e6a249f1c7db94a7dda63762d84ddd4f0347..f392b594a2fbf043a7dca963161715197639b36b 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -42,6 +42,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
     struct ldb_message_element *el;
     int ret;
     const char *name = NULL;
+    const char *fullname = NULL;
     const char *pwd;
     const char *gecos;
     const char *homedir;
@@ -82,6 +83,22 @@ int sdap_save_user(TALLOC_CTX *memctx,
         goto fail;
     }
 
+    if (opts->schema_type == SDAP_SCHEMA_AD) {
+        ret = sysdb_attrs_get_el(attrs,
+                         opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &el);
+        if (ret == EOK) {
+            if (el->num_values == 0) {
+                fullname = NULL;
+            } else {
+                fullname = (const char *)el->values[0].data;
+            }
+        } else if (ret == ENOENT) {
+            fullname = NULL;
+        } else {
+            goto fail;
+        }
+    }
+
     ret = sysdb_attrs_get_el(attrs,
                              opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
     if (ret) goto fail;
@@ -343,8 +360,8 @@ int sdap_save_user(TALLOC_CTX *memctx,
 
     DEBUG(6, ("Storing info for user %s\n", name));
 
-    ret = sysdb_store_user(ctx, name, pwd, uid, gid, gecos, homedir, shell,
-                           user_attrs, missing, cache_timeout, now);
+    ret = sysdb_store_user(ctx, name, fullname, pwd, uid, gid, gecos, homedir,
+                           shell, user_attrs, missing, cache_timeout, now);
     if (ret) goto fail;
 
     if (_usn_value) {
diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 451bdff5be7ffb817921a7f063a57e769d751c1a..26fa92f6619195a2b76b66045fbd8a031343ea0d 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -254,6 +254,7 @@ static int save_user(struct sysdb_ctx *sysdb, bool lowercase,
 
     ret = sysdb_store_user(sysdb,
                            real_name,
+                           NULL,
                            pwd->pw_passwd,
                            pwd->pw_uid,
                            pwd->pw_gid,
diff --git a/src/responder/pac/pacsrv_cmd.c b/src/responder/pac/pacsrv_cmd.c
index b7edf81d5fa483ece1555a06388e76975956703e..b86baffd9dc17caef343bc50ded1f70b900a2792 100644
--- a/src/responder/pac/pacsrv_cmd.c
+++ b/src/responder/pac/pacsrv_cmd.c
@@ -250,7 +250,7 @@ static errno_t save_pac_user(struct pac_req_ctx *pr_ctx)
             goto done;
         }
 
-        ret = sysdb_store_user(sysdb, pwd->pw_name, NULL,
+        ret = sysdb_store_user(sysdb, pwd->pw_name, NULL, NULL,
                                pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos,
                                pwd->pw_dir,
                                pwd->pw_shell, NULL, NULL,
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index d9afe7b8830c05dec8bae534f154270bedda84e8..bbbc85c31c0d6ea277b9153e9bd14df2c0c49375 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -182,14 +182,16 @@ struct test_data {
 
 static int test_add_user(struct test_data *data)
 {
+    char *fullname;
     char *homedir;
     char *gecos;
     int ret;
 
+    fullname = talloc_asprintf(data, "Test User %d fullname", data->uid);
     homedir = talloc_asprintf(data, "/home/testuser%d", data->uid);
     gecos = talloc_asprintf(data, "Test User %d", data->uid);
 
-    ret = sysdb_add_user(data->ctx->sysdb, data->username,
+    ret = sysdb_add_user(data->ctx->sysdb, data->username, fullname,
                          data->uid, 0, gecos, homedir, "/bin/bash",
                          NULL, 0, 0);
     return ret;
@@ -197,14 +199,16 @@ static int test_add_user(struct test_data *data)
 
 static int test_store_user(struct test_data *data)
 {
+    char *fullname;
     char *homedir;
     char *gecos;
     int ret;
 
+    fullname = talloc_asprintf(data, "Test User %d fullname", data->uid);
     homedir = talloc_asprintf(data, "/home/testuser%d", data->uid);
     gecos = talloc_asprintf(data, "Test User %d", data->uid);
 
-    ret = sysdb_store_user(data->ctx->sysdb, data->username, "x",
+    ret = sysdb_store_user(data->ctx->sysdb, data->username, fullname, "x",
                            data->uid, 0, gecos, homedir,
                            data->shell ? data->shell : "/bin/bash",
                            NULL, NULL, -1, 0);
@@ -2259,7 +2263,7 @@ START_TEST(test_user_rename)
     fail_unless(ret == EOK, "Could not set up the test");
 
     /* Store and verify the first user */
-    ret = sysdb_store_user(test_ctx->sysdb, fromname, NULL, userid, 0,
+    ret = sysdb_store_user(test_ctx->sysdb, fromname, NULL, NULL, userid, 0,
                            fromname, "/", "/bin/sh", NULL, NULL, 0, 0);
     fail_unless(ret == EOK, "Could not add first user");
 
@@ -2280,11 +2284,11 @@ START_TEST(test_user_rename)
                 name, fromname);
 
     /* Perform rename and check that GID is the same, but name changed */
-    ret = sysdb_add_user(test_ctx->sysdb, toname, userid, 0,
+    ret = sysdb_add_user(test_ctx->sysdb, toname, NULL, userid, 0,
                          fromname, "/", "/bin/sh", NULL, 0, 0);
     fail_unless(ret == EEXIST, "A second user added with low level call?");
 
-    ret = sysdb_store_user(test_ctx->sysdb, toname, NULL, userid, 0,
+    ret = sysdb_store_user(test_ctx->sysdb, toname, NULL, NULL, userid, 0,
                            fromname, "/", "/bin/sh", NULL, NULL, 0, 0);
     fail_unless(ret == EOK, "Could not add second user");
 
@@ -2868,7 +2872,7 @@ START_TEST(test_odd_characters)
 
     /* Add */
     ret = sysdb_add_basic_user(test_ctx->sysdb,
-                               odd_username,
+                               odd_username, "",
                                10000, 10000,
                                "","","");
     fail_unless(ret == EOK, "sysdb_add_basic_user error [%d][%s]",
@@ -3482,7 +3486,7 @@ START_TEST(test_sysdb_subdomain_store_user)
                               NULL, NULL);
     fail_unless(subdomain != NULL, "new_subdomain failed.");
 
-    ret = sysdb_store_user(subdomain->sysdb, "subdomuser", NULL, 12345, 0,
+    ret = sysdb_store_user(subdomain->sysdb, "subdomuser", NULL, NULL, 12345, 0,
                            "Sub Domain User", "/home/subdomuser", "/bin/bash",
                            NULL, NULL, -1, 0);
     fail_unless(ret == EOK, "sysdb_store_user failed.");
diff --git a/src/tools/sss_seed.c b/src/tools/sss_seed.c
index 18d0b9d08cdd954153bd974e9974befbc52f6579..71f6d215d113f6aba328c64e1099bd683a1c8eae 100644
--- a/src/tools/sss_seed.c
+++ b/src/tools/sss_seed.c
@@ -736,7 +736,7 @@ static int seed_cache_user(struct seed_ctx *sctx)
     in_transaction = true;
 
     if (sctx->user_cached == false) {
-        ret = sysdb_add_user(sctx->sysdb, sctx->uctx->name,
+        ret = sysdb_add_user(sctx->sysdb, sctx->uctx->name, NULL,
                              sctx->uctx->uid, sctx->uctx->gid,
                              sctx->uctx->gecos, sctx->uctx->home,
                              sctx->uctx->shell, NULL, 0, 0);
diff --git a/src/tools/sss_sync_ops.c b/src/tools/sss_sync_ops.c
index 7183eb3e667c6cee08e46c917771df4c8dad4448..042cd318cfbdde5d8264a5b4494027515e162128 100644
--- a/src/tools/sss_sync_ops.c
+++ b/src/tools/sss_sync_ops.c
@@ -466,7 +466,7 @@ int useradd(TALLOC_CTX *mem_ctx,
 {
     int ret;
 
-    ret = sysdb_add_user(sysdb, data->name, data->uid, data->gid,
+    ret = sysdb_add_user(sysdb, data->name, NULL, data->uid, data->gid,
                          data->gecos, data->home, data->shell, NULL, 0, 0);
     if (ret) {
         goto done;
-- 
1.7.6.5

