From 1f2662c8f97c9c0fa250055d4b6750abfc6d0835 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Oct 11 2017 15:28:53 +0000 Subject: sysdb: sanitize search filter input This patch sanitizes the input for sysdb searches by UPN/email, SID and UUID. This security issue was assigned CVE-2017-12173 Reviewed-by: Lukáš Slebodník Reviewed-by: Jakub Hrozek --- diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 4cfef68..0e39a62 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -601,6 +601,7 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, int ret; const char *def_attrs[] = { SYSDB_NAME, SYSDB_UPN, SYSDB_CANONICAL_UPN, SYSDB_USER_EMAIL, NULL }; + char *sanitized; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { @@ -608,6 +609,12 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, goto done; } + ret = sss_filter_sanitize(tmp_ctx, upn, &sanitized); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n"); + goto done; + } + if (domain_scope == true) { base_dn = sysdb_user_base_dn(tmp_ctx, domain); } else { @@ -620,7 +627,7 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs ? attrs : def_attrs, - SYSDB_PWUPN_FILTER, upn, upn, upn); + SYSDB_PWUPN_FILTER, sanitized, sanitized, sanitized); if (ret != EOK) { ret = sysdb_error_to_errno(ret); goto done; @@ -4823,17 +4830,31 @@ static errno_t sysdb_search_object_by_str_attr(TALLOC_CTX *mem_ctx, bool expect_only_one_result, struct ldb_result **_res) { - char *filter; + char *filter = NULL; errno_t ret; + char *sanitized = NULL; + + if (str == NULL) { + return EINVAL; + } + + ret = sss_filter_sanitize(NULL, str, &sanitized); + if (ret != EOK || sanitized == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n"); + goto done; + } - filter = talloc_asprintf(NULL, filter_tmpl, str); + filter = talloc_asprintf(NULL, filter_tmpl, sanitized); if (filter == NULL) { - return ENOMEM; + ret = ENOMEM; + goto done; } ret = sysdb_search_object_attr(mem_ctx, domain, filter, attrs, expect_only_one_result, _res); +done: + talloc_free(sanitized); talloc_free(filter); return ret; } @@ -4922,7 +4943,8 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx, struct ldb_result **res) { int ret; - char *user_filter; + char *user_filter = NULL; + char *filter = NULL; ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_MAPPED_CERT, NULL, NULL, &user_filter); @@ -4931,10 +4953,15 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx, return ret; } - ret = sysdb_search_object_by_str_attr(mem_ctx, domain, - SYSDB_USER_CERT_FILTER, - user_filter, attrs, false, res); + filter = talloc_asprintf(NULL, SYSDB_USER_CERT_FILTER, user_filter); talloc_free(user_filter); + if (filter == NULL) { + return ENOMEM; + } + + ret = sysdb_search_object_attr(mem_ctx, domain, filter, attrs, false, res); + + talloc_free(filter); return ret; } diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 63572e0..4652661 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -6513,6 +6513,13 @@ START_TEST(test_upn_basic) fail_unless(strcmp(str, UPN_PRINC) == 0, "Expected [%s], got [%s].", UPN_PRINC, str); + /* check if input is sanitized */ + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, false, + "abc@def.ghi)(name="UPN_USER_NAME")(abc=xyz", + NULL, &msg); + fail_unless(ret == ENOENT, + "sysdb_search_user_by_upn failed with un-sanitized input."); + talloc_free(test_ctx); } END_TEST