The attached three patches reflect the discussion we had on #sssd and
sssd-devel mailing list. They also fix
https://fedorahosted.org/sssd/ticket/1123

[PATCH 1/3] sss_get_cased_name utility function
I moved the ternary operator expression into a separate function. It's
being used all over the place now.

[PATCH 2/3] Return user and group names lowercased in case insensitive
domains
Does what it says on the box. Is there a way to force the same for
initgroups? As far as I can see, we don't even send the netgroup name
back to the NSS module..

[PATCH 3/3] Honor case sensitive flag when creating the ccname
The homedir template is handled automatically in patch #2, but we need
to handle the ccname templates as well.
From 2fdd65fdc1213547830da1ca416edbc877161599 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Wed, 21 Dec 2011 18:00:25 +0100
Subject: [PATCH 1/3] sss_get_cased_name utility function

---
 src/responder/nss/nsssrv_cmd.c      |    9 +++------
 src/responder/nss/nsssrv_netgroup.c |    9 ++++++---
 src/responder/pam/pamsrv_cmd.c      |    4 ++--
 src/util/usertools.c                |    9 +++++++++
 src/util/util.h                     |    4 ++++
 5 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 
0bd2f75ee32a10acbaa44709f05b5a7017811f3c..71c949f1d41a64782c8f1da8f3d4b2b2375c15bb
 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -741,8 +741,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx)
         dctx->domain = dom;
 
         talloc_free(name);
-        name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) :
-                                  sss_tc_utf8_str_tolower(dctx, cmdctx->name);
+        name = sss_get_cased_name(dctx, cmdctx->name, dom->case_sensitive);
         if (!name) return ENOMEM;
 
         /* verify this user has not yet been negatively cached,
@@ -2033,8 +2032,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx 
*dctx)
         dctx->domain = dom;
 
         talloc_free(name);
-        name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) :
-                                sss_tc_utf8_str_tolower(dctx, cmdctx->name);
+        name = sss_get_cased_name(dctx, cmdctx->name, dom->case_sensitive);
         if (!name) return ENOMEM;
 
         /* verify this group has not yet been negatively cached,
@@ -3104,8 +3102,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx 
*dctx)
         dctx->domain = dom;
 
         talloc_free(name);
-        name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) :
-                                    sss_tc_utf8_str_tolower(dctx, 
cmdctx->name);
+        name = sss_get_cased_name(dctx, cmdctx->name, dom->case_sensitive);
         if (!name) return ENOMEM;
 
         /* verify this user has not yet been negatively cached,
diff --git a/src/responder/nss/nsssrv_netgroup.c 
b/src/responder/nss/nsssrv_netgroup.c
index 
39ba4ff7a3ca8d48a88edea2e857df53a61e501c..1b089f71908e878ae72f20d975218c2a50d45cbb
 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -402,9 +402,12 @@ static errno_t lookup_netgr_step(struct setent_step_ctx 
*step_ctx)
         step_ctx->dctx->domain = dom;
 
         talloc_free(name);
-        name = dom->case_sensitive ? \
-                    talloc_strdup(step_ctx, step_ctx->name) :
-                    sss_tc_utf8_str_tolower(step_ctx, step_ctx->name);
+        name = sss_get_cased_name(step_ctx, step_ctx->name,
+                                  dom->case_sensitive);
+        if (!name) {
+            DEBUG(SSSDBG_CRIT_FAILURE, ("sss_get_cased_name failed\n"));
+            return ENOMEM;
+        }
 
         DEBUG(4, ("Requesting info for [%s@%s]\n",
                   name, dom->name));
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 
ced9df0634459fc0b4a4d229183ef5300073f86f..3b2d509e237b12516e1234a34a8542ae09752c43
 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -859,8 +859,8 @@ static int pam_check_user_search(struct pam_auth_req *preq)
         preq->domain = dom;
 
         talloc_free(name);
-        name = dom->case_sensitive ? talloc_strdup(preq, preq->pd->user) :
-                                sss_tc_utf8_str_tolower(preq, preq->pd->user);
+        name = sss_get_cased_name(preq, preq->pd->user,
+                                  dom->case_sensitive);
         if (!name) {
             return ENOMEM;
         }
diff --git a/src/util/usertools.c b/src/util/usertools.c
index 
738ac62d78ea1cee409aa2d228060c75025a87e7..64e8b1037fca322492e2d7c55152a7b07592df85
 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -173,3 +173,12 @@ int sss_parse_name(TALLOC_CTX *memctx,
 
     return EOK;
 }
+
+char *
+sss_get_cased_name(TALLOC_CTX *mem_ctx,
+                   const char *orig_name,
+                   bool case_sensitive)
+{
+    return case_sensitive ? talloc_strdup(mem_ctx, orig_name) :
+                            sss_tc_utf8_str_tolower(mem_ctx, orig_name);
+}
diff --git a/src/util/util.h b/src/util/util.h
index 
4ff112b7556a6634961c41edaf6d95d42f29c5d4..5428f0af60d17e066dd098aa1026287f0dc89be8
 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -401,6 +401,10 @@ int sss_parse_name(TALLOC_CTX *memctx,
                    struct sss_names_ctx *snctx,
                    const char *orig, char **domain, char **name);
 
+char *
+sss_get_cased_name(TALLOC_CTX *mem_ctx, const char *orig_name,
+                   bool case_sensitive);
+
 /* from backup-file.c */
 int backup_file(const char *src, int dbglvl);
 
