[SSSD] [PATCH] Make it possible to inherit ignore_group_members, ldap_purge_cache_timeout and ldap_use_tokengroups into subdomains

Jakub Hrozek jhrozek at redhat.com
Wed Jun 3 15:36:50 UTC 2015


On Wed, Jun 03, 2015 at 03:36:03PM +0200, Pavel Reichl wrote:
> Hello Jakub,
> 
> 1st patch:
> I remember Lukas having problems with such patches - to quote him:
> >The most problematic part is that man page is updated before feature
> >is implemented. Opposite order of patches could be acceptable
> >but I prefer to have change in man page for small features in the same patch.
> I'm CCing him if he wants to comment otherwise it's fine by me.
> >+++ 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 parametrs can be
> >inherited.
> typo:  paramet*e*rs

Fixed

> >+                        </para>
> >+                        <para>
> 
> 2nd patch)
> Would you mind making parent_dom const?

Done

> >+void dp_option_inherit(struct sss_domain_info *parent_dom,
> >+                       int option,
> >+                       struct dp_option *parent_opts,
> >+                       struct dp_option *subdom_opts)
> 
> 3rd patch)
> >+errno_t sdap_copy_map_entry(struct sdap_attr_map *src_map,
> const?

Done

> >+                            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);
> formatting issue

Fixed

> >+        if (dst_map[entry_index].name == NULL) {
> >+            return ENOMEM;
> >+        }
> >+    } else {
> >+        src_map->name = NULL;
>                 dst_map?
> >+    }
> >+
> >+    return EOK;
> >+}
> >+
> I suppose that test_sdap_copy_map_entry_null_name needs dst_map not to be
> nulled to work properly.

Fixed

> 
> 
> 5th patch)
> >+static void sdap_inherit_user_options(struct sss_domain_info *parent_dom,
> >+                                      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;
> >+
> >+    for (i = 0; inherit_options[i] != SDAP_OPTS_USER; i++) {
> >+        sdap_copy_map_entry(parent_user_map, child_user_map, i);
> s/i/inherit_options[i] ?

No, the parameter is an integer.

> >+    }
> >+}
> 
> I'm going to test the patches now.
> 
> Thanks!

Thank you, new patches are attached.
-------------- next part --------------
>From e5dba59a12d8d2a05238a767f3587dcbd7f20e22 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at 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

-------------- next part --------------
>From 99c0793df036f8bc1226687d648ee6953447b30b Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at 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    | 163 +++++++++++++++++++++++++++++++------
 3 files changed, 201 insertions(+), 24 deletions(-)

diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 5df493e9d1ae21ada6f5fd6198a6d9c36680d044..4e741547c06cf8bb9da83871eaba963280c7484d 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(const struct sss_domain_info *parent_dom,
+                       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..7e503acacf739ccea01355283f9b82453f306bec 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(const struct sss_domain_info *parent_dom,
+                       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,
+                                    parent_dom->sd_inherit, 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..b443e93e8bed338390bd0abf5f9a48bded84c73b 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,69 @@ 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 sss_domain_info *parent_dom;
+    struct dp_option *opts_copy;
+    const char *s;
+    const char *sd_inherit_match[] = { "string_nodefault",
+                                       "blob_nodefault",
+                                       "int_nodefault",
+                                       "bool_true",
+                                       NULL };
+
+    parent_dom = talloc(opts, struct sss_domain_info);
+    assert_non_null(parent_dom);
+
+    ret = dp_copy_defaults(parent_dom, test_def_opts,
+                           OPT_NUM_OPTS, &opts_copy);
+    assert_int_equal(ret, EOK);
+    assert_defaults(opts);
+
+    parent_dom->sd_inherit = NULL;
+    dp_option_inherit(parent_dom, OPT_STRING_NODEFAULT,
+                      opts, opts_copy);
+    s = dp_opt_get_string(opts_copy, OPT_STRING_NODEFAULT);
+    assert_null(s);
+
+    /* test inheritance */
+    parent_dom->sd_inherit = discard_const(sd_inherit_match);
+
+    /* string */
+    assert_nondefault_string_empty(opts_copy);
+    set_nondefault_string(opts);
+    dp_option_inherit(parent_dom, 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(parent_dom, 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(parent_dom, 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(parent_dom, 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 +493,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

-------------- next part --------------
>From 47aaf2986f32a5a824fa39684649bbde48f75e9f Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at 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

-------------- next part --------------
>From 59586d5fcd4fd81b72b98f98b01e76aa633b06a5 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at 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

-------------- next part --------------
>From 2e9fa3c57a23b21ca6452e60c1f70669301c097a Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at 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/ldap_common.c   | 47 ++++++++++++++++++++++++++++++++++++++
 src/providers/ldap/ldap_common.h   |  3 +++
 5 files changed, 67 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..7785582693ece96a642c52c5210290305cfbc718 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,
+                         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..31785b6fdb94124c17105f35e0053050a6842e44 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,
+                         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/ldap_common.c b/src/providers/ldap/ldap_common.c
index 8133431cc35f008768484b43cf7926d41fa0b2e0..bf1005937a95621abba2a36ee9d1e6a43594f898 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -962,3 +962,50 @@ sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
 
     return sdap_ctx;
 }
+
+static void sdap_inherit_basic_options(struct sss_domain_info *parent_dom,
+                                       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(parent_dom,
+                          inherit_options[i],
+                          parent_opts,
+                          subdom_opts);
+    }
+}
+
+static void sdap_inherit_user_options(struct sss_domain_info *parent_dom,
+                                      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;
+
+    for (i = 0; inherit_options[i] != SDAP_OPTS_USER; i++) {
+        sdap_copy_map_entry(parent_user_map, child_user_map, i);
+    }
+}
+
+void sdap_inherit_options(struct sss_domain_info *parent_dom,
+                          struct sdap_options *parent_sdap_opts,
+                          struct sdap_options *child_sdap_opts)
+{
+    sdap_inherit_basic_options(parent_dom,
+                               parent_sdap_opts->basic,
+                               child_sdap_opts->basic);
+
+    sdap_inherit_user_options(parent_dom,
+                              parent_sdap_opts->user_map,
+                              child_sdap_opts->user_map);
+}
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index c142af3452a0bc9a10d90d13c9586c4dd78a768b..33d4259a50026777d55cb51faac23a107b9307fd 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -331,4 +331,7 @@ sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
 errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx,
                           struct sdap_id_ctx *id_ctx);
 
+void sdap_inherit_options(struct sss_domain_info *parent_dom,
+                          struct sdap_options *parent_sdap_opts,
+                          struct sdap_options *child_sdap_opts);
 #endif /* _LDAP_COMMON_H_ */
-- 
2.1.0



More information about the sssd-devel mailing list