URL: https://github.com/SSSD/sssd/pull/73
Author: celestian
 Title: #73: AD_PROVIDER: Enabled subdomains (1.13)
Action: opened

PR body:
"""
This is backport of https://fedorahosted.org/sssd/ticket/2828 to 1.13.
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/73/head:pr73
git checkout pr73
From 66a0759c2e832426a04f9072022a8b2faae45858 Mon Sep 17 00:00:00 2001
From: Petr Cech <pc...@redhat.com>
Date: Fri, 13 May 2016 05:21:07 -0400
Subject: [PATCH 1/4] AD_PROVIDER: Add ad_enabled_domains option

Resolves:
https://fedorahosted.org/sssd/ticket/2828
---
 src/config/SSSDConfig/__init__.py.in   |  1 +
 src/config/etc/sssd.api.d/sssd-ad.conf |  1 +
 src/man/sssd-ad.5.xml                  | 27 +++++++++++++++++++++++++++
 src/providers/ad/ad_common.h           |  1 +
 src/providers/ad/ad_opts.c             |  1 +
 5 files changed, 31 insertions(+)

diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index ae9f973..11c290b 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -185,6 +185,7 @@ option_strings = {
 
     # [provider/ad]
     'ad_domain' : _('Active Directory domain'),
+    'ad_enabled_domains' : _('Enabled Active Directory domains'),
     'ad_server' : _('Active Directory server address'),
     'ad_backup_server' : _('Active Directory backup server address'),
     'ad_hostname' : _('Active Directory client hostname'),
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 23006d2..0d16387 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -1,5 +1,6 @@
 [provider/ad]
 ad_domain = str, None, false
+ad_enabled_domains = str, None, false
 ad_server = str, None, false
 ad_backup_server = str, None, false
 ad_hostname = str, None, false
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 54a4b56..d7d7651 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -114,6 +114,33 @@ ldap_id_mapping = False
                 </varlistentry>
 
                 <varlistentry>
+                    <term>ad_enabled_domains (string)</term>
+                    <listitem>
+                        <para>
+                            A comma-separated list of enabled Active Directory domains.
+                            If provided, SSSD will ignore any domains not listed in this
+                            option. If left unset, all domains from the AD forest will
+                            be available.
+                        </para>
+                        <para>
+                            For proper operation, this option must be specified in all
+                            lower-case and as the fully qualified domain name of the
+                            Active Directory domain. For example:
+                            <programlisting>
+ad_enabled_domains = sales.example.com, eng.example.com
+                            </programlisting>
+                        </para>
+                        <para>
+                            The short domain name (also known as the NetBIOS or the flat
+                            name) will be autodetected by SSSD.
+                        </para>
+                        <para>
+                            Default: Not set
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+                <varlistentry>
                     <term>ad_server, ad_backup_server (string)</term>
                     <listitem>
                         <para>
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index c795a41..2f5f3a4 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -42,6 +42,7 @@ struct ad_options;
 
 enum ad_basic_opt {
     AD_DOMAIN = 0,
+    AD_ENABLED_DOMAINS,
     AD_SERVER,
     AD_BACKUP_SERVER,
     AD_HOSTNAME,
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index 15024ad..aefcaaf 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -28,6 +28,7 @@
 
 struct dp_option ad_basic_opts[] = {
     { "ad_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "ad_enabled_domains", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ad_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ad_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ad_hostname", DP_OPT_STRING, NULL_STRING, NULL_STRING },

From 2b60425312bddd95fe30a2058608921f77d0f1f5 Mon Sep 17 00:00:00 2001
From: Petr Cech <pc...@redhat.com>
Date: Tue, 21 Jun 2016 08:34:15 +0200
Subject: [PATCH 2/4] AD_PROVIDER: Initializing of ad_enabled_domains

We add ad_enabled_domains into ad_subdomains_ctx.

Resolves:
https://fedorahosted.org/sssd/ticket/2828
---
 src/providers/ad/ad_subdomains.c | 81 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index f7e7e62..c74e494 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -63,6 +63,7 @@ struct ad_subdomains_ctx {
     struct sdap_id_conn_ctx *ldap_ctx;
     struct sss_idmap_ctx *idmap_ctx;
     char *domain_name;
+    const char **ad_enabled_domains;
 
     time_t last_refreshed;
     struct tevent_timer *timer_event;
@@ -91,6 +92,79 @@ struct ad_subdomains_req_ctx {
     char *forest;
 };
 
+static errno_t ad_get_enabled_domains(TALLOC_CTX *mem_ctx,
+                                      struct ad_id_ctx *ad_id_ctx,
+                                      const char *ad_domain,
+                                      const char ***_ad_enabled_domains)
+{
+    int ret;
+    const char *str;
+    const char *option_name;
+    const char **domains = NULL;
+    int count;
+    bool is_ad_in_domains;
+    TALLOC_CTX *tmp_ctx = NULL;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        return ENOMEM;
+    }
+
+    str = dp_opt_get_cstring(ad_id_ctx->ad_options->basic, AD_ENABLED_DOMAINS);
+    if (str == NULL) {
+        *_ad_enabled_domains = NULL;
+        ret = EOK;
+        goto done;
+    }
+
+    count = 0;
+    ret = split_on_separator(tmp_ctx, str, ',', true, true,
+                             discard_const_p(char **, &domains), &count);
+    if (ret != EOK) {
+        option_name = ad_id_ctx->ad_options->basic[AD_ENABLED_DOMAINS].opt_name;
+        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse option [%s], [%i] [%s]!\n",
+                                   option_name, ret, sss_strerror(ret));
+        ret = EINVAL;
+        goto done;
+    }
+
+    is_ad_in_domains = false;
+    for (int i = 0; i < count; i++) {
+        is_ad_in_domains += strcmp(ad_domain, domains[i]) == 0 ? true : false;
+    }
+
+    if (is_ad_in_domains == false) {
+        domains = talloc_realloc(tmp_ctx, domains, const char*, count + 2);
+        if (domains == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        domains[count] = talloc_strdup(domains, ad_domain);
+        if (domains[count] == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        domains[count + 1] = NULL;
+    } else {
+        domains = talloc_realloc(tmp_ctx, domains, const char*, count + 1);
+        if (domains == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        domains[count] = NULL;
+    }
+
+    *_ad_enabled_domains = talloc_steal(mem_ctx, domains);
+    ret = EOK;
+
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
 static errno_t
 ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
                      struct ad_id_ctx *id_ctx,
@@ -1182,6 +1256,7 @@ int ad_subdom_init(struct be_ctx *be_ctx,
                    void **pvt_data)
 {
     struct ad_subdomains_ctx *ctx;
+    const char **ad_enabled_domains = NULL;
     int ret;
     enum idmap_error_code err;
 
@@ -1191,6 +1266,11 @@ int ad_subdom_init(struct be_ctx *be_ctx,
         return ENOMEM;
     }
 
+    ret = ad_get_enabled_domains(ctx, id_ctx, ad_domain, &ad_enabled_domains);
+    if (ret != EOK) {
+        return EINVAL;
+    }
+
     ctx->be_ctx = be_ctx;
     ctx->sdom = id_ctx->sdap_id_ctx->opts->sdom;
     ctx->ldap_ctx = id_ctx->ldap_ctx;
@@ -1200,6 +1280,7 @@ int ad_subdom_init(struct be_ctx *be_ctx,
         DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
         return ENOMEM;
     }
+    ctx->ad_enabled_domains = ad_enabled_domains;
     ctx->ad_id_ctx = id_ctx;
     *ops = &ad_subdomains_ops;
     *pvt_data = ctx;

From 4c320a977e740b753c2afb487e1b2aa88ad7834c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Thu, 3 Nov 2016 08:42:07 +0100
Subject: [PATCH 3/4] AD_PROVIDER: ad_enabled_domains - only master

We can skip looking up other domains if option ad_enabled_domains
contains only master domain.

Resolves:
https://fedorahosted.org/sssd/ticket/2828
---
 src/providers/ad/ad_subdomains.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index c74e494..9f60665 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -649,6 +649,7 @@ static void ad_subdomains_get_conn_done(struct tevent_req *req)
         goto fail;
     }
 
+    /* connect to the DC we are a member of */
     req = ad_master_domain_send(ctx, ctx->sd_ctx->be_ctx->ev,
                                 ctx->sd_ctx->ldap_ctx,
                                 ctx->sdap_op,
@@ -699,6 +700,22 @@ static void ad_subdomains_master_dom_done(struct tevent_req *req)
         goto done;
     }
 
+    /*
+     * If ad_enabled_domains contains only master domain
+     * we shouldn't lookup other domains.
+     */
+    if (ctx->sd_ctx->ad_enabled_domains != NULL) {
+        if (talloc_array_length(ctx->sd_ctx->ad_enabled_domains) == 2) {
+            if (strcasecmp(ctx->sd_ctx->ad_enabled_domains[0],
+                           ctx->sd_ctx->be_ctx->domain->name) == 0) {
+                DEBUG(SSSDBG_TRACE_FUNC,
+                      "No other enabled domain than master.\n");
+                ret = EOK;
+                goto done;
+            }
+        }
+    }
+
     if (ctx->forest == NULL ||
           strcasecmp(ctx->sd_ctx->be_ctx->domain->name, ctx->forest) != 0) {
         DEBUG(SSSDBG_TRACE_FUNC,

From 7f41f3b22d9206736c39a076a7285c6c29ef89ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Thu, 3 Nov 2016 08:44:34 +0100
Subject: [PATCH 4/4] AD_PROVIDER: ad_enabled_domains - other then master

We can skip looking up other domains if
option ad_enabled_domains doesn't contain them.

Resolves:
https://fedorahosted.org/sssd/ticket/2828
---
 src/providers/ad/ad_subdomains.c | 40 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 9f60665..11dc4ed 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -165,6 +165,16 @@ static errno_t ad_get_enabled_domains(TALLOC_CTX *mem_ctx,
     return ret;
 }
 
+static bool is_domain_enabled(const char *domain,
+                              const char **enabled_doms)
+{
+   if (enabled_doms == NULL) {
+        return true;
+    }
+
+    return string_in_list(domain, discard_const_p(char *, enabled_doms), false);
+}
+
 static errno_t
 ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
                      struct ad_id_ctx *id_ctx,
@@ -1023,6 +1033,7 @@ static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx)
 
 static errno_t ad_subdomains_process(TALLOC_CTX *mem_ctx,
                                      struct sss_domain_info *domain,
+                                     const char **enabled_domains_list,
                                      size_t nsd, struct sysdb_attrs **sd,
                                      struct sysdb_attrs *root,
                                      size_t *_nsd_out,
@@ -1031,9 +1042,10 @@ static errno_t ad_subdomains_process(TALLOC_CTX *mem_ctx,
     size_t i, sdi;
     struct sysdb_attrs **sd_out;
     const char *sd_name;
+    const char *root_name;
     errno_t ret;
 
-    if (root == NULL) {
+    if (root == NULL && enabled_domains_list == NULL) {
         /* We are connected directly to the root domain. The 'sd'
          * list is complete and we can just use it
          */
@@ -1060,6 +1072,13 @@ static errno_t ad_subdomains_process(TALLOC_CTX *mem_ctx,
             goto fail;
         }
 
+        if (is_domain_enabled(sd_name, enabled_domains_list) == false) {
+            DEBUG(SSSDBG_TRACE_FUNC, "Disabling subdomain %s\n", sd_name);
+            continue;
+        } else {
+            DEBUG(SSSDBG_TRACE_FUNC, "Enabling subdomain %s\n", sd_name);
+        }
+
         if (strcasecmp(sd_name, domain->name) == 0) {
             DEBUG(SSSDBG_TRACE_INTERNAL,
                   "Not including primary domain %s in the subdomain list\n",
@@ -1072,9 +1091,23 @@ static errno_t ad_subdomains_process(TALLOC_CTX *mem_ctx,
     }
 
     /* Now include the root */
-    sd_out[sdi] = talloc_steal(sd_out, root);
+    if (root != NULL) {
+        ret = sysdb_attrs_get_string(root, AD_AT_TRUST_PARTNER, &root_name);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+            goto fail;
+        }
+
+        if (is_domain_enabled(root_name, enabled_domains_list) == true) {
+            sd_out[sdi] = talloc_steal(sd_out, root);
+            sdi++;
+        } else {
+            DEBUG(SSSDBG_TRACE_FUNC, "Disabling forest root domain %s\n",
+                                     root_name);
+        }
+    }
 
-    *_nsd_out = sdi+1;
+    *_nsd_out = sdi;
     *_sd_out = sd_out;
     return EOK;
 
@@ -1142,6 +1175,7 @@ static void ad_subdomains_get_slave_domain_done(struct tevent_req *req)
      * subdomains
      */
     ret = ad_subdomains_process(ctx, ctx->sd_ctx->be_ctx->domain,
+                                ctx->sd_ctx->ad_enabled_domains,
                                 ctx->reply_count, ctx->reply,
                                 ctx->root_domain_attrs, &nsubdoms, &subdoms);
     if (ret != EOK) {
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to