[SSSD] [PATCH] AD: Do not remove non-root domains when looking up root domain

Jakub Hrozek jhrozek at redhat.com
Tue May 13 13:25:42 UTC 2014


Hi,

The attached patch fixes a potential segfault when SSSD is enrolled with
a non-root AD domain and a user from another non-root domain would log
in.

Please see the commit message for details.
-------------- next part --------------
>From 8e3b0109541daf7b9a1b4250bf4cf32ad949ed67 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 13 May 2014 15:18:07 +0200
Subject: [PATCH] AD: Do not remove non-root domains when looking up root
 domain

https://fedorahosted.org/sssd/ticket/2322

When the AD subdomains code looked up the root domain subsequently
(after the domain list was already populated), the non-root domains
might have been removed along with their respective tasks, because the
root domain lookup only ever matched a single root domain.

This could cause havoc especially during login when different lookups
for different domains might be going on during user group refresh.
---
 src/providers/ad/ad_subdomains.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 58510c3f9548dd22c61c00d6145bde79c29fda61..102b62fcd6c0b5202c6a1761f1110fea28d461db 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -325,13 +325,15 @@ done:
 }
 
 static errno_t ad_subdomains_refresh(struct ad_subdomains_ctx *ctx,
-                                     int count, struct sysdb_attrs **reply,
+                                     int count, bool root_domain,
+                                     struct sysdb_attrs **reply,
                                      bool *changes)
 {
     struct sdap_domain *sdom;
     struct sss_domain_info *domain, *dom;
     bool handled[count];
     const char *value;
+    const char *root_name = NULL;
     int c, h;
     int ret;
     bool enumerate;
@@ -340,10 +342,27 @@ static errno_t ad_subdomains_refresh(struct ad_subdomains_ctx *ctx,
     memset(handled, 0, sizeof(bool) * count);
     h = 0;
 
+    if (root_domain) {
+        ret = sysdb_attrs_get_string(reply[0], AD_AT_TRUST_PARTNER,
+                                     &root_name);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+            goto done;
+        }
+    }
+
     /* check existing subdomains */
     for (dom = get_next_domain(domain, true);
          dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
          dom = get_next_domain(dom, false)) {
+
+        /* If we are handling root domain, skip all the other domains. We don't
+         * want to accidentally remove non-root domains
+         */
+        if (root_name && strcmp(root_name, dom->name) != 0) {
+            continue;
+        }
+
         for (c = 0; c < count; c++) {
             if (handled[c]) {
                 continue;
@@ -721,7 +740,7 @@ static void ad_subdomains_get_root_domain_done(struct tevent_req *req)
         goto fail;
     }
 
-    ret = ad_subdomains_refresh(ctx->sd_ctx, 1, reply, &has_changes);
+    ret = ad_subdomains_refresh(ctx->sd_ctx, 1, true, reply, &has_changes);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "ad_subdomains_refresh failed.\n");
         goto fail;
@@ -1014,7 +1033,7 @@ static void ad_subdomains_get_slave_domain_done(struct tevent_req *req)
     }
 
     /* Got all the subdomains, let's process them */
-    ret = ad_subdomains_refresh(ctx->sd_ctx, nsubdoms, subdoms,
+    ret = ad_subdomains_refresh(ctx->sd_ctx, nsubdoms, false, subdoms,
                                 &refresh_has_changes);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "Failed to refresh subdomains.\n");
-- 
1.9.0



More information about the sssd-devel mailing list