Blame SOURCES/0006-sudo-format-runas-attributes-to-correct-output-name.patch

5fca41
From 3a18e33f983cd17860b6ff41f9d538ee8fcc6d98 Mon Sep 17 00:00:00 2001
5fca41
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
5fca41
Date: Wed, 27 Feb 2019 14:06:06 +0100
5fca41
Subject: [PATCH 6/6] sudo: format runas attributes to correct output name
5fca41
5fca41
sudo internally calls getpwnam and getgrnam on user and groups
5fca41
that should be used for the invoked command. Output of these calls
5fca41
is compared to values in runAsUser/Group attributes.
5fca41
5fca41
When different output format is used then what is present in LDAP,
5fca41
this comparison will fail, denying user to use sudo. Now, we convert
5fca41
these attributes into correct output name, respecting domain resolution
5fca41
order, fully qualified domains and fqname format.
5fca41
5fca41
E.g. sudo call:
5fca41
sudo -u tuser@ipa.vm -g tgroup@ipa.vm id
5fca41
5fca41
Resolves:
5fca41
https://pagure.io/SSSD/sssd/issue/3957
5fca41
5fca41
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
5fca41
(cherry picked from commit 0aa657165f189035c160beda4840e3271fc56c88)
5fca41
---
5fca41
 src/responder/sudo/sudosrv_get_sudorules.c | 101 ++++++++++++++++++++-
5fca41
 1 file changed, 99 insertions(+), 2 deletions(-)
5fca41
5fca41
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
5fca41
index a420c76fb..d928a5ead 100644
5fca41
--- a/src/responder/sudo/sudosrv_get_sudorules.c
5fca41
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
5fca41
@@ -113,6 +113,95 @@ sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool lower_wins)
5fca41
     return EOK;
5fca41
 }
5fca41
 
5fca41
+static errno_t sudosrv_format_runas(struct resp_ctx *rctx,
5fca41
+                                    struct sysdb_attrs *rule,
5fca41
+                                    const char *attr)
5fca41
+{
5fca41
+    TALLOC_CTX *tmp_ctx;
5fca41
+    struct ldb_message_element *el;
5fca41
+    struct sss_domain_info *dom;
5fca41
+    const char *value;
5fca41
+    char *fqname;
5fca41
+    unsigned int i;
5fca41
+    errno_t ret;
5fca41
+
5fca41
+    tmp_ctx = talloc_new(NULL);
5fca41
+    if (tmp_ctx == NULL) {
5fca41
+        DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
5fca41
+        return ENOMEM;
5fca41
+    }
5fca41
+
5fca41
+    ret = sysdb_attrs_get_el_ext(rule, attr, false, &el);
5fca41
+    if (ret == ENOENT) {
5fca41
+        ret = EOK;
5fca41
+        goto done;
5fca41
+    } else if (ret != EOK) {
5fca41
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get %s attribute "
5fca41
+              "[%d]: %s\n", attr, ret, sss_strerror(ret));
5fca41
+        goto done;
5fca41
+    }
5fca41
+
5fca41
+    for (i = 0; i < el->num_values; i++) {
5fca41
+        value = (const char *)el->values[i].data;
5fca41
+        if (value == NULL) {
5fca41
+            continue;
5fca41
+        }
5fca41
+
5fca41
+        dom = find_domain_by_object_name_ex(rctx->domains, value, true);
5fca41
+        if (dom == NULL) {
5fca41
+            continue;
5fca41
+        }
5fca41
+
5fca41
+        ret = sss_output_fqname(tmp_ctx, dom, value,
5fca41
+                                rctx->override_space, &fqname);
5fca41
+        if (ret != EOK) {
5fca41
+            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to convert %s to output fqname "
5fca41
+                  "[%d]: %s\n", value, ret, sss_strerror(ret));
5fca41
+            goto done;
5fca41
+        }
5fca41
+
5fca41
+        talloc_free(el->values[i].data);
5fca41
+        el->values[i].data = (uint8_t*)talloc_steal(el->values, fqname);
5fca41
+        el->values[i].length = strlen(fqname);
5fca41
+    }
5fca41
+
5fca41
+done:
5fca41
+    talloc_free(tmp_ctx);
5fca41
+
5fca41
+    return ret;
5fca41
+}
5fca41
+
5fca41
+static errno_t sudosrv_format_rules(struct resp_ctx *rctx,
5fca41
+                                    struct sysdb_attrs **rules,
5fca41
+                                    uint32_t num_rules)
5fca41
+{
5fca41
+    uint32_t i;
5fca41
+    errno_t ret;
5fca41
+
5fca41
+
5fca41
+    for (i = 0; i < num_rules; i++) {
5fca41
+        ret = sudosrv_format_runas(rctx, rules[i],
5fca41
+                                   SYSDB_SUDO_CACHE_AT_RUNAS);
5fca41
+        if (ret != EOK) {
5fca41
+            return ret;
5fca41
+        }
5fca41
+
5fca41
+        ret = sudosrv_format_runas(rctx, rules[i],
5fca41
+                                   SYSDB_SUDO_CACHE_AT_RUNASUSER);
5fca41
+        if (ret != EOK) {
5fca41
+            return ret;
5fca41
+        }
5fca41
+
5fca41
+        ret = sudosrv_format_runas(rctx, rules[i],
5fca41
+                                   SYSDB_SUDO_CACHE_AT_RUNASGROUP);
5fca41
+        if (ret != EOK) {
5fca41
+            return ret;
5fca41
+        }
5fca41
+    }
5fca41
+
5fca41
+    return ret;
5fca41
+}
5fca41
+
5fca41
 static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
