Blame SOURCES/0084-KRB5-Drop-privileges-in-the-child-not-the-back-end.patch

905b4d
From 6422e4a1fea8176fab2f92711cd593904d549cfe Mon Sep 17 00:00:00 2001
905b4d
From: Jakub Hrozek <jhrozek@redhat.com>
905b4d
Date: Mon, 13 Oct 2014 21:13:38 +0200
905b4d
Subject: [PATCH 84/92] KRB5: Drop privileges in the child, not the back end
905b4d
MIME-Version: 1.0
905b4d
Content-Type: text/plain; charset=UTF-8
905b4d
Content-Transfer-Encoding: 8bit
905b4d
905b4d
In future patches, sssd_be will be running as a non-privileged user, who
905b4d
will execute the setuid krb5_child. In this case, the child will start
905b4d
as root and drop the privileges as soon as possible.
905b4d
905b4d
However, we need to also remove the privilege drop in sssd_be, because
905b4d
if we dropped to the user who is authenticating, we wouldn't be even
905b4d
allowed to execute krb5_child. The krb5_child permissions should be
905b4d
4750, owned by root.sssd, to make sure only root and sssd can execute
905b4d
the child and if executed by sssd, the child will run as root.
905b4d
905b4d
Related:
905b4d
https://fedorahosted.org/sssd/ticket/2370
905b4d
905b4d
Reviewed-by: Sumit Bose <sbose@redhat.com>
905b4d
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
905b4d
---
905b4d
 src/providers/krb5/krb5_child.c         | 71 ++++++++++++++++++++++++++-------
905b4d
 src/providers/krb5/krb5_child_handler.c |  8 ----
905b4d
 2 files changed, 57 insertions(+), 22 deletions(-)
905b4d
905b4d
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
905b4d
index 3234a4e6c740db5e05f7db8eb7f4ea0cc126e7ce..b0bf76fb3b8a77831b114c47acff8cd0d3fd780d 100644
905b4d
--- a/src/providers/krb5/krb5_child.c
905b4d
+++ b/src/providers/krb5/krb5_child.c
905b4d
@@ -1840,11 +1840,60 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand)
905b4d
     return EOK;
905b4d
 }
905b4d
 
905b4d
-static int k5c_setup(struct krb5_req *kr, uint32_t offline)
905b4d
+enum k5c_fast_opt {
905b4d
+    K5C_FAST_NEVER,
905b4d
+    K5C_FAST_TRY,
905b4d
+    K5C_FAST_DEMAND,
905b4d
+};
905b4d
+
905b4d
+static errno_t check_use_fast(enum k5c_fast_opt *_fast_val)
905b4d
 {
905b4d
-    krb5_error_code kerr;
905b4d
     char *use_fast_str;
905b4d
+    enum k5c_fast_opt fast_val;
905b4d
+
905b4d
+    use_fast_str = getenv(SSSD_KRB5_USE_FAST);
905b4d
+    if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
905b4d
+        DEBUG(SSSDBG_CONF_SETTINGS, "Not using FAST.\n");
905b4d
+        fast_val = K5C_FAST_NEVER;
905b4d
+    } else if (strcasecmp(use_fast_str, "try") == 0) {
905b4d
+        fast_val = K5C_FAST_TRY;
905b4d
+    } else if (strcasecmp(use_fast_str, "demand") == 0) {
905b4d
+        fast_val = K5C_FAST_DEMAND;
905b4d
+    } else {
905b4d
+        DEBUG(SSSDBG_CRIT_FAILURE,
905b4d
+                "Unsupported value [%s] for krb5_use_fast.\n",
905b4d
+                use_fast_str);
905b4d
+        return EINVAL;
905b4d
+    }
905b4d
+
905b4d
+    *_fast_val = fast_val;
905b4d
+    return EOK;
905b4d
+}
905b4d
+
905b4d
+static int k5c_setup(struct krb5_req *kr, uint32_t offline)
905b4d
+{
905b4d
+    krb5_error_code kerr;
905b4d
     int parse_flags;
905b4d
+    enum k5c_fast_opt fast_val;
905b4d
+
905b4d
+    kerr = check_use_fast(&fast_val);
905b4d
+    if (kerr != EOK) {
905b4d
+        return kerr;
905b4d
+    }
905b4d
+
905b4d
+    if (offline || (fast_val == K5C_FAST_NEVER && kr->validate == false)) {
905b4d
+        /* If krb5_child was started as setuid, but we don't need to
905b4d
+         * perform either validation or FAST, just drop privileges to
905b4d
+         * the user who is logging in. The same applies to the offline case
905b4d
+         */
905b4d
+        kerr = become_user(kr->uid, kr->gid);
905b4d
+        if (kerr != 0) {
905b4d
+            DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
905b4d
+            return kerr;
905b4d
+        }
905b4d
+    }
905b4d
+    DEBUG(SSSDBG_TRACE_INTERNAL,
905b4d
+          "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
905b4d
 
905b4d
     kr->realm = getenv(SSSD_KRB5_REALM);
905b4d
     if (kr->realm == NULL) {
905b4d
@@ -1931,18 +1980,12 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
905b4d
     if (!offline) {
905b4d
         set_canonicalize_option(kr->options);
905b4d
 
905b4d
-        use_fast_str = getenv(SSSD_KRB5_USE_FAST);
905b4d
-        if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
905b4d
-            DEBUG(SSSDBG_CONF_SETTINGS, "Not using FAST.\n");
905b4d
-        } else if (strcasecmp(use_fast_str, "try") == 0) {
905b4d
-            kerr = k5c_setup_fast(kr, false);
905b4d
-        } else if (strcasecmp(use_fast_str, "demand") == 0) {
905b4d
-            kerr = k5c_setup_fast(kr, true);
905b4d
-        } else {
905b4d
-            DEBUG(SSSDBG_CRIT_FAILURE,
905b4d
-                  "Unsupported value [%s] for krb5_use_fast.\n",
905b4d
-                   use_fast_str);
905b4d
-            return EINVAL;
905b4d
+        if (fast_val != K5C_FAST_NEVER) {
905b4d
+            kerr = k5c_setup_fast(kr, fast_val == K5C_FAST_DEMAND);
905b4d
+            if (kerr != EOK) {
905b4d
+                DEBUG(SSSDBG_OP_FAILURE, "Cannot set up FAST\n");
905b4d
+                return kerr;
905b4d
+            }
905b4d
         }
905b4d
     }
905b4d
 
905b4d
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
905b4d
index 4ba939deb3e0e282b3ca9b2b21226ea7e64e311b..71c7f9c9f662e16b94afda0c8c0ae24666f0ba15 100644
905b4d
--- a/src/providers/krb5/krb5_child_handler.c
905b4d
+++ b/src/providers/krb5/krb5_child_handler.c
905b4d
@@ -284,14 +284,6 @@ static errno_t fork_child(struct tevent_req *req)
905b4d
     pid = fork();
905b4d
 
905b4d
     if (pid == 0) { /* child */
905b4d
-        if (state->kr->run_as_user) {
905b4d
-            ret = become_user(state->kr->uid, state->kr->gid);
905b4d
-            if (ret != EOK) {
905b4d
-                DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
905b4d
-                return ret;
905b4d
-            }
905b4d
-        }
905b4d
-
905b4d
         err = exec_child(state,
905b4d
                          pipefd_to_child, pipefd_from_child,
905b4d
                          KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd);
905b4d
-- 
905b4d
1.9.3
905b4d