219 lines
7.8 KiB
Diff
219 lines
7.8 KiB
Diff
|
From e7aee44602eb36ee1e1201ad6c7234562b8bb703 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@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 <fidencio@redhat.com>
|
||
|
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||
|
(cherry picked from commit cf4f5e031ecbdfba0b55a4f69a06175a2e718e67)
|
||
|
---
|
||
|
src/db/sysdb.h | 2 +
|
||
|
src/db/sysdb_search.c | 116 ++++++++++++++++++++++++++++++++++--------
|
||
|
2 files changed, 97 insertions(+), 21 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..66c4977b3 100644
|
||
|
--- a/src/db/sysdb_search.c
|
||
|
+++ b/src/db/sysdb_search.c
|
||
|
@@ -893,8 +893,9 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx,
|
||
|
const char *fmt_filter;
|
||
|
char *sanitized_name;
|
||
|
struct ldb_dn *base_dn;
|
||
|
- struct ldb_result *res;
|
||
|
+ struct ldb_result *res = NULL;
|
||
|
char *lc_sanitized_name;
|
||
|
+ const char *originalad_sanitized_name;
|
||
|
int ret;
|
||
|
|
||
|
tmp_ctx = talloc_new(NULL);
|
||
|
@@ -902,30 +903,67 @@ 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);
|
||
|
+ res = NULL;
|
||
|
+ }
|
||
|
+ }
|
||
|
} 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 (res == NULL) {
|
||
|
+ 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,10 +1083,11 @@ 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;
|
||
|
- struct ldb_result *res;
|
||
|
+ struct ldb_result *res = NULL;
|
||
|
int ret;
|
||
|
|
||
|
tmp_ctx = talloc_new(NULL);
|
||
|
@@ -1057,22 +1096,57 @@ 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);
|
||
|
+ res = NULL;
|
||
|
+ }
|
||
|
+ }
|
||
|
} 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 (res == NULL) {
|
||
|
+ 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);
|
||
|
--
|
||
|
2.17.0
|
||
|
|