From 7ecb5aea65cb1899f16e7a41bffa93d074defd4a Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Jun 20 2014 11:45:30 +0000 Subject: sysdb: add sysdb_search_user_by_upn() with tests Reviewed-by: Jakub Hrozek --- diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 1057090..95834ee 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -148,6 +148,7 @@ #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_PWUPN_FILTER "(&("SYSDB_UC")(|("SYSDB_UPN"=%s)("SYSDB_CANONICAL_UPN"=%s)))" #define SYSDB_PWENT_FILTER "("SYSDB_UC")" #define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" @@ -527,6 +528,12 @@ int sysdb_search_user_by_sid_str(TALLOC_CTX *mem_ctx, const char **attrs, struct ldb_message **msg); +int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *sid_str, + const char **attrs, + struct ldb_message **msg); + /* Search Group (by gid, sid or name) */ int sysdb_search_group_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 915ef1a..50f3391 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -435,6 +435,66 @@ int sysdb_search_user_by_sid_str(TALLOC_CTX *mem_ctx, sid_str, attrs, msg); } +int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *upn, + const char **attrs, + struct ldb_message **msg) +{ + TALLOC_CTX *tmp_ctx; + const char *def_attrs[] = { SYSDB_NAME, SYSDB_UPN, SYSDB_CANONICAL_UPN, + NULL }; + struct ldb_message **msgs = NULL; + struct ldb_dn *basedn; + size_t msgs_count = 0; + char *filter; + int ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, + SYSDB_TMPL_USER_BASE, domain->name); + if (basedn == NULL) { + ret = ENOMEM; + goto done; + } + + filter = talloc_asprintf(tmp_ctx, SYSDB_PWUPN_FILTER, upn, upn); + if (filter == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, + filter, attrs?attrs:def_attrs, &msgs_count, + &msgs); + if (ret != EOK) { + goto done; + } + + if (msgs_count > 1) { + DEBUG(SSSDBG_OP_FAILURE, + "Search for upn [%s] returns more than one result.\n", upn); + ret = EINVAL; + goto done; + } + + *msg = talloc_steal(mem_ctx, msgs[0]); + +done: + if (ret == ENOENT) { + DEBUG(SSSDBG_TRACE_FUNC, "No entry with upn [%s] found.\n", upn); + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); + } + + talloc_zfree(tmp_ctx); + return ret; +} + /* =Search-Group-by-[GID/SID/NAME]============================================ */ int sysdb_search_group_by_name(TALLOC_CTX *mem_ctx, diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 3d67441..ac78f36 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -5214,6 +5214,228 @@ START_TEST(test_confdb_list_all_domain_names_single_dom) } END_TEST +#define UPN_USER_NAME "upn_user" +#define UPN_PRINC "upn_user@UPN.TEST" +#define UPN_PRINC_WRONG_CASE "UpN_uSeR@uPn.TeSt" +#define UPN_CANON_PRINC "upn_user@UPN.CANON" +#define UPN_CANON_PRINC_WRONG_CASE "uPn_UsEr@UpN.CaNoN" + +START_TEST(test_upn_basic) +{ + struct sysdb_test_ctx *test_ctx; + struct sysdb_attrs *attrs; + int ret; + struct ldb_message *msg; + const char *str; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + attrs = sysdb_new_attrs(test_ctx); + fail_unless(attrs != NULL, "sysdb_new_attrs failed.\n"); + + ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, UPN_PRINC); + fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); + + ret = sysdb_attrs_add_string(attrs, SYSDB_CANONICAL_UPN, UPN_CANON_PRINC); + fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); + + ret = sysdb_store_user(test_ctx->domain, + UPN_USER_NAME, "x", + 12345, 0, "UPN USER", "/home/upn_user", + "/bin/bash", NULL, + attrs, NULL, -1, 0); + fail_unless(ret == EOK, "Could not store user."); + + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, + "abc@def.ghi", NULL, &msg); + fail_unless(ret == ENOENT, + "sysdb_search_user_by_upn failed with non-existing UPN."); + + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, + UPN_PRINC, NULL, &msg); + fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", + UPN_USER_NAME, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_PRINC) == 0, + "Expected [%s], got [%s].", UPN_PRINC, str); + + talloc_free(test_ctx); +} +END_TEST + +START_TEST(test_upn_basic_case) +{ + struct sysdb_test_ctx *test_ctx; + int ret; + struct ldb_message *msg; + const char *str; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, + UPN_PRINC_WRONG_CASE, NULL, &msg); + fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", + UPN_USER_NAME, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_PRINC) == 0, + "Expected [%s], got [%s].", UPN_PRINC, str); + + talloc_free(test_ctx); +} +END_TEST + +START_TEST(test_upn_canon) +{ + struct sysdb_test_ctx *test_ctx; + int ret; + struct ldb_message *msg; + const char *str; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, + UPN_CANON_PRINC, NULL, &msg); + fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", + UPN_USER_NAME, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_PRINC) == 0, + "Expected [%s], got [%s].", UPN_PRINC, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_CANON_PRINC) == 0, + "Expected [%s], got [%s].", UPN_CANON_PRINC, str); + + talloc_free(test_ctx); +} +END_TEST + +START_TEST(test_upn_canon_case) +{ + struct sysdb_test_ctx *test_ctx; + int ret; + struct ldb_message *msg; + const char *str; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, + UPN_CANON_PRINC_WRONG_CASE, NULL, &msg); + fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", + UPN_USER_NAME, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_PRINC) == 0, + "Expected [%s], got [%s].", UPN_PRINC, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_CANON_PRINC) == 0, + "Expected [%s], got [%s].", UPN_CANON_PRINC, str); + + talloc_free(test_ctx); +} +END_TEST + +START_TEST(test_upn_dup) +{ + struct sysdb_test_ctx *test_ctx; + struct sysdb_attrs *attrs; + int ret; + struct ldb_message *msg; + const char *str; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + attrs = sysdb_new_attrs(test_ctx); + fail_unless(attrs != NULL, "sysdb_new_attrs failed.\n"); + + ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, UPN_CANON_PRINC); + fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); + + ret = sysdb_store_user(test_ctx->domain, + UPN_USER_NAME"_dup", "x", + 23456, 0, "UPN USER DUP", "/home/upn_user_dup", + "/bin/bash", NULL, + attrs, NULL, -1, 0); + fail_unless(ret == EOK, "Could not store user."); + + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, + UPN_CANON_PRINC, NULL, &msg); + fail_unless(ret == EINVAL, + "sysdb_search_user_by_upn failed for duplicated UPN."); + + ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, + UPN_PRINC, NULL, &msg); + fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", + UPN_USER_NAME, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_PRINC) == 0, + "Expected [%s], got [%s].", UPN_PRINC, str); + + str = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL); + fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); + fail_unless(strcmp(str, UPN_CANON_PRINC) == 0, + "Expected [%s], got [%s].", UPN_CANON_PRINC, str); + + talloc_free(test_ctx); +} +END_TEST + START_TEST(test_confdb_list_all_domain_names_multi_dom) { int ret; @@ -5610,6 +5832,15 @@ Suite *create_sysdb_suite(void) suite_add_tcase(s, tc_autofs); #endif + TCase *tc_upn = tcase_create("SYSDB UPN tests"); + tcase_add_test(tc_upn, test_upn_basic); + tcase_add_test(tc_upn, test_upn_basic_case); + tcase_add_test(tc_upn, test_upn_canon); + tcase_add_test(tc_upn, test_upn_canon_case); + tcase_add_test(tc_upn, test_upn_dup); + + suite_add_tcase(s, tc_upn); + /* ConfDB tests -- modify confdb, must always be last!! */ TCase *tc_confdb = tcase_create("confDB tests");