|
|
bb7cd1 |
From c7c087b5485d50e8689d31fd9d52af935ae398be Mon Sep 17 00:00:00 2001
|
|
|
956cae |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
956cae |
Date: Sun, 9 Apr 2017 20:50:47 +0200
|
|
|
bb7cd1 |
Subject: [PATCH 142/142] HBAC: Do not rely on originalMemberOf, use the sysdb
|
|
|
956cae |
memberof links instead
|
|
|
956cae |
|
|
|
956cae |
The IPA HBAC code used to read the group members from the
|
|
|
956cae |
originalMemberOf attribute value for performance reasons. However,
|
|
|
956cae |
especially on IPA clients trusting an AD domain, the originalMemberOf
|
|
|
956cae |
attribute value is often not synchronized correctly.
|
|
|
956cae |
|
|
|
956cae |
Instead of going through the work of maintaining both member/memberOf
|
|
|
956cae |
and originalMemberOf, let's just do an ASQ search for the group names of
|
|
|
956cae |
the groups the user is a member of in the cache and read their
|
|
|
956cae |
SYSBD_NAME attribute.
|
|
|
956cae |
|
|
|
956cae |
To avoid clashing between similarly-named groups in IPA and in AD, we
|
|
|
956cae |
look at the container of the group.
|
|
|
956cae |
|
|
|
956cae |
Resolves:
|
|
|
956cae |
https://pagure.io/SSSD/sssd/issue/3382
|
|
|
956cae |
|
|
|
956cae |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
956cae |
(cherry picked from commit c92e49144978ad3b6c9fffa8803ebdad8f6f5b18)
|
|
|
956cae |
---
|
|
|
956cae |
src/providers/ipa/ipa_hbac_common.c | 97 +++++++++++++++++++++++++------------
|
|
|
956cae |
1 file changed, 67 insertions(+), 30 deletions(-)
|
|
|
956cae |
|
|
|
956cae |
diff --git a/src/providers/ipa/ipa_hbac_common.c b/src/providers/ipa/ipa_hbac_common.c
|
|
|
956cae |
index b99b75d322930f16412f6abd4cdf0d7e0b59c32c..ba677965a3eb68a54baf99b1875bca2acbb76c99 100644
|
|
|
956cae |
--- a/src/providers/ipa/ipa_hbac_common.c
|
|
|
956cae |
+++ b/src/providers/ipa/ipa_hbac_common.c
|
|
|
956cae |
@@ -507,15 +507,15 @@ hbac_eval_user_element(TALLOC_CTX *mem_ctx,
|
|
|
956cae |
struct hbac_request_element **user_element)
|
|
|
956cae |
{
|
|
|
956cae |
errno_t ret;
|
|
|
956cae |
- unsigned int i;
|
|
|
956cae |
unsigned int num_groups = 0;
|
|
|
956cae |
TALLOC_CTX *tmp_ctx;
|
|
|
956cae |
- const char *member_dn;
|
|
|
956cae |
struct hbac_request_element *users;
|
|
|
956cae |
- struct ldb_message *msg;
|
|
|
956cae |
- struct ldb_message_element *el;
|
|
|
956cae |
- const char *attrs[] = { SYSDB_ORIG_MEMBEROF, NULL };
|
|
|
956cae |
char *shortname;
|
|
|
956cae |
+ const char *fqgroupname = NULL;
|
|
|
956cae |
+ struct sss_domain_info *ipa_domain;
|
|
|
956cae |
+ struct ldb_dn *ipa_groups_basedn;
|
|
|
956cae |
+ struct ldb_result *res;
|
|
|
956cae |
+ int exp_comp;
|
|
|
956cae |
|
|
|
956cae |
tmp_ctx = talloc_new(mem_ctx);
|
|
|
956cae |
if (tmp_ctx == NULL) return ENOMEM;
|
|
|
956cae |
@@ -533,56 +533,93 @@ hbac_eval_user_element(TALLOC_CTX *mem_ctx,
|
|
|
956cae |
}
|
|
|
956cae |
users->name = talloc_steal(users, shortname);
|
|
|
956cae |
|
|
|
956cae |
- /* Read the originalMemberOf attribute
|
|
|
956cae |
- * This will give us the list of both POSIX and
|
|
|
956cae |
- * non-POSIX groups that this user belongs to.
|
|
|
956cae |
+ ipa_domain = get_domains_head(domain);
|
|
|
956cae |
+ if (ipa_domain == NULL) {
|
|
|
956cae |
+ ret = EINVAL;
|
|
|
956cae |
+ goto done;
|
|
|
956cae |
+ }
|
|
|
956cae |
+
|
|
|
956cae |
+ ipa_groups_basedn = ldb_dn_new_fmt(tmp_ctx, sysdb_ctx_get_ldb(domain->sysdb),
|
|
|
956cae |
+ SYSDB_TMPL_GROUP_BASE, ipa_domain->name);
|
|
|
956cae |
+ if (ipa_groups_basedn == NULL) {
|
|
|
956cae |
+ ret = ENOMEM;
|
|
|
956cae |
+ goto done;
|
|
|
956cae |
+ }
|
|
|
956cae |
+
|
|
|
956cae |
+ /* +1 because there will be a RDN preceding the base DN */
|
|
|
956cae |
+ exp_comp = ldb_dn_get_comp_num(ipa_groups_basedn) + 1;
|
|
|
956cae |
+
|
|
|
956cae |
+ /*
|
|
|
956cae |
+ * Get all the groups the user is a member of.
|
|
|
956cae |
+ * This includes both POSIX and non-POSIX groups.
|
|
|
956cae |
*/
|
|
|
956cae |
- ret = sysdb_search_user_by_name(tmp_ctx, domain, username,
|
|
|
956cae |
- attrs, &msg;;
|
|
|
956cae |
+ ret = sysdb_initgroups(tmp_ctx, domain, username, &res;;
|
|
|
956cae |
if (ret != EOK) {
|
|
|
956cae |
DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
956cae |
- "Could not determine user memberships for [%s]\n",
|
|
|
956cae |
- users->name);
|
|
|
956cae |
+ "sysdb_asq_search failed [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
956cae |
goto done;
|
|
|
956cae |
}
|
|
|
956cae |
|
|
|
956cae |
- el = ldb_msg_find_element(msg, SYSDB_ORIG_MEMBEROF);
|
|
|
956cae |
- if (el == NULL || el->num_values == 0) {
|
|
|
956cae |
+ if (res->count == 0) {
|
|
|
956cae |
+ /* This should not happen at this point */
|
|
|
956cae |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
956cae |
+ "User [%s] not found in cache.\n", username);
|
|
|
956cae |
+ ret = ENOENT;
|
|
|
956cae |
+ goto done;
|
|
|
956cae |
+ } else if (res->count == 1) {
|
|
|
956cae |
+ /* The first item is the user entry */
|
|
|
956cae |
DEBUG(SSSDBG_TRACE_LIBS, "No groups for [%s]\n", users->name);
|
|
|
956cae |
ret = create_empty_grouplist(users);
|
|
|
956cae |
goto done;
|
|
|
956cae |
}
|
|
|
956cae |
DEBUG(SSSDBG_TRACE_LIBS,
|
|
|
956cae |
- "[%d] groups for [%s]\n", el->num_values, users->name);
|
|
|
956cae |
+ "[%u] groups for [%s]\n", res->count - 1, username);
|
|
|
956cae |
|
|
|
956cae |
- users->groups = talloc_array(users, const char *, el->num_values + 1);
|
|
|
956cae |
+ /* This also includes the sentinel, b/c we'll skip the user entry below */
|
|
|
956cae |
+ users->groups = talloc_array(users, const char *, res->count);
|
|
|
956cae |
if (users->groups == NULL) {
|
|
|
956cae |
ret = ENOMEM;
|
|
|
956cae |
goto done;
|
|
|
956cae |
}
|
|
|
956cae |
|
|
|
956cae |
- for (i = 0; i < el->num_values; i++) {
|
|
|
956cae |
- member_dn = (const char *)el->values[i].data;
|
|
|
956cae |
+ /* Start counting from 1 to exclude the user entry */
|
|
|
956cae |
+ for (size_t i = 1; i < res->count; i++) {
|
|
|
956cae |
+ /* Only groups from the IPA domain can be referenced from HBAC rules. To
|
|
|
956cae |
+ * avoid evaluating groups which might even have the same name, but come
|
|
|
956cae |
+ * from a trusted domain, we first copy the DN to a temporary one..
|
|
|
956cae |
+ */
|
|
|
956cae |
+ if (ldb_dn_get_comp_num(res->msgs[i]->dn) != exp_comp
|
|
|
956cae |
+ || ldb_dn_compare_base(ipa_groups_basedn,
|
|
|
956cae |
+ res->msgs[i]->dn) != 0) {
|
|
|
956cae |
+ DEBUG(SSSDBG_FUNC_DATA,
|
|
|
956cae |
+ "Skipping non-IPA group %s\n",
|
|
|
956cae |
+ ldb_dn_get_linearized(res->msgs[i]->dn));
|
|
|
956cae |
+ continue;
|
|
|
956cae |
+ }
|
|
|
956cae |
|
|
|
956cae |
- ret = get_ipa_groupname(users->groups, domain->sysdb, member_dn,
|
|
|
956cae |
- &users->groups[num_groups]);
|
|
|
956cae |
- if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) {
|
|
|
956cae |
+ fqgroupname = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL);
|
|
|
956cae |
+ if (fqgroupname == NULL) {
|
|
|
956cae |
DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
956cae |
- "Skipping malformed entry [%s]\n", member_dn);
|
|
|
956cae |
+ "Skipping malformed entry [%s]\n",
|
|
|
956cae |
+ ldb_dn_get_linearized(res->msgs[i]->dn));
|
|
|
956cae |
continue;
|
|
|
956cae |
- } else if (ret == EOK) {
|
|
|
956cae |
- DEBUG(SSSDBG_TRACE_LIBS, "Added group [%s] for user [%s]\n",
|
|
|
956cae |
- users->groups[num_groups], users->name);
|
|
|
956cae |
- num_groups++;
|
|
|
956cae |
+ }
|
|
|
956cae |
+
|
|
|
956cae |
+ ret = sss_parse_internal_fqname(tmp_ctx, fqgroupname,
|
|
|
956cae |
+ &shortname, NULL);
|
|
|
956cae |
+ if (ret != EOK) {
|
|
|
956cae |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Malformed name %s, skipping!\n", fqgroupname);
|
|
|
956cae |
continue;
|
|
|
956cae |
}
|
|
|
956cae |
- /* Skip entries that are not groups */
|
|
|
956cae |
- DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
956cae |
- "Skipping non-group memberOf [%s]\n", member_dn);
|
|
|
956cae |
+
|
|
|
956cae |
+ users->groups[num_groups] = talloc_steal(users->groups, shortname);
|
|
|
956cae |
+ DEBUG(SSSDBG_TRACE_LIBS, "Added group [%s] for user [%s]\n",
|
|
|
956cae |
+ users->groups[num_groups], users->name);
|
|
|
956cae |
+ num_groups++;
|
|
|
956cae |
}
|
|
|
956cae |
users->groups[num_groups] = NULL;
|
|
|
956cae |
|
|
|
956cae |
- if (num_groups < el->num_values) {
|
|
|
956cae |
+ if (num_groups < (res->count - 1)) {
|
|
|
956cae |
/* Shrink the array memory */
|
|
|
956cae |
users->groups = talloc_realloc(users, users->groups, const char *,
|
|
|
956cae |
num_groups+1);
|
|
|
956cae |
--
|
|
|
956cae |
2.9.4
|
|
|
956cae |
|