>From 669ba173b0daaef99fab6ea1a8d5e5eb71c2cea1 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <pavel.reichl@redhat.com>
Date: Thu, 14 Nov 2013 21:34:51 +0000
Subject: [PATCH 1/2] SSSD: Improved domain detection

A bit more elegant way of detection of what domain the group member belongs to

Resolves:
https://fedorahosted.org/sssd/ticket/2132
---
 src/providers/ldap/ldap_common.c | 39 ++++++++++++++++++++++++++++-----------
 src/util/sss_ldap.c              | 28 +++++++++++++++++++++++-----
 src/util/sss_ldap.h              |  6 ++++++
 3 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index e29a5219768df154608aad9740dd9ed44c14e22e..482271b8c22095116c7090e3ec70ed2a3c763b34 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -68,23 +68,40 @@ sdap_domain_get_by_dn(struct sdap_options *opts,
                       const char *dn)
 {
     struct sdap_domain *sditer = NULL;
-    char *dc = NULL;
+    struct sdap_domain *sdmatch = NULL;
+    TALLOC_CTX *tmp_ctx = NULL;
+    int match_len;
+    int best_match_len = 0;
 
-    dc = strstr(dn, "dc=");
-    if (dc == NULL) {
-        dc = strstr(dn, "DC=");
-        if (dc == NULL) {
-            return NULL;
-        }
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        return NULL;
     }
 
     DLIST_FOR_EACH(sditer, opts->sdom) {
-        if (strcasecmp(sditer->basedn, dc) == 0) {
-            return sditer;
+        if (sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->search_bases,
+                                            NULL, &match_len)
+            || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn,
+                   sditer->user_search_bases, NULL, &match_len)
+            || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn,
+                   sditer->group_search_bases, NULL, &match_len)
+            || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn,
+                   sditer->netgroup_search_bases, NULL, &match_len)
+            || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn,
+                   sditer->sudo_search_bases, NULL, &match_len)
+            || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn,
+                   sditer->service_search_bases, NULL, &match_len)
+            || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn,
+                   sditer->autofs_search_bases, NULL, &match_len)) {
+            if (best_match_len < match_len) {
+                /*this is a longer match*/
+                best_match_len = match_len;
+                sdmatch = sditer;
+            }
         }
     }
-
-    return NULL;
+    talloc_free(tmp_ctx);
+    return sdmatch;
 }
 
 errno_t
diff --git a/src/util/sss_ldap.c b/src/util/sss_ldap.c
index 6d7b0907ca2fa48d9cff5257ab6bbba0ae7dd5c6..e1a05e8f60afb692ac95c99a443febac72a31187 100644
--- a/src/util/sss_ldap.c
+++ b/src/util/sss_ldap.c
@@ -470,10 +470,13 @@ int sss_ldap_init_recv(struct tevent_req *req, LDAP **ldap, int *sd)
  * _filter will contain combined filters from all possible search bases
  * or NULL if it should be empty
  */
-bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
-                                 const char *dn,
-                                 struct sdap_search_base **search_bases,
-                                 char **_filter)
+
+
+bool sss_ldap_dn_in_search_bases_len(TALLOC_CTX *mem_ctx,
+                                     const char *dn,
+                                     struct sdap_search_base **search_bases,
+                                     char **_filter,
+                                     int *_match_len)
 {
     struct sdap_search_base *base;
     int basedn_len, dn_len;
@@ -484,6 +487,7 @@ bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
     bool backslash_found = false;
     char *filter = NULL;
     bool ret = false;
+    int match_len;
 
     if (dn == NULL) {
         DEBUG(SSSDBG_FUNC_DATA, ("dn is NULL\n"));
@@ -511,6 +515,7 @@ bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
         if (!base_confirmed) {
             continue;
         }
+        match_len = basedn_len;
 
         switch (base->scope) {
         case LDAP_SCOPE_BASE:
@@ -558,6 +563,9 @@ bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
          *  Append filter otherwise.
          */
         ret = true;
+        if (_match_len) {
+            *_match_len = match_len;
+        }
 
         if (base->filter == NULL || _filter == NULL) {
             goto done;
@@ -575,7 +583,8 @@ bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
         if (filter != NULL) {
             *_filter = talloc_asprintf(mem_ctx, "(|%s)", filter);
             if (*_filter == NULL) {
-                DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_asprintf_append() failed\n"));
+                DEBUG(SSSDBG_CRIT_FAILURE,
+                      ("talloc_asprintf_append() failed\n"));
                 ret = false;
                 goto done;
             }
@@ -589,6 +598,15 @@ done:
     return ret;
 }
 
+bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
+                                 const char *dn,
+                                 struct sdap_search_base **search_bases,
+                                 char **_filter)
+{
+    return sss_ldap_dn_in_search_bases_len(mem_ctx, dn, search_bases, _filter,
+                                           NULL);
+}
+
 char *sss_ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t flags)
 {
     char hex[9]; /* 4 bytes in hex + terminating zero */
diff --git a/src/util/sss_ldap.h b/src/util/sss_ldap.h
index e5c30eb2115d422ef5a52cc5cd75c85be8fbe2d7..f298b2fbb30cf1532f8e94504ffb83ef73880b81 100644
--- a/src/util/sss_ldap.h
+++ b/src/util/sss_ldap.h
@@ -74,6 +74,12 @@ bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx,
                                  struct sdap_search_base **search_bases,
                                  char **_filter);
 
+bool sss_ldap_dn_in_search_bases_len(TALLOC_CTX *mem_ctx,
+                                     const char *dn,
+                                     struct sdap_search_base **search_bases,
+                                     char **_filter,
+                                     int *_match_len);
+
 char *sss_ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t flags);
 
 #endif /* __SSS_LDAP_H__ */
-- 
1.8.3.1

