On Fri, Jun 05, 2015 at 02:38:00PM +0200, Pavel Reichl wrote: > CI passed: > http://sssd-ci.duckdns.org/logs/job/16/81/summary.html > > My testing passed. I found just one nitpick and I leave it to Jakub's > discretion how to handle it. > > ACK
Thanks, good idea. Please see one more round of patches, only the sdap_copy_map_entry() call was changed.
>From 4b3d4d65b912cf6015bc469207b0dc4a6b3bd5d2 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Wed, 29 Apr 2015 19:41:14 +0200 Subject: [PATCH 1/5] confdb: Add new option subdomain_inherit Adds a new option subdomain_inherit that would allow administrators to pick and choose which option to pass to subdomains. This option is required for: https://fedorahosted.org/sssd/ticket/2644 as a short-term fix. The proper solution is described in: https://fedorahosted.org/sssd/ticket/2599 --- src/confdb/confdb.c | 13 +++++++++++++ src/confdb/confdb.h | 2 ++ src/config/SSSDConfig/__init__.py.in | 1 + src/config/SSSDConfigTest.py | 6 ++++-- src/config/etc/sssd.api.conf | 1 + src/man/sssd.conf.5.xml | 20 +++++++++++++++++++- 6 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c index 87960c4db6e698ee5c3b2a24ca18f8d53458c7ca..9af754912e248b83a71b253109e408bf004eda31 100644 --- a/src/confdb/confdb.c +++ b/src/confdb/confdb.c @@ -1256,6 +1256,19 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, } } + tmp = ldb_msg_find_attr_as_string(res->msgs[0], + CONFDB_DOMAIN_SUBDOMAIN_INHERIT, + NULL); + if (tmp != NULL) { + ret = split_on_separator(domain, tmp, ',', true, true, + &domain->sd_inherit, NULL); + if (ret != 0) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Cannot parse %s\n", CONFDB_SUBDOMAIN_ENUMERATE); + goto done; + } + } + ret = get_entry_as_uint32(res->msgs[0], &domain->subdomain_refresh_interval, CONFDB_DOMAIN_SUBDOMAIN_REFRESH, 14400); if (ret != EOK || domain->subdomain_refresh_interval == 0) { diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index c8c91288cd63df7629a98802b7b5373df92d6ca4..93fbce5e5e46e4a7517d971f2ab886ded65a68f3 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -187,6 +187,7 @@ #define CONFDB_DOMAIN_PWD_EXPIRATION_WARNING "pwd_expiration_warning" #define CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL "refresh_expired_interval" #define CONFDB_DOMAIN_OFFLINE_TIMEOUT "offline_timeout" +#define CONFDB_DOMAIN_SUBDOMAIN_INHERIT "subdomain_inherit" /* Local Provider */ #define CONFDB_LOCAL_DEFAULT_SHELL "default_shell" @@ -268,6 +269,7 @@ struct sss_domain_info { struct sss_domain_info *next; bool disabled; + char **sd_inherit; }; /** diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index f58c52faf7dd3f9199bd0af4286546d4fe804a88..af7f1bffbd910c0dee177eb64996233ac18fff19 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -148,6 +148,7 @@ option_strings = { 'dyndns_auth' : _("What kind of authentication should be used to perform the DNS update"), 'subdomain_enumerate' : _('Control enumeration of trusted domains'), 'subdomain_refresh_interval' : _('How often should subdomains list be refreshed'), + 'subdomain_inherit' : _('List of options that should be inherited into a subdomain'), # [provider/ipa] 'ipa_domain' : _('IPA domain'), diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index 60f51ca769503be42ba9c82cdb07cf555407d61b..c6ba9f05106990d9e43df106305babb2dafdeea5 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -546,7 +546,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'hostid_provider', 'subdomains_provider', 'realmd_tags', - 'subdomain_refresh_interval'] + 'subdomain_refresh_interval', + 'subdomain_inherit'] self.assertTrue(type(options) == dict, "Options should be a dictionary") @@ -908,7 +909,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'hostid_provider', 'subdomains_provider', 'realmd_tags', - 'subdomain_refresh_interval'] + 'subdomain_refresh_interval', + 'subdomain_inherit'] self.assertTrue(type(options) == dict, "Options should be a dictionary") diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index f1ac6366c73c03fe5c60c79bfe7b15fde9382215..7ad84cd826a648ca61d9d2ede70e7886049d469a 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -132,6 +132,7 @@ default_shell = str, None, false description = str, None, false realmd_tags = str, None, false subdomain_refresh_interval = int, None, false +subdomain_inherit = str, None, false #Entry cache timeouts entry_cache_user_timeout = int, None, false diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index b5782b7942939fd18fb2e719e0c3e8c31ae25621..7d0ba057437f6b4b053b5ce3abec9d5324124d14 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -479,7 +479,25 @@ </para> </listitem> </varlistentry> - + <varlistentry> + <term>subdomain_inherit (string)</term> + <listitem> + <para> + Specifies a list of configuration parameters that + should be inherited by a subdomain. Please note + that only selected parameters can be inherited. + </para> + <para> + Example: + <programlisting> +subdomain_inherit = ldap_purge_cache_timeout + </programlisting> + </para> + <para> + Default: none + </para> + </listitem> + </varlistentry> </variablelist> </refsect2> -- 2.1.0
>From a7da33e414754ce0b05c39596216915039d76259 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Wed, 6 May 2015 08:06:53 +0200 Subject: [PATCH 2/5] DP: Add a function to inherit DP options, if set Related to: https://fedorahosted.org/sssd/ticket/2644 Adds a utility function that checks if a DP option is present in the subdomain_inherit list. If it is, then the option is set from source to destination dp_option array. --- src/providers/data_provider.h | 5 ++ src/providers/data_provider_opts.c | 57 +++++++++++++ src/tests/cmocka/test_dp_opts.c | 159 +++++++++++++++++++++++++++++++------ 3 files changed, 197 insertions(+), 24 deletions(-) diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index 5df493e9d1ae21ada6f5fd6198a6d9c36680d044..657d2b798cf28fa59c9f644e343f2a2482609bad 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -277,6 +277,11 @@ struct dp_option { #define DP_OPTION_TERMINATOR { NULL, 0, NULL_STRING, NULL_STRING } +void dp_option_inherit(char **inherit_opt_list, + int option, + struct dp_option *parent_opts, + struct dp_option *subdom_opts); + int dp_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, diff --git a/src/providers/data_provider_opts.c b/src/providers/data_provider_opts.c index 8ad84560b7329fb1602c675affa4bd0bdf9ecc2e..9db43fc4077d3b14f2358029c7d532e440930879 100644 --- a/src/providers/data_provider_opts.c +++ b/src/providers/data_provider_opts.c @@ -21,6 +21,63 @@ #include "data_provider.h" +/* =Copy-Option-From-Subdomain-If-Allowed================================= */ +void dp_option_inherit(char **inherit_opt_list, + int option, + struct dp_option *parent_opts, + struct dp_option *subdom_opts) +{ + errno_t ret; + bool inherit_option; + + inherit_option = string_in_list(parent_opts[option].opt_name, + inherit_opt_list, false); + if (inherit_option == false) { + DEBUG(SSSDBG_CONF_SETTINGS, + "Option %s is not set up to be inherited\n", + parent_opts[option].opt_name); + return; + } + + DEBUG(SSSDBG_CONF_SETTINGS, + "Will inherit option %s\n", parent_opts[option].opt_name); + switch (parent_opts[option].type) { + case DP_OPT_NUMBER: + ret = dp_opt_set_int(subdom_opts, + option, + dp_opt_get_int(parent_opts, + option)); + break; + case DP_OPT_STRING: + ret = dp_opt_set_string(subdom_opts, + option, + dp_opt_get_string(parent_opts, + option)); + break; + case DP_OPT_BLOB: + ret = dp_opt_set_blob(subdom_opts, + option, + dp_opt_get_blob(parent_opts, + option)); + break; + case DP_OPT_BOOL: + ret = dp_opt_set_bool(subdom_opts, + option, + dp_opt_get_bool(parent_opts, + option)); + break; + default: + ret = EINVAL; + break; + } + + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Failed to inherit option %s\n", parent_opts[option].opt_name); + /* Not fatal */ + } +} + /* =Retrieve-Options====================================================== */ int dp_get_options(TALLOC_CTX *memctx, diff --git a/src/tests/cmocka/test_dp_opts.c b/src/tests/cmocka/test_dp_opts.c index 9192eaaca605526547a1f7be1830c9940cf9ccb4..9d4d4720c76679f60c7b7abaafa307bb4e22ff73 100644 --- a/src/tests/cmocka/test_dp_opts.c +++ b/src/tests/cmocka/test_dp_opts.c @@ -285,37 +285,63 @@ static int opt_test_getset_teardown(void **state) return 0; } +static void assert_nondefault_string_empty(struct dp_option *opts) +{ + char *s; + + s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); + assert_null(s); +} + +static void set_nondefault_string(struct dp_option *opts) +{ + int ret; + + ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1"); + assert_int_equal(ret, EOK); +} + +static void check_nondefault_string(struct dp_option *opts) +{ + char *s; + + s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); + assert_non_null(s); + assert_string_equal(s, "str1"); +} + void opt_test_getset_string(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); - int ret; - char *s; - s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); - assert_null(s); - - ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1"); - assert_int_equal(ret, EOK); - - s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); - assert_non_null(s); - assert_string_equal(s, "str1"); + assert_nondefault_string_empty(opts); + set_nondefault_string(opts); + check_nondefault_string(opts); } -void opt_test_getset_blob(void **state) +static void assert_nondefault_blob_empty(struct dp_option *opts) { - struct dp_option *opts = talloc_get_type(*state, struct dp_option); - int ret; struct dp_opt_blob b; b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT); assert_null(b.data); assert_int_equal(b.length, 0); +} + +static void set_nondefault_blob(struct dp_option *opts) +{ + struct dp_opt_blob b; + int ret; b.data = discard_const_p(uint8_t, "blob2"); b.length = strlen("blob2"); ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b); assert_int_equal(ret, EOK); +} + +static void check_nondefault_blob(struct dp_option *opts) +{ + struct dp_opt_blob b; b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT); assert_non_null(b.data); @@ -323,20 +349,43 @@ void opt_test_getset_blob(void **state) assert_memory_equal(b.data, "blob2", strlen("blob2")); } +void opt_test_getset_blob(void **state) +{ + struct dp_option *opts = talloc_get_type(*state, struct dp_option); + + assert_nondefault_blob_empty(opts); + set_nondefault_blob(opts); + check_nondefault_blob(opts); +} + +static void assert_nondefault_int_notset(struct dp_option *opts) +{ + int i; + i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); + assert_int_equal(i, 0); +} + +static void set_nondefault_int(struct dp_option *opts) +{ + int ret; + ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456); + assert_int_equal(ret, EOK); +} + +static void assert_nondefault_int_set(struct dp_option *opts) +{ + int i; + i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); + assert_int_equal(i, 456); +} + void opt_test_getset_int(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); - int ret; - int i; - i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); - assert_int_equal(i, 0); - - ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456); - assert_int_equal(ret, EOK); - - i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); - assert_int_equal(i, 456); + assert_nondefault_int_notset(opts); + set_nondefault_int(opts); + assert_nondefault_int_set(opts); } void opt_test_getset_bool(void **state) @@ -355,6 +404,65 @@ void opt_test_getset_bool(void **state) assert_false(b == true); } +void opt_test_inherit(void **state) +{ + struct dp_option *opts = talloc_get_type(*state, struct dp_option); + int ret; + struct dp_option *opts_copy; + const char *s; + const char *sd_inherit_match[] = { "string_nodefault", + "blob_nodefault", + "int_nodefault", + "bool_true", + NULL }; + + ret = dp_copy_defaults(opts, test_def_opts, + OPT_NUM_OPTS, &opts_copy); + assert_int_equal(ret, EOK); + assert_defaults(opts); + + dp_option_inherit(NULL, OPT_STRING_NODEFAULT, + opts, opts_copy); + s = dp_opt_get_string(opts_copy, OPT_STRING_NODEFAULT); + assert_null(s); + + /* string */ + assert_nondefault_string_empty(opts_copy); + set_nondefault_string(opts); + dp_option_inherit(discard_const(sd_inherit_match), + OPT_STRING_NODEFAULT, + opts, opts_copy); + check_nondefault_string(opts_copy); + + /* blob */ + assert_nondefault_blob_empty(opts_copy); + set_nondefault_blob(opts); + dp_option_inherit(discard_const(sd_inherit_match), + OPT_BLOB_NODEFAULT, + opts, opts_copy); + check_nondefault_blob(opts_copy); + + /* number */ + assert_nondefault_int_notset(opts_copy); + set_nondefault_int(opts); + dp_option_inherit(discard_const(sd_inherit_match), + OPT_INT_NODEFAULT, + opts, opts_copy); + assert_nondefault_int_set(opts_copy); + + /* bool */ + assert_true(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE)); + + ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false); + assert_int_equal(ret, EOK); + + dp_option_inherit(discard_const(sd_inherit_match), + OPT_BOOL_TRUE, + opts, opts_copy); + + assert_false(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE)); +} + int main(int argc, const char *argv[]) { int no_cleanup = 0; @@ -381,6 +489,9 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(opt_test_getset_blob, opt_test_getset_setup, opt_test_getset_teardown), + cmocka_unit_test_setup_teardown(opt_test_inherit, + opt_test_getset_setup, + opt_test_getset_teardown), cmocka_unit_test(opt_test_copy_default), cmocka_unit_test(opt_test_copy_options), cmocka_unit_test(opt_test_get) -- 2.1.0
>From c87d12b7ea9d4b917d4f4e0520625dfa1a3b0292 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Fri, 22 May 2015 18:31:42 +0200 Subject: [PATCH 3/5] SDAP: Add sdap_copy_map_entry --- src/providers/ldap/sdap.c | 17 +++++++++ src/providers/ldap/sdap.h | 4 +++ src/tests/cmocka/test_sdap.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index bae7d02c5b6dbf736ac8826d58b497efc7e4acec..2568bdd1feb0ddc0a89e44e074f4faff38572a37 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -28,6 +28,23 @@ /* =Retrieve-Options====================================================== */ +errno_t sdap_copy_map_entry(const struct sdap_attr_map *src_map, + struct sdap_attr_map *dst_map, + int entry_index) +{ + if (src_map[entry_index].name != NULL) { + dst_map[entry_index].name = talloc_strdup(dst_map, + src_map[entry_index].name); + if (dst_map[entry_index].name == NULL) { + return ENOMEM; + } + } else { + dst_map->name = NULL; + } + + return EOK; +} + int sdap_copy_map(TALLOC_CTX *memctx, struct sdap_attr_map *src_map, int num_entries, diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index d7f6c646e59a8af8347e39afb644d8ea40b9a4c3..e7e1b51941ef2557c10e93be534ae1618ca0c487 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -467,6 +467,10 @@ struct sdap_deref_attrs { struct sysdb_attrs *attrs; }; +errno_t sdap_copy_map_entry(const struct sdap_attr_map *src_map, + struct sdap_attr_map *dst_map, + int entry_index); + int sdap_copy_map(TALLOC_CTX *memctx, struct sdap_attr_map *src_map, int num_entries, diff --git a/src/tests/cmocka/test_sdap.c b/src/tests/cmocka/test_sdap.c index a1c9aefd86ba7b048916d681025dd1bb644b128e..dab449050e495c5a534e791368dddf3c150477f6 100644 --- a/src/tests/cmocka/test_sdap.c +++ b/src/tests/cmocka/test_sdap.c @@ -720,6 +720,81 @@ void test_parse_no_dn(void **state) talloc_free(map); } +struct copy_map_entry_test_ctx { + struct sdap_attr_map *src_map; + struct sdap_attr_map *dst_map; +}; + +static int copy_map_entry_test_setup(void **state) +{ + int ret; + struct copy_map_entry_test_ctx *test_ctx; + + assert_true(leak_check_setup()); + + test_ctx = talloc_zero(global_talloc_context, + struct copy_map_entry_test_ctx); + assert_non_null(test_ctx); + + ret = sdap_copy_map(test_ctx, rfc2307_user_map, + SDAP_OPTS_USER, &test_ctx->src_map); + assert_int_equal(ret, ERR_OK); + + ret = sdap_copy_map(test_ctx, rfc2307_user_map, + SDAP_OPTS_USER, &test_ctx->dst_map); + assert_int_equal(ret, ERR_OK); + + check_leaks_push(test_ctx); + *state = test_ctx; + return 0; +} + +static int copy_map_entry_test_teardown(void **state) +{ + struct copy_map_entry_test_ctx *test_ctx = talloc_get_type_abort(*state, + struct copy_map_entry_test_ctx); + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); + return 0; +} + +static const char *copy_uuid(struct copy_map_entry_test_ctx *test_ctx) +{ + errno_t ret; + + assert_null(test_ctx->dst_map[SDAP_AT_USER_UUID].name); + ret = sdap_copy_map_entry(test_ctx->src_map, test_ctx->dst_map, + SDAP_AT_USER_UUID); + assert_int_equal(ret, EOK); + return test_ctx->dst_map[SDAP_AT_USER_UUID].name; +} + +static void test_sdap_copy_map_entry(void **state) +{ + struct copy_map_entry_test_ctx *test_ctx = talloc_get_type_abort(*state, + struct copy_map_entry_test_ctx); + const char *uuid_set_val = "test_uuid_val"; + const char *uuid_val = NULL; + + test_ctx->src_map[SDAP_AT_USER_UUID].name = discard_const(uuid_set_val); + + uuid_val = copy_uuid(test_ctx); + assert_non_null(uuid_val); + assert_string_equal(uuid_val, uuid_set_val); + talloc_free(test_ctx->dst_map[SDAP_AT_USER_UUID].name); +} + +static void test_sdap_copy_map_entry_null_name(void **state) +{ + struct copy_map_entry_test_ctx *test_ctx = talloc_get_type_abort(*state, + struct copy_map_entry_test_ctx); + const char *uuid_val = NULL; + + uuid_val = copy_uuid(test_ctx); + assert_null(uuid_val); +} + int main(int argc, const char *argv[]) { poptContext pc; @@ -765,6 +840,14 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(test_parse_deref_map_mismatch, parse_entry_test_setup, parse_entry_test_teardown), + + /* Map option tests */ + cmocka_unit_test_setup_teardown(test_sdap_copy_map_entry, + copy_map_entry_test_setup, + copy_map_entry_test_teardown), + cmocka_unit_test_setup_teardown(test_sdap_copy_map_entry_null_name, + copy_map_entry_test_setup, + copy_map_entry_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ -- 2.1.0
>From eb66d2a39b87a566d5e232c1ffbe5a772f5abcc7 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Tue, 28 Apr 2015 17:04:51 +0200 Subject: [PATCH 4/5] UTIL: Inherit ignore_group_members Resolves: https://fedorahosted.org/sssd/ticket/2644 Allows the administrators to extend ignore_group_members to subdomains as well by setting: subdomain_inherit = ignore_group_members in the domain section. --- src/man/sssd.conf.5.xml | 4 ++++ src/util/domain_info_utils.c | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 7d0ba057437f6b4b053b5ce3abec9d5324124d14..55623991c981615e2ad552d7bc5ca956bd45cc62 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -486,6 +486,10 @@ Specifies a list of configuration parameters that should be inherited by a subdomain. Please note that only selected parameters can be inherited. + Currently the following options can be inherited: + </para> + <para> + ignore_group_members </para> <para> Example: diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index dc306848c3b3ba87a5ada1867878e13826da00a8..073ba3c6a2a46c51f762c3afebeebcd3a0e8b7c4 100644 --- a/src/util/domain_info_utils.c +++ b/src/util/domain_info_utils.c @@ -206,6 +206,7 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, const char *forest) { struct sss_domain_info *dom; + bool inherit_option; DEBUG(SSSDBG_TRACE_FUNC, "Creating [%s] as subdomain of [%s]!\n", name, parent->name); @@ -281,6 +282,14 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, dom->enumerate = enumerate; dom->fqnames = true; dom->mpg = mpg; + /* If the parent domain filters out group members, the subdomain should + * as well if configured */ + inherit_option = string_in_list(CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS, + parent->sd_inherit, false); + if (inherit_option) { + dom->ignore_group_members = parent->ignore_group_members; + } + /* If the parent domain explicitly limits ID ranges, the subdomain * should honour the limits as well. */ -- 2.1.0
>From 9cc7d9793d691442e3004e146367cce6b95e8325 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Tue, 28 Apr 2015 13:48:42 +0200 Subject: [PATCH 5/5] 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 --- 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 55623991c981615e2ad552d7bc5ca956bd45cc62..75d13a631e23c0c9518e05f48d66209c8c47d237 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -492,6 +492,15 @@ ignore_group_members </para> <para> + ldap_purge_cache_timeout + </para> + <para> + ldap_use_tokengroups + </para> + <para> + ldap_user_principal + </para> + <para> Example: <programlisting> subdomain_inherit = ldap_purge_cache_timeout diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c index 5a6e9338d6dc581fba4f76e8b28f92a558eb6294..71c01b9d75bad7488b8056e4dd0ab80ad65f0c7a 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 f863b806c8fed01f498d18b953832ebeba7a85d3..b0cf92e43f53d9efc38f5627eca00855b5e62173 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 2568bdd1feb0ddc0a89e44e074f4faff38572a37..051e3c1d248f738106cb80b97ca992f5e0212a3e 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 e7e1b51941ef2557c10e93be534ae1618ca0c487..6612ab200d7ee34be29512ba8df2744ab2a7ecd8 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 dab449050e495c5a534e791368dddf3c150477f6..cb3265f2cf66a1f4c6d55db20dfaf94179759f47 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, 0); + + 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, 0); +} + +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, 0); + + /* 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, 0); +} + +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, 0); + + /* 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. */ -- 2.1.0
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel