|
|
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 |
|