From 5d0cae396c75aaedcc8e41542e6e8504700b6ac8 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 28 Apr 2015 13:48:42 +0200 Subject: subdomains: Inherit cleanup period and tokengroup settings from parent domain Allows the administrator to extend the functionality of ldap_purge_cache_timeout, ldap_user_principal and ldap_use_tokengroups to the subdomains. This is a less intrusive way of achieving: https://fedorahosted.org/sssd/ticket/2627 Reviewed-by: Pavel Reichl (cherry picked from commit 9b162bf39ef75629f54ffa1d0bd5f9c13119b650) (cherry picked from commit 602eb710c62c192060debad3062f13677ec3b105) --- src/man/sssd.conf.5.xml | 9 +++ src/providers/ad/ad_subdomains.c | 4 + src/providers/ipa/ipa_subdomains.c | 4 + src/providers/ldap/sdap.c | 58 ++++++++++++++ src/providers/ldap/sdap.h | 4 + src/tests/cmocka/test_sdap.c | 160 +++++++++++++++++++++++++++++++++++++ 6 files changed, 239 insertions(+) diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index cf01a3b41..4961d5b95 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -488,6 +488,15 @@ ignore_group_members + + ldap_purge_cache_timeout + + + ldap_use_tokengroups + + + ldap_user_principal + Example: diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c index 5a6e9338d..71c01b9d7 100644 --- a/src/providers/ad/ad_subdomains.c +++ b/src/providers/ad/ad_subdomains.c @@ -183,6 +183,10 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, return EFAULT; } + sdap_inherit_options(subdom->parent->sd_inherit, + id_ctx->sdap_id_ctx->opts, + ad_id_ctx->sdap_id_ctx->opts); + /* Set up the ID mapping object */ ad_id_ctx->sdap_id_ctx->opts->idmap_ctx = id_ctx->sdap_id_ctx->opts->idmap_ctx; diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 44751e48c..d01ef6092 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -232,6 +232,10 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx, return EFAULT; } + sdap_inherit_options(subdom->parent->sd_inherit, + id_ctx->sdap_id_ctx->opts, + ad_id_ctx->sdap_id_ctx->opts); + ret = sdap_id_setup_tasks(be_ctx, ad_id_ctx->sdap_id_ctx, sdom, diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index 2568bdd1f..051e3c1d2 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -243,6 +243,64 @@ int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx, return EOK; } +static void sdap_inherit_basic_options(char **inherit_opt_list, + struct dp_option *parent_opts, + struct dp_option *subdom_opts) +{ + int inherit_options[] = { + SDAP_CACHE_PURGE_TIMEOUT, + SDAP_AD_USE_TOKENGROUPS, + SDAP_OPTS_BASIC /* sentinel */ + }; + int i; + + for (i = 0; inherit_options[i] != SDAP_OPTS_BASIC; i++) { + dp_option_inherit(inherit_opt_list, + inherit_options[i], + parent_opts, + subdom_opts); + } +} + +static void sdap_inherit_user_options(char **inherit_opt_list, + struct sdap_attr_map *parent_user_map, + struct sdap_attr_map *child_user_map) +{ + int inherit_options[] = { + SDAP_AT_USER_PRINC, + SDAP_OPTS_USER /* sentinel */ + }; + int i; + int opt_index; + bool inherit_option; + + for (i = 0; inherit_options[i] != SDAP_OPTS_USER; i++) { + opt_index = inherit_options[i]; + + inherit_option = string_in_list(parent_user_map[opt_index].opt_name, + inherit_opt_list, + false); + if (inherit_option == false) { + continue; + } + + sdap_copy_map_entry(parent_user_map, child_user_map, opt_index); + } +} + +void sdap_inherit_options(char **inherit_opt_list, + struct sdap_options *parent_sdap_opts, + struct sdap_options *child_sdap_opts) +{ + sdap_inherit_basic_options(inherit_opt_list, + parent_sdap_opts->basic, + child_sdap_opts->basic); + + sdap_inherit_user_options(inherit_opt_list, + parent_sdap_opts->user_map, + child_sdap_opts->user_map); +} + int sdap_get_map(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index e7e1b5194..6612ab200 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -491,6 +491,10 @@ int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map **_map, size_t *_new_size); +void sdap_inherit_options(char **inherit_opt_list, + struct sdap_options *parent_sdap_opts, + struct sdap_options *child_sdap_opts); + int sdap_get_map(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, diff --git a/src/tests/cmocka/test_sdap.c b/src/tests/cmocka/test_sdap.c index dab449050..a3d5bc7a2 100644 --- a/src/tests/cmocka/test_sdap.c +++ b/src/tests/cmocka/test_sdap.c @@ -795,6 +795,152 @@ static void test_sdap_copy_map_entry_null_name(void **state) assert_null(uuid_val); } +struct test_sdap_inherit_ctx { + struct sdap_options *parent_sdap_opts; + struct sdap_options *child_sdap_opts; +}; + +struct sdap_options *mock_sdap_opts(TALLOC_CTX *mem_ctx) +{ + int ret; + struct sdap_options *opts; + + opts = talloc_zero(mem_ctx, struct sdap_options); + assert_non_null(opts); + + ret = sdap_copy_map(opts, rfc2307_user_map, + SDAP_OPTS_USER, &opts->user_map); + assert_int_equal(ret, ERR_OK); + + ret = dp_copy_defaults(opts, default_basic_opts, + SDAP_OPTS_BASIC, &opts->basic); + assert_int_equal(ret, ERR_OK); + + return opts; +} + +static int test_sdap_inherit_option_setup(void **state) +{ + int ret; + struct test_sdap_inherit_ctx *test_ctx; + + assert_true(leak_check_setup()); + + test_ctx = talloc_zero(global_talloc_context, + struct test_sdap_inherit_ctx); + assert_non_null(test_ctx); + + test_ctx->child_sdap_opts = talloc_zero(test_ctx, struct sdap_options); + + test_ctx->parent_sdap_opts = mock_sdap_opts(test_ctx); + assert_non_null(test_ctx->parent_sdap_opts); + test_ctx->child_sdap_opts = mock_sdap_opts(test_ctx); + assert_non_null(test_ctx->child_sdap_opts); + + test_ctx->parent_sdap_opts->user_map[SDAP_AT_USER_PRINC].name = \ + discard_const("test_princ"); + + ret = dp_opt_set_int(test_ctx->parent_sdap_opts->basic, + SDAP_CACHE_PURGE_TIMEOUT, 123); + assert_int_equal(ret, EOK); + + *state = test_ctx; + return 0; +} + +static int test_sdap_inherit_option_teardown(void **state) +{ + struct test_sdap_inherit_ctx *test_ctx = \ + talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); + + talloc_free(test_ctx); + assert_true(leak_check_teardown()); + return 0; +} + +static void test_sdap_inherit_option_null(void **state) +{ + struct test_sdap_inherit_ctx *test_ctx = \ + talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); + int val; + + val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, + SDAP_CACHE_PURGE_TIMEOUT); + assert_int_equal(val, 10800); + + sdap_inherit_options(NULL, + test_ctx->parent_sdap_opts, + test_ctx->child_sdap_opts); + + val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, + SDAP_CACHE_PURGE_TIMEOUT); + assert_int_equal(val, 10800); +} + +static void test_sdap_inherit_option_notset(void **state) +{ + struct test_sdap_inherit_ctx *test_ctx = \ + talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); + int val; + const char *inherit_options[] = { "ldap_use_tokengroups", NULL }; + + val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, + SDAP_CACHE_PURGE_TIMEOUT); + assert_int_equal(val, 10800); + + /* parent has nondefault, but it's not supposed to be inherited */ + sdap_inherit_options(discard_const(inherit_options), + test_ctx->parent_sdap_opts, + test_ctx->child_sdap_opts); + + val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, + SDAP_CACHE_PURGE_TIMEOUT); + assert_int_equal(val, 10800); +} + +static void test_sdap_inherit_option_basic(void **state) +{ + struct test_sdap_inherit_ctx *test_ctx = \ + talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); + int val; + const char *inherit_options[] = { "ldap_purge_cache_timeout", NULL }; + + val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, + SDAP_CACHE_PURGE_TIMEOUT); + assert_int_equal(val, 10800); + + /* parent has nondefault, but it's not supposed to be inherited */ + sdap_inherit_options(discard_const(inherit_options), + test_ctx->parent_sdap_opts, + test_ctx->child_sdap_opts); + + val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, + SDAP_CACHE_PURGE_TIMEOUT); + assert_int_equal(val, 123); +} + +static void test_sdap_inherit_option_user(void **state) +{ + struct test_sdap_inherit_ctx *test_ctx = \ + talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); + const char *inherit_options[] = { "ldap_user_principal", NULL }; + + assert_string_equal( + test_ctx->child_sdap_opts->user_map[SDAP_AT_USER_PRINC].name, + "krbPrincipalName"); + + /* parent has nondefault, but it's not supposed to be inherited */ + sdap_inherit_options(discard_const(inherit_options), + test_ctx->parent_sdap_opts, + test_ctx->child_sdap_opts); + + assert_string_equal( + test_ctx->child_sdap_opts->user_map[SDAP_AT_USER_PRINC].name, + "test_princ"); + + talloc_free(test_ctx->child_sdap_opts->user_map[SDAP_AT_USER_PRINC].name); +} + int main(int argc, const char *argv[]) { poptContext pc; @@ -848,6 +994,20 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(test_sdap_copy_map_entry_null_name, copy_map_entry_test_setup, copy_map_entry_test_teardown), + + /* Option inherit tests */ + cmocka_unit_test_setup_teardown(test_sdap_inherit_option_null, + test_sdap_inherit_option_setup, + test_sdap_inherit_option_teardown), + cmocka_unit_test_setup_teardown(test_sdap_inherit_option_notset, + test_sdap_inherit_option_setup, + test_sdap_inherit_option_teardown), + cmocka_unit_test_setup_teardown(test_sdap_inherit_option_basic, + test_sdap_inherit_option_setup, + test_sdap_inherit_option_teardown), + cmocka_unit_test_setup_teardown(test_sdap_inherit_option_user, + test_sdap_inherit_option_setup, + test_sdap_inherit_option_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ -- cgit