-- 
1.7.6.4

From 0c2f9de9135c3f61488045ef1a3947db68e2fb4f Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Wed, 21 Dec 2011 18:05:26 +0100
Subject: [PATCH 2/3] Return user and group names lowercased in case
 insensitive domains

---
 src/responder/nss/nsssrv_cmd.c |   44 +++++++++++++++++++++++++++++----------
 1 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 
71c949f1d41a64782c8f1da8f3d4b2b2375c15bb..3bc30ab8641b1787ded15165890e61836e46e802
 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -353,6 +353,7 @@ static int fill_pwent(struct sss_packet *packet,
     struct ldb_message *msg;
     uint8_t *body;
     const char *name;
+    const char *orig_name;
     const char *gecos;
     const char *homedir;
     const char *shell;
@@ -381,23 +382,23 @@ static int fill_pwent(struct sss_packet *packet,
 
         msg = msgs[i];
 
-        name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
+        orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
         uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);
         gid = get_gid_override(msg, dom);
 
-        if (!name || !uid || !gid) {
+        if (!orig_name || !uid || !gid) {
             DEBUG(2, ("Incomplete or fake user object for %s[%llu]! 
Skipping\n",
-                      name?name:"<NULL>", (unsigned long long int)uid));
+                      orig_name?orig_name:"<NULL>", (unsigned long long 
int)uid));
             continue;
         }
 
         if (filter_users) {
             ncret = sss_ncache_check_user(nctx->ncache,
                                         nctx->neg_timeout,
-                                        dom, name);
+                                        dom, orig_name);
             if (ncret == EEXIST) {
                 DEBUG(4, ("User [%s@%s] filtered out! (negative cache)\n",
-                          name, domain));
+                          orig_name, domain));
                 continue;
             }
         }
@@ -409,6 +410,13 @@ static int fill_pwent(struct sss_packet *packet,
             packet_initialized = true;
         }
 
+        name = sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive);
+        if (name == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  ("sss_get_cased_name failed, skipping\n"));
+            continue;
+        }
+
         gecos = ldb_msg_find_attr_as_string(msg, SYSDB_GECOS, NULL);
         homedir = get_homedir_override(tmp_ctx, msg, nctx, dom, name, uid);
         shell = get_shell_override(tmp_ctx, msg, nctx);
@@ -1733,7 +1741,8 @@ static int fill_grent(struct sss_packet *packet,
     uint8_t *body;
     size_t blen;
     uint32_t gid;
-    const char *name;
+    const char *orig_name;
+    char *name;
     size_t nsize;
     size_t delim;
     size_t dom_len;
@@ -1745,6 +1754,7 @@ static int fill_grent(struct sss_packet *packet,
     bool add_domain = dom->fqnames;
     const char *domain = dom->name;
     const char *namefmt = nctx->rctx->names->fq_fmt;
+    TALLOC_CTX *tmp_ctx = NULL;
 
     if (add_domain) {
         delim = 1;
@@ -1767,6 +1777,8 @@ static int fill_grent(struct sss_packet *packet,
     rsize = 0;
 
     for (i = 0; i < *count; i++) {
+        talloc_zfree(tmp_ctx);
+        tmp_ctx = talloc_new(NULL);
         msg = msgs[i];
 
         /* new group */
@@ -1782,24 +1794,31 @@ static int fill_grent(struct sss_packet *packet,
         rsize = 0;
 
         /* find group name/gid */
-        name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
+        orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
         gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0);
-        if (!name || !gid) {
+        if (!orig_name || !gid) {
             DEBUG(2, ("Incomplete group object for %s[%llu]! Skipping\n",
-                      name?name:"<NULL>", (unsigned long long int)gid));
+                      orig_name?orig_name:"<NULL>", (unsigned long long 
int)gid));
             continue;
         }
 
         if (filter_groups) {
             ret = sss_ncache_check_group(nctx->ncache,
-                                         nctx->neg_timeout, dom, name);
+                                         nctx->neg_timeout, dom, orig_name);
             if (ret == EEXIST) {
                 DEBUG(4, ("Group [%s@%s] filtered out! (negative cache)\n",
-                          name, domain));
+                          orig_name, domain));
                 continue;
             }
         }
 
+        name = sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive);
+        if (name == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  ("sss_get_cased_name failed, skipping\n"));
+            continue;
+        }
+
         nsize = strlen(name) + 1; /* includes terminating \0 */
         if (add_domain) nsize += delim + dom_len;
 
