URL: https://github.com/SSSD/sssd/pull/608 Author: sumit-bose Title: #608: AD: consider resource_groups in PAC as well Action: opened
PR body: """ With recent versions of Active Directory the SIDs of Domain Local groups might be only available in the resource_groups section of the PAC, this feature is also called SID compression. To get a complete list of groups the user is a member of the SIDs from this section must be extracted as well. Resolves https://pagure.io/SSSD/sssd/issue/3767 """ To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/608/head:pr608 git checkout pr608
From 5117f155411b86d233256bc36671655a23fcf4d4 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Thu, 28 Jun 2018 12:41:41 +0200 Subject: [PATCH] AD: consider resource_groups in PAC as well With recent versions of Active Directory the SIDs of Domain Local groups might be only available in the resource_groups section of the PAC, this feature is also called SID compression. To get a complete list of groups the user is a member of the SIDs from this section must be extracted as well. Resolves https://pagure.io/SSSD/sssd/issue/3767 --- src/providers/ad/ad_pac.c | 121 ++++++++++++++++++++++++++++++-------- src/tests/cmocka/test_ad_common.c | 91 ++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 23 deletions(-) diff --git a/src/providers/ad/ad_pac.c b/src/providers/ad/ad_pac.c index 1a344725f..5873204e1 100644 --- a/src/providers/ad/ad_pac.c +++ b/src/providers/ad/ad_pac.c @@ -146,6 +146,82 @@ errno_t check_if_pac_is_available(TALLOC_CTX *mem_ctx, return EOK; } +static errno_t +add_sids_from_rid_array_to_hash_table(struct dom_sid *dom_sid, + struct samr_RidWithAttributeArray *groups, + struct sss_idmap_ctx *idmap_ctx, + hash_table_t *sid_table) +{ + enum idmap_error_code err; + char *dom_sid_str = NULL; + size_t dom_sid_str_len; + char *sid_str = NULL; + char *rid_start; + hash_key_t key; + hash_value_t value; + int ret; + size_t c; + TALLOC_CTX *tmp_ctx = NULL; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); + return ENOMEM; + } + + key.type = HASH_KEY_STRING; + value.type = HASH_VALUE_ULONG; + + err = sss_idmap_smb_sid_to_sid(idmap_ctx, dom_sid, &dom_sid_str); + if (err != IDMAP_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); + ret = EFAULT; + goto done; + } + + dom_sid_str_len = strlen(dom_sid_str); + sid_str = talloc_zero_size(tmp_ctx, dom_sid_str_len + 12); + if (sid_str == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); + ret = ENOMEM; + goto done; + } + rid_start = sid_str + dom_sid_str_len; + + memcpy(sid_str, dom_sid_str, dom_sid_str_len); + + for (c = 0; c < groups->count; c++) { + memset(rid_start, '\0', 12); + ret = snprintf(rid_start, 12, "-%lu", + (unsigned long) groups->rids[c].rid); + if (ret < 0 || ret > 12) { + DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); + ret = EIO; + goto done; + } + + key.str = sid_str; + value.ul = 0; + + ret = hash_enter(sid_table, &key, &value); + if (ret != HASH_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", + ret, hash_error_string(ret)); + ret = EIO; + goto done; + } + + } + + ret = EOK; + +done: + sss_idmap_free_sid(idmap_ctx, dom_sid_str); + talloc_free(tmp_ctx); + + return ret; +} + errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, struct sss_idmap_ctx *idmap_ctx, struct PAC_LOGON_INFO *logon_info, @@ -157,6 +233,7 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, int ret; size_t s; struct netr_SamInfo3 *info3; + struct PAC_DOMAIN_GROUP_MEMBERSHIP *resource_groups; char *sid_str = NULL; char *msid_str = NULL; char *user_dom_sid_str = NULL; @@ -188,9 +265,11 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, } info3 = &logon_info->info3; + resource_groups = &logon_info->resource_groups; ret = sss_hash_create(tmp_ctx, - info3->sidcount + info3->base.groups.count + 2, + info3->sidcount + info3->base.groups.count + 2 + + resource_groups->groups.count, &sid_table); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); @@ -265,28 +344,13 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, goto done; } - - for (s = 0; s < info3->base.groups.count; s++) { - memset(rid_start, '\0', 12); - ret = snprintf(rid_start, 12, "-%lu", - (unsigned long) info3->base.groups.rids[s].rid); - if (ret < 0 || ret > 12) { - DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); - ret = EIO; - goto done; - } - - key.str = sid_str; - value.ul = 0; - - ret = hash_enter(sid_table, &key, &value); - if (ret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", - ret, hash_error_string(ret)); - ret = EIO; - goto done; - } - + ret = add_sids_from_rid_array_to_hash_table(info3->base.domain_sid, + &info3->base.groups, + idmap_ctx, sid_table); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "add_sids_from_rid_array_to_hash_table failed.\n"); + goto done; } for(s = 0; s < info3->sidcount; s++) { @@ -311,6 +375,17 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, } } + if (resource_groups->domain_sid != NULL) { + ret = add_sids_from_rid_array_to_hash_table(resource_groups->domain_sid, + &resource_groups->groups, + idmap_ctx, sid_table); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "add_sids_from_rid_array_to_hash_table failed.\n"); + goto done; + } + } + num_sids = hash_count(sid_table); sid_list = talloc_array(tmp_ctx, char *, num_sids); if (sid_list == NULL) { diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c index 39ebbc633..b2283027b 100644 --- a/src/tests/cmocka/test_ad_common.c +++ b/src/tests/cmocka/test_ad_common.c @@ -207,6 +207,29 @@ static void test_check_if_pac_is_available(void **state) "BEAEUAVgBFAEwAdv///4yBQZ5ZQnp3qwj2lKGcd0UAAAAAdv//" \ "/39fn4UneD5l6YxP8w/U0coAAAAA" +#define TEST_PAC_RESOURCE_GROUPS_BASE64 \ + "BQAAAAAAAAABAAAA8AEAAFgAAAAAAAAACgAAABQAAABIAgAA" \ + "AAAAAAwAAABYAAAAYAIAAAAAAAAGAAAAEAAAALgCAAAAAAAA" \ + "BwAAABQAAADIAgAAAAAAAAEQCADMzMzM4AEAAAAAAAAAAAIA" \ + "Rr0gPUQO1AH/////////f/////////9/TRPNRwtu0wFN0zZy" \ + "1G7TAf////////9/CgAKAAQAAgAKAAoACAACAAAAAAAMAAIA" \ + "AAAAABAAAgAAAAAAFAACAAAAAAAYAAIACwAAAFEEAAABAgAA" \ + "AwAAABwAAgAgAgAAAAAAAAAAAAAAAAAAAAAAAAQABgAgAAIA" \ + "BgAIACQAAgAoAAIAAAAAAAAAAAAQAgAAAAAAAAAAAAAAAAAA" \ + "AAAAAAAAAAAAAAAAAAAAAAEAAAAsAAIANAACAAEAAAA4AAIA" \ + "BQAAAAAAAAAFAAAAdAB1AHMAZQByAAAABQAAAAAAAAAFAAAA" \ + "dAB1AHMAZQByAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAECAAAHAAAA" \ + "YgQAAAcAAABjBAAABwAAAAMAAAAAAAAAAgAAAEQAQwAEAAAA" \ + "AAAAAAMAAABXAEkATgAAAAQAAAABBAAAAAAABRUAAAAkYm0r" \ + "SyFumd73jX0BAAAAMAACAAcAAAABAAAAAQEAAAAAABIBAAAA" \ + "BAAAAAEEAAAAAAAFFQAAACRibStLIW6Z3veNfQEAAABoBAAA" \ + "BwAAIAAAAACAEuVfRA7UAQoAdAB1AHMAZQByAAAAAAAoABAA" \ + "HAA4AAAAAAAAAAAAdAB1AHMAZQByAEAAdwBpAG4ALgB0AHIA" \ + "dQBzAHQALgB0AGUAcwB0AFcASQBOAC4AVABSAFUAUwBUAC4A" \ + "VABFAFMAVAAAAAAAEAAAAOGTj7I9Qn7XebOqdHb///+fHhrZ" \ + "kBt0So4jOFBk84sDAAAAAA==" + static void test_ad_get_data_from_pac(void **state) { int ret; @@ -303,6 +326,71 @@ static void test_ad_get_sids_from_pac(void **state) sss_idmap_free(idmap_ctx); } +static void test_ad_get_sids_from_pac_with_resource_groups(void **state) +{ + int ret; + struct PAC_LOGON_INFO *logon_info; + uint8_t *test_pac_blob; + size_t test_pac_blob_size; + char *user_sid; + char *primary_group_sid; + size_t num_sids; + char **sid_list; + struct sss_idmap_ctx *idmap_ctx; + enum idmap_error_code err; + size_t c; + size_t s; + + const char *sid_check_list[] = { "S-1-5-21-728588836-2574131531-2106456030-513", + "S-1-5-21-728588836-2574131531-2106456030-1122", + "S-1-5-21-728588836-2574131531-2106456030-1123", + "S-1-5-21-728588836-2574131531-2106456030-1128", + "S-1-18-1", + NULL }; + + struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, + struct ad_common_test_ctx); + + err = sss_idmap_init(sss_idmap_talloc, test_ctx, sss_idmap_talloc_free, + &idmap_ctx); + assert_int_equal(err, IDMAP_SUCCESS); + + test_pac_blob = sss_base64_decode(test_ctx, TEST_PAC_RESOURCE_GROUPS_BASE64, + &test_pac_blob_size); + assert_non_null(test_pac_blob_size); + + ret = ad_get_data_from_pac(test_ctx, test_pac_blob, test_pac_blob_size, + &logon_info); + assert_int_equal(ret, EOK); + + ret = ad_get_sids_from_pac(test_ctx, idmap_ctx, logon_info, &user_sid, + &primary_group_sid, &num_sids, &sid_list); + assert_int_equal(ret, EOK); + assert_string_equal(user_sid, + "S-1-5-21-728588836-2574131531-2106456030-1105"); + assert_string_equal(primary_group_sid, + "S-1-5-21-728588836-2574131531-2106456030-513"); + assert_int_equal(num_sids, 5); + + for (c = 0; sid_check_list[c] != NULL; c++) { + for (s = 0; s < num_sids; s++) { + if (strcmp(sid_check_list[c], sid_list[s]) == 0) { + break; + } + } + if (s == num_sids) { + fail_msg("SID [%s] not found in SID list.", sid_check_list[c]); + } + } + + talloc_free(test_pac_blob); + talloc_free(logon_info); + talloc_free(user_sid); + talloc_free(primary_group_sid); + talloc_free(sid_list); + sss_idmap_free(idmap_ctx); +} + static void test_ad_get_pac_data_from_user_entry(void **state) { int ret; @@ -912,6 +1000,9 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(test_ad_get_sids_from_pac, test_ad_common_setup, test_ad_common_teardown), + cmocka_unit_test_setup_teardown(test_ad_get_sids_from_pac_with_resource_groups, + test_ad_common_setup, + test_ad_common_teardown), cmocka_unit_test_setup_teardown(test_ad_get_pac_data_from_user_entry, test_ad_common_setup, test_ad_common_teardown),
_______________________________________________ sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/sssd-devel@lists.fedorahosted.org/message/MRCQOUVRXVMJCZDRMDOEUHYDAVTHUDYL/