>From d6ba404928fcab035b5f0d21333dd9c90a7300a6 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Wed, 3 Apr 2013 21:04:49 +0200 Subject: [PATCH] Fix krbcc dir creation issue with MIT krb5 1.11 In krb5-libs 1.11, function krb5_cc_resolve verify if credential cache dir exists. If it doesn't exist, than it will be created. We have to ensure, that it will be created with right uid, gid and permissions. There is check in krb_auth_send, whether cached user data in ldb contains SYSDB_CCACHE_FILE attribute. If it is available, then old ccache is checked in function check_old_ccache. Gdm clean user directory (in /run/user/) after logout. This is the reason why SYSDB_CCACHE_FILE attribute was found in ldb cache and directory did not exist and then in function krb5_cc_resolve was created with wrong permissions. https://fedorahosted.org/sssd/ticket/1822 --- src/providers/krb5/krb5_auth.c | 4 +-- src/providers/krb5/krb5_utils.c | 67 ++++++++++++++++++++++++++++++++++++++--- src/providers/krb5/krb5_utils.h | 3 +- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 00025bfc156eaf641217194c6301f4d70a773a73..b96620c5f66956742fd3be26a016f9d2c3275c17 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -104,8 +104,8 @@ check_old_ccache(const char *old_ccache, struct krb5child_req *kr, cc_template = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL); - ret = old_cc_ops->check_existing(old_ccache, kr->uid, realm, kr->upn, - cc_template, active, valid); + ret = old_cc_ops->check_existing(old_ccache, kr->uid, kr->gid, realm, + kr->upn, cc_template, active, valid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Cannot check if saved ccache %s is active and valid\n", diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c index ad77c7cc8305a98cc263cd7c6222979f361d0155..bfc1dde804a39aa88439b94c6ffbabc659c0dde1 100644 --- a/src/providers/krb5/krb5_utils.c +++ b/src/providers/krb5/krb5_utils.c @@ -843,8 +843,29 @@ cc_check_template(const char *cc_template) } } -errno_t -cc_file_check_existing(const char *location, uid_t uid, +static errno_t +sss_set_uid_and_gid(uid_t uid, gid_t gid){ + int ret; + + ret = setegid(gid); + if (0 > ret) { + ret = errno; + DEBUG(SSSDBG_MINOR_FAILURE, ("Could not set gid:%d, [%s]", + gid, strerror(ret))); + } + + ret = seteuid(uid); + if (0 > ret) { + ret = errno; + DEBUG(SSSDBG_MINOR_FAILURE, ("Could not set uid:%d, [%s]", + uid, strerror(errno))); + } + + return ret; +} + +static errno_t +cc_file_check_existing(const char *location, uid_t uid, gid_t gid, const char *realm, const char *princ, const char *cc_template, bool *_active, bool *_valid) { @@ -855,6 +876,9 @@ cc_file_check_existing(const char *location, uid_t uid, krb5_ccache ccache = NULL; krb5_context context = NULL; krb5_error_code kerr; + mode_t old_umask; + uid_t process_uid = getuid(); + gid_t process_gid = getgid(); filename = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_FILE); if (!filename) { @@ -881,6 +905,13 @@ cc_file_check_existing(const char *location, uid_t uid, return EIO; } + ret = sss_set_uid_and_gid(uid, gid); + if (ret != 0) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set user uid:%d and gid:%d\n", + uid, gid)); + } + old_umask = umask(~S_IRWXU); + kerr = krb5_cc_resolve(context, location, &ccache); if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, context, kerr); @@ -889,6 +920,15 @@ cc_file_check_existing(const char *location, uid_t uid, return EIO; } + ret = sss_set_uid_and_gid(process_uid, process_gid); + if (ret != 0) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Could not restore back uid:%d and gid:%d\n", + process_uid, process_gid)); + return ret; + } + umask(old_umask); + kerr = check_for_valid_tgt(context, ccache, realm, princ, &valid); krb5_free_context(context); krb5_cc_close(context, ccache); @@ -992,8 +1032,8 @@ get_ccache_for_princ(krb5_context context, const char *location, return krberr; } -errno_t -cc_dir_check_existing(const char *location, uid_t uid, +static errno_t +cc_dir_check_existing(const char *location, uid_t uid, gid_t gid, const char *realm, const char *princ, const char *cc_template, bool *_active, bool *_valid) { @@ -1007,6 +1047,9 @@ cc_dir_check_existing(const char *location, uid_t uid, const char *dir; char *tmp; errno_t ret; + mode_t old_umask; + uid_t process_uid = getuid(); + gid_t process_gid = getgid(); type = sss_krb5_get_type(location); if (type != SSS_KRB5_TYPE_DIR) { @@ -1052,6 +1095,13 @@ cc_dir_check_existing(const char *location, uid_t uid, return EIO; } + ret = sss_set_uid_and_gid(uid, gid); + if (ret != 0) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set user uid:%d and gid:%d\n", + uid, gid)); + } + old_umask = umask(~S_IRWXU); + krberr = krb5_cc_resolve(context, location, &ccache); if (krberr == KRB5_FCC_NOFILE || ccache == NULL) { /* KRB5_FCC_NOFILE would be returned if the directory components @@ -1070,6 +1120,15 @@ cc_dir_check_existing(const char *location, uid_t uid, goto done; } + ret = sss_set_uid_and_gid(process_uid, process_gid); + if (ret != 0) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Could not restore back uid:%d and gid:%d\n", + process_uid, process_gid)); + return ret; + } + umask(old_umask); + krberr = check_for_valid_tgt(context, ccache, realm, princ, &valid); if (krberr != EOK) { KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr); diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h index aad2770d4d3beb28c3ccb06278ee4cfc88562c85..bc658591ad41d116a4e706bf850d7bb4d43c8e46 100644 --- a/src/providers/krb5/krb5_utils.h +++ b/src/providers/krb5/krb5_utils.h @@ -45,7 +45,8 @@ errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb, /* Operations on a credential cache */ typedef errno_t (*cc_be_create_fn)(const char *location, pcre *illegal_re, uid_t uid, gid_t gid, bool private_path); -typedef errno_t (*cc_be_check_existing)(const char *location, uid_t uid, +typedef errno_t (*cc_be_check_existing)(const char *location, + uid_t uid, gid_t gid, const char *realm, const char *princ, const char *cc_template, bool *active, bool *valid); -- 1.8.1.4