Backport simplification of ccache management from 1.11.1
- Resolves: rhbz#1010553 - sssd setting KRB5CCNAME=(null) on login
This commit is contained in:
parent
c5481c88cf
commit
8d72fcd900
168
0001-krb5-Add-calls-to-change-and-restore-credentials.patch
Normal file
168
0001-krb5-Add-calls-to-change-and-restore-credentials.patch
Normal file
@ -0,0 +1,168 @@
|
||||
From 0371fbcf60d4dd8e25b9bb0a83029c812b66f3d6 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Wed, 28 Aug 2013 21:19:32 -0400
|
||||
Subject: [PATCH 01/14] krb5: Add calls to change and restore credentials
|
||||
|
||||
In some cases we want to temporarily assume user credentials but allow the
|
||||
process to regain back the original credentials (normally regaining uid 0).
|
||||
|
||||
Related:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_become_user.c | 125 ++++++++++++++++++++++++++++++++++
|
||||
src/providers/krb5/krb5_utils.h | 6 ++
|
||||
2 files changed, 131 insertions(+)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_become_user.c b/src/providers/krb5/krb5_become_user.c
|
||||
index 70bc5630ece21505b58bd1a8795d7ab4b7864460..567cf237569f70a6b0fd500327438f2dbb08d24d 100644
|
||||
--- a/src/providers/krb5/krb5_become_user.c
|
||||
+++ b/src/providers/krb5/krb5_become_user.c
|
||||
@@ -70,3 +70,128 @@ errno_t become_user(uid_t uid, gid_t gid)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+struct sss_creds {
|
||||
+ uid_t uid;
|
||||
+ gid_t gid;
|
||||
+ int num_gids;
|
||||
+ gid_t gids[];
|
||||
+};
|
||||
+
|
||||
+errno_t restore_creds(struct sss_creds *saved_creds);
|
||||
+
|
||||
+/* This is a reversible version of become_user, and returns the saved
|
||||
+ * credentials so that creds can be switched back calling restore_creds */
|
||||
+errno_t switch_creds(TALLOC_CTX *mem_ctx,
|
||||
+ uid_t uid, gid_t gid,
|
||||
+ int num_gids, gid_t *gids,
|
||||
+ struct sss_creds **saved_creds)
|
||||
+{
|
||||
+ struct sss_creds *ssc = NULL;
|
||||
+ int size;
|
||||
+ int ret;
|
||||
+
|
||||
+ DEBUG(SSSDBG_FUNC_DATA, ("Switch user to [%d][%d].\n", uid, gid));
|
||||
+
|
||||
+ if (saved_creds) {
|
||||
+ /* save current user credentials */
|
||||
+ size = getgroups(0, NULL);
|
||||
+ if (size == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Getgroups failed! (%d, %s)\n",
|
||||
+ ret, strerror(ret)));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ssc = talloc_size(mem_ctx,
|
||||
+ (sizeof(struct sss_creds) + size * sizeof(gid_t)));
|
||||
+ if (!ssc) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Allocation failed!\n"));
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ ssc->num_gids = size;
|
||||
+
|
||||
+ size = getgroups(ssc->num_gids, ssc->gids);
|
||||
+ if (size == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Getgroups failed! (%d, %s)\n",
|
||||
+ ret, strerror(ret)));
|
||||
+ /* free ssc immediately otherwise the code will try to restore
|
||||
+ * wrong creds */
|
||||
+ talloc_zfree(ssc);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* we care only about effective ids */
|
||||
+ ssc->uid = geteuid();
|
||||
+ ssc->gid = getegid();
|
||||
+ }
|
||||
+
|
||||
+ /* if we are regaining root set euid first so that we have CAP_SETUID back,
|
||||
+ * ane the other calls work too, otherwise call it last so that we can
|
||||
+ * change groups before we loose CAP_SETUID */
|
||||
+ if (uid == 0) {
|
||||
+ ret = setresuid(0, 0, 0);
|
||||
+ if (ret == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ ("setresuid failed [%d][%s].\n", ret, strerror(ret)));
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* TODO: use prctl to get/set capabilities too ? */
|
||||
+
|
||||
+ /* try to setgroups first should always work if CAP_SETUID is set,
|
||||
+ * otherwise it will always fail, failure is not critical though as
|
||||
+ * generally we only really care about uid and at mot primary gid */
|
||||
+ ret = setgroups(num_gids, gids);
|
||||
+ if (ret == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ ("setgroups failed [%d][%s].\n", ret, strerror(ret)));
|
||||
+ }
|
||||
+
|
||||
+ /* change gid now, (leaves saved gid to current, so we can restore) */
|
||||
+ ret = setresgid(-1, gid, -1);
|
||||
+ if (ret == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ ("setresgid failed [%d][%s].\n", ret, strerror(ret)));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (uid != 0) {
|
||||
+ /* change uid, (leaves saved uid to current, so we can restore) */
|
||||
+ ret = setresuid(-1, uid, -1);
|
||||
+ if (ret == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ ("setresuid failed [%d][%s].\n", ret, strerror(ret)));
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+
|
||||
+done:
|
||||
+ if (ret) {
|
||||
+ if (ssc) {
|
||||
+ /* attempt to restore creds first */
|
||||
+ restore_creds(ssc);
|
||||
+ talloc_free(ssc);
|
||||
+ }
|
||||
+ } else if (saved_creds) {
|
||||
+ *saved_creds = ssc;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t restore_creds(struct sss_creds *saved_creds)
|
||||
+{
|
||||
+ return switch_creds(saved_creds,
|
||||
+ saved_creds->uid,
|
||||
+ saved_creds->gid,
|
||||
+ saved_creds->num_gids,
|
||||
+ saved_creds->gids, NULL);
|
||||
+}
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index cdc9f23641905cff300077f708087e98ba683e0d..aac3ec72ec7e1664ae96cc4e53d368e22448f5f1 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -80,6 +80,12 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
|
||||
bool case_sensitive, bool *private_path);
|
||||
|
||||
errno_t become_user(uid_t uid, gid_t gid);
|
||||
+struct sss_creds;
|
||||
+errno_t switch_creds(TALLOC_CTX *mem_ctx,
|
||||
+ uid_t uid, gid_t gid,
|
||||
+ int num_gids, gid_t *gids,
|
||||
+ struct sss_creds **saved_creds);
|
||||
+errno_t restore_creds(struct sss_creds *saved_creds);
|
||||
|
||||
errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
||||
struct tgt_times *tgtt);
|
||||
--
|
||||
1.8.3.1
|
||||
|
154
0002-krb5-Add-helper-to-destroy-ccache-as-user.patch
Normal file
154
0002-krb5-Add-helper-to-destroy-ccache-as-user.patch
Normal file
@ -0,0 +1,154 @@
|
||||
From 04c49a183f49c28f9ef900bdbc4eb30f23278e17 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Wed, 28 Aug 2013 22:12:07 -0400
|
||||
Subject: [PATCH 02/14] krb5: Add helper to destroy ccache as user
|
||||
|
||||
This function safely destroy a ccache given a cache name and user crdentials.
|
||||
It becomes the user so no possible races can compromise the system, then
|
||||
uses libkrb5 functions to properly destroy a ccache, independently of the
|
||||
cache type.
|
||||
Finally restores the original credentials after closing the ccache handlers.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_utils.c | 109 ++++++++++++++++++++++++++++++++++++++++
|
||||
src/providers/krb5/krb5_utils.h | 2 +
|
||||
2 files changed, 111 insertions(+)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index 6bf1cf610dd20afc7a600e9505c4bae2ff675fcc..1141f3fc839a78927dab5f50267c52d5b44b46ba 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -818,6 +818,115 @@ done:
|
||||
}
|
||||
|
||||
|
||||
+struct sss_krb5_ccache {
|
||||
+ struct sss_creds *creds;
|
||||
+ krb5_context context;
|
||||
+ krb5_ccache ccache;
|
||||
+};
|
||||
+
|
||||
+static int sss_free_krb5_ccache(void *mem)
|
||||
+{
|
||||
+ struct sss_krb5_ccache *cc = talloc_get_type(mem, struct sss_krb5_ccache);
|
||||
+
|
||||
+ if (cc->ccache) {
|
||||
+ krb5_cc_close(cc->context, cc->ccache);
|
||||
+ }
|
||||
+ krb5_free_context(cc->context);
|
||||
+ restore_creds(cc->creds);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static errno_t sss_open_ccache_as_user(TALLOC_CTX *mem_ctx,
|
||||
+ const char *ccname,
|
||||
+ uid_t uid, gid_t gid,
|
||||
+ struct sss_krb5_ccache **ccache)
|
||||
+{
|
||||
+ struct sss_krb5_ccache *cc;
|
||||
+ krb5_error_code kerr;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ cc = talloc_zero(mem_ctx, struct sss_krb5_ccache);
|
||||
+ if (!cc) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+ talloc_set_destructor((TALLOC_CTX *)cc, sss_free_krb5_ccache);
|
||||
+
|
||||
+ ret = switch_creds(cc, uid, gid, 0, NULL, &cc->creds);
|
||||
+ if (ret) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kerr = krb5_init_context(&cc->context);
|
||||
+ if (kerr) {
|
||||
+ ret = EIO;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kerr = krb5_cc_resolve(cc->context, ccname, &cc->ccache);
|
||||
+ if (kerr == KRB5_FCC_NOFILE || cc->ccache == NULL) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, ("ccache %s is missing or empty\n", ccname));
|
||||
+ ret = ERR_NOT_FOUND;
|
||||
+ goto done;
|
||||
+ } else if (kerr != 0) {
|
||||
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
|
||||
+ ret = ERR_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret) {
|
||||
+ talloc_free(cc);
|
||||
+ } else {
|
||||
+ *ccache = cc;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static errno_t sss_destroy_ccache(struct sss_krb5_ccache *cc)
|
||||
+{
|
||||
+ krb5_error_code kerr;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ kerr = krb5_cc_destroy(cc->context, cc->ccache);
|
||||
+ if (kerr) {
|
||||
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_destroy failed.\n"));
|
||||
+ ret = EIO;
|
||||
+ }
|
||||
+
|
||||
+ /* krb5_cc_destroy frees cc->ccache in all events */
|
||||
+ cc->ccache = NULL;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid)
|
||||
+{
|
||||
+ struct sss_krb5_ccache *cc = NULL;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
|
||||
+ if (ret) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_destroy_ccache(cc);
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
|
||||
/*======== ccache back end utilities ========*/
|
||||
struct sss_krb5_cc_be *
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index aac3ec72ec7e1664ae96cc4e53d368e22448f5f1..ebcfe938af913f107b8816c3209b690ac90e797e 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -87,6 +87,8 @@ errno_t switch_creds(TALLOC_CTX *mem_ctx,
|
||||
struct sss_creds **saved_creds);
|
||||
errno_t restore_creds(struct sss_creds *saved_creds);
|
||||
|
||||
+errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);
|
||||
+
|
||||
errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
||||
struct tgt_times *tgtt);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
279
0003-krb5-Use-krb5_cc_destroy-to-remove-old-ccaches.patch
Normal file
279
0003-krb5-Use-krb5_cc_destroy-to-remove-old-ccaches.patch
Normal file
@ -0,0 +1,279 @@
|
||||
From a70e88f62e8ba48c5042b881f20ed6586cb135a8 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Wed, 28 Aug 2013 23:18:37 -0400
|
||||
Subject: [PATCH 03/14] 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 150f53e72cfa68dc5d32aa90ad475a72000ba3fb..25a4cbf83c790b85fab9ccccd611f59704a5b301 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 db0aa936ff5577afedf72cb43f1c71485e16505c..5d33dddb6d3bf28c7021580a3859a257b1507210 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 1141f3fc839a78927dab5f50267c52d5b44b46ba..0245cc9d008f64e00717dc3e878357ddf2fae9fa 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 ebcfe938af913f107b8816c3209b690ac90e797e..ac29d61e9e4efe963c835e8646ce540e09dc8dd7 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 24d077289d64d52488a3419ffc4494f59d6bc5df..dff62ab64dd1948d20da6b640a0570ee8ea6b11d 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);
|
||||
--
|
||||
1.8.3.1
|
||||
|
357
0004-krb5-Replace-type-specific-ccache-principal-check.patch
Normal file
357
0004-krb5-Replace-type-specific-ccache-principal-check.patch
Normal file
@ -0,0 +1,357 @@
|
||||
From 1536e39c191a013bc50bb6fd4b8eaef11cf0d436 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 00:58:24 -0400
|
||||
Subject: [PATCH 04/14] krb5: Replace type-specific ccache/principal check
|
||||
|
||||
Instead of having duplicate functions that are type custom use a signle common
|
||||
function that also performs access to the cache as the user owner, implicitly
|
||||
validating correctness of ownership.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 11 +-
|
||||
src/providers/krb5/krb5_utils.c | 220 +++++++++++++++-------------------------
|
||||
src/providers/krb5/krb5_utils.h | 6 +-
|
||||
3 files changed, 89 insertions(+), 148 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index 5d33dddb6d3bf28c7021580a3859a257b1507210..976fdec097a06ae5b211a5a93dcb13b9548031ef 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -837,7 +837,6 @@ static void krb5_auth_done(struct tevent_req *subreq)
|
||||
uint8_t *buf = NULL;
|
||||
ssize_t len = -1;
|
||||
struct krb5_child_response *res;
|
||||
- const char *store_ccname;
|
||||
struct fo_server *search_srv;
|
||||
krb5_deltat renew_interval_delta;
|
||||
char *renew_interval_str;
|
||||
@@ -1076,17 +1075,15 @@ static void krb5_auth_done(struct tevent_req *subreq)
|
||||
goto done;
|
||||
}
|
||||
|
||||
- store_ccname = kr->cc_be->ccache_for_princ(kr, kr->ccname,
|
||||
- kr->upn);
|
||||
- if (store_ccname == NULL) {
|
||||
+ ret = sss_krb5_check_ccache_princ(kr->uid, kr->gid, kr->ccname, kr->upn);
|
||||
+ if (ret) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
("No ccache for %s in %s?\n", kr->upn, kr->ccname));
|
||||
- ret = EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (kr->old_ccname) {
|
||||
- ret = safe_remove_old_ccache_file(kr->old_ccname, store_ccname,
|
||||
+ ret = safe_remove_old_ccache_file(kr->old_ccname, kr->ccname,
|
||||
kr->uid, kr->gid);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
@@ -1096,7 +1093,7 @@ static void krb5_auth_done(struct tevent_req *subreq)
|
||||
}
|
||||
|
||||
ret = krb5_save_ccname(state, state->sysdb, state->domain,
|
||||
- pd->user, store_ccname);
|
||||
+ pd->user, kr->ccname);
|
||||
if (ret) {
|
||||
DEBUG(1, ("krb5_save_ccname failed.\n"));
|
||||
goto done;
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index 0245cc9d008f64e00717dc3e878357ddf2fae9fa..ce3cab60d71a8b3329eeedbd82bec6ecb750948c 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -928,6 +928,89 @@ done:
|
||||
}
|
||||
|
||||
|
||||
+/* This function is called only as a way to validate that we have the
|
||||
+ * right cache */
|
||||
+errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
||||
+ const char *ccname, const char *principal)
|
||||
+{
|
||||
+ struct sss_krb5_ccache *cc = NULL;
|
||||
+ krb5_principal ccprinc = NULL;
|
||||
+ krb5_principal kprinc = NULL;
|
||||
+ krb5_error_code kerr;
|
||||
+ const char *cc_type;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
|
||||
+ if (ret) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ cc_type = krb5_cc_get_type(cc->context, cc->ccache);
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
+ ("Searching for [%s] in cache of type [%s]\n", principal, cc_type));
|
||||
+
|
||||
+ kerr = krb5_parse_name(cc->context, principal, &kprinc);
|
||||
+ if (kerr != 0) {
|
||||
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_parse_name failed.\n"));
|
||||
+ ret = ERR_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kerr = krb5_cc_get_principal(cc->context, cc->ccache, &ccprinc);
|
||||
+ if (kerr != 0) {
|
||||
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_get_principal failed.\n"));
|
||||
+ }
|
||||
+
|
||||
+ if (ccprinc) {
|
||||
+ if (krb5_principal_compare(cc->context, kprinc, ccprinc) == TRUE) {
|
||||
+ /* found in the primary ccache */
|
||||
+ ret = EOK;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
+
|
||||
+ if (krb5_cc_support_switch(cc->context, cc_type)) {
|
||||
+
|
||||
+ krb5_cc_close(cc->context, cc->ccache);
|
||||
+ cc->ccache = NULL;
|
||||
+
|
||||
+ kerr = krb5_cc_set_default_name(cc->context, ccname);
|
||||
+ if (kerr != 0) {
|
||||
+ KRB5_DEBUG(SSSDBG_MINOR_FAILURE, cc->context, kerr);
|
||||
+ /* try to continue despite failure */
|
||||
+ }
|
||||
+
|
||||
+ kerr = krb5_cc_cache_match(cc->context, kprinc, &cc->ccache);
|
||||
+ if (kerr == 0) {
|
||||
+ ret = EOK;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ KRB5_DEBUG(SSSDBG_TRACE_INTERNAL, cc->context, kerr);
|
||||
+ }
|
||||
+
|
||||
+#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
+
|
||||
+ ret = ERR_NOT_FOUND;
|
||||
+
|
||||
+done:
|
||||
+ krb5_free_principal(cc->context, ccprinc);
|
||||
+ krb5_free_principal(cc->context, kprinc);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*======== ccache back end utilities ========*/
|
||||
struct sss_krb5_cc_be *
|
||||
get_cc_be_ops(enum sss_krb5_cc_type type)
|
||||
@@ -1113,18 +1196,10 @@ cc_file_check_existing(const char *location, uid_t uid,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-const char *
|
||||
-cc_file_cache_for_princ(TALLOC_CTX *mem_ctx, const char *location,
|
||||
- const char *princ)
|
||||
-{
|
||||
- return talloc_strdup(mem_ctx, location);
|
||||
-}
|
||||
-
|
||||
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,
|
||||
};
|
||||
|
||||
#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
@@ -1246,67 +1321,10 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-const char *
|
||||
-cc_dir_cache_for_princ(TALLOC_CTX *mem_ctx, const char *location,
|
||||
- const char *princ)
|
||||
-{
|
||||
- krb5_context context = NULL;
|
||||
- krb5_error_code krberr;
|
||||
- char *name = NULL;
|
||||
- const char *ccname;
|
||||
- krb5_principal client_principal = NULL;
|
||||
-
|
||||
- ccname = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_DIR);
|
||||
- if (!ccname) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot get ccname file from %s\n",
|
||||
- location));
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* ccname already points to a subsidiary cache */
|
||||
- if (ccname[0] == ':' && ccname[1] && ccname[1] == '/') {
|
||||
- return talloc_strdup(mem_ctx, location);
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_init_context(&context);
|
||||
- if (krberr) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("Failed to init kerberos context\n"));
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_parse_name(context, princ, &client_principal);
|
||||
- if (krberr != 0) {
|
||||
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_parse_name failed.\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- /* This function is called only as a way to validate that,
|
||||
- * we have the right cache
|
||||
- */
|
||||
- name = sss_get_ccache_name_for_principal(mem_ctx, context,
|
||||
- client_principal, location);
|
||||
- if (name == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Could not get full name of ccache\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- talloc_zfree(name);
|
||||
- /* everytime return location for dir_cache */
|
||||
- name = talloc_strdup(mem_ctx, location);
|
||||
-
|
||||
-done:
|
||||
- krb5_free_principal(context, client_principal);
|
||||
- krb5_free_context(context);
|
||||
-
|
||||
- return name;
|
||||
-}
|
||||
-
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
@@ -1362,82 +1380,10 @@ cc_keyring_check_existing(const char *location, uid_t uid,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-const char *
|
||||
-cc_keyring_cache_for_princ(TALLOC_CTX *mem_ctx, const char *location,
|
||||
- const char *princ)
|
||||
-{
|
||||
- krb5_context context = NULL;
|
||||
- krb5_error_code krberr;
|
||||
- char *name = NULL;
|
||||
- const char *residual;
|
||||
- size_t i;
|
||||
- size_t count;
|
||||
- krb5_principal client_principal = NULL;
|
||||
-
|
||||
- residual = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_KEYRING);
|
||||
- if (!residual) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot get residual from %s\n",
|
||||
- location));
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* residual already points to a subsidiary cache if it of the
|
||||
- * form "KEYRING:<type>:<UID>:krb5_cc_XXXXXXX"
|
||||
- * For simplicity, we'll count the colons, up to three.
|
||||
- */
|
||||
- i = count = 0;
|
||||
- while (residual[i] && count < 3) {
|
||||
- if (residual[i] == ':') {
|
||||
- count ++;
|
||||
- }
|
||||
- i++;
|
||||
- }
|
||||
-
|
||||
- if (count >= 3) {
|
||||
- return talloc_strdup(mem_ctx, location);
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_init_context(&context);
|
||||
- if (krberr) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("Failed to init kerberos context\n"));
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_parse_name(context, princ, &client_principal);
|
||||
- if (krberr != 0) {
|
||||
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_parse_name failed.\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- name = sss_get_ccache_name_for_principal(mem_ctx, context,
|
||||
- client_principal, location);
|
||||
- if (name == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Could not get full name of ccache\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- talloc_zfree(name);
|
||||
-
|
||||
- /* Always return the master name here.
|
||||
- * We do the above only to ensure that the
|
||||
- * principal-specific name exists and can
|
||||
- * be found.
|
||||
- */
|
||||
- name = talloc_strdup(mem_ctx, location);
|
||||
-
|
||||
-done:
|
||||
- krb5_free_principal(context, client_principal);
|
||||
- krb5_free_context(context);
|
||||
-
|
||||
- return name;
|
||||
-}
|
||||
-
|
||||
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,
|
||||
};
|
||||
|
||||
#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index ac29d61e9e4efe963c835e8646ce540e09dc8dd7..a73098d4090199c5a49bdf0adf5115e9120eeb5b 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -49,9 +49,6 @@ typedef errno_t (*cc_be_check_existing)(const char *location, uid_t uid,
|
||||
const char *realm, const char *princ,
|
||||
const char *cc_template, bool *active,
|
||||
bool *valid);
|
||||
-typedef const char * (*cc_be_ccache_for_princ)(TALLOC_CTX *mem_ctx,
|
||||
- const char *location,
|
||||
- const char *princ);
|
||||
|
||||
/* A ccache back end */
|
||||
struct sss_krb5_cc_be {
|
||||
@@ -59,7 +56,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;
|
||||
};
|
||||
|
||||
extern struct sss_krb5_cc_be file_cc;
|
||||
@@ -86,6 +82,8 @@ errno_t switch_creds(TALLOC_CTX *mem_ctx,
|
||||
errno_t restore_creds(struct sss_creds *saved_creds);
|
||||
|
||||
errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);
|
||||
+errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
||||
+ const char *ccname, const char *principal);
|
||||
|
||||
errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
||||
struct tgt_times *tgtt);
|
||||
--
|
||||
1.8.3.1
|
||||
|
220
0005-krb5-Move-determination-of-user-being-active.patch
Normal file
220
0005-krb5-Move-determination-of-user-being-active.patch
Normal file
@ -0,0 +1,220 @@
|
||||
From bfd32c9e8f302d7722838a68572c6801f5640657 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 11:31:23 -0400
|
||||
Subject: [PATCH 05/14] krb5: Move determination of user being active
|
||||
|
||||
The way a user is checked for being active does not depend on the ccache
|
||||
type so move that check out of the ccache specific functions.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 10 +++++++--
|
||||
src/providers/krb5/krb5_utils.c | 47 +++++++----------------------------------
|
||||
src/providers/krb5/krb5_utils.h | 3 +--
|
||||
3 files changed, 17 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index 976fdec097a06ae5b211a5a93dcb13b9548031ef..178f18a3c5dec4772a59c6d6cfbcdc419c20d48c 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -76,7 +76,7 @@ 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);
|
||||
+ cc_template, valid);
|
||||
if (ret == ENOENT) {
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
("Saved ccache %s doesn't exist.\n", old_ccache));
|
||||
@@ -84,11 +84,17 @@ check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
|
||||
}
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("Cannot check if saved ccache %s is active and valid\n",
|
||||
+ ("Cannot check if saved ccache %s is valid\n",
|
||||
old_ccache));
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = check_if_uid_is_active(kr->uid, active);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, ("check_if_uid_is_active failed.\n"));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
return EOK;
|
||||
}
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index ce3cab60d71a8b3329eeedbd82bec6ecb750948c..7f2ca2d5ba570e3467ec7dc4060f58f38b1f3428 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -1066,14 +1066,11 @@ cc_file_create(const char *location, pcre *illegal_re,
|
||||
}
|
||||
|
||||
static errno_t
|
||||
-cc_residual_is_used(uid_t uid, const char *ccname,
|
||||
- enum sss_krb5_cc_type type, bool *result)
|
||||
+cc_residual_exists(uid_t uid, const char *ccname,
|
||||
+ enum sss_krb5_cc_type type)
|
||||
{
|
||||
int ret;
|
||||
struct stat stat_buf;
|
||||
- bool active;
|
||||
-
|
||||
- *result = false;
|
||||
|
||||
if (ccname == NULL || *ccname == '\0') {
|
||||
return EINVAL;
|
||||
@@ -1086,7 +1083,6 @@ cc_residual_is_used(uid_t uid, const char *ccname,
|
||||
if (ret == ENOENT) {
|
||||
DEBUG(SSSDBG_FUNC_DATA, ("Cache file [%s] does not exist, "
|
||||
"it will be recreated\n", ccname));
|
||||
- *result = false;
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
@@ -1123,20 +1119,6 @@ cc_residual_is_used(uid_t uid, const char *ccname,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- ret = check_if_uid_is_active(uid, &active);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("check_if_uid_is_active failed.\n"));
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- if (!active) {
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, ("User [%d] is not active\n", uid));
|
||||
- } else {
|
||||
- DEBUG(SSSDBG_TRACE_LIBS,
|
||||
- ("User [%d] is still active, reusing ccache [%s].\n",
|
||||
- uid, ccname));
|
||||
- *result = true;
|
||||
- }
|
||||
return EOK;
|
||||
}
|
||||
|
||||
@@ -1157,10 +1139,9 @@ cc_check_template(const char *cc_template)
|
||||
errno_t
|
||||
cc_file_check_existing(const char *location, uid_t uid,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *_active, bool *_valid)
|
||||
+ const char *cc_template, bool *_valid)
|
||||
{
|
||||
errno_t ret;
|
||||
- bool active;
|
||||
bool valid;
|
||||
const char *filename;
|
||||
|
||||
@@ -1175,14 +1156,13 @@ cc_file_check_existing(const char *location, uid_t uid,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- ret = cc_residual_is_used(uid, filename, SSS_KRB5_TYPE_FILE, &active);
|
||||
+ ret = cc_residual_exists(uid, filename, SSS_KRB5_TYPE_FILE);
|
||||
if (ret != EOK) {
|
||||
if (ret != ENOENT) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
("Could not check if ccache is active.\n"));
|
||||
}
|
||||
cc_check_template(cc_template);
|
||||
- active = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1191,7 +1171,6 @@ cc_file_check_existing(const char *location, uid_t uid,
|
||||
return ret;
|
||||
}
|
||||
|
||||
- *_active = active;
|
||||
*_valid = valid;
|
||||
return EOK;
|
||||
}
|
||||
@@ -1222,10 +1201,8 @@ cc_dir_create(const char *location, pcre *illegal_re,
|
||||
errno_t
|
||||
cc_dir_check_existing(const char *location, uid_t uid,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *_active, bool *_valid)
|
||||
+ const char *cc_template, bool *_valid)
|
||||
{
|
||||
- bool active;
|
||||
- bool active_primary = false;
|
||||
bool valid;
|
||||
enum sss_krb5_cc_type type;
|
||||
const char *filename;
|
||||
@@ -1279,7 +1256,7 @@ cc_dir_check_existing(const char *location, uid_t uid,
|
||||
dir = tmp;
|
||||
}
|
||||
|
||||
- ret = cc_residual_is_used(uid, dir, SSS_KRB5_TYPE_DIR, &active);
|
||||
+ ret = cc_residual_exists(uid, dir, SSS_KRB5_TYPE_DIR);
|
||||
if (ret != EOK) {
|
||||
if (ret != ENOENT) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
@@ -1298,8 +1275,7 @@ cc_dir_check_existing(const char *location, uid_t uid,
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
- ret = cc_residual_is_used(uid, primary_file, SSS_KRB5_TYPE_FILE,
|
||||
- &active_primary);
|
||||
+ ret = cc_residual_exists(uid, primary_file, SSS_KRB5_TYPE_FILE);
|
||||
if (ret != EOK && ret != ENOENT) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
("Could not check if file 'primary' [%s] in dir ccache"
|
||||
@@ -1312,7 +1288,6 @@ cc_dir_check_existing(const char *location, uid_t uid,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- *_active = active;
|
||||
*_valid = valid;
|
||||
ret = EOK;
|
||||
|
||||
@@ -1351,11 +1326,9 @@ cc_keyring_create(const char *location, pcre *illegal_re,
|
||||
errno_t
|
||||
cc_keyring_check_existing(const char *location, uid_t uid,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *_active,
|
||||
- bool *_valid)
|
||||
+ const char *cc_template, bool *_valid)
|
||||
{
|
||||
errno_t ret;
|
||||
- bool active;
|
||||
bool valid;
|
||||
const char *residual;
|
||||
|
||||
@@ -1366,16 +1339,12 @@ cc_keyring_check_existing(const char *location, uid_t uid,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- /* The keyring cache is always active */
|
||||
- active = true;
|
||||
-
|
||||
/* Check if any user is actively using this cache */
|
||||
ret = check_cc_validity(location, realm, princ, &valid);
|
||||
if (ret != EOK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- *_active = active;
|
||||
*_valid = valid;
|
||||
return EOK;
|
||||
}
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index a73098d4090199c5a49bdf0adf5115e9120eeb5b..ca33205817cbb726a75b809f71d1fb1589744e15 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -47,8 +47,7 @@ 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,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *active,
|
||||
- bool *valid);
|
||||
+ const char *cc_template, bool *valid);
|
||||
|
||||
/* A ccache back end */
|
||||
struct sss_krb5_cc_be {
|
||||
--
|
||||
1.8.3.1
|
||||
|
160
0006-krb5-move-template-check-to-initializzation.patch
Normal file
160
0006-krb5-move-template-check-to-initializzation.patch
Normal file
@ -0,0 +1,160 @@
|
||||
From 5dc3b01fd9b2fa244e7c2820ce04602c9f059370 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 12:21:39 -0400
|
||||
Subject: [PATCH 06/14] krb5: move template check to initializzation
|
||||
|
||||
The randomized template check realy only makes sense for the FILE ccache
|
||||
which is the only one that normally needs to use randomizing chars.
|
||||
Also it is better to warn the admin early rather than to warn 'when it
|
||||
is too late'.
|
||||
So move the check at initialization time when we determine what the
|
||||
template actually is.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 5 +----
|
||||
src/providers/krb5/krb5_common.c | 17 +++++++++++++++++
|
||||
src/providers/krb5/krb5_utils.c | 22 +++-------------------
|
||||
src/providers/krb5/krb5_utils.h | 2 +-
|
||||
4 files changed, 22 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index 178f18a3c5dec4772a59c6d6cfbcdc419c20d48c..ca00ce7a3aefa6dae3116f57c994d1f5cd1f50ea 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -60,7 +60,6 @@ check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
|
||||
const char *realm, bool *active, bool *valid)
|
||||
{
|
||||
struct sss_krb5_cc_be *old_cc_ops;
|
||||
- const char *cc_template;
|
||||
errno_t ret;
|
||||
|
||||
/* ccache file might be of a different type if the user changed
|
||||
@@ -73,10 +72,8 @@ check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- 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, valid);
|
||||
+ valid);
|
||||
if (ret == ENOENT) {
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
("Saved ccache %s doesn't exist.\n", old_ccache));
|
||||
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
|
||||
index c7ce574d513702132cb7e0c8ca4f1f1b80430f0b..de7ae0a8fe345c38f9458fb9642a5c1b83c906f5 100644
|
||||
--- a/src/providers/krb5/krb5_common.c
|
||||
+++ b/src/providers/krb5/krb5_common.c
|
||||
@@ -144,6 +144,19 @@ static errno_t sss_get_system_ccname_template(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
#endif
|
||||
|
||||
+static void sss_check_cc_template(const char *cc_template)
|
||||
+{
|
||||
+ size_t template_len;
|
||||
+
|
||||
+ template_len = strlen(cc_template);
|
||||
+ if (template_len >= 6 &&
|
||||
+ strcmp(cc_template + (template_len - 6), "XXXXXX") != 0) {
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, ("ccache file name template [%s] doesn't "
|
||||
+ "contain randomizing characters (XXXXXX), file might not "
|
||||
+ "be rewritable\n", cc_template));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
errno_t check_and_export_options(struct dp_option *opts,
|
||||
struct sss_domain_info *dom,
|
||||
struct krb5_ctx *krb5_ctx)
|
||||
@@ -282,6 +295,10 @@ errno_t check_and_export_options(struct dp_option *opts,
|
||||
switch (cc_be) {
|
||||
case SSS_KRB5_TYPE_FILE:
|
||||
DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type FILE\n"));
|
||||
+ /* warn if the file type (which is usally created in a sticky bit
|
||||
+ * laden directory) does not have randomizing chracters */
|
||||
+ sss_check_cc_template(ccname);
|
||||
+
|
||||
krb5_ctx->cc_be = &file_cc;
|
||||
if (ccname[0] != '/') {
|
||||
/* FILE:/path/to/cc */
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index 7f2ca2d5ba570e3467ec7dc4060f58f38b1f3428..b174462ee4e8f3992e6d9c06f91118098c598149 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -1122,24 +1122,10 @@ cc_residual_exists(uid_t uid, const char *ccname,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-static void
|
||||
-cc_check_template(const char *cc_template)
|
||||
-{
|
||||
- size_t template_len;
|
||||
-
|
||||
- template_len = strlen(cc_template);
|
||||
- if (template_len >= 6 &&
|
||||
- strcmp(cc_template + (template_len - 6), "XXXXXX") != 0) {
|
||||
- DEBUG(SSSDBG_CONF_SETTINGS, ("ccache file name template [%s] doesn't "
|
||||
- "contain randomizing characters (XXXXXX), file might not "
|
||||
- "be rewritable\n", cc_template));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
errno_t
|
||||
cc_file_check_existing(const char *location, uid_t uid,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *_valid)
|
||||
+ bool *_valid)
|
||||
{
|
||||
errno_t ret;
|
||||
bool valid;
|
||||
@@ -1162,7 +1148,6 @@ cc_file_check_existing(const char *location, uid_t uid,
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
("Could not check if ccache is active.\n"));
|
||||
}
|
||||
- cc_check_template(cc_template);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1201,7 +1186,7 @@ cc_dir_create(const char *location, pcre *illegal_re,
|
||||
errno_t
|
||||
cc_dir_check_existing(const char *location, uid_t uid,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *_valid)
|
||||
+ bool *_valid)
|
||||
{
|
||||
bool valid;
|
||||
enum sss_krb5_cc_type type;
|
||||
@@ -1262,7 +1247,6 @@ cc_dir_check_existing(const char *location, uid_t uid,
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
("Could not check if ccache is active.\n"));
|
||||
}
|
||||
- cc_check_template(cc_template);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1326,7 +1310,7 @@ cc_keyring_create(const char *location, pcre *illegal_re,
|
||||
errno_t
|
||||
cc_keyring_check_existing(const char *location, uid_t uid,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *_valid)
|
||||
+ bool *_valid)
|
||||
{
|
||||
errno_t ret;
|
||||
bool valid;
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index ca33205817cbb726a75b809f71d1fb1589744e15..e241666289193bdc3c5eccadfffc4d3d669dff16 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -47,7 +47,7 @@ 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,
|
||||
const char *realm, const char *princ,
|
||||
- const char *cc_template, bool *valid);
|
||||
+ bool *valid);
|
||||
|
||||
/* A ccache back end */
|
||||
struct sss_krb5_cc_be {
|
||||
--
|
||||
1.8.3.1
|
||||
|
201
0007-krb5-Make-check_for_valid_tgt-static.patch
Normal file
201
0007-krb5-Make-check_for_valid_tgt-static.patch
Normal file
@ -0,0 +1,201 @@
|
||||
From c121e65ed592bf3611053ee38032fd33c8d1b285 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 12:27:49 -0400
|
||||
Subject: [PATCH 07/14] krb5: Make check_for_valid_tgt() static
|
||||
|
||||
check_for_valid_tgt() is used exclusively in krb5_uitls.c so move it there.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_utils.c | 74 +++++++++++++++++++++++++++++++++++++++++
|
||||
src/util/sss_krb5.c | 72 ---------------------------------------
|
||||
src/util/sss_krb5.h | 4 ---
|
||||
3 files changed, 74 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index b174462ee4e8f3992e6d9c06f91118098c598149..463a5eb409d076825f25d45c034d58f4a89780eb 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -761,6 +761,80 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static krb5_error_code check_for_valid_tgt(krb5_context context,
|
||||
+ krb5_ccache ccache,
|
||||
+ const char *realm,
|
||||
+ const char *client_princ_str,
|
||||
+ bool *result)
|
||||
+{
|
||||
+ krb5_error_code krberr;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ krb5_creds mcred;
|
||||
+ krb5_creds cred;
|
||||
+ char *server_name = NULL;
|
||||
+ krb5_principal client_principal = NULL;
|
||||
+ krb5_principal server_principal = NULL;
|
||||
+
|
||||
+ *result = false;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(1, ("talloc_new failed.\n"));
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ server_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
|
||||
+ if (server_name == NULL) {
|
||||
+ DEBUG(1, ("talloc_asprintf failed.\n"));
|
||||
+ krberr = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ krberr = krb5_parse_name(context, server_name, &server_principal);
|
||||
+ if (krberr != 0) {
|
||||
+ DEBUG(1, ("krb5_parse_name failed.\n"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ krberr = krb5_parse_name(context, client_princ_str, &client_principal);
|
||||
+ if (krberr != 0) {
|
||||
+ DEBUG(1, ("krb5_parse_name failed.\n"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ memset(&mcred, 0, sizeof(mcred));
|
||||
+ memset(&cred, 0, sizeof(mcred));
|
||||
+ mcred.client = client_principal;
|
||||
+ mcred.server = server_principal;
|
||||
+
|
||||
+ krberr = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
|
||||
+ if (krberr != 0) {
|
||||
+ DEBUG(1, ("krb5_cc_retrieve_cred failed.\n"));
|
||||
+ krberr = 0;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(7, ("TGT end time [%d].\n", cred.times.endtime));
|
||||
+
|
||||
+ if (cred.times.endtime > time(NULL)) {
|
||||
+ DEBUG(3, ("TGT is valid.\n"));
|
||||
+ *result = true;
|
||||
+ }
|
||||
+ krb5_free_cred_contents(context, &cred);
|
||||
+
|
||||
+ krberr = 0;
|
||||
+
|
||||
+done:
|
||||
+ if (client_principal != NULL) {
|
||||
+ krb5_free_principal(context, client_principal);
|
||||
+ }
|
||||
+ if (server_principal != NULL) {
|
||||
+ krb5_free_principal(context, server_principal);
|
||||
+ }
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return krberr;
|
||||
+}
|
||||
+
|
||||
static errno_t
|
||||
check_cc_validity(const char *location,
|
||||
const char *realm,
|
||||
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
|
||||
index b25ed24919555666422e6a87ded8688ca76c345f..440edab8a4624b33b7d358e64ead93949fc3de88 100644
|
||||
--- a/src/util/sss_krb5.c
|
||||
+++ b/src/util/sss_krb5.c
|
||||
@@ -546,78 +546,6 @@ void KRB5_CALLCONV sss_krb5_free_unparsed_name(krb5_context context, char *name)
|
||||
}
|
||||
|
||||
|
||||
-krb5_error_code check_for_valid_tgt(krb5_context context,
|
||||
- krb5_ccache ccache, const char *realm,
|
||||
- const char *client_princ_str, bool *result)
|
||||
-{
|
||||
- krb5_error_code krberr;
|
||||
- TALLOC_CTX *tmp_ctx = NULL;
|
||||
- krb5_creds mcred;
|
||||
- krb5_creds cred;
|
||||
- char *server_name = NULL;
|
||||
- krb5_principal client_principal = NULL;
|
||||
- krb5_principal server_principal = NULL;
|
||||
-
|
||||
- *result = false;
|
||||
-
|
||||
- tmp_ctx = talloc_new(NULL);
|
||||
- if (tmp_ctx == NULL) {
|
||||
- DEBUG(1, ("talloc_new failed.\n"));
|
||||
- return ENOMEM;
|
||||
- }
|
||||
-
|
||||
- server_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
|
||||
- if (server_name == NULL) {
|
||||
- DEBUG(1, ("talloc_asprintf failed.\n"));
|
||||
- krberr = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_parse_name(context, server_name, &server_principal);
|
||||
- if (krberr != 0) {
|
||||
- DEBUG(1, ("krb5_parse_name failed.\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_parse_name(context, client_princ_str, &client_principal);
|
||||
- if (krberr != 0) {
|
||||
- DEBUG(1, ("krb5_parse_name failed.\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- memset(&mcred, 0, sizeof(mcred));
|
||||
- memset(&cred, 0, sizeof(mcred));
|
||||
- mcred.client = client_principal;
|
||||
- mcred.server = server_principal;
|
||||
-
|
||||
- krberr = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
|
||||
- if (krberr != 0) {
|
||||
- DEBUG(1, ("krb5_cc_retrieve_cred failed.\n"));
|
||||
- krberr = 0;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- DEBUG(7, ("TGT end time [%d].\n", cred.times.endtime));
|
||||
-
|
||||
- if (cred.times.endtime > time(NULL)) {
|
||||
- DEBUG(3, ("TGT is valid.\n"));
|
||||
- *result = true;
|
||||
- }
|
||||
- krb5_free_cred_contents(context, &cred);
|
||||
-
|
||||
- krberr = 0;
|
||||
-
|
||||
-done:
|
||||
- if (client_principal != NULL) {
|
||||
- krb5_free_principal(context, client_principal);
|
||||
- }
|
||||
- if (server_principal != NULL) {
|
||||
- krb5_free_principal(context, server_principal);
|
||||
- }
|
||||
- talloc_free(tmp_ctx);
|
||||
- return krberr;
|
||||
-}
|
||||
-
|
||||
krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_expire_callback(
|
||||
krb5_context context,
|
||||
krb5_get_init_creds_opt *opt,
|
||||
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
|
||||
index b1074f813a6b12d132b8c3d0290ad914b003e70f..aaf2a64882254ba173fb57c5dab47d246082392c 100644
|
||||
--- a/src/util/sss_krb5.h
|
||||
+++ b/src/util/sss_krb5.h
|
||||
@@ -70,10 +70,6 @@ void KRB5_CALLCONV sss_krb5_get_init_creds_opt_free (krb5_context context,
|
||||
|
||||
void KRB5_CALLCONV sss_krb5_free_unparsed_name(krb5_context context, char *name);
|
||||
|
||||
-krb5_error_code check_for_valid_tgt(krb5_context context,
|
||||
- krb5_ccache ccache, const char *realm,
|
||||
- const char *client_princ_str, bool *result);
|
||||
-
|
||||
int sss_krb5_verify_keytab_ex(const char *principal, const char *keytab_name,
|
||||
krb5_context context, krb5_keytab keytab);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
568
0008-krb5-Use-new-function-to-validate-ccaches.patch
Normal file
568
0008-krb5-Use-new-function-to-validate-ccaches.patch
Normal file
@ -0,0 +1,568 @@
|
||||
From 84ce563e3f430eec1225a6f8493eb0a6c9a3013a Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 16:35:43 -0400
|
||||
Subject: [PATCH 08/14] krb5: Use new function to validate ccaches
|
||||
|
||||
This function replaces and combines check_for_valid_tgt() and type specific
|
||||
functions that checked for ccache existence by using generic krb5 cache
|
||||
function and executing them as the target user (implicitly validate the
|
||||
target use rcan properly access the ccache).
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 30 ++-
|
||||
src/providers/krb5/krb5_utils.c | 423 +++++++---------------------------------
|
||||
src/providers/krb5/krb5_utils.h | 6 +-
|
||||
3 files changed, 88 insertions(+), 371 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index ca00ce7a3aefa6dae3116f57c994d1f5cd1f50ea..1ea179be3af48b16129aeb4c2d850a66244f7d08 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -59,27 +59,25 @@ static errno_t
|
||||
check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
|
||||
const char *realm, bool *active, bool *valid)
|
||||
{
|
||||
- struct sss_krb5_cc_be *old_cc_ops;
|
||||
errno_t ret;
|
||||
|
||||
- /* ccache file might be of a different type if the user changed
|
||||
- * configuration
|
||||
- */
|
||||
- old_cc_ops = get_cc_be_ops_ccache(old_ccache);
|
||||
- if (old_cc_ops == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Cannot get operations on saved ccache %s\n", old_ccache));
|
||||
- return EINVAL;
|
||||
- }
|
||||
+ *active = false;
|
||||
+ *valid = false;
|
||||
|
||||
- ret = old_cc_ops->check_existing(old_ccache, kr->uid, realm, kr->upn,
|
||||
- valid);
|
||||
- if (ret == ENOENT) {
|
||||
+ ret = sss_krb5_cc_verify_ccache(old_ccache,
|
||||
+ kr->uid, kr->gid,
|
||||
+ realm, kr->upn);
|
||||
+ switch (ret) {
|
||||
+ case ERR_NOT_FOUND:
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
("Saved ccache %s doesn't exist.\n", old_ccache));
|
||||
- return ret;
|
||||
- }
|
||||
- if (ret != EOK) {
|
||||
+ return ENOENT;
|
||||
+ case EINVAL:
|
||||
+ /* cache found but no tgt or expired */
|
||||
+ case EOK:
|
||||
+ *valid = true;
|
||||
+ break;
|
||||
+ default:
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
("Cannot check if saved ccache %s is valid\n",
|
||||
old_ccache));
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index 463a5eb409d076825f25d45c034d58f4a89780eb..c4849e74bd43b096b585398970f5b81e946212e9 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -761,136 +761,6 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static krb5_error_code check_for_valid_tgt(krb5_context context,
|
||||
- krb5_ccache ccache,
|
||||
- const char *realm,
|
||||
- const char *client_princ_str,
|
||||
- bool *result)
|
||||
-{
|
||||
- krb5_error_code krberr;
|
||||
- TALLOC_CTX *tmp_ctx = NULL;
|
||||
- krb5_creds mcred;
|
||||
- krb5_creds cred;
|
||||
- char *server_name = NULL;
|
||||
- krb5_principal client_principal = NULL;
|
||||
- krb5_principal server_principal = NULL;
|
||||
-
|
||||
- *result = false;
|
||||
-
|
||||
- tmp_ctx = talloc_new(NULL);
|
||||
- if (tmp_ctx == NULL) {
|
||||
- DEBUG(1, ("talloc_new failed.\n"));
|
||||
- return ENOMEM;
|
||||
- }
|
||||
-
|
||||
- server_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
|
||||
- if (server_name == NULL) {
|
||||
- DEBUG(1, ("talloc_asprintf failed.\n"));
|
||||
- krberr = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_parse_name(context, server_name, &server_principal);
|
||||
- if (krberr != 0) {
|
||||
- DEBUG(1, ("krb5_parse_name failed.\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_parse_name(context, client_princ_str, &client_principal);
|
||||
- if (krberr != 0) {
|
||||
- DEBUG(1, ("krb5_parse_name failed.\n"));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- memset(&mcred, 0, sizeof(mcred));
|
||||
- memset(&cred, 0, sizeof(mcred));
|
||||
- mcred.client = client_principal;
|
||||
- mcred.server = server_principal;
|
||||
-
|
||||
- krberr = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
|
||||
- if (krberr != 0) {
|
||||
- DEBUG(1, ("krb5_cc_retrieve_cred failed.\n"));
|
||||
- krberr = 0;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- DEBUG(7, ("TGT end time [%d].\n", cred.times.endtime));
|
||||
-
|
||||
- if (cred.times.endtime > time(NULL)) {
|
||||
- DEBUG(3, ("TGT is valid.\n"));
|
||||
- *result = true;
|
||||
- }
|
||||
- krb5_free_cred_contents(context, &cred);
|
||||
-
|
||||
- krberr = 0;
|
||||
-
|
||||
-done:
|
||||
- if (client_principal != NULL) {
|
||||
- krb5_free_principal(context, client_principal);
|
||||
- }
|
||||
- if (server_principal != NULL) {
|
||||
- krb5_free_principal(context, server_principal);
|
||||
- }
|
||||
- talloc_free(tmp_ctx);
|
||||
- return krberr;
|
||||
-}
|
||||
-
|
||||
-static errno_t
|
||||
-check_cc_validity(const char *location,
|
||||
- const char *realm,
|
||||
- const char *princ,
|
||||
- bool *_valid)
|
||||
-{
|
||||
- errno_t ret;
|
||||
- bool valid = false;
|
||||
- krb5_ccache ccache = NULL;
|
||||
- krb5_context context = NULL;
|
||||
- krb5_error_code krberr;
|
||||
-
|
||||
- krberr = krb5_init_context(&context);
|
||||
- if (krberr) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
|
||||
- return EIO;
|
||||
- }
|
||||
-
|
||||
- krberr = krb5_cc_resolve(context, location, &ccache);
|
||||
- if (krberr == KRB5_FCC_NOFILE || ccache == NULL) {
|
||||
- /* KRB5_FCC_NOFILE would be returned if the directory components
|
||||
- * of the DIR cache do not exist, which is the case in /run
|
||||
- * after a reboot
|
||||
- */
|
||||
- DEBUG(SSSDBG_TRACE_FUNC,
|
||||
- ("ccache %s is missing or empty\n", location));
|
||||
- valid = false;
|
||||
- ret = EOK;
|
||||
- goto done;
|
||||
- } else if (krberr != 0) {
|
||||
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
|
||||
- ret = EIO;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- krberr = check_for_valid_tgt(context, ccache, realm, princ, &valid);
|
||||
- if (krberr != EOK) {
|
||||
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Could not check if ccache contains a valid principal\n"));
|
||||
- ret = EIO;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- ret = EOK;
|
||||
-
|
||||
-done:
|
||||
- if (ret == EOK) {
|
||||
- *_valid = valid;
|
||||
- }
|
||||
- if (ccache) krb5_cc_close(context, ccache);
|
||||
- krb5_free_context(context);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
|
||||
struct sss_krb5_ccache {
|
||||
struct sss_creds *creds;
|
||||
@@ -1085,6 +955,78 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
||||
+ const char *realm, const char *principal)
|
||||
+{
|
||||
+ struct sss_krb5_ccache *cc = NULL;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ krb5_principal tgt_princ = NULL;
|
||||
+ krb5_principal princ = NULL;
|
||||
+ char *tgt_name;
|
||||
+ krb5_creds mcred = { 0 };
|
||||
+ krb5_creds cred = { 0 };
|
||||
+ krb5_error_code kerr;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new failed.\n"));
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
|
||||
+ if (ret) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ tgt_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
|
||||
+ if (!tgt_name) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new failed.\n"));
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kerr = krb5_parse_name(cc->context, tgt_name, &tgt_princ);
|
||||
+ if (kerr) {
|
||||
+ KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
|
||||
+ if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL;
|
||||
+ else ret = ERR_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kerr = krb5_parse_name(cc->context, principal, &princ);
|
||||
+ if (kerr) {
|
||||
+ KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
|
||||
+ if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL;
|
||||
+ else ret = ERR_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ mcred.client = princ;
|
||||
+ mcred.server = tgt_princ;
|
||||
+ mcred.times.endtime = time(NULL);
|
||||
+
|
||||
+ kerr = krb5_cc_retrieve_cred(cc->context, cc->ccache,
|
||||
+ KRB5_TC_MATCH_TIMES, &mcred, &cred);
|
||||
+ if (kerr) {
|
||||
+ if (kerr == KRB5_CC_NOTFOUND) {
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("TGT not found or expired.\n"));
|
||||
+ ret = EINVAL;
|
||||
+ } else {
|
||||
+ KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
|
||||
+ ret = ERR_INTERNAL;
|
||||
+ }
|
||||
+ }
|
||||
+ krb5_free_cred_contents(cc->context, &cred);
|
||||
+
|
||||
+done:
|
||||
+ if (tgt_princ) krb5_free_principal(cc->context, tgt_princ);
|
||||
+ if (princ) krb5_free_principal(cc->context, princ);
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*======== ccache back end utilities ========*/
|
||||
struct sss_krb5_cc_be *
|
||||
get_cc_be_ops(enum sss_krb5_cc_type type)
|
||||
@@ -1139,105 +1081,9 @@ cc_file_create(const char *location, pcre *illegal_re,
|
||||
return create_ccache_dir_head(filename, illegal_re, uid, gid, private_path);
|
||||
}
|
||||
|
||||
-static errno_t
|
||||
-cc_residual_exists(uid_t uid, const char *ccname,
|
||||
- enum sss_krb5_cc_type type)
|
||||
-{
|
||||
- int ret;
|
||||
- struct stat stat_buf;
|
||||
-
|
||||
- if (ccname == NULL || *ccname == '\0') {
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- ret = lstat(ccname, &stat_buf);
|
||||
-
|
||||
- if (ret == -1) {
|
||||
- ret = errno;
|
||||
- if (ret == ENOENT) {
|
||||
- DEBUG(SSSDBG_FUNC_DATA, ("Cache file [%s] does not exist, "
|
||||
- "it will be recreated\n", ccname));
|
||||
- return ENOENT;
|
||||
- }
|
||||
-
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("stat failed [%d][%s].\n", ret, strerror(ret)));
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- if (stat_buf.st_uid != uid) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("Cache file [%s] exists, but is owned by [%d] instead of "
|
||||
- "[%d].\n", ccname, stat_buf.st_uid, uid));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- switch (type) {
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_DIR:
|
||||
- ret = S_ISDIR(stat_buf.st_mode);
|
||||
- break;
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
- case SSS_KRB5_TYPE_FILE:
|
||||
- ret = S_ISREG(stat_buf.st_mode);
|
||||
- break;
|
||||
- default:
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unsupported ccache type\n"));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (ret == 0) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("Cache file [%s] exists, but is not the expected type\n",
|
||||
- ccname));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- return EOK;
|
||||
-}
|
||||
-
|
||||
-errno_t
|
||||
-cc_file_check_existing(const char *location, uid_t uid,
|
||||
- const char *realm, const char *princ,
|
||||
- bool *_valid)
|
||||
-{
|
||||
- errno_t ret;
|
||||
- bool valid;
|
||||
- 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_OP_FAILURE, ("Only absolute path names are allowed.\n"));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- ret = cc_residual_exists(uid, filename, SSS_KRB5_TYPE_FILE);
|
||||
- if (ret != EOK) {
|
||||
- if (ret != ENOENT) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("Could not check if ccache is active.\n"));
|
||||
- }
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- ret = check_cc_validity(location, realm, princ, &valid);
|
||||
- if (ret != EOK) {
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- *_valid = valid;
|
||||
- return EOK;
|
||||
-}
|
||||
-
|
||||
struct sss_krb5_cc_be file_cc = {
|
||||
.type = SSS_KRB5_TYPE_FILE,
|
||||
.create = cc_file_create,
|
||||
- .check_existing = cc_file_check_existing,
|
||||
};
|
||||
|
||||
#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
@@ -1257,107 +1103,9 @@ cc_dir_create(const char *location, pcre *illegal_re,
|
||||
return create_ccache_dir_head(dir_name, illegal_re, uid, gid, private_path);
|
||||
}
|
||||
|
||||
-errno_t
|
||||
-cc_dir_check_existing(const char *location, uid_t uid,
|
||||
- const char *realm, const char *princ,
|
||||
- bool *_valid)
|
||||
-{
|
||||
- bool valid;
|
||||
- enum sss_krb5_cc_type type;
|
||||
- const char *filename;
|
||||
- const char *dir;
|
||||
- char *tmp;
|
||||
- char *primary_file;
|
||||
- errno_t ret;
|
||||
- TALLOC_CTX *tmp_ctx;
|
||||
-
|
||||
- type = sss_krb5_get_type(location);
|
||||
- if (type != SSS_KRB5_TYPE_DIR) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("%s is not of type DIR:\n", location));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- filename = sss_krb5_cc_file_path(location);
|
||||
- if (!filename) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Existing ccname does not contain path into the collection"));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (filename[0] != '/') {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Only absolute path names are allowed.\n"));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- tmp_ctx = talloc_new(NULL);
|
||||
- if (tmp_ctx == NULL) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
|
||||
- return ENOMEM;
|
||||
- }
|
||||
-
|
||||
- tmp = talloc_strdup(tmp_ctx, filename);
|
||||
- if (!tmp) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_strdup failed.\n"));
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (0 == strncmp(location, "DIR::", 5)) {
|
||||
- dir = dirname(tmp);
|
||||
- if (!dir) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Cannot get base directory of %s.\n", tmp));
|
||||
- ret = EINVAL;
|
||||
- goto done;
|
||||
- }
|
||||
- } else {
|
||||
- dir = tmp;
|
||||
- }
|
||||
-
|
||||
- ret = cc_residual_exists(uid, dir, SSS_KRB5_TYPE_DIR);
|
||||
- if (ret != EOK) {
|
||||
- if (ret != ENOENT) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("Could not check if ccache is active.\n"));
|
||||
- }
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- /* If primary file isn't in ccache dir, we will ignore it.
|
||||
- * But if primary file has wrong permissions, we will fail.
|
||||
- */
|
||||
- primary_file = talloc_asprintf(tmp_ctx, "%s/primary", dir);
|
||||
- if (!primary_file) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_asprintf failed.\n"));
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
- ret = cc_residual_exists(uid, primary_file, SSS_KRB5_TYPE_FILE);
|
||||
- if (ret != EOK && ret != ENOENT) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("Could not check if file 'primary' [%s] in dir ccache"
|
||||
- " is active.\n", primary_file));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- ret = check_cc_validity(location, realm, princ, &valid);
|
||||
- if (ret != EOK) {
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- *_valid = valid;
|
||||
- ret = EOK;
|
||||
-
|
||||
-done:
|
||||
- talloc_free(tmp_ctx);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
struct sss_krb5_cc_be dir_cc = {
|
||||
.type = SSS_KRB5_TYPE_DIR,
|
||||
.create = cc_dir_create,
|
||||
- .check_existing = cc_dir_check_existing,
|
||||
};
|
||||
|
||||
|
||||
@@ -1381,36 +1129,9 @@ cc_keyring_create(const char *location, pcre *illegal_re,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-errno_t
|
||||
-cc_keyring_check_existing(const char *location, uid_t uid,
|
||||
- const char *realm, const char *princ,
|
||||
- bool *_valid)
|
||||
-{
|
||||
- errno_t ret;
|
||||
- bool valid;
|
||||
- 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;
|
||||
- }
|
||||
-
|
||||
- /* Check if any user is actively using this cache */
|
||||
- ret = check_cc_validity(location, realm, princ, &valid);
|
||||
- if (ret != EOK) {
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- *_valid = valid;
|
||||
- return EOK;
|
||||
-}
|
||||
-
|
||||
struct sss_krb5_cc_be keyring_cc = {
|
||||
.type = SSS_KRB5_TYPE_KEYRING,
|
||||
.create = cc_keyring_create,
|
||||
- .check_existing = cc_keyring_check_existing,
|
||||
};
|
||||
|
||||
#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index e241666289193bdc3c5eccadfffc4d3d669dff16..b364f87aa6e6f0070e8acb5559ee92f2e001e0a5 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -45,16 +45,12 @@ 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,
|
||||
- const char *realm, const char *princ,
|
||||
- bool *valid);
|
||||
|
||||
/* A ccache back end */
|
||||
struct sss_krb5_cc_be {
|
||||
enum sss_krb5_cc_type type;
|
||||
|
||||
cc_be_create_fn create;
|
||||
- cc_be_check_existing check_existing;
|
||||
};
|
||||
|
||||
extern struct sss_krb5_cc_be file_cc;
|
||||
@@ -83,6 +79,8 @@ errno_t restore_creds(struct sss_creds *saved_creds);
|
||||
errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);
|
||||
errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
||||
const char *ccname, const char *principal);
|
||||
+errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
||||
+ const char *realm, const char *principal);
|
||||
|
||||
errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
||||
struct tgt_times *tgtt);
|
||||
--
|
||||
1.8.3.1
|
||||
|
348
0009-krb5-Unify-function-to-create-ccache-files.patch
Normal file
348
0009-krb5-Unify-function-to-create-ccache-files.patch
Normal file
@ -0,0 +1,348 @@
|
||||
From 1c022b3556f442f57326c4a3f250128b1bd232ae Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 17:25:01 -0400
|
||||
Subject: [PATCH 09/14] krb5: Unify function to create ccache files
|
||||
|
||||
Only 2 types (FILE and DIR) need to precreate files or directories
|
||||
on the file system, and the 2 functions were basically identical.
|
||||
|
||||
Consolidate all in one common function and use that function directly
|
||||
where needed instead of using indirection.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 6 ++--
|
||||
src/providers/krb5/krb5_utils.c | 71 ++++++++++-------------------------------
|
||||
src/providers/krb5/krb5_utils.h | 14 ++------
|
||||
src/tests/krb5_child-test.c | 6 ++--
|
||||
src/tests/krb5_utils-tests.c | 40 +++++++++++------------
|
||||
5 files changed, 43 insertions(+), 94 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index 1ea179be3af48b16129aeb4c2d850a66244f7d08..d2c53f98c04cda01c2a8e0efe038f5cd5fa82839 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -333,9 +333,9 @@ static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- ret = kr->cc_be->create(kr->ccname,
|
||||
- kr->krb5_ctx->illegal_path_re,
|
||||
- kr->uid, kr->gid, private_path);
|
||||
+ ret = sss_krb5_precreate_ccache(kr->ccname,
|
||||
+ kr->krb5_ctx->illegal_path_re,
|
||||
+ kr->uid, kr->gid, private_path);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, ("ccache creation failed.\n"));
|
||||
return ret;
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index c4849e74bd43b096b585398970f5b81e946212e9..83e61e14ecc116b9556231c5d8a0f55b63260c77 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -722,19 +722,31 @@ done:
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-static errno_t
|
||||
-create_ccache_dir_head(const char *parent, pcre *illegal_re,
|
||||
- uid_t uid, gid_t gid, bool private_path)
|
||||
+errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re,
|
||||
+ uid_t uid, gid_t gid, bool private_path)
|
||||
{
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ const char *filename;
|
||||
char *ccdirname;
|
||||
- TALLOC_CTX *tmp_ctx = NULL;
|
||||
char *end;
|
||||
errno_t ret;
|
||||
|
||||
+ if (ccname[0] == '/') {
|
||||
+ filename = ccname;
|
||||
+ } else if (strncmp(ccname, "FILE:", 5) == 0) {
|
||||
+ filename = ccname + 5;
|
||||
+ } else if (strncmp(ccname, "DIR:", 4) == 0) {
|
||||
+ filename = ccname + 4;
|
||||
+ } else {
|
||||
+ /* only FILE and DIR types need precreation so far, we ignore any
|
||||
+ * other type */
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (!tmp_ctx) return ENOMEM;
|
||||
|
||||
- ccdirname = talloc_strdup(tmp_ctx, parent);
|
||||
+ ccdirname = talloc_strdup(tmp_ctx, filename);
|
||||
if (ccdirname == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_strdup failed.\n"));
|
||||
ret = ENOMEM;
|
||||
@@ -1066,72 +1078,23 @@ get_cc_be_ops_ccache(const char *ccache)
|
||||
}
|
||||
|
||||
/*======== Operations on the FILE: back end ========*/
|
||||
-errno_t
|
||||
-cc_file_create(const char *location, pcre *illegal_re,
|
||||
- uid_t uid, gid_t gid, bool private_path)
|
||||
-{
|
||||
- const char *filename;
|
||||
-
|
||||
- filename = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_FILE);
|
||||
- if (filename == NULL) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("Bad ccache type %s\n", location));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- return create_ccache_dir_head(filename, illegal_re, uid, gid, private_path);
|
||||
-}
|
||||
|
||||
struct sss_krb5_cc_be file_cc = {
|
||||
.type = SSS_KRB5_TYPE_FILE,
|
||||
- .create = cc_file_create,
|
||||
};
|
||||
|
||||
#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
/*======== Operations on the DIR: back end ========*/
|
||||
-errno_t
|
||||
-cc_dir_create(const char *location, pcre *illegal_re,
|
||||
- uid_t uid, gid_t gid, bool private_path)
|
||||
-{
|
||||
- const char *dir_name;
|
||||
-
|
||||
- dir_name = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_DIR);
|
||||
- if (dir_name == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Bad residual type\n"));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- return create_ccache_dir_head(dir_name, illegal_re, uid, gid, private_path);
|
||||
-}
|
||||
|
||||
struct sss_krb5_cc_be dir_cc = {
|
||||
.type = SSS_KRB5_TYPE_DIR,
|
||||
- .create = cc_dir_create,
|
||||
};
|
||||
|
||||
|
||||
/*======== Operations on the KEYRING: back end ========*/
|
||||
|
||||
-errno_t
|
||||
-cc_keyring_create(const char *location, pcre *illegal_re,
|
||||
- uid_t uid, gid_t gid, bool private_path)
|
||||
-{
|
||||
- const char *residual;
|
||||
-
|
||||
- residual = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_KEYRING);
|
||||
- if (residual == NULL) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("Bad ccache type %s\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,
|
||||
};
|
||||
|
||||
#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index b364f87aa6e6f0070e8acb5559ee92f2e001e0a5..5f720335aab1ac6e493843ac197c5af881a9b998 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -42,15 +42,9 @@ errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb,
|
||||
const char *user,
|
||||
const char *upn);
|
||||
|
||||
-/* 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);
|
||||
-
|
||||
/* A ccache back end */
|
||||
struct sss_krb5_cc_be {
|
||||
enum sss_krb5_cc_type type;
|
||||
-
|
||||
- cc_be_create_fn create;
|
||||
};
|
||||
|
||||
extern struct sss_krb5_cc_be file_cc;
|
||||
@@ -58,9 +52,6 @@ extern struct sss_krb5_cc_be file_cc;
|
||||
errno_t create_ccache_dir(const char *dirname, pcre *illegal_re,
|
||||
uid_t uid, gid_t gid, bool private_path);
|
||||
|
||||
-errno_t cc_file_create(const char *filename, pcre *illegal_re,
|
||||
- uid_t uid, gid_t gid, bool private_path);
|
||||
-
|
||||
struct sss_krb5_cc_be *get_cc_be_ops(enum sss_krb5_cc_type type);
|
||||
struct sss_krb5_cc_be *get_cc_be_ops_ccache(const char *ccache);
|
||||
|
||||
@@ -76,6 +67,8 @@ errno_t switch_creds(TALLOC_CTX *mem_ctx,
|
||||
struct sss_creds **saved_creds);
|
||||
errno_t restore_creds(struct sss_creds *saved_creds);
|
||||
|
||||
+errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re,
|
||||
+ uid_t uid, gid_t gid, bool private_path);
|
||||
errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);
|
||||
errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
||||
const char *ccname, const char *principal);
|
||||
@@ -90,9 +83,6 @@ errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
||||
extern struct sss_krb5_cc_be dir_cc;
|
||||
extern struct sss_krb5_cc_be keyring_cc;
|
||||
|
||||
-errno_t cc_dir_create(const char *location, pcre *illegal_re,
|
||||
- uid_t uid, gid_t gid, bool private_path);
|
||||
-
|
||||
#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
|
||||
|
||||
diff --git a/src/tests/krb5_child-test.c b/src/tests/krb5_child-test.c
|
||||
index dff62ab64dd1948d20da6b640a0570ee8ea6b11d..5ea30014f9c8f748e85506627b7f40d72b913b1b 100644
|
||||
--- a/src/tests/krb5_child-test.c
|
||||
+++ b/src/tests/krb5_child-test.c
|
||||
@@ -287,9 +287,9 @@ create_dummy_req(TALLOC_CTX *mem_ctx, const char *user,
|
||||
DEBUG(SSSDBG_FUNC_DATA, ("ccname [%s] uid [%llu] gid [%llu]\n",
|
||||
kr->ccname, kr->uid, kr->gid));
|
||||
|
||||
- ret = kr->krb5_ctx->cc_be->create(kr->ccname,
|
||||
- kr->krb5_ctx->illegal_path_re,
|
||||
- kr->uid, kr->gid, private);
|
||||
+ ret = sss_krb5_precreate_ccache(kr->ccname,
|
||||
+ kr->krb5_ctx->illegal_path_re,
|
||||
+ kr->uid, kr->gid, private);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, ("create_ccache_dir failed.\n"));
|
||||
goto fail;
|
||||
diff --git a/src/tests/krb5_utils-tests.c b/src/tests/krb5_utils-tests.c
|
||||
index 4715774ff189700bc1cbeb6c90f4438445a594b0..ea0292569135e0fc22a44251cfc4e8719a15837f 100644
|
||||
--- a/src/tests/krb5_utils-tests.c
|
||||
+++ b/src/tests/krb5_utils-tests.c
|
||||
@@ -117,14 +117,14 @@ START_TEST(test_pub_ccache_dir)
|
||||
|
||||
ret = chmod(testpath, 0754);
|
||||
fail_unless(ret == EOK, "chmod failed.");
|
||||
- ret = cc_file_create(filename, NULL, 12345, 12345, false);
|
||||
- fail_unless(ret == EINVAL, "cc_file_create does not return EINVAL "
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, false);
|
||||
+ fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL "
|
||||
"while x-bit is missing.");
|
||||
|
||||
ret = chmod(testpath, 0755);
|
||||
fail_unless(ret == EOK, "chmod failed.");
|
||||
- ret = cc_file_create(filename, NULL, 12345, 12345, false);
|
||||
- fail_unless(ret == EOK, "cc_file_create failed.");
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, false);
|
||||
+ fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed.");
|
||||
|
||||
check_dir(subdirname, 0, 0, 01777);
|
||||
RMDIR(subdirname);
|
||||
@@ -158,7 +158,7 @@ START_TEST(test_pub_ccache_dir_in_user_dir)
|
||||
filename = talloc_asprintf(tmp_ctx, "%s/ccfile", subdirname);
|
||||
fail_unless(filename != NULL, "talloc_asprintf failed.");
|
||||
|
||||
- ret = cc_file_create(filename, NULL, 12345, 12345, false);
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, false);
|
||||
fail_unless(ret == EINVAL, "Creating public ccache dir in user dir "
|
||||
"does not failed with EINVAL.");
|
||||
|
||||
@@ -193,14 +193,14 @@ START_TEST(test_priv_ccache_dir)
|
||||
|
||||
ret = chmod(testpath, 0754);
|
||||
fail_unless(ret == EOK, "chmod failed.");
|
||||
- ret = cc_file_create(filename, NULL, uid, gid, true);
|
||||
- fail_unless(ret == EINVAL, "cc_file_create does not return EINVAL "
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true);
|
||||
+ fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL "
|
||||
"while x-bit is missing.");
|
||||
|
||||
ret = chmod(testpath, 0755);
|
||||
fail_unless(ret == EOK, "chmod failed.");
|
||||
- ret = cc_file_create(filename, NULL, uid, gid, true);
|
||||
- fail_unless(ret == EOK, "cc_file_create failed.");
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true);
|
||||
+ fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed.");
|
||||
|
||||
check_dir(subdir, uid, gid, 0700);
|
||||
RMDIR(subdir);
|
||||
@@ -248,14 +248,14 @@ START_TEST(test_private_ccache_dir_in_user_dir)
|
||||
|
||||
ret = chmod(user_dir, 0600);
|
||||
fail_unless(ret == EOK, "chmod failed.");
|
||||
- ret = cc_file_create(filename, NULL, uid, gid, true);
|
||||
- fail_unless(ret == EINVAL, "cc_file_create does not return EINVAL "
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true);
|
||||
+ fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL "
|
||||
"while x-bit is missing.");
|
||||
|
||||
ret = chmod(user_dir, 0700);
|
||||
fail_unless(ret == EOK, "chmod failed.");
|
||||
- ret = cc_file_create(filename, NULL, uid, gid, true);
|
||||
- fail_unless(ret == EOK, "cc_file_create failed.");
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true);
|
||||
+ fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed.");
|
||||
|
||||
check_dir(dn3, uid, gid, 0700);
|
||||
RMDIR(dn3);
|
||||
@@ -292,7 +292,7 @@ START_TEST(test_private_ccache_dir_in_wrong_user_dir)
|
||||
filename = talloc_asprintf(tmp_ctx, "%s/ccfile", subdirname);
|
||||
fail_unless(filename != NULL, "talloc_asprintf failed.");
|
||||
|
||||
- ret = cc_file_create(filename, NULL, 12345, 12345, true);
|
||||
+ ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, true);
|
||||
fail_unless(ret == EINVAL, "Creating private ccache dir in wrong user "
|
||||
"dir does not failed with EINVAL.");
|
||||
|
||||
@@ -357,7 +357,6 @@ START_TEST(test_illegal_patterns)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
START_TEST(test_cc_dir_create)
|
||||
{
|
||||
char *residual;
|
||||
@@ -386,8 +385,8 @@ START_TEST(test_cc_dir_create)
|
||||
residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir");
|
||||
fail_unless(residual != NULL, "talloc_asprintf failed.");
|
||||
|
||||
- ret = cc_dir_create(residual, illegal_re, uid, gid, true);
|
||||
- fail_unless(ret == EOK, "cc_dir_create failed\n");
|
||||
+ ret = sss_krb5_precreate_ccache(residual, illegal_re, uid, gid, true);
|
||||
+ fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n");
|
||||
ret = rmdir(dirname);
|
||||
if (ret < 0) ret = errno;
|
||||
fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret));
|
||||
@@ -399,8 +398,8 @@ START_TEST(test_cc_dir_create)
|
||||
residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir/");
|
||||
fail_unless(residual != NULL, "talloc_asprintf failed.");
|
||||
|
||||
- ret = cc_dir_create(residual, illegal_re, uid, gid, true);
|
||||
- fail_unless(ret == EOK, "cc_dir_create failed\n");
|
||||
+ ret = sss_krb5_precreate_ccache(residual, illegal_re, uid, gid, true);
|
||||
+ fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n");
|
||||
ret = rmdir(dirname);
|
||||
if (ret < 0) ret = errno;
|
||||
fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret));
|
||||
@@ -408,7 +407,6 @@ START_TEST(test_cc_dir_create)
|
||||
free(cwd);
|
||||
}
|
||||
END_TEST
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
|
||||
|
||||
void setup_talloc_context(void)
|
||||
@@ -774,9 +772,7 @@ Suite *krb5_utils_suite (void)
|
||||
tcase_add_checked_fixture (tc_create_dir, setup_create_dir,
|
||||
teardown_create_dir);
|
||||
tcase_add_test (tc_create_dir, test_illegal_patterns);
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
tcase_add_test (tc_create_dir, test_cc_dir_create);
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
if (getuid() == 0) {
|
||||
tcase_add_test (tc_create_dir, test_priv_ccache_dir);
|
||||
tcase_add_test (tc_create_dir, test_private_ccache_dir_in_user_dir);
|
||||
--
|
||||
1.8.3.1
|
||||
|
337
0010-krb5-Remove-unused-ccache-backend-infrastructure.patch
Normal file
337
0010-krb5-Remove-unused-ccache-backend-infrastructure.patch
Normal file
@ -0,0 +1,337 @@
|
||||
From d20a5a74666413cadbf64c02eb656a5a3b4bb1de Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 20:11:42 -0400
|
||||
Subject: [PATCH 10/14] krb5: Remove unused ccache backend infrastructure
|
||||
|
||||
Remove struct sss_krb5_cc_be and the remaining functions that reference
|
||||
it as they are all unused now.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 26 -----------------
|
||||
src/providers/krb5/krb5_auth.h | 1 -
|
||||
src/providers/krb5/krb5_common.c | 54 ++++++++++--------------------------
|
||||
src/providers/krb5/krb5_common.h | 2 --
|
||||
src/providers/krb5/krb5_utils.c | 60 ----------------------------------------
|
||||
src/providers/krb5/krb5_utils.h | 17 ------------
|
||||
src/tests/krb5_child-test.c | 23 ---------------
|
||||
7 files changed, 15 insertions(+), 168 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index d2c53f98c04cda01c2a8e0efe038f5cd5fa82839..1585f709655853827f2778010452a58657add5d0 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -324,15 +324,6 @@ static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
- if (kr->cc_be == NULL) {
|
||||
- kr->cc_be = get_cc_be_ops_ccache(kr->ccname);
|
||||
- }
|
||||
- if (kr->cc_be == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Cannot get operations on new ccache %s\n", kr->ccname));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
ret = sss_krb5_precreate_ccache(kr->ccname,
|
||||
kr->krb5_ctx->illegal_path_re,
|
||||
kr->uid, kr->gid, private_path);
|
||||
@@ -340,19 +331,6 @@ static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
|
||||
DEBUG(SSSDBG_OP_FAILURE, ("ccache creation failed.\n"));
|
||||
return ret;
|
||||
}
|
||||
- } else {
|
||||
- DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
- ("Saved ccache %s if of different type than ccache in "
|
||||
- "configuration file, reusing the old ccache\n",
|
||||
- kr->old_ccname));
|
||||
-
|
||||
- kr->cc_be = get_cc_be_ops_ccache(kr->old_ccname);
|
||||
- if (kr->cc_be == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Cannot get operations on saved ccache %s\n",
|
||||
- kr->old_ccname));
|
||||
- return EINVAL;
|
||||
- }
|
||||
}
|
||||
|
||||
return EOK;
|
||||
@@ -614,10 +592,6 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- /* The type of the ccache might change during the request if we
|
||||
- * end up reusing an old ccache */
|
||||
- kr->cc_be = krb5_ctx->cc_be;
|
||||
-
|
||||
ccache_file = ldb_msg_find_attr_as_string(res->msgs[0],
|
||||
SYSDB_CCACHE_FILE,
|
||||
NULL);
|
||||
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h
|
||||
index d31925dae6187b3c839e32502fd349e4d64deb32..022dc9b7645f18d01a8a334371e178aa470d92a1 100644
|
||||
--- a/src/providers/krb5/krb5_auth.h
|
||||
+++ b/src/providers/krb5/krb5_auth.h
|
||||
@@ -41,7 +41,6 @@ struct krb5child_req {
|
||||
struct pam_data *pd;
|
||||
struct krb5_ctx *krb5_ctx;
|
||||
|
||||
- struct sss_krb5_cc_be *cc_be;
|
||||
const char *ccname;
|
||||
const char *old_ccname;
|
||||
const char *homedir;
|
||||
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
|
||||
index de7ae0a8fe345c38f9458fb9642a5c1b83c906f5..dedb734fc397d3df3eb7717b19c56051fb2243bb 100644
|
||||
--- a/src/providers/krb5/krb5_common.c
|
||||
+++ b/src/providers/krb5/krb5_common.c
|
||||
@@ -167,7 +167,6 @@ errno_t check_and_export_options(struct dp_option *opts,
|
||||
const char *dummy;
|
||||
char *use_fast_str;
|
||||
char *fast_principal;
|
||||
- enum sss_krb5_cc_type cc_be;
|
||||
char *ccname;
|
||||
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
@@ -291,53 +290,30 @@ errno_t check_and_export_options(struct dp_option *opts,
|
||||
}
|
||||
}
|
||||
|
||||
- cc_be = sss_krb5_get_type(ccname);
|
||||
- switch (cc_be) {
|
||||
- case SSS_KRB5_TYPE_FILE:
|
||||
+ if ((ccname[0] == '/') || (strncmp(ccname, "FILE:", 5) == 0)) {
|
||||
DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type FILE\n"));
|
||||
/* warn if the file type (which is usally created in a sticky bit
|
||||
* laden directory) does not have randomizing chracters */
|
||||
sss_check_cc_template(ccname);
|
||||
|
||||
- krb5_ctx->cc_be = &file_cc;
|
||||
- if (ccname[0] != '/') {
|
||||
- /* FILE:/path/to/cc */
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- DEBUG(SSSDBG_CONF_SETTINGS, ("The ccname template was "
|
||||
+ if (ccname[0] == '/') {
|
||||
+ /* /path/to/cc prepend FILE: */
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, ("The ccname template was "
|
||||
"missing an explicit type, but is an absolute "
|
||||
"path specifier. Assuming FILE:\n"));
|
||||
|
||||
- ccname = talloc_asprintf(tmp_ctx, "FILE:%s", ccname);
|
||||
- if (!ccname) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
+ ccname = talloc_asprintf(tmp_ctx, "FILE:%s", ccname);
|
||||
+ if (!ccname) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = dp_opt_set_string(opts, KRB5_CCNAME_TMPL, ccname);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("dp_opt_set_string failed.\n"));
|
||||
+ goto done;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- ret = dp_opt_set_string(opts, KRB5_CCNAME_TMPL, ccname);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("dp_opt_set_string failed.\n"));
|
||||
- goto done;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_DIR:
|
||||
- DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type DIR\n"));
|
||||
- krb5_ctx->cc_be = &dir_cc;
|
||||
- break;
|
||||
-
|
||||
- case SSS_KRB5_TYPE_KEYRING:
|
||||
- DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type KEYRING\n"));
|
||||
- krb5_ctx->cc_be = &keyring_cc;
|
||||
- break;
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
- default:
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("Unknown ccname database\n"));
|
||||
- ret = EINVAL;
|
||||
- goto done;
|
||||
}
|
||||
|
||||
ret = EOK;
|
||||
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
|
||||
index e56bd496e04a7a5c8776a34648aabe0f2d73a3b9..eac0d6b1f0c0fec4a107a7b830d8b0c927f4fe42 100644
|
||||
--- a/src/providers/krb5/krb5_common.h
|
||||
+++ b/src/providers/krb5/krb5_common.h
|
||||
@@ -89,7 +89,6 @@ struct krb5_service {
|
||||
struct fo_service;
|
||||
struct deferred_auth_ctx;
|
||||
struct renew_tgt_ctx;
|
||||
-struct sss_krb5_cc_be;
|
||||
|
||||
enum krb5_config_type {
|
||||
K5C_GENERIC,
|
||||
@@ -127,7 +126,6 @@ struct krb5_ctx {
|
||||
struct krb5_service *kpasswd_service;
|
||||
int child_debug_fd;
|
||||
|
||||
- struct sss_krb5_cc_be *cc_be;
|
||||
pcre *illegal_path_re;
|
||||
|
||||
struct deferred_auth_ctx *deferred_auth_ctx;
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index 83e61e14ecc116b9556231c5d8a0f55b63260c77..d0ccd2d7e03bcabe07113b5abb43d9119b35321c 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -1039,66 +1039,6 @@ done:
|
||||
}
|
||||
|
||||
|
||||
-/*======== ccache back end utilities ========*/
|
||||
-struct sss_krb5_cc_be *
|
||||
-get_cc_be_ops(enum sss_krb5_cc_type type)
|
||||
-{
|
||||
- struct sss_krb5_cc_be *be = NULL;
|
||||
-
|
||||
- switch (type) {
|
||||
- case SSS_KRB5_TYPE_FILE:
|
||||
- be = &file_cc;
|
||||
- break;
|
||||
-
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_DIR:
|
||||
- be = &dir_cc;
|
||||
- break;
|
||||
-
|
||||
- case SSS_KRB5_TYPE_KEYRING:
|
||||
- be = &keyring_cc;
|
||||
- break;
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
- case SSS_KRB5_TYPE_UNKNOWN:
|
||||
- be = NULL;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return be;
|
||||
-}
|
||||
-
|
||||
-struct sss_krb5_cc_be *
|
||||
-get_cc_be_ops_ccache(const char *ccache)
|
||||
-{
|
||||
- enum sss_krb5_cc_type type;
|
||||
-
|
||||
- type = sss_krb5_get_type(ccache);
|
||||
- return get_cc_be_ops(type);
|
||||
-}
|
||||
-
|
||||
-/*======== Operations on the FILE: back end ========*/
|
||||
-
|
||||
-struct sss_krb5_cc_be file_cc = {
|
||||
- .type = SSS_KRB5_TYPE_FILE,
|
||||
-};
|
||||
-
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
-/*======== Operations on the DIR: back end ========*/
|
||||
-
|
||||
-struct sss_krb5_cc_be dir_cc = {
|
||||
- .type = SSS_KRB5_TYPE_DIR,
|
||||
-};
|
||||
-
|
||||
-
|
||||
-/*======== Operations on the KEYRING: back end ========*/
|
||||
-
|
||||
-struct sss_krb5_cc_be keyring_cc = {
|
||||
- .type = SSS_KRB5_TYPE_KEYRING,
|
||||
-};
|
||||
-
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
errno_t get_domain_or_subdomain(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx,
|
||||
char *domain_name,
|
||||
struct sss_domain_info **dom)
|
||||
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
||||
index 5f720335aab1ac6e493843ac197c5af881a9b998..e41309e765b58f7cd2567f1d13fea30d093fd344 100644
|
||||
--- a/src/providers/krb5/krb5_utils.h
|
||||
+++ b/src/providers/krb5/krb5_utils.h
|
||||
@@ -42,19 +42,9 @@ errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb,
|
||||
const char *user,
|
||||
const char *upn);
|
||||
|
||||
-/* A ccache back end */
|
||||
-struct sss_krb5_cc_be {
|
||||
- enum sss_krb5_cc_type type;
|
||||
-};
|
||||
-
|
||||
-extern struct sss_krb5_cc_be file_cc;
|
||||
-
|
||||
errno_t create_ccache_dir(const char *dirname, pcre *illegal_re,
|
||||
uid_t uid, gid_t gid, bool private_path);
|
||||
|
||||
-struct sss_krb5_cc_be *get_cc_be_ops(enum sss_krb5_cc_type type);
|
||||
-struct sss_krb5_cc_be *get_cc_be_ops_ccache(const char *ccache);
|
||||
-
|
||||
char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
|
||||
const char *template, bool file_mode,
|
||||
bool case_sensitive, bool *private_path);
|
||||
@@ -78,13 +68,6 @@ errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
||||
errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
||||
struct tgt_times *tgtt);
|
||||
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
-
|
||||
-extern struct sss_krb5_cc_be dir_cc;
|
||||
-extern struct sss_krb5_cc_be keyring_cc;
|
||||
-
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
|
||||
errno_t get_domain_or_subdomain(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx,
|
||||
char *domain_name,
|
||||
diff --git a/src/tests/krb5_child-test.c b/src/tests/krb5_child-test.c
|
||||
index 5ea30014f9c8f748e85506627b7f40d72b913b1b..c32ccc318e9826d598bb29a766ed1839fd9bf066 100644
|
||||
--- a/src/tests/krb5_child-test.c
|
||||
+++ b/src/tests/krb5_child-test.c
|
||||
@@ -196,7 +196,6 @@ create_dummy_req(TALLOC_CTX *mem_ctx, const char *user,
|
||||
const char *ccname, const char *ccname_template,
|
||||
int timeout)
|
||||
{
|
||||
- enum sss_krb5_cc_type cc_be;
|
||||
struct krb5child_req *kr;
|
||||
struct passwd *pwd;
|
||||
bool private = false;
|
||||
@@ -262,28 +261,6 @@ create_dummy_req(TALLOC_CTX *mem_ctx, const char *user,
|
||||
}
|
||||
if (!kr->ccname) goto fail;
|
||||
|
||||
- cc_be = sss_krb5_get_type(kr->ccname);
|
||||
- switch (cc_be) {
|
||||
- case SSS_KRB5_TYPE_FILE:
|
||||
- kr->krb5_ctx->cc_be = &file_cc;
|
||||
- break;
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_DIR:
|
||||
- kr->krb5_ctx->cc_be = &dir_cc;
|
||||
- break;
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
- default:
|
||||
- if (tmpl[0] != '/') {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("Unkown ccname database\n"));
|
||||
- ret = EINVAL;
|
||||
- goto fail;
|
||||
- }
|
||||
- DEBUG(SSSDBG_CONF_SETTINGS, ("The ccname template was "
|
||||
- "missing an explicit type, but looks like an absolute "
|
||||
- "path specifier. Assuming FILE:\n"));
|
||||
- kr->krb5_ctx->cc_be = &file_cc;
|
||||
- break;
|
||||
- }
|
||||
DEBUG(SSSDBG_FUNC_DATA, ("ccname [%s] uid [%llu] gid [%llu]\n",
|
||||
kr->ccname, kr->uid, kr->gid));
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
69
0011-krb5-Remove-unused-function.patch
Normal file
69
0011-krb5-Remove-unused-function.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From 0dbcc64a5cee58d5fffaaef923302d9c7a951a7d Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Fri, 30 Aug 2013 20:55:38 -0400
|
||||
Subject: [PATCH 11/14] krb5: Remove unused function
|
||||
|
||||
Related:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/util/sss_krb5.c | 30 ------------------------------
|
||||
src/util/sss_krb5.h | 2 --
|
||||
2 files changed, 32 deletions(-)
|
||||
|
||||
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
|
||||
index 440edab8a4624b33b7d358e64ead93949fc3de88..d4fee42a0297d5bb46135669a5fc12857ea95936 100644
|
||||
--- a/src/util/sss_krb5.c
|
||||
+++ b/src/util/sss_krb5.c
|
||||
@@ -921,36 +921,6 @@ sss_krb5_residual_by_type(const char *full_location,
|
||||
}
|
||||
|
||||
const char *
|
||||
-sss_krb5_cc_file_path(const char *full_location)
|
||||
-{
|
||||
- enum sss_krb5_cc_type cc_type;
|
||||
- const char *residual;
|
||||
-
|
||||
- cc_type = sss_krb5_get_type(full_location);
|
||||
- residual = sss_krb5_residual_by_type(full_location, cc_type);
|
||||
-
|
||||
- switch(cc_type) {
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_KEYRING:
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
- case SSS_KRB5_TYPE_FILE:
|
||||
- return residual;
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_DIR:
|
||||
- /* DIR::/run/user/tkt_foo */
|
||||
- if (residual[0] == ':') {
|
||||
- ++residual;
|
||||
- }
|
||||
- return residual;
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
- case SSS_KRB5_TYPE_UNKNOWN:
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
-const char *
|
||||
sss_krb5_residual_check_type(const char *full_location,
|
||||
enum sss_krb5_cc_type expected_type)
|
||||
{
|
||||
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
|
||||
index aaf2a64882254ba173fb57c5dab47d246082392c..efde48b62170a142ebfca907013c3558ec47f428 100644
|
||||
--- a/src/util/sss_krb5.h
|
||||
+++ b/src/util/sss_krb5.h
|
||||
@@ -154,8 +154,6 @@ sss_krb5_get_type(const char *full_location);
|
||||
const char *
|
||||
sss_krb5_residual_by_type(const char *full_location, enum sss_krb5_cc_type type);
|
||||
const char *
|
||||
-sss_krb5_cc_file_path(const char *full_location);
|
||||
-const char *
|
||||
sss_krb5_residual_check_type(const char *full_location,
|
||||
enum sss_krb5_cc_type expected_type);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
97
0012-krb5-Add-file-dir-path-precheck.patch
Normal file
97
0012-krb5-Add-file-dir-path-precheck.patch
Normal file
@ -0,0 +1,97 @@
|
||||
From 14050f35224360883e20ebd810d3eb40f39267cf Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Sat, 31 Aug 2013 14:21:22 -0400
|
||||
Subject: [PATCH 12/14] krb5: Add file/dir path precheck
|
||||
|
||||
Add a precheck on the actual existence at all of the file/dir ccname
|
||||
targeted (for FILE/DIR types), and bail early if nothing is available.
|
||||
|
||||
While testing I found out that without this check, the krb5_cc_resolve()
|
||||
function we call as user to check old paths would try to create the
|
||||
directory if it didn't exist.
|
||||
|
||||
With a ccname of DIR:/tmp/ccdir_1000 saved in the user entry this would
|
||||
cause two undesirable side effects:
|
||||
|
||||
First it would actually create a directory with the old name, when it
|
||||
should not.
|
||||
|
||||
Second, because for some reason the umask is set to 0127 in sssd_be, it
|
||||
would create the directory with permission 600 (missing the 'x' traverse
|
||||
bit on the directory. If the new ccache has the same name it would cause
|
||||
the krb5_child process to fal to store the credential cache in it.
|
||||
|
||||
Related:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 1 +
|
||||
src/providers/krb5/krb5_utils.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 35 insertions(+)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index 1585f709655853827f2778010452a58657add5d0..7cfa3e943c15c0f515f3372079cee18dd7978c92 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -69,6 +69,7 @@ check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
|
||||
realm, kr->upn);
|
||||
switch (ret) {
|
||||
case ERR_NOT_FOUND:
|
||||
+ case ENOENT:
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
("Saved ccache %s doesn't exist.\n", old_ccache));
|
||||
return ENOENT;
|
||||
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
||||
index d0ccd2d7e03bcabe07113b5abb43d9119b35321c..bb933d7f722cbef90b73f4a721382165572c69b9 100644
|
||||
--- a/src/providers/krb5/krb5_utils.c
|
||||
+++ b/src/providers/krb5/krb5_utils.c
|
||||
@@ -967,6 +967,30 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errno_t sss_low_level_path_check(const char *ccname)
|
||||
+{
|
||||
+ const char *filename;
|
||||
+ struct stat buf;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (ccname[0] == '/') {
|
||||
+ filename = ccname;
|
||||
+ } else if (strncmp(ccname, "FILE:", 5) == 0) {
|
||||
+ filename = ccname + 5;
|
||||
+ } else if (strncmp(ccname, "DIR:", 4) == 0) {
|
||||
+ filename = ccname + 4;
|
||||
+ if (filename[0] == ':') filename += 1;
|
||||
+ } else {
|
||||
+ /* only FILE and DIR types need file checks so far, we ignore any
|
||||
+ * other type */
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
+ ret = stat(filename, &buf);
|
||||
+ if (ret == -1) return errno;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
||||
const char *realm, const char *principal)
|
||||
{
|
||||
@@ -980,6 +1004,16 @@ errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
||||
krb5_error_code kerr;
|
||||
errno_t ret;
|
||||
|
||||
+ /* first of all verify if the old ccache file/dir exists as we may be
|
||||
+ * trying to verify if an old ccache exists at all. If no file/dir
|
||||
+ * exists bail out immediately otherwise a following krb5_cc_resolve()
|
||||
+ * call may actually create paths and files we do not want to have
|
||||
+ * around */
|
||||
+ ret = sss_low_level_path_check(ccname);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (tmp_ctx == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new failed.\n"));
|
||||
--
|
||||
1.8.3.1
|
||||
|
582
0013-krb5_child-Simplify-ccache-creation.patch
Normal file
582
0013-krb5_child-Simplify-ccache-creation.patch
Normal file
@ -0,0 +1,582 @@
|
||||
From a6a0d4edebccd3cf04f9813fc65185845626b5d4 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Mon, 2 Sep 2013 23:52:46 -0400
|
||||
Subject: [PATCH 13/14] krb5_child: Simplify ccache creation
|
||||
|
||||
The containing ccache directory is precreated by the parent code,
|
||||
so there is no special need to do so here for any type.
|
||||
Also the special handling for the FILE ccache temporary file is not really
|
||||
useful, because libkrb5 internally unlinks and then recreate the file, so
|
||||
mkstemp cannot really prevent subtle races, it can only make sure the file is
|
||||
unique at creation time.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/providers/krb5/krb5_child.c | 480 ++++++++--------------------------------
|
||||
1 file changed, 90 insertions(+), 390 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
|
||||
index 842b50e6e23cf9b00f51c0a01cfd960e4156ee21..4f56736de152d1443add8b69db261faf3b75529f 100644
|
||||
--- a/src/providers/krb5/krb5_child.c
|
||||
+++ b/src/providers/krb5/krb5_child.c
|
||||
@@ -424,11 +424,7 @@ static krb5_error_code create_empty_cred(krb5_context ctx, krb5_principal princ,
|
||||
|
||||
done:
|
||||
if (kerr != 0) {
|
||||
- if (cred != NULL && cred->client != NULL) {
|
||||
- krb5_free_principal(ctx, cred->client);
|
||||
- }
|
||||
-
|
||||
- free(cred);
|
||||
+ krb5_free_creds(ctx, cred);
|
||||
} else {
|
||||
*_cred = cred;
|
||||
}
|
||||
@@ -436,281 +432,38 @@ done:
|
||||
return kerr;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
-static bool need_switch_to_principal(krb5_context ctx, krb5_principal princ)
|
||||
-{
|
||||
- krb5_error_code kerr;
|
||||
- krb5_ccache default_cc = NULL;
|
||||
- krb5_principal default_princ = NULL;
|
||||
- char *default_full_name = NULL;
|
||||
- char *full_name = NULL;
|
||||
- bool ret = false;
|
||||
-
|
||||
- kerr = krb5_cc_default(ctx, &default_cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_TRACE_INTERNAL, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- kerr = krb5_cc_get_principal(ctx, default_cc, &default_princ);
|
||||
- if (kerr == KRB5_FCC_NOFILE) {
|
||||
- /* There is not any default cache. */
|
||||
- ret = true;
|
||||
- goto done;
|
||||
- } else if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_TRACE_INTERNAL, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- kerr = krb5_unparse_name(ctx, default_princ, &default_full_name);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_TRACE_INTERNAL, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- kerr = krb5_unparse_name(ctx, princ, &full_name);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_TRACE_INTERNAL, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- DEBUG(SSSDBG_FUNC_DATA,
|
||||
- ("Comparing default principal [%s] and new principal [%s].\n",
|
||||
- default_full_name, full_name));
|
||||
- if (0 == strcmp(default_full_name, full_name)) {
|
||||
- ret = true;
|
||||
- }
|
||||
-
|
||||
-done:
|
||||
- if (default_cc != NULL) {
|
||||
- kerr = krb5_cc_close(ctx, default_cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* all functions can be safely called with NULL. */
|
||||
- krb5_free_principal(ctx, default_princ);
|
||||
- krb5_free_unparsed_name(ctx, default_full_name);
|
||||
- krb5_free_unparsed_name(ctx, full_name);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
-static krb5_error_code
|
||||
-store_creds_in_ccache(krb5_context ctx, krb5_principal princ,
|
||||
- krb5_ccache cc, krb5_creds *creds)
|
||||
-{
|
||||
- krb5_error_code kerr;
|
||||
- krb5_creds *l_cred;
|
||||
- char *ccname;
|
||||
-
|
||||
- if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) {
|
||||
- kerr = krb5_cc_get_full_name(ctx, cc, &ccname);
|
||||
- if (kerr != 0) {
|
||||
- DEBUG(SSSDBG_TRACE_ALL,
|
||||
- ("Couldn't determine full name of ccache\n"));
|
||||
- } else {
|
||||
- DEBUG(SSSDBG_TRACE_ALL,
|
||||
- ("Storing credentials in [%s]\n", ccname));
|
||||
- krb5_free_string(ctx, ccname);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- kerr = krb5_cc_initialize(ctx, cc, princ);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (creds == NULL) {
|
||||
- kerr = create_empty_cred(ctx, princ, &l_cred);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
- } else {
|
||||
- l_cred = creds;
|
||||
- }
|
||||
-
|
||||
- kerr = krb5_cc_store_cred(ctx, cc, l_cred);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- if (need_switch_to_principal(ctx, princ)) {
|
||||
- kerr = krb5_cc_switch(ctx, cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
- kerr = krb5_cc_close(ctx, cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
-done:
|
||||
- return kerr;
|
||||
-}
|
||||
|
||||
-static krb5_error_code create_ccache_file(krb5_context ctx,
|
||||
- krb5_principal princ,
|
||||
- char *ccname, krb5_creds *creds)
|
||||
+static errno_t handle_randomized(char *in)
|
||||
{
|
||||
- krb5_error_code kerr;
|
||||
- krb5_ccache tmp_cc = NULL;
|
||||
- char *cc_file_name;
|
||||
- int fd = -1;
|
||||
size_t ccname_len;
|
||||
- char *dummy;
|
||||
- char *tmp_ccname;
|
||||
- TALLOC_CTX *tmp_ctx = NULL;
|
||||
- mode_t old_umask;
|
||||
+ char *ccname = NULL;
|
||||
+ int ret;
|
||||
+ int fd;
|
||||
|
||||
- DEBUG(SSSDBG_FUNC_DATA, ("Creating ccache at [%s]\n", ccname));
|
||||
-
|
||||
- if (strncmp(ccname, "FILE:", 5) == 0) {
|
||||
- cc_file_name = ccname + 5;
|
||||
+ /* We only treat the FILE type case in a special way due to the history
|
||||
+ * of storing FILE type ccache in /tmp and associated security issues */
|
||||
+ if (in[0] == '/') {
|
||||
+ ccname = in;
|
||||
+ } else if (strncmp(in, "FILE:", 5) == 0) {
|
||||
+ ccname = in + 5;
|
||||
} else {
|
||||
- cc_file_name = ccname;
|
||||
- }
|
||||
-
|
||||
- if (cc_file_name[0] != '/') {
|
||||
- DEBUG(1, ("Ccache filename is not an absolute path.\n"));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- tmp_ctx = talloc_new(tmp_ctx);
|
||||
- if (tmp_ctx == NULL) {
|
||||
- DEBUG(1, ("talloc_new failed.\n"));
|
||||
- return ENOMEM;
|
||||
- }
|
||||
-
|
||||
- dummy = strrchr(cc_file_name, '/');
|
||||
- tmp_ccname = talloc_strndup(tmp_ctx, cc_file_name,
|
||||
- (size_t) (dummy-cc_file_name));
|
||||
- if (tmp_ccname == NULL) {
|
||||
- DEBUG(1, ("talloc_strdup failed.\n"));
|
||||
- kerr = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
- tmp_ccname = talloc_asprintf_append(tmp_ccname, "/.krb5cc_dummy_XXXXXX");
|
||||
- if (tmp_ccname == NULL) {
|
||||
- kerr = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- old_umask = umask(077);
|
||||
- fd = mkstemp(tmp_ccname);
|
||||
- umask(old_umask);
|
||||
- if (fd == -1) {
|
||||
- kerr = errno;
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("mkstemp failed [%d][%s].\n", kerr, strerror(kerr)));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- kerr = krb5_cc_resolve(ctx, tmp_ccname, &tmp_cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- kerr = store_creds_in_ccache(ctx, princ, tmp_cc, creds);
|
||||
- if (fd != -1) {
|
||||
- close(fd);
|
||||
- fd = -1;
|
||||
- }
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
-
|
||||
- ccname_len = strlen(cc_file_name);
|
||||
- if (ccname_len >= 6 && strcmp(cc_file_name + (ccname_len - 6), "XXXXXX") == 0) {
|
||||
- fd = mkstemp(cc_file_name);
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
+ ccname_len = strlen(ccname);
|
||||
+ if (ccname_len >= 6 && strcmp(ccname + (ccname_len - 6), "XXXXXX") == 0) {
|
||||
+ /* NOTE: this call is only used to create a unique name, as later
|
||||
+ * krb5_cc_initialize() will unlink and recreate the file.
|
||||
+ * This is ok because this part of the code is called with
|
||||
+ * privileges already dropped when handling user ccache, or the ccache
|
||||
+ * is stored in a private directory. So we do not have huge issues if
|
||||
+ * something races, we mostly care only about not accidentally use
|
||||
+ * an existing name and thus failing in the process of saving the
|
||||
+ * cache. Malicious races can only be avoided by libkrb5 itself. */
|
||||
+ fd = mkstemp(ccname);
|
||||
if (fd == -1) {
|
||||
- kerr = errno;
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("mkstemp failed [%d][%s].\n", kerr, strerror(kerr)));
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- kerr = rename(tmp_ccname, cc_file_name);
|
||||
- if (kerr == -1) {
|
||||
- kerr = errno;
|
||||
- DEBUG(1, ("rename failed [%d][%s].\n", kerr, strerror(kerr)));
|
||||
- }
|
||||
-
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, ("Created ccache file: [%s]\n", ccname));
|
||||
-
|
||||
-done:
|
||||
- if (kerr != 0 && tmp_cc != NULL) {
|
||||
- krb5_cc_destroy(ctx, tmp_cc);
|
||||
- }
|
||||
-
|
||||
- if (fd != -1) {
|
||||
- close(fd);
|
||||
- }
|
||||
-
|
||||
- talloc_free(tmp_ctx);
|
||||
- return kerr;
|
||||
-}
|
||||
-
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
-
|
||||
-static errno_t
|
||||
-create_ccdir(const char *dirname, uid_t uid, gid_t gid)
|
||||
-{
|
||||
- mode_t old_umask;
|
||||
- struct stat statbuf;
|
||||
- errno_t ret;
|
||||
-
|
||||
- old_umask = umask(0000);
|
||||
- ret = mkdir(dirname, 0700);
|
||||
- umask(old_umask);
|
||||
- if (ret == -1) {
|
||||
- /* Failing the mkdir is only OK if the directory already
|
||||
- * exists AND it is owned by the same user and group and
|
||||
- * has the correct permissions.
|
||||
- */
|
||||
- ret = errno;
|
||||
- if (ret == EEXIST) {
|
||||
- errno = 0;
|
||||
- ret = stat(dirname, &statbuf);
|
||||
- if (ret == -1) {
|
||||
- ret = errno;
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("stat failed [%d]: %s\n", ret, strerror(ret)));
|
||||
- return EIO;
|
||||
- }
|
||||
-
|
||||
- if (statbuf.st_uid != uid || statbuf.st_gid != gid) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("The directory %s is owned by %d/%d, expected %d/%d\n",
|
||||
- dirname, statbuf.st_uid, statbuf.st_gid, uid, gid));
|
||||
- return EACCES;
|
||||
- }
|
||||
-
|
||||
- if ((statbuf.st_mode & ~S_IFMT) != 0700) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("The directory %s has wrong permissions %o, expected 0700\n",
|
||||
- dirname, (statbuf.st_mode & ~S_IFMT)));
|
||||
- return EACCES;
|
||||
- }
|
||||
- } else {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("mkdir [%s] failed [%d]: %s\n",
|
||||
- dirname, ret, strerror(ret)));
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, ("mkstemp(\"%s\") failed!\n", ccname));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -718,136 +471,79 @@ create_ccdir(const char *dirname, uid_t uid, gid_t gid)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-static krb5_error_code
|
||||
-create_ccache_in_dir(uid_t uid, gid_t gid,
|
||||
- krb5_context ctx,
|
||||
- krb5_principal princ,
|
||||
- char *ccname, krb5_creds *creds)
|
||||
+/* NOTE: callers rely on 'name' being *changed* if it needs to be randomized,
|
||||
+ * as they will then send the name back to the new name via the return call
|
||||
+ * k5c_attach_ccname_msg(). Callers will send in a copy of the name if they
|
||||
+ * do not care for changes. */
|
||||
+static krb5_error_code create_ccache(char *ccname, krb5_creds *creds)
|
||||
{
|
||||
+ krb5_context kctx = NULL;
|
||||
+ krb5_ccache kcc = NULL;
|
||||
+ const char *type;
|
||||
krb5_error_code kerr;
|
||||
- krb5_ccache tmp_cc = NULL;
|
||||
- const char *dirname;
|
||||
-
|
||||
- DEBUG(SSSDBG_FUNC_DATA, ("Creating ccache at [%s]\n", ccname));
|
||||
-
|
||||
- dirname = sss_krb5_residual_check_type(ccname, SSS_KRB5_TYPE_DIR);
|
||||
- if (dirname == NULL) {
|
||||
- return EIO;
|
||||
+#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
+ krb5_ccache cckcc;
|
||||
+ bool switch_to_cc = false;
|
||||
+#endif
|
||||
+
|
||||
+ /* Set a restrictive umask, just in case we end up creating any file */
|
||||
+ umask(077);
|
||||
+
|
||||
+ /* we create a new context here as the main process one may have been
|
||||
+ * opened as root and contain possibly references (even open handles ?)
|
||||
+ * to resources we do not have or do not want to have access to */
|
||||
+ kerr = krb5_init_context(&kctx);
|
||||
+ if (kerr) {
|
||||
+ KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
+ return ERR_INTERNAL;
|
||||
}
|
||||
|
||||
- if (dirname[0] == ':') {
|
||||
- /* Cache name in the form of DIR::filepath represents a single
|
||||
- * ccache in a collection that we are trying to reuse.
|
||||
- * See src/lib/krb5/ccache/cc_dir.c in the MIT Kerberos tree.
|
||||
- */
|
||||
- kerr = krb5_cc_resolve(ctx, ccname, &tmp_cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
- } else if (dirname[0] == '/') {
|
||||
- /* An absolute path denotes that krb5_child should create a new
|
||||
- * ccache. We can afford to just call mkdir(dirname) because we
|
||||
- * only want the last component to be created.
|
||||
- */
|
||||
+ kerr = handle_randomized(ccname);
|
||||
+ if (kerr) goto done;
|
||||
|
||||
- kerr = create_ccdir(dirname, uid, gid);
|
||||
- if (kerr) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("Cannot create directory %s\n", dirname));
|
||||
- goto done;
|
||||
- }
|
||||
+ kerr = krb5_cc_resolve(kctx, ccname, &kcc);
|
||||
+ if (kerr) goto done;
|
||||
|
||||
- kerr = krb5_cc_set_default_name(ctx, ccname);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
+ type = krb5_cc_get_type(kctx, kcc);
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, ("Initializing ccache of type [%s]\n", type));
|
||||
|
||||
- kerr = krb5_cc_new_unique(ctx, "DIR", NULL, &tmp_cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
+#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
+ if (krb5_cc_support_switch(kctx, type)) {
|
||||
+ kerr = krb5_cc_set_default_name(kctx, ccname);
|
||||
+ if (kerr) goto done;
|
||||
+
|
||||
+ kerr = krb5_cc_cache_match(kctx, creds->client, &cckcc);
|
||||
+ if (kerr == KRB5_CC_NOTFOUND) {
|
||||
+ kerr = krb5_cc_new_unique(kctx, type, NULL, &cckcc);
|
||||
+ switch_to_cc = true;
|
||||
}
|
||||
- } else {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- ("Wrong residual format for DIR in ccache %s\n", ccname));
|
||||
- return EIO;
|
||||
+ if (kerr) goto done;
|
||||
+ krb5_cc_close(kctx, kcc);
|
||||
+ kcc = cckcc;
|
||||
}
|
||||
+#endif
|
||||
|
||||
- kerr = store_creds_in_ccache(ctx, princ, tmp_cc, creds);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
-done:
|
||||
- if (kerr != 0 && tmp_cc != NULL) {
|
||||
- krb5_cc_destroy(ctx, tmp_cc);
|
||||
- }
|
||||
- return kerr;
|
||||
-}
|
||||
-
|
||||
-static krb5_error_code
|
||||
-create_ccache_keyring(krb5_context ctx,
|
||||
- krb5_principal princ,
|
||||
- char *ccname,
|
||||
- krb5_creds *creds)
|
||||
-{
|
||||
- krb5_error_code kerr;
|
||||
- krb5_ccache tmp_cc = NULL;
|
||||
-
|
||||
- DEBUG(SSSDBG_FUNC_DATA, ("Creating ccache at [%s]\n", ccname));
|
||||
+ kerr = krb5_cc_initialize(kctx, kcc, creds->client);
|
||||
+ if (kerr) goto done;
|
||||
|
||||
- kerr = krb5_cc_resolve(ctx, ccname, &tmp_cc);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
- goto done;
|
||||
- }
|
||||
+ kerr = krb5_cc_store_cred(kctx, kcc, creds);
|
||||
+ if (kerr) goto done;
|
||||
|
||||
- kerr = store_creds_in_ccache(ctx, princ, tmp_cc, creds);
|
||||
- if (kerr != 0) {
|
||||
- KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
- goto done;
|
||||
+#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
+ if (switch_to_cc) {
|
||||
+ kerr = krb5_cc_switch(kctx, kcc);
|
||||
+ if (kerr) goto done;
|
||||
}
|
||||
+#endif
|
||||
|
||||
done:
|
||||
- if (kerr != 0 && tmp_cc != NULL) {
|
||||
- krb5_cc_destroy(ctx, tmp_cc);
|
||||
+ if (kcc) {
|
||||
+ /* FIXME: should we krb5_cc_destroy in case of error ? */
|
||||
+ krb5_cc_close(kctx, kcc);
|
||||
}
|
||||
-
|
||||
return kerr;
|
||||
}
|
||||
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
-static krb5_error_code
|
||||
-create_ccache(uid_t uid, gid_t gid, krb5_context ctx,
|
||||
- krb5_principal princ, char *ccname, krb5_creds *creds)
|
||||
-{
|
||||
- enum sss_krb5_cc_type cctype;
|
||||
-
|
||||
- cctype = sss_krb5_get_type(ccname);
|
||||
- switch (cctype) {
|
||||
- case SSS_KRB5_TYPE_FILE:
|
||||
- return create_ccache_file(ctx, princ, ccname, creds);
|
||||
-
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_DIR:
|
||||
- return create_ccache_in_dir(uid, gid, ctx, princ, ccname, creds);
|
||||
-
|
||||
- case SSS_KRB5_TYPE_KEYRING:
|
||||
- return create_ccache_keyring(ctx, princ, ccname, creds);
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
- default:
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unknown cache type\n"));
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- return EINVAL; /* Should never get here */
|
||||
-}
|
||||
-
|
||||
static errno_t pack_response_packet(TALLOC_CTX *mem_ctx, errno_t error,
|
||||
struct response_data *resp_list,
|
||||
uint8_t **_buf, size_t *_len)
|
||||
@@ -1176,7 +872,7 @@ static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
|
||||
}
|
||||
|
||||
/* Use the updated principal in the creds in case canonicalized */
|
||||
- kerr = create_ccache_file(ctx, creds.client, ccname, &creds);
|
||||
+ kerr = create_ccache(ccname, &creds);
|
||||
if (kerr != 0) {
|
||||
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
goto done;
|
||||
@@ -1255,8 +951,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
|
||||
}
|
||||
|
||||
/* Use the updated principal in the creds in case canonicalized */
|
||||
- kerr = create_ccache(kr->uid, kr->gid, kr->ctx,
|
||||
- principal, cc_name, kr->creds);
|
||||
+ kerr = create_ccache(cc_name, kr->creds);
|
||||
if (kerr != 0) {
|
||||
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
goto done;
|
||||
@@ -1647,18 +1342,23 @@ done:
|
||||
|
||||
static errno_t create_empty_ccache(struct krb5_req *kr)
|
||||
{
|
||||
+ krb5_creds *creds = NULL;
|
||||
krb5_error_code kerr;
|
||||
|
||||
DEBUG(SSSDBG_TRACE_LIBS, ("Creating empty ccache\n"));
|
||||
|
||||
- kerr = create_ccache(kr->uid, kr->gid, kr->ctx,
|
||||
- kr->princ, kr->ccname, NULL);
|
||||
+ kerr = create_empty_cred(kr->ctx, kr->princ, &creds);
|
||||
+ if (kerr == 0) {
|
||||
+ kerr = create_ccache(kr->ccname, creds);
|
||||
+ }
|
||||
if (kerr != 0) {
|
||||
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
|
||||
} else {
|
||||
kerr = k5c_attach_ccname_msg(kr);
|
||||
}
|
||||
|
||||
+ krb5_free_creds(kr->ctx, creds);
|
||||
+
|
||||
return map_krb5_error(kerr);
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
127
0014-krb5-Remove-unused-helper-functions.patch
Normal file
127
0014-krb5-Remove-unused-helper-functions.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From 077fa994f62641a13665b6a07d38b3d5a903dcdc Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Tue, 3 Sep 2013 20:57:58 -0400
|
||||
Subject: [PATCH 14/14] krb5: Remove unused helper functions
|
||||
|
||||
these functions are not needed anymore.
|
||||
|
||||
Related:
|
||||
https://fedorahosted.org/sssd/ticket/2061
|
||||
---
|
||||
src/util/sss_krb5.c | 80 -----------------------------------------------------
|
||||
src/util/sss_krb5.h | 8 ------
|
||||
2 files changed, 88 deletions(-)
|
||||
|
||||
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
|
||||
index d4fee42a0297d5bb46135669a5fc12857ea95936..f8a7e6f9be15c7b2dfee9906af914533bd8ac4cd 100644
|
||||
--- a/src/util/sss_krb5.c
|
||||
+++ b/src/util/sss_krb5.c
|
||||
@@ -854,86 +854,6 @@ sss_krb5_free_keytab_entry_contents(krb5_context context,
|
||||
}
|
||||
#endif
|
||||
|
||||
-#define SSS_KRB5_FILE "FILE:"
|
||||
-#define SSS_KRB5_DIR "DIR:"
|
||||
-#define SSS_KRB5_KEYRING "KEYRING:"
|
||||
-
|
||||
-enum sss_krb5_cc_type
|
||||
-sss_krb5_get_type(const char *full_location)
|
||||
-{
|
||||
- if (!full_location) {
|
||||
- return SSS_KRB5_TYPE_UNKNOWN;
|
||||
- }
|
||||
-
|
||||
- if (strncmp(full_location, SSS_KRB5_FILE,
|
||||
- sizeof(SSS_KRB5_FILE)-1) == 0) {
|
||||
- return SSS_KRB5_TYPE_FILE;
|
||||
- }
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- else if (strncmp(full_location, SSS_KRB5_DIR,
|
||||
- sizeof(SSS_KRB5_DIR)-1) == 0) {
|
||||
- return SSS_KRB5_TYPE_DIR;
|
||||
- }
|
||||
- else if (strncmp(full_location, SSS_KRB5_KEYRING,
|
||||
- sizeof(SSS_KRB5_KEYRING)-1) == 0) {
|
||||
- return SSS_KRB5_TYPE_KEYRING;
|
||||
- }
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
- else if (full_location[0] == '/') {
|
||||
- return SSS_KRB5_TYPE_FILE;
|
||||
- }
|
||||
-
|
||||
- return SSS_KRB5_TYPE_UNKNOWN;
|
||||
-}
|
||||
-
|
||||
-const char *
|
||||
-sss_krb5_residual_by_type(const char *full_location,
|
||||
- enum sss_krb5_cc_type type)
|
||||
-{
|
||||
- size_t offset;
|
||||
-
|
||||
- if (full_location == NULL) return NULL;
|
||||
-
|
||||
- switch (type) {
|
||||
- case SSS_KRB5_TYPE_FILE:
|
||||
- if (full_location[0] == '/') {
|
||||
- offset = 0;
|
||||
- } else {
|
||||
- offset = sizeof(SSS_KRB5_FILE)-1;
|
||||
- }
|
||||
- break;
|
||||
-#ifdef HAVE_KRB5_CC_COLLECTION
|
||||
- case SSS_KRB5_TYPE_DIR:
|
||||
- offset = sizeof(SSS_KRB5_DIR)-1;
|
||||
- break;
|
||||
-
|
||||
- case SSS_KRB5_TYPE_KEYRING:
|
||||
- offset = sizeof(SSS_KRB5_KEYRING)-1;
|
||||
- break;
|
||||
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
||||
-
|
||||
- default:
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- return full_location + offset;
|
||||
-}
|
||||
-
|
||||
-const char *
|
||||
-sss_krb5_residual_check_type(const char *full_location,
|
||||
- enum sss_krb5_cc_type expected_type)
|
||||
-{
|
||||
- enum sss_krb5_cc_type type;
|
||||
-
|
||||
- type = sss_krb5_get_type(full_location);
|
||||
- if (type != expected_type) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("Unexpected ccache type\n"));
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- return sss_krb5_residual_by_type(full_location, type);
|
||||
-}
|
||||
|
||||
#ifdef HAVE_KRB5_SET_TRACE_CALLBACK
|
||||
|
||||
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
|
||||
index efde48b62170a142ebfca907013c3558ec47f428..db47e0a6b61fc706cdadc74ad1d4c1e9e7ef3589 100644
|
||||
--- a/src/util/sss_krb5.h
|
||||
+++ b/src/util/sss_krb5.h
|
||||
@@ -149,14 +149,6 @@ enum sss_krb5_cc_type {
|
||||
SSS_KRB5_TYPE_UNKNOWN
|
||||
};
|
||||
|
||||
-enum sss_krb5_cc_type
|
||||
-sss_krb5_get_type(const char *full_location);
|
||||
-const char *
|
||||
-sss_krb5_residual_by_type(const char *full_location, enum sss_krb5_cc_type type);
|
||||
-const char *
|
||||
-sss_krb5_residual_check_type(const char *full_location,
|
||||
- enum sss_krb5_cc_type expected_type);
|
||||
-
|
||||
/* === Compatibility routines for the Heimdal Kerberos implementation === */
|
||||
|
||||
void sss_krb5_princ_realm(krb5_context context, krb5_const_principal princ,
|
||||
--
|
||||
1.8.3.1
|
||||
|
20
sssd.spec
20
sssd.spec
@ -8,7 +8,7 @@
|
||||
|
||||
Name: sssd
|
||||
Version: 1.11.0
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Group: Applications/System
|
||||
Summary: System Security Services Daemon
|
||||
License: GPLv3+
|
||||
@ -17,6 +17,20 @@ Source0: https://fedorahosted.org/released/sssd/%{name}-%{version}.tar.gz
|
||||
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
|
||||
### Patches ###
|
||||
Patch0001: 0001-krb5-Add-calls-to-change-and-restore-credentials.patch
|
||||
Patch0002: 0002-krb5-Add-helper-to-destroy-ccache-as-user.patch
|
||||
Patch0003: 0003-krb5-Use-krb5_cc_destroy-to-remove-old-ccaches.patch
|
||||
Patch0004: 0004-krb5-Replace-type-specific-ccache-principal-check.patch
|
||||
Patch0005: 0005-krb5-Move-determination-of-user-being-active.patch
|
||||
Patch0006: 0006-krb5-move-template-check-to-initializzation.patch
|
||||
Patch0007: 0007-krb5-Make-check_for_valid_tgt-static.patch
|
||||
Patch0008: 0008-krb5-Use-new-function-to-validate-ccaches.patch
|
||||
Patch0009: 0009-krb5-Unify-function-to-create-ccache-files.patch
|
||||
Patch0010: 0010-krb5-Remove-unused-ccache-backend-infrastructure.patch
|
||||
Patch0011: 0011-krb5-Remove-unused-function.patch
|
||||
Patch0012: 0012-krb5-Add-file-dir-path-precheck.patch
|
||||
Patch0013: 0013-krb5_child-Simplify-ccache-creation.patch
|
||||
Patch0014: 0014-krb5-Remove-unused-helper-functions.patch
|
||||
|
||||
### Dependencies ###
|
||||
Requires: sssd-common = %{version}-%{release}
|
||||
@ -676,6 +690,10 @@ fi
|
||||
%postun -n libsss_idmap -p /sbin/ldconfig
|
||||
|
||||
%changelog
|
||||
* Wed Aug 28 2013 Jakub Hrozek <jhrozek@redhat.com> - 1.11.0-2
|
||||
- Backport simplification of ccache management from 1.11.1
|
||||
- Resolves: rhbz#1010553 - sssd setting KRB5CCNAME=(null) on login
|
||||
|
||||
* Wed Aug 28 2013 Jakub Hrozek <jhrozek@redhat.com> - 1.11.0-1
|
||||
- New upstream release 1.11.0
|
||||
- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.0
|
||||
|
Loading…
Reference in New Issue
Block a user