URL: https://github.com/SSSD/sssd/pull/464
Author: fidencio
 Title: #464: SYSDB: Properly handle name/gid override when using domain 
resolution order
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/464/head:pr464
git checkout pr464
From 2fb2244f88d1d0e068ee13c088ea67e04edf7e6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fiden...@redhat.com>
Date: Tue, 5 Dec 2017 21:14:09 +0100
Subject: [PATCH] SYSDB: Properly handle name/gid override when using domain
 resolution order
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When using name/gid override together with domain resolution order the
mpg name/gid may be returned instead of the overridden one.

In order to avoid that, let's add a check in case the domain supports
mpg so we can ensure that the originalADname and originalADgidNumber
attributes are the very same as the ones searched and then normally
proceed with the current flow in the code. In case those are not the
same, we *must* follow the code path for the non-mpg domains and then
return the proper values.

Resolves: https://pagure.io/SSSD/sssd/issue/3595

Signed-off-by: Fabiano FidĂȘncio <fiden...@redhat.com>
---
 src/db/sysdb.h        |   2 +
 src/db/sysdb_search.c | 110 +++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 93 insertions(+), 19 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 2660314a7..d9c8fd5d6 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -258,6 +258,8 @@
                            SYSDB_OVERRIDE_OBJECT_DN, \
                            SYSDB_DEFAULT_OVERRIDE_NAME, \
                            SYSDB_UUID, \
+                           ORIGINALAD_PREFIX SYSDB_NAME, \
+                           ORIGINALAD_PREFIX SYSDB_GIDNUM, \
                            NULL}
 
 #define SYSDB_NETGR_ATTRS {SYSDB_NAME, SYSDB_NETGROUP_TRIPLE, \
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
index b7ceb6e59..24c0203ba 100644
--- a/src/db/sysdb_search.c
+++ b/src/db/sysdb_search.c
@@ -895,6 +895,7 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx,
     struct ldb_dn *base_dn;
     struct ldb_result *res;
     char *lc_sanitized_name;
+    const char *originalad_sanitized_name;
     int ret;
 
     tmp_ctx = talloc_new(NULL);
@@ -902,30 +903,66 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
+    ret = sss_filter_sanitize_for_dom(tmp_ctx, name, domain,
+                                      &sanitized_name, &lc_sanitized_name);
+    if (ret != EOK) {
+        goto done;
+    }
+
     if (domain->mpg) {
+        /* In case the domain supports magic private groups we *must*
+         * check whether the searched name is the very same as the
+         * originalADname attribute.
+         *
+         * In case those are not the same, we're dealing with an
+         * override and in order to return the proper overridden group
+         * we must use the very same search used by a non-mpg domain
+         */
         fmt_filter = SYSDB_GRNAM_MPG_FILTER;
         base_dn = sysdb_domain_dn(tmp_ctx, domain);
+        if (base_dn == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
+                         LDB_SCOPE_SUBTREE, attrs, fmt_filter,
+                         lc_sanitized_name, sanitized_name, sanitized_name);
+        if (ret != EOK) {
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
+
+        if (res->count > 0) {
+            originalad_sanitized_name = ldb_msg_find_attr_as_string(
+                    res->msgs[0], ORIGINALAD_PREFIX SYSDB_NAME, NULL);
+
+            if (originalad_sanitized_name != NULL
+                    && strcmp(originalad_sanitized_name, sanitized_name) != 0) {
+                fmt_filter = SYSDB_GRNAM_FILTER;
+                base_dn = sysdb_group_base_dn(tmp_ctx, domain);
+            }
+        }
     } else {
         fmt_filter = SYSDB_GRNAM_FILTER;
         base_dn = sysdb_group_base_dn(tmp_ctx, domain);
     }
-    if (!base_dn) {
+    if (base_dn == NULL) {
         ret = ENOMEM;
         goto done;
     }
 
-    ret = sss_filter_sanitize_for_dom(tmp_ctx, name, domain,
-                                      &sanitized_name, &lc_sanitized_name);
-    if (ret != EOK) {
-        goto done;
-    }
-
-    ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
-                     LDB_SCOPE_SUBTREE, attrs, fmt_filter,
-                     lc_sanitized_name, sanitized_name, sanitized_name);
-    if (ret) {
-        ret = sysdb_error_to_errno(ret);
-        goto done;
+    /* We just do the ldb_search here in case domain is *not* a MPG *or*
+     * it's a MPG and we're dealing with a overriden group, which has to
+     * use the very same filter as a non MPG domain. */
+    if (strcmp(fmt_filter, SYSDB_GRNAM_FILTER) == 0) {
+        ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
+                         LDB_SCOPE_SUBTREE, attrs, fmt_filter,
+                         lc_sanitized_name, sanitized_name, sanitized_name);
+        if (ret != EOK) {
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
     }
 
     ret = mpg_res_convert(res);
@@ -1045,6 +1082,7 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx,
 {
     TALLOC_CTX *tmp_ctx;
     unsigned long int ul_gid = gid;
+    unsigned long int ul_originalad_gid;
     static const char *attrs[] = SYSDB_GRSRC_ATTRS;
     const char *fmt_filter;
     struct ldb_dn *base_dn;
@@ -1057,22 +1095,56 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx,
     }
 
     if (domain->mpg) {
+        /* In case the domain supports magic private groups we *must*
+         * check whether the searched gid is the very same as the
+         * originalADgidNumber attribute.
+         *
+         * In case those are not the same, we're dealing with an
+         * override and in order to return the proper overridden group
+         * we must use the very same search used by a non-mpg domain
+         */
         fmt_filter = SYSDB_GRGID_MPG_FILTER;
         base_dn = sysdb_domain_dn(tmp_ctx, domain);
+        if (base_dn == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
+                         LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid);
+        if (ret != EOK) {
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
+
+        if (res->count > 0) {
+            ul_originalad_gid = ldb_msg_find_attr_as_uint64(
+                    res->msgs[0], ORIGINALAD_PREFIX SYSDB_GIDNUM, 0);
+
+            if (ul_originalad_gid != 0 && ul_originalad_gid != ul_gid) {
+                fmt_filter = SYSDB_GRGID_FILTER;
+                base_dn = sysdb_group_base_dn(tmp_ctx, domain);
+            }
+        }
     } else {
         fmt_filter = SYSDB_GRGID_FILTER;
         base_dn = sysdb_group_base_dn(tmp_ctx, domain);
     }
-    if (!base_dn) {
+    if (base_dn == NULL) {
         ret = ENOMEM;
         goto done;
     }
 
-    ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
-                     LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid);
-    if (ret) {
-        ret = sysdb_error_to_errno(ret);
-        goto done;
+    /* We just do the ldb_search here in case domain is *not* a MPG *or*
+     * it's a MPG and we're dealing with a overriden group, which has to
+     * use the very same filter as a non MPG domain. */
+    if (strcmp(fmt_filter, SYSDB_GRGID_FILTER) == 0) {
+        ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
+                         LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid);
+        if (ret != EOK) {
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
     }
 
     ret = mpg_res_convert(res);
_______________________________________________
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