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

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