From a70e88f62e8ba48c5042b881f20ed6586cb135a8 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 28 Aug 2013 23:18:37 -0400 Subject: krb5: Use krb5_cc_destroy to remove old ccaches This completely replaces the per-ccache-type custom code to remove old cacches and instead uses libkrb5 base doperations (krb5_cc_destroy) and operating as the user owner. Resolves: https://fedorahosted.org/sssd/ticket/2061 --- Makefile.am | 2 ++ src/providers/krb5/krb5_auth.c | 63 +++++++++++------------------------- src/providers/krb5/krb5_utils.c | 71 ----------------------------------------- src/providers/krb5/krb5_utils.h | 2 -- src/tests/krb5_child-test.c | 2 +- 5 files changed, 21 insertions(+), 119 deletions(-) diff --git a/Makefile.am b/Makefile.am index 150f53e72..25a4cbf83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -962,6 +962,7 @@ strtonum_tests_LDADD = \ krb5_utils_tests_SOURCES = \ src/tests/krb5_utils-tests.c \ src/providers/krb5/krb5_utils.c \ + src/providers/krb5/krb5_become_user.c \ src/providers/krb5/krb5_common.c \ src/util/sss_krb5.c \ src/util/find_uid.c \ @@ -1532,6 +1533,7 @@ libsss_ldap_la_SOURCES = \ src/providers/ldap/ldap_access.c \ src/providers/krb5/krb5_common.c \ src/providers/krb5/krb5_utils.c \ + src/providers/krb5/krb5_become_user.c \ src/util/user_info_msg.c \ src/util/sss_ldap.c \ src/util/sss_krb5.c diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index db0aa936f..5d33dddb6 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -40,48 +40,19 @@ #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_utils.h" -static errno_t safe_remove_old_ccache_file(struct sss_krb5_cc_be *cc_be, - const char *princ, - const char *old_ccache, - const char *new_ccache) +static errno_t safe_remove_old_ccache_file(const char *old_ccache, + const char *new_ccache, + uid_t uid, gid_t gid) { - int ret; - enum sss_krb5_cc_type old_type; - struct sss_krb5_cc_be *old_cc_ops; - - if (old_ccache == NULL) { - DEBUG(SSSDBG_FUNC_DATA, ("No old ccache, nothing to do\n")); - return EOK; - } - - if (new_ccache == NULL) { - DEBUG(SSSDBG_OP_FAILURE, - ("Missing new ccache file, old ccache file is not deleted.\n")); - return EINVAL; - } - - old_type = sss_krb5_get_type(old_ccache); - old_cc_ops = get_cc_be_ops(old_type); - if (!old_cc_ops) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot get ccache operations\n")); - return EINVAL; - } - - if (cc_be->type == old_type && - strcmp(old_ccache, new_ccache) == 0) { + if ((old_ccache == new_ccache) + || (old_ccache && new_ccache + && (strcmp(old_ccache, new_ccache) == 0))) { DEBUG(SSSDBG_TRACE_FUNC, ("New and old ccache file are the same, " - "no one will be deleted.\n")); + "none will be deleted.\n")); return EOK; } - ret = old_cc_ops->remove(old_ccache); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - ("Cannot remove ccache [%s]\n", old_ccache)); - return EIO; - } - - return EOK; + return sss_krb5_cc_destroy(old_ccache, uid, gid); } static errno_t @@ -1037,8 +1008,8 @@ static void krb5_auth_done(struct tevent_req *subreq) * used. */ if (pd->cmd == SSS_PAM_AUTHENTICATE && !kr->active_ccache) { if (kr->old_ccname != NULL) { - ret = safe_remove_old_ccache_file(kr->cc_be, kr->upn, - kr->old_ccname, "dummy"); + ret = safe_remove_old_ccache_file(kr->old_ccname, NULL, + kr->uid, kr->gid); if (ret != EOK) { DEBUG(1, ("Failed to remove old ccache file [%s], " "please remove it manually.\n", kr->old_ccname)); @@ -1114,12 +1085,14 @@ static void krb5_auth_done(struct tevent_req *subreq) goto done; } - ret = safe_remove_old_ccache_file(kr->cc_be, kr->upn, - kr->old_ccname, store_ccname); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, - ("Failed to remove old ccache file [%s], " - "please remove it manually.\n", kr->old_ccname)); + if (kr->old_ccname) { + ret = safe_remove_old_ccache_file(kr->old_ccname, store_ccname, + kr->uid, kr->gid); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Failed to remove old ccache file [%s], " + "please remove it manually.\n", kr->old_ccname)); + } } ret = krb5_save_ccname(state, state->sysdb, state->domain, diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c index 1141f3fc8..0245cc9d0 100644 --- a/src/providers/krb5/krb5_utils.c +++ b/src/providers/krb5/krb5_utils.c @@ -1120,42 +1120,11 @@ cc_file_cache_for_princ(TALLOC_CTX *mem_ctx, const char *location, return talloc_strdup(mem_ctx, location); } -errno_t -cc_file_remove(const char *location) -{ - errno_t ret; - const char *filename; - - filename = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_FILE); - if (!filename) { - DEBUG(SSSDBG_CRIT_FAILURE, ("%s is not of type FILE:\n", location)); - return EINVAL; - } - - if (filename[0] != '/') { - DEBUG(SSSDBG_CRIT_FAILURE, - ("Ccache file name [%s] is not an absolute path.\n", filename)); - return EINVAL; - } - - errno = 0; - ret = unlink(filename); - if (ret == -1 && errno != ENOENT) { - ret = errno; - DEBUG(SSSDBG_CRIT_FAILURE, - ("unlink [%s] failed [%d][%s].\n", filename, ret, - strerror(ret))); - return ret; - } - return EOK; -} - struct sss_krb5_cc_be file_cc = { .type = SSS_KRB5_TYPE_FILE, .create = cc_file_create, .check_existing = cc_file_check_existing, .ccache_for_princ = cc_file_cache_for_princ, - .remove = cc_file_remove, }; #ifdef HAVE_KRB5_CC_COLLECTION @@ -1333,32 +1302,11 @@ done: return name; } -errno_t -cc_dir_remove(const char *location) -{ - const char *subsidiary; - - if (sss_krb5_get_type(location) != SSS_KRB5_TYPE_DIR) { - DEBUG(SSSDBG_CRIT_FAILURE, ("%s is not of type DIR\n", location)); - return EINVAL; - } - - subsidiary = sss_krb5_cc_file_path(location); - if (!subsidiary) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot get subsidiary cache from %s\n", - location)); - return EINVAL; - } - - return cc_file_remove(subsidiary); -} - struct sss_krb5_cc_be dir_cc = { .type = SSS_KRB5_TYPE_DIR, .create = cc_dir_create, .check_existing = cc_dir_check_existing, .ccache_for_princ = cc_dir_cache_for_princ, - .remove = cc_dir_remove }; @@ -1485,30 +1433,11 @@ done: return name; } -errno_t -cc_keyring_remove(const char *location) -{ - const char *residual; - - residual = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_KEYRING); - if (!residual) { - DEBUG(SSSDBG_CRIT_FAILURE, - ("%s is not of type KEYRING:\n", location)); - return EINVAL; - } - - /* No special steps are needed to create a kernel keyring. - * Everything is handled in libkrb5. - */ - return EOK; -} - struct sss_krb5_cc_be keyring_cc = { .type = SSS_KRB5_TYPE_KEYRING, .create = cc_keyring_create, .check_existing = cc_keyring_check_existing, .ccache_for_princ = cc_keyring_cache_for_princ, - .remove = cc_keyring_remove }; #endif /* HAVE_KRB5_CC_COLLECTION */ diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h index ebcfe938a..ac29d61e9 100644 --- a/src/providers/krb5/krb5_utils.h +++ b/src/providers/krb5/krb5_utils.h @@ -52,7 +52,6 @@ typedef errno_t (*cc_be_check_existing)(const char *location, uid_t uid, typedef const char * (*cc_be_ccache_for_princ)(TALLOC_CTX *mem_ctx, const char *location, const char *princ); -typedef errno_t (*cc_be_remove)(const char *location); /* A ccache back end */ struct sss_krb5_cc_be { @@ -61,7 +60,6 @@ struct sss_krb5_cc_be { cc_be_create_fn create; cc_be_check_existing check_existing; cc_be_ccache_for_princ ccache_for_princ; - cc_be_remove remove; }; extern struct sss_krb5_cc_be file_cc; diff --git a/src/tests/krb5_child-test.c b/src/tests/krb5_child-test.c index 24d077289..dff62ab64 100644 --- a/src/tests/krb5_child-test.c +++ b/src/tests/krb5_child-test.c @@ -561,7 +561,7 @@ done: if (rm_ccache && ctx->res && ctx->res->ccname && ctx->kr) { - ctx->kr->krb5_ctx->cc_be->remove(ctx->res->ccname); + sss_krb5_cc_destroy(ctx->res->ccname, ctx->kr->uid, ctx->kr->gid); } free(password); talloc_free(ctx); -- cgit