@@ -1865,7 +1884,7 @@ static int fill_grent(struct sss_packet *packet,
             memnum = 0;
 
             for (j = 0; j < el->num_values; j++) {
-                name = (const char *)el->values[j].data;
+                name = (char *)el->values[j].data;
 
                 if (nctx->filter_users_in_groups) {
                     ret = sss_ncache_check_user(nctx->ncache,
@@ -1943,6 +1962,7 @@ static int fill_grent(struct sss_packet *packet,
         num++;
         continue;
     }
+    talloc_zfree(tmp_ctx);
 
 done:
     *count = i;
-- 
1.7.6.4

From 962984e3bdb2dfc9964b24d24dc9adc0d94cce46 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Wed, 21 Dec 2011 19:17:42 +0100
Subject: [PATCH 3/3] Honor case sensitive flag when creating the ccname
 template

---
 src/providers/krb5/krb5_auth.c  |    4 ++-
 src/providers/krb5/krb5_utils.c |   16 +++++++++++--
 src/providers/krb5/krb5_utils.h |    2 +-
 src/tests/krb5_utils-tests.c    |   46 +++++++++++++++++++++++++++++++++------
 4 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index 
6aaf7fbefd47609c926f6b5d8ea492295d4f090f..66cee473c73ca19cce5f58e13026b192267c1531
 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -626,7 +626,9 @@ static void krb5_find_ccache_step(struct tevent_req *req)
             kr->ccname = expand_ccname_template(kr, kr,
                                           
dp_opt_get_cstring(kr->krb5_ctx->opts,
                                                              KRB5_CCNAME_TMPL),
-                                                true, &private_path);
+                                                true,
+                                                
state->be_ctx->domain->case_sensitive,
+                                                &private_path);
             if (kr->ccname == NULL) {
                 DEBUG(1, ("expand_ccname_template failed.\n"));
                 ret = ENOMEM;
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index 
7fb0c8b381359ae4ee3a96f59420f7231dc3c64e..2957598cce0dc58334eb64807143e9284350ab8a
 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -30,13 +30,14 @@
 
 char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
                              const char *template, bool file_mode,
-                             bool *private_path)
+                             bool case_sensitive, bool *private_path)
 {
     char *copy;
     char *p;
     char *n;
     char *result = NULL;
     char *dummy;
+    char *name;
     char *res = NULL;
     const char *cache_dir_tmpl;
     TALLOC_CTX *tmp_ctx = NULL;
@@ -79,8 +80,16 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct 
krb5child_req *kr,
                               "because user name is empty.\n"));
                     goto done;
                 }
+                name = sss_get_cased_name(tmp_ctx, kr->pd->user,
+                                          case_sensitive);
+                if (!name) {
+                    DEBUG(SSSDBG_CRIT_FAILURE,
+                          ("sss_get_cased_name failed\n"));
+                    goto done;
+                }
+
                 result = talloc_asprintf_append(result, "%s%s", p,
-                                                kr->pd->user);
+                                                name);
                 if (!file_mode) *private_path = true;
                 break;
             case 'U':
@@ -132,7 +141,8 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct 
krb5child_req *kr,
                     }
 
                     dummy = expand_ccname_template(tmp_ctx, kr, cache_dir_tmpl,
-                                                   false, private_path);
+                                                   false, case_sensitive,
+                                                   private_path);
                     if (dummy == NULL) {
                         DEBUG(1, ("Expanding credential cache directory "
                                   "template failed.\n"));
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
index 
8977e14f403930a0550be2294fd55f9040d15605..7cc57d42f460380a97d4c7d149cbedc8e516e977
 100644
--- a/src/providers/krb5/krb5_utils.h
+++ b/src/providers/krb5/krb5_utils.h
@@ -33,7 +33,7 @@
 
 char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
                              const char *template, bool file_mode,
-                             bool *private_path);
+                             bool case_sensitive, bool *private_path);
 
 errno_t become_user(uid_t uid, gid_t gid);
 
diff --git a/src/tests/krb5_utils-tests.c b/src/tests/krb5_utils-tests.c
index 
6993398a459e1edca7eaad6f1777e18e685b128f..aacc384de2e0113fdaed861cf007b10f41b7aa6c
 100644
--- a/src/tests/krb5_utils-tests.c
+++ b/src/tests/krb5_utils-tests.c
@@ -421,7 +421,7 @@ static void do_test(const char *file_template, const char 
*dir_template,
     fail_unless(ret == EOK, "Failed to set Ccache dir");
 
     result = expand_ccname_template(tmp_ctx, kr, file_template, true,
-                                    &private_path);
+                                    true, &private_path);
 
     fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
     fail_unless(strcmp(result, expected) == 0,
@@ -448,6 +448,37 @@ START_TEST(test_username)
 }
 END_TEST
 
+START_TEST(test_case_sensitive)
+{
+    char *result;
+    int ret;
+    bool private_path = false;
+    const char *file_template = BASE"_%u";
+    const char *expected_cs = BASE"_TestUser";
+    const char *expected_ci = BASE"_testuser";
+
+    kr->pd->user = discard_const("TestUser");
+    ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, CCACHE_DIR);
+    fail_unless(ret == EOK, "Failed to set Ccache dir");
+
+    result = expand_ccname_template(tmp_ctx, kr, file_template, true,
+                                    true, &private_path);
+
+    fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
+    fail_unless(strcmp(result, expected_cs) == 0,
+                "Expansion failed, result [%s], expected [%s].",
+                result, expected_cs);
+
+    result = expand_ccname_template(tmp_ctx, kr, file_template, true,
+                                    false, &private_path);
+
+    fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
+    fail_unless(strcmp(result, expected_ci) == 0,
+                "Expansion failed, result [%s], expected [%s].",
+                result, expected_ci);
+}
+END_TEST
+
 START_TEST(test_uid)
 {
     do_test(BASE"_%U", CCACHE_DIR, BASE"_"UID, false);
@@ -488,7 +519,7 @@ START_TEST(test_ccache_dir)
     fail_unless(ret == EOK, "Failed to set Ccache dir");
 
     result = expand_ccname_template(tmp_ctx, kr, "%d/"FILENAME, true,
-                                    &private_path);
+                                    true, &private_path);
 
     fail_unless(result == NULL, "Using %%d in ccache dir should fail.");
     fail_unless(private_path == false,
@@ -509,7 +540,7 @@ START_TEST(test_pid)
     fail_unless(ret == EOK, "Failed to set Ccache dir");
 
     result = expand_ccname_template(tmp_ctx, kr, "%d/"FILENAME, true,
-                                    &private_path);
+                                    true, &private_path);
 
     fail_unless(result == NULL, "Using %%P in ccache dir should fail.");
     fail_unless(private_path == false,
@@ -533,7 +564,7 @@ START_TEST(test_unknow_template)
     bool private_path = false;
 
     result = expand_ccname_template(tmp_ctx, kr, test_template, true,
-                                    &private_path);
+                                    true, &private_path);
 
     fail_unless(result == NULL, "Unknown template [%s] should fail.",
                 test_template);
@@ -542,7 +573,7 @@ START_TEST(test_unknow_template)
     fail_unless(ret == EOK, "Failed to set Ccache dir");
     test_template = "%d/"FILENAME;
     result = expand_ccname_template(tmp_ctx, kr, test_template, true,
-                                    &private_path);
+                                    true, &private_path);
 
     fail_unless(result == NULL, "Unknown template [%s] should fail.",
                 test_template);
@@ -559,7 +590,7 @@ START_TEST(test_NULL)
     bool private_path = false;
 
     result = expand_ccname_template(tmp_ctx, kr, test_template, true,
-                                    &private_path);
+                                    true, &private_path);
 
     fail_unless(result == NULL, "Expected NULL as a result for an empty 
input.",
                 test_template);
@@ -576,7 +607,7 @@ START_TEST(test_no_substitution)
     bool private_path = false;
 
     result = expand_ccname_template(tmp_ctx, kr, test_template, true,
-                                    &private_path);
+                                    true, &private_path);
 
     fail_unless(result != NULL, "Cannot expand template [%s].", test_template);
     fail_unless(strcmp(result, test_template) == 0,
@@ -599,6 +630,7 @@ Suite *krb5_utils_suite (void)
     tcase_add_test (tc_ccname_template, test_NULL);
     tcase_add_test (tc_ccname_template, test_unknow_template);
     tcase_add_test (tc_ccname_template, test_username);
+    tcase_add_test (tc_ccname_template, test_case_sensitive);
     tcase_add_test (tc_ccname_template, test_uid);
     tcase_add_test (tc_ccname_template, test_upn);
     tcase_add_test (tc_ccname_template, test_realm);
-- 
1.7.6.4

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to