5fca41
                                    struct sss_domain_info *domain,
5fca41
                                    const char **attrs,
5fca41
@@ -301,6 +390,7 @@ static errno_t sudosrv_cached_rules_by_ng(TALLOC_CTX *mem_ctx,
5fca41
 }
5fca41
 
5fca41
 static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx,
5fca41
+                                    struct resp_ctx *rctx,
5fca41
                                     struct sss_domain_info *domain,
5fca41
                                     uid_t cli_uid,
5fca41
                                     uid_t orig_uid,
5fca41
@@ -368,6 +458,12 @@ static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx,
5fca41
         goto done;
5fca41
     }
5fca41
 
5fca41
+    ret = sudosrv_format_rules(rctx, rules, num_rules);
5fca41
+    if (ret != EOK) {
5fca41
+        DEBUG(SSSDBG_OP_FAILURE, "Could not format sudo rules\n");
5fca41
+        goto done;
5fca41
+    }
5fca41
+
5fca41
     *_rules = talloc_steal(mem_ctx, rules);
5fca41
     *_num_rules = num_rules;
5fca41
 
5fca41
@@ -412,6 +508,7 @@ static errno_t sudosrv_cached_defaults(TALLOC_CTX *mem_ctx,
5fca41
 }
5fca41
 
5fca41
 static errno_t sudosrv_fetch_rules(TALLOC_CTX *mem_ctx,
5fca41
+                                   struct resp_ctx *rctx,
5fca41
                                    enum sss_sudo_type type,
5fca41
                                    struct sss_domain_info *domain,
5fca41
                                    uid_t cli_uid,
5fca41
@@ -433,7 +530,7 @@ static errno_t sudosrv_fetch_rules(TALLOC_CTX *mem_ctx,
5fca41
               username, domain->name);
5fca41
         debug_name = "rules";
5fca41
 
5fca41
-        ret = sudosrv_cached_rules(mem_ctx, domain,
5fca41
+        ret = sudosrv_cached_rules(mem_ctx, rctx, domain,
5fca41
                                    cli_uid, orig_uid, username, groups,
5fca41
                                    inverse_order, &rules, &num_rules);
5fca41
 
5fca41
@@ -760,7 +857,7 @@ static void sudosrv_get_rules_done(struct tevent_req *subreq)
5fca41
               "in cache.\n");
5fca41
     }
5fca41
 
5fca41
-    ret = sudosrv_fetch_rules(state, state->type, state->domain,
5fca41
+    ret = sudosrv_fetch_rules(state, state->rctx, state->type, state->domain,
5fca41
                               state->cli_uid,
5fca41
                               state->orig_uid,
5fca41
                               state->orig_username,
5fca41
-- 
5fca41
2.19.1
5fca41