From 3e57163a7bfae0e5e90ca8c412c1f10f01dbbeda Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 13 Dec 2013 11:44:59 +0100 Subject: [PATCH 5/5] Use lower-case name for case-insensitive searches The patch makes sure that a completely lower-cased version of a fully qualified name is used for case insensitive searches. Currently there are code paths where the domain name was used as configured and was not lower-cased. To make sure this patch does not break with old entries in the cache or case sensitive domains a third template was added to the related filters templates which is either filled with a completely lower-cased version or with the old version. The other two template values are unchanged. --- src/db/sysdb.h | 10 +++++----- src/db/sysdb_ops.c | 8 +++++--- src/db/sysdb_search.c | 30 ++++++++++++++++++++-------- src/responder/pam/pam_LOCAL_domain.c | 4 ++-- src/tests/cmocka/test_utils.c | 38 ++++++++++++++++++++++++++++++++++++ src/util/sss_tc_utf8.c | 30 ++++++++++++++++++++++++++++ src/util/util.h | 6 ++++++ 7 files changed, 108 insertions(+), 18 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index f3358d6..f1ed815 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -144,23 +144,23 @@ #define SYSDB_NC "objectclass="SYSDB_NETGROUP_CLASS #define SYSDB_MPGC "|("SYSDB_UC")("SYSDB_GC")" -#define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" +#define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_PWUID_FILTER "(&("SYSDB_UC")("SYSDB_UIDNUM"=%lu))" #define SYSDB_PWSID_FILTER "(&("SYSDB_UC")("SYSDB_SID_STR"=%s))" #define SYSDB_PWENT_FILTER "("SYSDB_UC")" -#define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" +#define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_GRGID_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=%lu))" #define SYSDB_GRSID_FILTER "(&("SYSDB_GC")("SYSDB_SID_STR"=%s))" #define SYSDB_GRENT_FILTER "("SYSDB_GC")" -#define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" +#define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_GRGID_MPG_FILTER "(&("SYSDB_MPGC")("SYSDB_GIDNUM"=%lu))" #define SYSDB_GRENT_MPG_FILTER "("SYSDB_MPGC")" #define SYSDB_INITGR_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=*))" -#define SYSDB_NETGR_FILTER "(&("SYSDB_NC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" -#define SYSDB_NETGR_TRIPLES_FILTER "(|("SYSDB_NAME"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_MEMBEROF"=%s))" +#define SYSDB_NETGR_FILTER "(&("SYSDB_NC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" +#define SYSDB_NETGR_TRIPLES_FILTER "(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_MEMBEROF"=%s))" #define SYSDB_SID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_SID_STR"=%s))" diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 890bf1e..a5dfd44 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -305,6 +305,7 @@ int sysdb_search_user_by_name(TALLOC_CTX *mem_ctx, struct ldb_dn *basedn; size_t msgs_count = 0; char *sanitized_name; + char *lc_sanitized_name; char *filter; int ret; @@ -320,13 +321,14 @@ int sysdb_search_user_by_name(TALLOC_CTX *mem_ctx, goto done; } - ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name); + ret = sss_filter_sanitize_for_dom(tmp_ctx, name, domain, &sanitized_name, + &lc_sanitized_name); if (ret != EOK) { goto done; } - filter = talloc_asprintf(tmp_ctx, SYSDB_PWNAM_FILTER, sanitized_name, - sanitized_name); + filter = talloc_asprintf(tmp_ctx, SYSDB_PWNAM_FILTER, lc_sanitized_name, + sanitized_name, sanitized_name); if (!filter) { ret = ENOMEM; goto done; diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c index d15fc73..308710a 100644 --- a/src/db/sysdb_search.c +++ b/src/db/sysdb_search.c @@ -38,6 +38,7 @@ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn; struct ldb_result *res; char *sanitized_name; + char *lc_sanitized_name; const char *src_name; int ret; @@ -61,13 +62,15 @@ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, goto done; } - ret = sss_filter_sanitize(tmp_ctx, src_name, &sanitized_name); + ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain, + &sanitized_name, &lc_sanitized_name); if (ret != EOK) { goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_PWNAM_FILTER, + lc_sanitized_name, sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); @@ -214,6 +217,7 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn; struct ldb_result *res; const char *src_name; + char *lc_sanitized_name; int ret; tmp_ctx = talloc_new(NULL); @@ -243,14 +247,15 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx, goto done; } - ret = sss_filter_sanitize(tmp_ctx, src_name, &sanitized_name); + ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain, + &sanitized_name, &lc_sanitized_name); if (ret != EOK) { goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, fmt_filter, - sanitized_name, sanitized_name); + lc_sanitized_name, sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); goto done; @@ -481,6 +486,7 @@ int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn; struct ldb_result *res; char *sanitized_name; + char *lc_sanitized_name; int ret; tmp_ctx = talloc_new(NULL); @@ -495,14 +501,15 @@ int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, goto done; } - ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name); + ret = sss_filter_sanitize_for_dom(tmp_ctx, name, domain, &sanitized_name, + &lc_sanitized_name); if (ret != EOK) { goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attributes, - SYSDB_PWNAM_FILTER, sanitized_name, + SYSDB_PWNAM_FILTER, lc_sanitized_name, sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); @@ -785,6 +792,7 @@ errno_t sysdb_getnetgr(TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn; struct ldb_result *result; char *sanitized_netgroup; + char *lc_sanitized_netgroup; char *netgroup_dn; int lret; errno_t ret; @@ -802,7 +810,9 @@ errno_t sysdb_getnetgr(TALLOC_CTX *mem_ctx, goto done; } - ret = sss_filter_sanitize(tmp_ctx, netgroup, &sanitized_netgroup); + ret = sss_filter_sanitize_for_dom(tmp_ctx, netgroup, domain, + &sanitized_netgroup, + &lc_sanitized_netgroup); if (ret != EOK) { goto done; } @@ -816,7 +826,7 @@ errno_t sysdb_getnetgr(TALLOC_CTX *mem_ctx, lret = ldb_search(sysdb->ldb, tmp_ctx, &result, base_dn, LDB_SCOPE_SUBTREE, attrs, - SYSDB_NETGR_TRIPLES_FILTER, + SYSDB_NETGR_TRIPLES_FILTER, lc_sanitized_netgroup, sanitized_netgroup, sanitized_netgroup, netgroup_dn); ret = sysdb_error_to_errno(lret); @@ -843,6 +853,7 @@ int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn; struct ldb_result *result; char *sanitized_netgroup; + char *lc_sanitized_netgroup; int ret; tmp_ctx = talloc_new(NULL); @@ -857,7 +868,9 @@ int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx, goto done; } - ret = sss_filter_sanitize(tmp_ctx, netgrname, &sanitized_netgroup); + ret = sss_filter_sanitize_for_dom(tmp_ctx, netgrname, domain, + &sanitized_netgroup, + &lc_sanitized_netgroup); if (ret != EOK) { goto done; } @@ -865,6 +878,7 @@ int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx, ret = ldb_search(sysdb->ldb, tmp_ctx, &result, base_dn, LDB_SCOPE_SUBTREE, attributes, SYSDB_NETGR_FILTER, + lc_sanitized_netgroup, sanitized_netgroup, sanitized_netgroup); if (ret) { diff --git a/src/responder/pam/pam_LOCAL_domain.c b/src/responder/pam/pam_LOCAL_domain.c index e7776cb..49ddbcd 100644 --- a/src/responder/pam/pam_LOCAL_domain.c +++ b/src/responder/pam/pam_LOCAL_domain.c @@ -258,12 +258,12 @@ int LOCAL_pam_handler(struct pam_auth_req *preq) if (res->count < 1) { DEBUG(4, ("No user found with filter ["SYSDB_PWNAM_FILTER"]\n", - pd->user, pd->user)); + pd->user, pd->user, pd->user)); pd->pam_status = PAM_USER_UNKNOWN; goto done; } else if (res->count > 1) { DEBUG(4, ("More than one object found with filter ["SYSDB_PWNAM_FILTER"]\n", - pd->user, pd->user)); + pd->user, pd->user, pd->user)); lreq->error = EFAULT; goto done; } diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c index 1be59ab..61e8e9f 100644 --- a/src/tests/cmocka/test_utils.c +++ b/src/tests/cmocka/test_utils.c @@ -177,6 +177,41 @@ void test_find_subdomain_by_sid_missing_sid(void **state) } } +#define TEST_SANITIZE_INPUT "TestUser@Test.Domain" +#define TEST_SANITIZE_LC_INPUT "testuser@test.domain" + +void test_sss_filter_sanitize_for_dom(void **state) +{ + struct dom_list_test_ctx *test_ctx; + int ret; + char *sanitized; + char *lc_sanitized; + struct sss_domain_info *dom; + + test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); + dom = test_ctx->dom_list; + + dom->case_sensitive = true; + + ret = sss_filter_sanitize_for_dom(test_ctx, TEST_SANITIZE_INPUT, dom, + &sanitized, &lc_sanitized); + assert_int_equal(ret, EOK); + assert_string_equal(sanitized, TEST_SANITIZE_INPUT); + assert_string_equal(lc_sanitized, TEST_SANITIZE_INPUT); + talloc_free(sanitized); + talloc_free(lc_sanitized); + + dom->case_sensitive = false; + + ret = sss_filter_sanitize_for_dom(test_ctx, TEST_SANITIZE_INPUT, dom, + &sanitized, &lc_sanitized); + assert_int_equal(ret, EOK); + assert_string_equal(sanitized, TEST_SANITIZE_INPUT); + assert_string_equal(lc_sanitized, TEST_SANITIZE_LC_INPUT); + talloc_free(sanitized); + talloc_free(lc_sanitized); +} + int main(int argc, const char *argv[]) { poptContext pc; @@ -194,6 +229,9 @@ int main(int argc, const char *argv[]) setup_dom_list, teardown_dom_list), unit_test_setup_teardown(test_find_subdomain_by_sid_missing_sid, setup_dom_list, teardown_dom_list), + + unit_test_setup_teardown(test_sss_filter_sanitize_for_dom, + setup_dom_list, teardown_dom_list), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ diff --git a/src/util/sss_tc_utf8.c b/src/util/sss_tc_utf8.c index 6a97621..e1426a4 100644 --- a/src/util/sss_tc_utf8.c +++ b/src/util/sss_tc_utf8.c @@ -55,3 +55,33 @@ sss_tc_utf8_tolower(TALLOC_CTX *mem_ctx, const uint8_t *s, size_t len, size_t *_ return ret; } +errno_t sss_filter_sanitize_for_dom(TALLOC_CTX *mem_ctx, + const char *input, + struct sss_domain_info *dom, + char **sanitized, + char **lc_sanitized) +{ + int ret; + + ret = sss_filter_sanitize(mem_ctx, input, sanitized); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("sss_filter_sanitize failed.\n")); + return ret; + } + + if (dom->case_sensitive) { + *lc_sanitized = talloc_strdup(mem_ctx, *sanitized); + } else { + *lc_sanitized = sss_tc_utf8_str_tolower(mem_ctx, *sanitized); + } + + if (*lc_sanitized == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("%s failed.\n", + dom->case_sensitive ? + "talloc_strdup" : + "sss_tc_utf8_str_tolower")); + return ENOMEM; + } + + return EOK; +} diff --git a/src/util/util.h b/src/util/util.h index 058c1c2..3334476 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -484,6 +484,12 @@ errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx, const char *input, char **sanitized); +errno_t sss_filter_sanitize_for_dom(TALLOC_CTX *mem_ctx, + const char *input, + struct sss_domain_info *dom, + char **sanitized, + char **lc_sanitized); + char * sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr); -- 1.8.3.1