summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-10-13 21:13:38 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-30 16:36:50 +0100
commit54ddaca98815177a5185e929c3ffe007c977be35 (patch)
treea297536c8b0caa0e82c0f669e15fe4887f4a944c
parent25a2d146599efde8f155cf8edf169bf852c58b0e (diff)
downloadsssd-54ddaca98815177a5185e929c3ffe007c977be35.tar.gz
sssd-54ddaca98815177a5185e929c3ffe007c977be35.tar.xz
sssd-54ddaca98815177a5185e929c3ffe007c977be35.zip
KRB5: Drop privileges in the child, not the back end
In future patches, sssd_be will be running as a non-privileged user, who will execute the setuid krb5_child. In this case, the child will start as root and drop the privileges as soon as possible. However, we need to also remove the privilege drop in sssd_be, because if we dropped to the user who is authenticating, we wouldn't be even allowed to execute krb5_child. The krb5_child permissions should be 4750, owned by root.sssd, to make sure only root and sssd can execute the child and if executed by sssd, the child will run as root.
-rw-r--r--src/providers/krb5/krb5_child.c55
-rw-r--r--src/providers/krb5/krb5_child_handler.c8
2 files changed, 43 insertions, 20 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 3234a4e6c..1c657de2d 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1840,11 +1840,52 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand)
return EOK;
}
+static errno_t check_use_fast(bool *_fast)
+{
+ char *use_fast_str;
+ bool fast = false;
+
+ use_fast_str = getenv(SSSD_KRB5_USE_FAST);
+ if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Not using FAST.\n");
+ } else if (strcasecmp(use_fast_str, "try") == 0 ||
+ strcasecmp(use_fast_str, "demand") == 0) {
+ fast = true;
+ } else {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Unsupported value [%s] for krb5_use_fast.\n",
+ use_fast_str);
+ return EINVAL;
+ }
+
+ *_fast = fast;
+ return EOK;
+}
+
static int k5c_setup(struct krb5_req *kr, uint32_t offline)
{
krb5_error_code kerr;
- char *use_fast_str;
int parse_flags;
+ bool use_fast;
+
+ kerr = check_use_fast(&use_fast);
+ if (kerr != EOK) {
+ return kerr;
+ }
+
+ if (offline || (use_fast == false && kr->validate == false)) {
+ /* If krb5_child was started as setuid, but we don't need to
+ * perform either validation or FAST, just drop privileges to
+ * the SSSD user. The same applies to the offline case
+ */
+ kerr = become_user(kr->uid, kr->gid);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
+ return kerr;
+ }
+ }
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
kr->realm = getenv(SSSD_KRB5_REALM);
if (kr->realm == NULL) {
@@ -1931,18 +1972,8 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
if (!offline) {
set_canonicalize_option(kr->options);
- use_fast_str = getenv(SSSD_KRB5_USE_FAST);
- if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
- DEBUG(SSSDBG_CONF_SETTINGS, "Not using FAST.\n");
- } else if (strcasecmp(use_fast_str, "try") == 0) {
+ if (use_fast) {
kerr = k5c_setup_fast(kr, false);
- } else if (strcasecmp(use_fast_str, "demand") == 0) {
- kerr = k5c_setup_fast(kr, true);
- } else {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Unsupported value [%s] for krb5_use_fast.\n",
- use_fast_str);
- return EINVAL;
}
}
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
index 4ba939deb..71c7f9c9f 100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -284,14 +284,6 @@ static errno_t fork_child(struct tevent_req *req)
pid = fork();
if (pid == 0) { /* child */
- if (state->kr->run_as_user) {
- ret = become_user(state->kr->uid, state->kr->gid);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
- return ret;
- }
- }
-
err = exec_child(state,
pipefd_to_child, pipefd_from_child,
KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd);