|
|
836b22 |
From a61b80d7f10bbdfaa10fde1f868c9fb4b7abe62f Mon Sep 17 00:00:00 2001
|
|
|
836b22 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
836b22 |
Date: Mon, 10 Dec 2018 17:44:13 +0100
|
|
|
836b22 |
Subject: [PATCH] krb5_child: fix permissions during SC auth
|
|
|
836b22 |
MIME-Version: 1.0
|
|
|
836b22 |
Content-Type: text/plain; charset=UTF-8
|
|
|
836b22 |
Content-Transfer-Encoding: 8bit
|
|
|
836b22 |
|
|
|
836b22 |
For PKINIT we might need access to the pcscd socket which by default is
|
|
|
836b22 |
only allowed for authenticated users. Since PKINIT is part of the
|
|
|
836b22 |
authentication and the user is not authenticated yet, we have to use
|
|
|
836b22 |
different privileges and can only drop it only after the TGT is
|
|
|
836b22 |
received. The fast_uid and fast_gid are the IDs the backend is running
|
|
|
836b22 |
with. This can be either root or the 'sssd' user. Root is allowed by
|
|
|
836b22 |
default and the 'sssd' user is allowed with the help of the
|
|
|
836b22 |
sssd-pcsc.rules policy-kit rule. So those IDs are a suitable choice. We
|
|
|
836b22 |
can only call switch_creds() because after the TGT is returned we have
|
|
|
836b22 |
to switch to the IDs of the user to store the TGT.
|
|
|
836b22 |
|
|
|
836b22 |
The final change to the IDs of the user is not only important for KCM
|
|
|
836b22 |
type credential caches but for file based ccache types like FILE or DIR
|
|
|
836b22 |
as well.
|
|
|
836b22 |
|
|
|
836b22 |
Related to https://pagure.io/SSSD/sssd/issue/3903
|
|
|
836b22 |
|
|
|
836b22 |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
836b22 |
(cherry picked from commit e49e9f727e4960c8a0a2ed50488dac6e51ddf284)
|
|
|
836b22 |
|
|
|
836b22 |
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
|
|
836b22 |
---
|
|
|
836b22 |
src/providers/krb5/krb5_child.c | 64 ++++++++++++++++++++-------------
|
|
|
836b22 |
1 file changed, 39 insertions(+), 25 deletions(-)
|
|
|
836b22 |
|
|
|
836b22 |
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
|
|
|
836b22 |
index a86d9a7ae..ae63b14d1 100644
|
|
|
836b22 |
--- a/src/providers/krb5/krb5_child.c
|
|
|
836b22 |
+++ b/src/providers/krb5/krb5_child.c
|
|
|
836b22 |
@@ -108,6 +108,7 @@ struct krb5_req {
|
|
|
836b22 |
|
|
|
836b22 |
uid_t fast_uid;
|
|
|
836b22 |
gid_t fast_gid;
|
|
|
836b22 |
+ struct sss_creds *pcsc_saved_creds;
|
|
|
836b22 |
|
|
|
836b22 |
struct cli_opts *cli_opts;
|
|
|
836b22 |
};
|
|
|
836b22 |
@@ -1755,6 +1756,22 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
|
|
|
836b22 |
goto done;
|
|
|
836b22 |
}
|
|
|
836b22 |
|
|
|
836b22 |
+ kerr = restore_creds(kr->pcsc_saved_creds);
|
|
|
836b22 |
+ if (kerr != 0) {
|
|
|
836b22 |
+ DEBUG(SSSDBG_OP_FAILURE, "restore_creds failed.\n");
|
|
|
836b22 |
+ }
|
|
|
836b22 |
+ /* Make sure ccache is created and written as the user */
|
|
|
836b22 |
+ if (geteuid() != kr->uid || getegid() != kr->gid) {
|
|
|
836b22 |
+ kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain);
|
|
|
836b22 |
+ if (kerr != 0) {
|
|
|
836b22 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
|
|
|
836b22 |
+ goto done;
|
|
|
836b22 |
+ }
|
|
|
836b22 |
+ }
|
|
|
836b22 |
+
|
|
|
836b22 |
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
836b22 |
+ "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
|
|
|
836b22 |
+
|
|
|
836b22 |
/* If kr->ccname is cache collection (DIR:/...), we want to work
|
|
|
836b22 |
* directly with file ccache (DIR::/...), but cache collection
|
|
|
836b22 |
* should be returned back to back end.
|
|
|
836b22 |
@@ -3011,20 +3028,6 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
|
|
|
836b22 |
krb5_error_code kerr;
|
|
|
836b22 |
int parse_flags;
|
|
|
836b22 |
|
|
|
836b22 |
- if (offline || (kr->fast_val == K5C_FAST_NEVER && kr->validate == false)) {
|
|
|
836b22 |
- /* If krb5_child was started as setuid, but we don't need to
|
|
|
836b22 |
- * perform either validation or FAST, just drop privileges to
|
|
|
836b22 |
- * the user who is logging in. The same applies to the offline case.
|
|
|
836b22 |
- */
|
|
|
836b22 |
- kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain);
|
|
|
836b22 |
- if (kerr != 0) {
|
|
|
836b22 |
- DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
|
|
|
836b22 |
- return kerr;
|
|
|
836b22 |
- }
|
|
|
836b22 |
- }
|
|
|
836b22 |
- DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
836b22 |
- "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
|
|
|
836b22 |
-
|
|
|
836b22 |
/* Set the global error context */
|
|
|
836b22 |
krb5_error_ctx = kr->ctx;
|
|
|
836b22 |
|
|
|
836b22 |
@@ -3218,8 +3221,8 @@ int main(int argc, const char *argv[])
|
|
|
836b22 |
const char *opt_logger = NULL;
|
|
|
836b22 |
errno_t ret;
|
|
|
836b22 |
krb5_error_code kerr;
|
|
|
836b22 |
- uid_t fast_uid;
|
|
|
836b22 |
- gid_t fast_gid;
|
|
|
836b22 |
+ uid_t fast_uid = 0;
|
|
|
836b22 |
+ gid_t fast_gid = 0;
|
|
|
836b22 |
struct cli_opts cli_opts = { 0 };
|
|
|
836b22 |
int sss_creds_password = 0;
|
|
|
836b22 |
|
|
|
836b22 |
@@ -3333,20 +3336,31 @@ int main(int argc, const char *argv[])
|
|
|
836b22 |
goto done;
|
|
|
836b22 |
}
|
|
|
836b22 |
|
|
|
836b22 |
- /* pkinit needs access to pcscd */
|
|
|
836b22 |
- if ((sss_authtok_get_type(kr->pd->authtok) != SSS_AUTHTOK_TYPE_SC_PIN
|
|
|
836b22 |
- && sss_authtok_get_type(kr->pd->authtok)
|
|
|
836b22 |
- != SSS_AUTHTOK_TYPE_SC_KEYPAD)) {
|
|
|
836b22 |
+ /* For PKINIT we might need access to the pcscd socket which by default
|
|
|
836b22 |
+ * is only allowed for authenticated users. Since PKINIT is part of
|
|
|
836b22 |
+ * the authentication and the user is not authenticated yet, we have
|
|
|
836b22 |
+ * to use different privileges and can only drop it only after the TGT is
|
|
|
836b22 |
+ * received. The fast_uid and fast_gid are the IDs the backend is running
|
|
|
836b22 |
+ * with. This can be either root or the 'sssd' user. Root is allowed by
|
|
|
836b22 |
+ * default and the 'sssd' user is allowed with the help of the
|
|
|
836b22 |
+ * sssd-pcsc.rules policy-kit rule. So those IDs are a suitable choice. We
|
|
|
836b22 |
+ * can only call switch_creds() because after the TGT is returned we have
|
|
|
836b22 |
+ * to switch to the IDs of the user to store the TGT. */
|
|
|
836b22 |
+ if (IS_SC_AUTHTOK(kr->pd->authtok)) {
|
|
|
836b22 |
+ kerr = switch_creds(kr, kr->fast_uid, kr->fast_gid, 0, NULL,
|
|
|
836b22 |
+ &kr->pcsc_saved_creds);
|
|
|
836b22 |
+ } else {
|
|
|
836b22 |
kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain);
|
|
|
836b22 |
- if (kerr != 0) {
|
|
|
836b22 |
- DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
|
|
|
836b22 |
- ret = EFAULT;
|
|
|
836b22 |
- goto done;
|
|
|
836b22 |
- }
|
|
|
836b22 |
+ }
|
|
|
836b22 |
+ if (kerr != 0) {
|
|
|
836b22 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
|
|
|
836b22 |
+ ret = EFAULT;
|
|
|
836b22 |
+ goto done;
|
|
|
836b22 |
}
|
|
|
836b22 |
|
|
|
836b22 |
DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
836b22 |
"Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
|
|
|
836b22 |
+
|
|
|
836b22 |
try_open_krb5_conf();
|
|
|
836b22 |
|
|
|
836b22 |
ret = k5c_setup(kr, offline);
|
|
|
836b22 |
--
|
|
|
836b22 |
2.21.1
|
|
|
836b22 |
|