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