|
|
905b4d |
From b53c6d5adcd51869fe2d84b6149b4894fa18a436 Mon Sep 17 00:00:00 2001
|
|
|
905b4d |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
Date: Sat, 18 Oct 2014 20:52:43 +0200
|
|
|
905b4d |
Subject: [PATCH 85/92] KRB5: Move ccache-related functions to krb5_ccache.c
|
|
|
905b4d |
MIME-Version: 1.0
|
|
|
905b4d |
Content-Type: text/plain; charset=UTF-8
|
|
|
905b4d |
Content-Transfer-Encoding: 8bit
|
|
|
905b4d |
|
|
|
905b4d |
Add a new module krb5_ccache.c that contains all ccache-related
|
|
|
905b4d |
operations. The only user of this module shall be krb5_child.c as the
|
|
|
905b4d |
other modules will run unprivileged and accessing the ccache requires
|
|
|
905b4d |
either privileges of root or the ccache owner.
|
|
|
905b4d |
|
|
|
905b4d |
Related:
|
|
|
905b4d |
https://fedorahosted.org/sssd/ticket/2370
|
|
|
905b4d |
|
|
|
905b4d |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
|
|
905b4d |
---
|
|
|
905b4d |
Makefile.am | 4 +
|
|
|
905b4d |
src/providers/krb5/krb5_auth.c | 16 +-
|
|
|
905b4d |
src/providers/krb5/krb5_auth.h | 1 +
|
|
|
905b4d |
src/providers/krb5/{krb5_utils.c => krb5_ccache.c} | 720 +++++----------------
|
|
|
905b4d |
src/providers/krb5/{krb5_utils.h => krb5_ccache.h} | 49 +-
|
|
|
905b4d |
src/providers/krb5/krb5_child.c | 1 +
|
|
|
905b4d |
src/providers/krb5/krb5_common.h | 7 -
|
|
|
905b4d |
src/providers/krb5/krb5_renew_tgt.c | 1 +
|
|
|
905b4d |
src/providers/krb5/krb5_utils.c | 674 +------------------
|
|
|
905b4d |
src/providers/krb5/krb5_utils.h | 15 -
|
|
|
905b4d |
src/tests/krb5_child-test.c | 1 +
|
|
|
905b4d |
src/tests/krb5_utils-tests.c | 1 +
|
|
|
905b4d |
12 files changed, 198 insertions(+), 1292 deletions(-)
|
|
|
905b4d |
copy src/providers/krb5/{krb5_utils.c => krb5_ccache.c} (57%)
|
|
|
905b4d |
copy src/providers/krb5/{krb5_utils.h => krb5_ccache.h} (53%)
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/Makefile.am b/Makefile.am
|
|
|
905b4d |
index 5f265dcefd16ce4efdde4d62f3cd5d02dbce255f..4a69ecb0cfe48e20bde958c9351c2a5ece5ffffa 100644
|
|
|
905b4d |
--- a/Makefile.am
|
|
|
905b4d |
+++ b/Makefile.am
|
|
|
905b4d |
@@ -568,6 +568,7 @@ dist_noinst_HEADERS = \
|
|
|
905b4d |
src/providers/krb5/krb5_utils.h \
|
|
|
905b4d |
src/providers/krb5/krb5_init_shared.h \
|
|
|
905b4d |
src/providers/krb5/krb5_opts.h \
|
|
|
905b4d |
+ src/providers/krb5/krb5_ccache.h \
|
|
|
905b4d |
src/providers/ldap/ldap_common.h \
|
|
|
905b4d |
src/providers/ldap/sdap.h \
|
|
|
905b4d |
src/providers/ldap/sdap_access.h \
|
|
|
905b4d |
@@ -1322,6 +1323,7 @@ strtonum_tests_LDADD = \
|
|
|
905b4d |
krb5_utils_tests_SOURCES = \
|
|
|
905b4d |
src/tests/krb5_utils-tests.c \
|
|
|
905b4d |
src/providers/krb5/krb5_utils.c \
|
|
|
905b4d |
+ src/providers/krb5/krb5_ccache.c \
|
|
|
905b4d |
src/providers/krb5/krb5_common.c \
|
|
|
905b4d |
src/util/sss_krb5.c \
|
|
|
905b4d |
src/providers/data_provider_fo.c \
|
|
|
905b4d |
@@ -1603,6 +1605,7 @@ stress_tests_LDADD = \
|
|
|
905b4d |
krb5_child_test_SOURCES = \
|
|
|
905b4d |
src/tests/krb5_child-test.c \
|
|
|
905b4d |
src/providers/krb5/krb5_utils.c \
|
|
|
905b4d |
+ src/providers/krb5/krb5_ccache.c \
|
|
|
905b4d |
src/providers/krb5/krb5_child_handler.c \
|
|
|
905b4d |
src/providers/krb5/krb5_common.c \
|
|
|
905b4d |
src/util/sss_krb5.c \
|
|
|
905b4d |
@@ -2306,6 +2309,7 @@ libsss_krb5_common_la_SOURCES = \
|
|
|
905b4d |
src/providers/krb5/krb5_access.c \
|
|
|
905b4d |
src/providers/krb5/krb5_child_handler.c \
|
|
|
905b4d |
src/providers/krb5/krb5_init_shared.c \
|
|
|
905b4d |
+ src/providers/krb5/krb5_ccache.c \
|
|
|
905b4d |
src/util/sss_krb5.c \
|
|
|
905b4d |
src/util/become_user.c \
|
|
|
905b4d |
$(NULL)
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
|
|
905b4d |
index c96b7aee99da8c3d43a67a04bb1f67ee048d4705..bd8b51f47462f1eaef8da61b42caedda3475a4e7 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_auth.c
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_auth.c
|
|
|
905b4d |
@@ -39,21 +39,7 @@
|
|
|
905b4d |
#include "util/child_common.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_auth.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_utils.h"
|
|
|
905b4d |
-
|
|
|
905b4d |
-static errno_t safe_remove_old_ccache_file(const char *old_ccache,
|
|
|
905b4d |
- const char *new_ccache,
|
|
|
905b4d |
- uid_t uid, gid_t gid)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- if ((old_ccache == new_ccache)
|
|
|
905b4d |
- || (old_ccache && new_ccache
|
|
|
905b4d |
- && (strcmp(old_ccache, new_ccache) == 0))) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_FUNC, "New and old ccache file are the same, "
|
|
|
905b4d |
- "none will be deleted.\n");
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- return sss_krb5_cc_destroy(old_ccache, uid, gid);
|
|
|
905b4d |
-}
|
|
|
905b4d |
+#include "providers/krb5/krb5_ccache.h"
|
|
|
905b4d |
|
|
|
905b4d |
static errno_t
|
|
|
905b4d |
check_old_ccache(const char *old_ccache, struct krb5child_req *kr,
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h
|
|
|
905b4d |
index 022dc9b7645f18d01a8a334371e178aa470d92a1..00cb658c418ade2e6a1d9b5362a40f97e0dc6c6b 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_auth.h
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_auth.h
|
|
|
905b4d |
@@ -32,6 +32,7 @@
|
|
|
905b4d |
#include "providers/dp_backend.h"
|
|
|
905b4d |
#include "util/child_common.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_common.h"
|
|
|
905b4d |
+#include "providers/krb5/krb5_ccache.h"
|
|
|
905b4d |
|
|
|
905b4d |
#define CCACHE_ENV_NAME "KRB5CCNAME"
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_ccache.c
|
|
|
905b4d |
similarity index 57%
|
|
|
905b4d |
copy from src/providers/krb5/krb5_utils.c
|
|
|
905b4d |
copy to src/providers/krb5/krb5_ccache.c
|
|
|
905b4d |
index 0d2e281198390043068e21b412b57de04df6a12b..5586963338616519f36e5d75e796a597d3ac2f22 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_utils.c
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_ccache.c
|
|
|
905b4d |
@@ -1,12 +1,13 @@
|
|
|
905b4d |
/*
|
|
|
905b4d |
SSSD
|
|
|
905b4d |
|
|
|
905b4d |
- Kerberos 5 Backend Module -- Utilities
|
|
|
905b4d |
+ Kerberos 5 Backend Module -- ccache related utilities
|
|
|
905b4d |
|
|
|
905b4d |
Authors:
|
|
|
905b4d |
Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
+ Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
|
|
|
905b4d |
- Copyright (C) 2009 Red Hat
|
|
|
905b4d |
+ Copyright (C) 2014 Red Hat
|
|
|
905b4d |
|
|
|
905b4d |
This program is free software; you can redistribute it and/or modify
|
|
|
905b4d |
it under the terms of the GNU General Public License as published by
|
|
|
905b4d |
@@ -21,427 +22,37 @@
|
|
|
905b4d |
You should have received a copy of the GNU General Public License
|
|
|
905b4d |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
905b4d |
*/
|
|
|
905b4d |
-#include <string.h>
|
|
|
905b4d |
-#include <stdlib.h>
|
|
|
905b4d |
-#include <libgen.h>
|
|
|
905b4d |
|
|
|
905b4d |
-#include "providers/krb5/krb5_utils.h"
|
|
|
905b4d |
-#include "providers/krb5/krb5_auth.h"
|
|
|
905b4d |
-#include "src/util/find_uid.h"
|
|
|
905b4d |
+#ifdef HAVE_KRB5_KRB5_H
|
|
|
905b4d |
+#include <krb5/krb5.h>
|
|
|
905b4d |
+#else
|
|
|
905b4d |
+#include <krb5.h>
|
|
|
905b4d |
+#endif
|
|
|
905b4d |
+
|
|
|
905b4d |
+#include "providers/krb5/krb5_ccache.h"
|
|
|
905b4d |
+#include "util/sss_krb5.h"
|
|
|
905b4d |
#include "util/util.h"
|
|
|
905b4d |
|
|
|
905b4d |
-errno_t find_or_guess_upn(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
|
|
|
905b4d |
- struct krb5_ctx *krb5_ctx,
|
|
|
905b4d |
- struct sss_domain_info *dom, const char *user,
|
|
|
905b4d |
- const char *user_dom, char **_upn)
|
|
|
905b4d |
+static errno_t
|
|
|
905b4d |
+check_ccache_re(const char *filename, pcre *illegal_re)
|
|
|
905b4d |
{
|
|
|
905b4d |
- const char *upn = NULL;
|
|
|
905b4d |
- int ret;
|
|
|
905b4d |
+ errno_t ret;
|
|
|
905b4d |
|
|
|
905b4d |
- if (krb5_ctx == NULL || dom == NULL || user == NULL || _upn == NULL) {
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (msg != NULL) {
|
|
|
905b4d |
- upn = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL);
|
|
|
905b4d |
- if (upn != NULL) {
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- upn = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL);
|
|
|
905b4d |
- if (upn != NULL) {
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = krb5_get_simple_upn(mem_ctx, krb5_ctx, dom, user,
|
|
|
905b4d |
- user_dom, _upn);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "krb5_get_simple_upn failed.\n");
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- if (ret == EOK && upn != NULL) {
|
|
|
905b4d |
- *_upn = talloc_strdup(mem_ctx, upn);
|
|
|
905b4d |
- if (*_upn == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb,
|
|
|
905b4d |
- struct sss_domain_info *domain,
|
|
|
905b4d |
- const char *user,
|
|
|
905b4d |
- const char *upn)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
- int ret;
|
|
|
905b4d |
- int sret;
|
|
|
905b4d |
- const char *attrs[] = {SYSDB_UPN, SYSDB_CANONICAL_UPN, NULL};
|
|
|
905b4d |
- struct sysdb_attrs *new_attrs;
|
|
|
905b4d |
- struct ldb_result *res;
|
|
|
905b4d |
- bool in_transaction = false;
|
|
|
905b4d |
- const char *cached_upn;
|
|
|
905b4d |
- const char *cached_canonical_upn;
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (sysdb == NULL || user == NULL || upn == NULL) {
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
- if (tmp_ctx == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sysdb_get_user_attr(tmp_ctx, domain, user, attrs, &res;;
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_user_attr failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (res->count != 1) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "[%d] user objects for name [%s] found, " \
|
|
|
905b4d |
- "expected 1.\n", res->count, user);
|
|
|
905b4d |
- ret = EINVAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- cached_upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL);
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (cached_upn != NULL && strcmp(cached_upn, upn) == 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_ALL, "Cached UPN and new one match, "
|
|
|
905b4d |
- "nothing to do.\n");
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- cached_canonical_upn = ldb_msg_find_attr_as_string(res->msgs[0],
|
|
|
905b4d |
- SYSDB_CANONICAL_UPN,
|
|
|
905b4d |
- NULL);
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (cached_canonical_upn != NULL
|
|
|
905b4d |
- && strcmp(cached_canonical_upn, upn) == 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_ALL, "Cached canonical UPN and new one match, "
|
|
|
905b4d |
- "nothing to do.\n");
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_LIBS, "Replacing canonical UPN [%s] with [%s] " \
|
|
|
905b4d |
- "for user [%s].\n",
|
|
|
905b4d |
- cached_canonical_upn == NULL ?
|
|
|
905b4d |
- "empty" : cached_canonical_upn,
|
|
|
905b4d |
- upn, user);
|
|
|
905b4d |
-
|
|
|
905b4d |
- new_attrs = sysdb_new_attrs(tmp_ctx);
|
|
|
905b4d |
- if (new_attrs == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n");
|
|
|
905b4d |
- ret = ENOMEM;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sysdb_attrs_add_string(new_attrs, SYSDB_CANONICAL_UPN, upn);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sysdb_transaction_start(sysdb);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
+ ret = pcre_exec(illegal_re, NULL, filename, strlen(filename),
|
|
|
905b4d |
+ 0, 0, NULL, 0);
|
|
|
905b4d |
+ if (ret == 0) {
|
|
|
905b4d |
DEBUG(SSSDBG_OP_FAILURE,
|
|
|
905b4d |
- "Error %d starting transaction (%s)\n", ret, strerror(ret));
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- in_transaction = true;
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sysdb_set_entry_attr(sysdb, res->msgs[0]->dn, new_attrs,
|
|
|
905b4d |
- cached_canonical_upn == NULL ? SYSDB_MOD_ADD :
|
|
|
905b4d |
- SYSDB_MOD_REP);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed [%d][%s].\n",
|
|
|
905b4d |
- ret, strerror(ret));
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sysdb_transaction_commit(sysdb);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "Failed to commit transaction!\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- in_transaction = false;
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- if (in_transaction) {
|
|
|
905b4d |
- sret = sysdb_transaction_cancel(sysdb);
|
|
|
905b4d |
- if (sret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- talloc_free(tmp_ctx);
|
|
|
905b4d |
-
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-#define S_EXP_UID "{uid}"
|
|
|
905b4d |
-#define L_EXP_UID (sizeof(S_EXP_UID) - 1)
|
|
|
905b4d |
-#define S_EXP_USERID "{USERID}"
|
|
|
905b4d |
-#define L_EXP_USERID (sizeof(S_EXP_USERID) - 1)
|
|
|
905b4d |
-#define S_EXP_EUID "{euid}"
|
|
|
905b4d |
-#define L_EXP_EUID (sizeof(S_EXP_EUID) - 1)
|
|
|
905b4d |
-#define S_EXP_USERNAME "{username}"
|
|
|
905b4d |
-#define L_EXP_USERNAME (sizeof(S_EXP_USERNAME) - 1)
|
|
|
905b4d |
-
|
|
|
905b4d |
-char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
|
|
|
905b4d |
- const char *template, bool file_mode,
|
|
|
905b4d |
- bool case_sensitive)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- char *copy;
|
|
|
905b4d |
- char *p;
|
|
|
905b4d |
- char *n;
|
|
|
905b4d |
- char *result = NULL;
|
|
|
905b4d |
- char *dummy;
|
|
|
905b4d |
- char *name;
|
|
|
905b4d |
- char *res = NULL;
|
|
|
905b4d |
- const char *cache_dir_tmpl;
|
|
|
905b4d |
- TALLOC_CTX *tmp_ctx = NULL;
|
|
|
905b4d |
- char action;
|
|
|
905b4d |
- bool rerun;
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (template == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "Missing template.\n");
|
|
|
905b4d |
- return NULL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
- if (!tmp_ctx) return NULL;
|
|
|
905b4d |
-
|
|
|
905b4d |
- copy = talloc_strdup(tmp_ctx, template);
|
|
|
905b4d |
- if (copy == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- result = talloc_strdup(tmp_ctx, "");
|
|
|
905b4d |
- if (result == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- p = copy;
|
|
|
905b4d |
- while ( (n = strchr(p, '%')) != NULL) {
|
|
|
905b4d |
- *n = '\0';
|
|
|
905b4d |
- n++;
|
|
|
905b4d |
- if ( *n == '\0' ) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "format error, single %% at the end of the template.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- rerun = true;
|
|
|
905b4d |
- action = *n;
|
|
|
905b4d |
- while (rerun) {
|
|
|
905b4d |
- rerun = false;
|
|
|
905b4d |
- switch (action) {
|
|
|
905b4d |
- case 'u':
|
|
|
905b4d |
- if (kr->pd->user == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Cannot expand user name template "
|
|
|
905b4d |
- "because user name is empty.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- name = sss_get_cased_name(tmp_ctx, kr->pd->user,
|
|
|
905b4d |
- case_sensitive);
|
|
|
905b4d |
- if (!name) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "sss_get_cased_name failed\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%s", p,
|
|
|
905b4d |
- name);
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- case 'U':
|
|
|
905b4d |
- if (kr->uid <= 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand uid template "
|
|
|
905b4d |
- "because uid is invalid.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%"SPRIuid, p,
|
|
|
905b4d |
- kr->uid);
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- case 'p':
|
|
|
905b4d |
- if (kr->upn == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Cannot expand user principal name template "
|
|
|
905b4d |
- "because upn is empty.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%s", p, kr->upn);
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- case '%':
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%%", p);
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- case 'r':
|
|
|
905b4d |
- dummy = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_REALM);
|
|
|
905b4d |
- if (dummy == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "Missing kerberos realm.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%s", p, dummy);
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- case 'h':
|
|
|
905b4d |
- if (kr->homedir == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Cannot expand home directory template "
|
|
|
905b4d |
- "because the path is not available.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%s", p, kr->homedir);
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- case 'd':
|
|
|
905b4d |
- if (file_mode) {
|
|
|
905b4d |
- cache_dir_tmpl = dp_opt_get_string(kr->krb5_ctx->opts,
|
|
|
905b4d |
- KRB5_CCACHEDIR);
|
|
|
905b4d |
- if (cache_dir_tmpl == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Missing credential cache directory.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- dummy = expand_ccname_template(tmp_ctx, kr, cache_dir_tmpl,
|
|
|
905b4d |
- false, case_sensitive);
|
|
|
905b4d |
- if (dummy == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Expanding credential cache directory "
|
|
|
905b4d |
- "template failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%s", p, dummy);
|
|
|
905b4d |
- talloc_zfree(dummy);
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "'%%d' is not allowed in this template.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- case 'P':
|
|
|
905b4d |
- if (!file_mode) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "'%%P' is not allowed in this template.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- if (kr->pd->cli_pid == 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand PID template "
|
|
|
905b4d |
- "because PID is not available.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%d", p,
|
|
|
905b4d |
- kr->pd->cli_pid);
|
|
|
905b4d |
- break;
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* Additional syntax from krb5.conf default_ccache_name */
|
|
|
905b4d |
- case '{':
|
|
|
905b4d |
- if (strncmp(n , S_EXP_UID, L_EXP_UID) == 0) {
|
|
|
905b4d |
- action = 'U';
|
|
|
905b4d |
- n += L_EXP_UID - 1;
|
|
|
905b4d |
- rerun = true;
|
|
|
905b4d |
- continue;
|
|
|
905b4d |
- } else if (strncmp(n , S_EXP_USERID, L_EXP_USERID) == 0) {
|
|
|
905b4d |
- action = 'U';
|
|
|
905b4d |
- n += L_EXP_USERID - 1;
|
|
|
905b4d |
- rerun = true;
|
|
|
905b4d |
- continue;
|
|
|
905b4d |
- } else if (strncmp(n , S_EXP_EUID, L_EXP_EUID) == 0) {
|
|
|
905b4d |
- /* SSSD does not distinguish betwen uid and euid,
|
|
|
905b4d |
- * so we treat both the same way */
|
|
|
905b4d |
- action = 'U';
|
|
|
905b4d |
- n += L_EXP_EUID - 1;
|
|
|
905b4d |
- rerun = true;
|
|
|
905b4d |
- continue;
|
|
|
905b4d |
- } else if (strncmp(n , S_EXP_USERNAME, L_EXP_USERNAME) == 0) {
|
|
|
905b4d |
- action = 'u';
|
|
|
905b4d |
- n += L_EXP_USERNAME - 1;
|
|
|
905b4d |
- rerun = true;
|
|
|
905b4d |
- continue;
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- /* ignore any expansion variable we do not understand and
|
|
|
905b4d |
- * let libkrb5 hndle it or fail */
|
|
|
905b4d |
- name = n;
|
|
|
905b4d |
- n = strchr(name, '}');
|
|
|
905b4d |
- if (!n) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Invalid substitution sequence in cache "
|
|
|
905b4d |
- "template. Missing closing '}' in [%s].\n",
|
|
|
905b4d |
- template);
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s%%%.*s", p,
|
|
|
905b4d |
- (int)(n - name + 1), name);
|
|
|
905b4d |
- }
|
|
|
905b4d |
- break;
|
|
|
905b4d |
- default:
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "format error, unknown template [%%%c].\n", *n);
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (result == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- p = n + 1;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- result = talloc_asprintf_append(result, "%s", p);
|
|
|
905b4d |
- if (result == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- res = talloc_move(mem_ctx, &result);
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- talloc_zfree(tmp_ctx);
|
|
|
905b4d |
- return res;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-static errno_t check_parent_stat(struct stat *parent_stat, uid_t uid)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- if (parent_stat->st_uid != 0 && parent_stat->st_uid != uid) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Private directory can only be created below a directory "
|
|
|
905b4d |
- "belonging to root or to [%"SPRIuid"].\n", uid);
|
|
|
905b4d |
+ "Illegal pattern in ccache directory name [%s].\n", filename);
|
|
|
905b4d |
return EINVAL;
|
|
|
905b4d |
+ } else if (ret == PCRE_ERROR_NOMATCH) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_TRACE_LIBS,
|
|
|
905b4d |
+ "Ccache directory name [%s] does not contain "
|
|
|
905b4d |
+ "illegal patterns.\n", filename);
|
|
|
905b4d |
+ return EOK;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- if (parent_stat->st_uid == uid) {
|
|
|
905b4d |
- if (!(parent_stat->st_mode & S_IXUSR)) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Parent directory does not have the search bit set for "
|
|
|
905b4d |
- "the owner.\n");
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- if (!(parent_stat->st_mode & S_IXOTH)) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Parent directory does not have the search bit set for "
|
|
|
905b4d |
- "others.\n");
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "pcre_exec failed [%d].\n", ret);
|
|
|
905b4d |
+ return EFAULT;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
struct string_list {
|
|
|
905b4d |
@@ -523,31 +134,37 @@ done:
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-static errno_t
|
|
|
905b4d |
-check_ccache_re(const char *filename, pcre *illegal_re)
|
|
|
905b4d |
+static errno_t check_parent_stat(struct stat *parent_stat, uid_t uid)
|
|
|
905b4d |
{
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = pcre_exec(illegal_re, NULL, filename, strlen(filename),
|
|
|
905b4d |
- 0, 0, NULL, 0);
|
|
|
905b4d |
- if (ret == 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE,
|
|
|
905b4d |
- "Illegal pattern in ccache directory name [%s].\n", filename);
|
|
|
905b4d |
+ if (parent_stat->st_uid != 0 && parent_stat->st_uid != uid) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
+ "Private directory can only be created below a directory "
|
|
|
905b4d |
+ "belonging to root or to [%"SPRIuid"].\n", uid);
|
|
|
905b4d |
return EINVAL;
|
|
|
905b4d |
- } else if (ret == PCRE_ERROR_NOMATCH) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_LIBS,
|
|
|
905b4d |
- "Ccache directory name [%s] does not contain "
|
|
|
905b4d |
- "illegal patterns.\n", filename);
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "pcre_exec failed [%d].\n", ret);
|
|
|
905b4d |
- return EFAULT;
|
|
|
905b4d |
+ if (parent_stat->st_uid == uid) {
|
|
|
905b4d |
+ if (!(parent_stat->st_mode & S_IXUSR)) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
+ "Parent directory does not have the search bit set for "
|
|
|
905b4d |
+ "the owner.\n");
|
|
|
905b4d |
+ return EINVAL;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ } else {
|
|
|
905b4d |
+ if (!(parent_stat->st_mode & S_IXOTH)) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
+ "Parent directory does not have the search bit set for "
|
|
|
905b4d |
+ "others.\n");
|
|
|
905b4d |
+ return EINVAL;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ return EOK;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-errno_t
|
|
|
905b4d |
-create_ccache_dir(const char *ccdirname, pcre *illegal_re,
|
|
|
905b4d |
- uid_t uid, gid_t gid)
|
|
|
905b4d |
+errno_t create_ccache_dir(const char *ccdirname,
|
|
|
905b4d |
+ pcre *illegal_re,
|
|
|
905b4d |
+ uid_t uid, gid_t gid)
|
|
|
905b4d |
{
|
|
|
905b4d |
int ret = EFAULT;
|
|
|
905b4d |
struct stat parent_stat;
|
|
|
905b4d |
@@ -625,113 +242,6 @@ done:
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
|
|
905b4d |
- struct tgt_times *tgtt)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- krb5_error_code kerr;
|
|
|
905b4d |
- krb5_context ctx = NULL;
|
|
|
905b4d |
- krb5_ccache cc = NULL;
|
|
|
905b4d |
- krb5_principal client_princ = NULL;
|
|
|
905b4d |
- krb5_principal server_princ = NULL;
|
|
|
905b4d |
- char *server_name;
|
|
|
905b4d |
- krb5_creds mcred;
|
|
|
905b4d |
- krb5_creds cred;
|
|
|
905b4d |
- const char *realm_name;
|
|
|
905b4d |
- int realm_length;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_init_context(&ctx;;
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_init_context failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_parse_name(ctx, client_name, &client_princ);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- sss_krb5_princ_realm(ctx, client_princ, &realm_name, &realm_length);
|
|
|
905b4d |
-
|
|
|
905b4d |
- server_name = talloc_asprintf(NULL, "krbtgt/%.*s@%.*s",
|
|
|
905b4d |
- realm_length, realm_name,
|
|
|
905b4d |
- realm_length, realm_name);
|
|
|
905b4d |
- if (server_name == NULL) {
|
|
|
905b4d |
- kerr = KRB5_CC_NOMEM;
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_parse_name(ctx, server_name, &server_princ);
|
|
|
905b4d |
- talloc_free(server_name);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_resolve(ctx, ccache_file, &cc);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- memset(&mcred, 0, sizeof(mcred));
|
|
|
905b4d |
- memset(&cred, 0, sizeof(mcred));
|
|
|
905b4d |
-
|
|
|
905b4d |
- mcred.server = server_princ;
|
|
|
905b4d |
- mcred.client = client_princ;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_retrieve_cred(ctx, cc, 0, &mcred, &cred);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_retrieve_cred failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tgtt->authtime = cred.times.authtime;
|
|
|
905b4d |
- tgtt->starttime = cred.times.starttime;
|
|
|
905b4d |
- tgtt->endtime = cred.times.endtime;
|
|
|
905b4d |
- tgtt->renew_till = cred.times.renew_till;
|
|
|
905b4d |
-
|
|
|
905b4d |
- krb5_free_cred_contents(ctx, &cred);
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_close(ctx, cc);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_close failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- cc = NULL;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = 0;
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- if (cc != NULL) {
|
|
|
905b4d |
- krb5_cc_close(ctx, cc);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (client_princ != NULL) {
|
|
|
905b4d |
- krb5_free_principal(ctx, client_princ);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (server_princ != NULL) {
|
|
|
905b4d |
- krb5_free_principal(ctx, server_princ);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (ctx != NULL) {
|
|
|
905b4d |
- krb5_free_context(ctx);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- return EIO;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re,
|
|
|
905b4d |
uid_t uid, gid_t gid)
|
|
|
905b4d |
{
|
|
|
905b4d |
@@ -783,7 +293,6 @@ done:
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-
|
|
|
905b4d |
struct sss_krb5_ccache {
|
|
|
905b4d |
struct sss_creds *creds;
|
|
|
905b4d |
krb5_context context;
|
|
|
905b4d |
@@ -895,7 +404,6 @@ done:
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-
|
|
|
905b4d |
/* This function is called only as a way to validate that we have the
|
|
|
905b4d |
* right cache */
|
|
|
905b4d |
errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
|
|
905b4d |
@@ -1086,22 +594,124 @@ done:
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t get_domain_or_subdomain(struct be_ctx *be_ctx,
|
|
|
905b4d |
- char *domain_name,
|
|
|
905b4d |
- struct sss_domain_info **dom)
|
|
|
905b4d |
+errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
|
|
905b4d |
+ struct tgt_times *tgtt)
|
|
|
905b4d |
{
|
|
|
905b4d |
+ krb5_error_code kerr;
|
|
|
905b4d |
+ krb5_context ctx = NULL;
|
|
|
905b4d |
+ krb5_ccache cc = NULL;
|
|
|
905b4d |
+ krb5_principal client_princ = NULL;
|
|
|
905b4d |
+ krb5_principal server_princ = NULL;
|
|
|
905b4d |
+ char *server_name;
|
|
|
905b4d |
+ krb5_creds mcred;
|
|
|
905b4d |
+ krb5_creds cred;
|
|
|
905b4d |
+ const char *realm_name;
|
|
|
905b4d |
+ int realm_length;
|
|
|
905b4d |
|
|
|
905b4d |
- if (domain_name != NULL &&
|
|
|
905b4d |
- strcasecmp(domain_name, be_ctx->domain->name) != 0) {
|
|
|
905b4d |
- *dom = find_domain_by_name(be_ctx->domain, domain_name, true);
|
|
|
905b4d |
- if (*dom == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- *dom = be_ctx->domain;
|
|
|
905b4d |
+ kerr = krb5_init_context(&ctx;;
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_init_context failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = krb5_parse_name(ctx, client_name, &client_princ);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ sss_krb5_princ_realm(ctx, client_princ, &realm_name, &realm_length);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ server_name = talloc_asprintf(NULL, "krbtgt/%.*s@%.*s",
|
|
|
905b4d |
+ realm_length, realm_name,
|
|
|
905b4d |
+ realm_length, realm_name);
|
|
|
905b4d |
+ if (server_name == NULL) {
|
|
|
905b4d |
+ kerr = KRB5_CC_NOMEM;
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = krb5_parse_name(ctx, server_name, &server_princ);
|
|
|
905b4d |
+ talloc_free(server_name);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = krb5_cc_resolve(ctx, ccache_file, &cc);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ memset(&mcred, 0, sizeof(mcred));
|
|
|
905b4d |
+ memset(&cred, 0, sizeof(mcred));
|
|
|
905b4d |
+
|
|
|
905b4d |
+ mcred.server = server_princ;
|
|
|
905b4d |
+ mcred.client = client_princ;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = krb5_cc_retrieve_cred(ctx, cc, 0, &mcred, &cred);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_retrieve_cred failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ tgtt->authtime = cred.times.authtime;
|
|
|
905b4d |
+ tgtt->starttime = cred.times.starttime;
|
|
|
905b4d |
+ tgtt->endtime = cred.times.endtime;
|
|
|
905b4d |
+ tgtt->renew_till = cred.times.renew_till;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ krb5_free_cred_contents(ctx, &cred);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = krb5_cc_close(ctx, cc);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_close failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ cc = NULL;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = 0;
|
|
|
905b4d |
+
|
|
|
905b4d |
+done:
|
|
|
905b4d |
+ if (cc != NULL) {
|
|
|
905b4d |
+ krb5_cc_close(ctx, cc);
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (client_princ != NULL) {
|
|
|
905b4d |
+ krb5_free_principal(ctx, client_princ);
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (server_princ != NULL) {
|
|
|
905b4d |
+ krb5_free_principal(ctx, server_princ);
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (ctx != NULL) {
|
|
|
905b4d |
+ krb5_free_context(ctx);
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ return EIO;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
return EOK;
|
|
|
905b4d |
}
|
|
|
905b4d |
+
|
|
|
905b4d |
+errno_t safe_remove_old_ccache_file(const char *old_ccache,
|
|
|
905b4d |
+ const char *new_ccache,
|
|
|
905b4d |
+ uid_t uid, gid_t gid)
|
|
|
905b4d |
+{
|
|
|
905b4d |
+ if ((old_ccache == new_ccache)
|
|
|
905b4d |
+ || (old_ccache && new_ccache
|
|
|
905b4d |
+ && (strcmp(old_ccache, new_ccache) == 0))) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_TRACE_FUNC, "New and old ccache file are the same, "
|
|
|
905b4d |
+ "none will be deleted.\n");
|
|
|
905b4d |
+ return EOK;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ return sss_krb5_cc_destroy(old_ccache, uid, gid);
|
|
|
905b4d |
+}
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_ccache.h
|
|
|
905b4d |
similarity index 53%
|
|
|
905b4d |
copy from src/providers/krb5/krb5_utils.h
|
|
|
905b4d |
copy to src/providers/krb5/krb5_ccache.h
|
|
|
905b4d |
index f54a07f7936a361c21ca933026ee753a89fe5808..9f0b3ac84b7af118c315ca00a7c52f200534d97e 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_utils.h
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_ccache.h
|
|
|
905b4d |
@@ -1,13 +1,13 @@
|
|
|
905b4d |
/*
|
|
|
905b4d |
SSSD
|
|
|
905b4d |
|
|
|
905b4d |
- Kerberos Backend, header file for utilities
|
|
|
905b4d |
+ Kerberos 5 Backend Module -- ccache related utilities
|
|
|
905b4d |
|
|
|
905b4d |
Authors:
|
|
|
905b4d |
Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
+ Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
|
|
|
905b4d |
- Copyright (C) 2009 Red Hat
|
|
|
905b4d |
-
|
|
|
905b4d |
+ Copyright (C) 2014 Red Hat
|
|
|
905b4d |
|
|
|
905b4d |
This program is free software; you can redistribute it and/or modify
|
|
|
905b4d |
it under the terms of the GNU General Public License as published by
|
|
|
905b4d |
@@ -23,45 +23,38 @@
|
|
|
905b4d |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
905b4d |
*/
|
|
|
905b4d |
|
|
|
905b4d |
-#ifndef __KRB5_UTILS_H__
|
|
|
905b4d |
-#define __KRB5_UTILS_H__
|
|
|
905b4d |
+#ifndef __KRB5_CCACHE_H__
|
|
|
905b4d |
+#define __KRB5_CCACHE_H__
|
|
|
905b4d |
|
|
|
905b4d |
-#include <talloc.h>
|
|
|
905b4d |
-#include "config.h"
|
|
|
905b4d |
+#include "util/util.h"
|
|
|
905b4d |
|
|
|
905b4d |
-#include "providers/krb5/krb5_auth.h"
|
|
|
905b4d |
-#include "providers/data_provider.h"
|
|
|
905b4d |
+struct tgt_times {
|
|
|
905b4d |
+ time_t authtime;
|
|
|
905b4d |
+ time_t starttime;
|
|
|
905b4d |
+ time_t endtime;
|
|
|
905b4d |
+ time_t renew_till;
|
|
|
905b4d |
+};
|
|
|
905b4d |
|
|
|
905b4d |
-errno_t find_or_guess_upn(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
|
|
|
905b4d |
- struct krb5_ctx *krb5_ctx,
|
|
|
905b4d |
- struct sss_domain_info *dom, const char *user,
|
|
|
905b4d |
- const char *user_dom, char **_upn);
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb,
|
|
|
905b4d |
- struct sss_domain_info *domain,
|
|
|
905b4d |
- const char *user,
|
|
|
905b4d |
- const char *upn);
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t create_ccache_dir(const char *dirname, pcre *illegal_re,
|
|
|
905b4d |
+errno_t create_ccache_dir(const char *ccdirname,
|
|
|
905b4d |
+ pcre *illegal_re,
|
|
|
905b4d |
uid_t uid, gid_t gid);
|
|
|
905b4d |
|
|
|
905b4d |
-char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
|
|
|
905b4d |
- const char *template, bool file_mode,
|
|
|
905b4d |
- bool case_sensitive);
|
|
|
905b4d |
-
|
|
|
905b4d |
errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re,
|
|
|
905b4d |
uid_t uid, gid_t gid);
|
|
|
905b4d |
+
|
|
|
905b4d |
errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);
|
|
|
905b4d |
+
|
|
|
905b4d |
errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
|
|
905b4d |
const char *ccname, const char *principal);
|
|
|
905b4d |
+
|
|
|
905b4d |
errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
|
|
905b4d |
const char *realm, const char *principal);
|
|
|
905b4d |
|
|
|
905b4d |
errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
|
|
905b4d |
struct tgt_times *tgtt);
|
|
|
905b4d |
|
|
|
905b4d |
+errno_t safe_remove_old_ccache_file(const char *old_ccache,
|
|
|
905b4d |
+ const char *new_ccache,
|
|
|
905b4d |
+ uid_t uid, gid_t gid);
|
|
|
905b4d |
|
|
|
905b4d |
-errno_t get_domain_or_subdomain(struct be_ctx *be_ctx,
|
|
|
905b4d |
- char *domain_name,
|
|
|
905b4d |
- struct sss_domain_info **dom);
|
|
|
905b4d |
-#endif /* __KRB5_UTILS_H__ */
|
|
|
905b4d |
+#endif /* __KRB5_CCACHE_H__ */
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
|
|
|
905b4d |
index b0bf76fb3b8a77831b114c47acff8cd0d3fd780d..7fa5f0c344a4afe110afa08f479f283aefce8d23 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_child.c
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_child.c
|
|
|
905b4d |
@@ -1885,6 +1885,7 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
|
|
|
905b4d |
/* If krb5_child was started as setuid, but we don't need to
|
|
|
905b4d |
* perform either validation or FAST, just drop privileges to
|
|
|
905b4d |
* the user who is logging in. The same applies to the offline case
|
|
|
905b4d |
+ * the user who is logging in. The same applies to the offline case.
|
|
|
905b4d |
*/
|
|
|
905b4d |
kerr = become_user(kr->uid, kr->gid);
|
|
|
905b4d |
if (kerr != 0) {
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
|
|
|
905b4d |
index eac0d6b1f0c0fec4a107a7b830d8b0c927f4fe42..a5cee6497e4930b16b1102a525d9fa3452845a58 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_common.h
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_common.h
|
|
|
905b4d |
@@ -73,13 +73,6 @@ enum krb5_opts {
|
|
|
905b4d |
|
|
|
905b4d |
typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
|
|
|
905b4d |
|
|
|
905b4d |
-struct tgt_times {
|
|
|
905b4d |
- time_t authtime;
|
|
|
905b4d |
- time_t starttime;
|
|
|
905b4d |
- time_t endtime;
|
|
|
905b4d |
- time_t renew_till;
|
|
|
905b4d |
-};
|
|
|
905b4d |
-
|
|
|
905b4d |
struct krb5_service {
|
|
|
905b4d |
char *name;
|
|
|
905b4d |
char *realm;
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_renew_tgt.c b/src/providers/krb5/krb5_renew_tgt.c
|
|
|
905b4d |
index 12963549829c4bbb0f799c5d00b9b8986ccfd485..5277c0f7691dd272a69b3024cb2c0bd7545a8fbd 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_renew_tgt.c
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_renew_tgt.c
|
|
|
905b4d |
@@ -27,6 +27,7 @@
|
|
|
905b4d |
#include "providers/krb5/krb5_common.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_auth.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_utils.h"
|
|
|
905b4d |
+#include "providers/krb5/krb5_ccache.h"
|
|
|
905b4d |
|
|
|
905b4d |
#define INITIAL_TGT_TABLE_SIZE 10
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
|
|
|
905b4d |
index 0d2e281198390043068e21b412b57de04df6a12b..ae72b04be236cfce9b6f794c602887491ba487a9 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_utils.c
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_utils.c
|
|
|
905b4d |
@@ -26,6 +26,7 @@
|
|
|
905b4d |
#include <libgen.h>
|
|
|
905b4d |
|
|
|
905b4d |
#include "providers/krb5/krb5_utils.h"
|
|
|
905b4d |
+#include "providers/krb5/krb5_ccache.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_auth.h"
|
|
|
905b4d |
#include "src/util/find_uid.h"
|
|
|
905b4d |
#include "util/util.h"
|
|
|
905b4d |
@@ -379,7 +380,7 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
|
|
|
905b4d |
name = n;
|
|
|
905b4d |
n = strchr(name, '}');
|
|
|
905b4d |
if (!n) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
"Invalid substitution sequence in cache "
|
|
|
905b4d |
"template. Missing closing '}' in [%s].\n",
|
|
|
905b4d |
template);
|
|
|
905b4d |
@@ -416,677 +417,6 @@ done:
|
|
|
905b4d |
return res;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
-static errno_t check_parent_stat(struct stat *parent_stat, uid_t uid)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- if (parent_stat->st_uid != 0 && parent_stat->st_uid != uid) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Private directory can only be created below a directory "
|
|
|
905b4d |
- "belonging to root or to [%"SPRIuid"].\n", uid);
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (parent_stat->st_uid == uid) {
|
|
|
905b4d |
- if (!(parent_stat->st_mode & S_IXUSR)) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Parent directory does not have the search bit set for "
|
|
|
905b4d |
- "the owner.\n");
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- if (!(parent_stat->st_mode & S_IXOTH)) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "Parent directory does not have the search bit set for "
|
|
|
905b4d |
- "others.\n");
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-struct string_list {
|
|
|
905b4d |
- struct string_list *next;
|
|
|
905b4d |
- struct string_list *prev;
|
|
|
905b4d |
- char *s;
|
|
|
905b4d |
-};
|
|
|
905b4d |
-
|
|
|
905b4d |
-static errno_t find_ccdir_parent_data(TALLOC_CTX *mem_ctx,
|
|
|
905b4d |
- const char *ccdirname,
|
|
|
905b4d |
- struct stat *parent_stat,
|
|
|
905b4d |
- struct string_list **missing_parents)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- int ret = EFAULT;
|
|
|
905b4d |
- char *parent = NULL;
|
|
|
905b4d |
- char *end;
|
|
|
905b4d |
- struct string_list *li;
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = stat(ccdirname, parent_stat);
|
|
|
905b4d |
- if (ret == EOK) {
|
|
|
905b4d |
- if ( !S_ISDIR(parent_stat->st_mode) ) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "[%s] is not a directory.\n", ccdirname);
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- if (errno != ENOENT) {
|
|
|
905b4d |
- ret = errno;
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "stat for [%s] failed: [%d][%s].\n", ccdirname, ret,
|
|
|
905b4d |
- strerror(ret));
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- li = talloc_zero(mem_ctx, struct string_list);
|
|
|
905b4d |
- if (li == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "talloc_zero failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- li->s = talloc_strdup(li, ccdirname);
|
|
|
905b4d |
- if (li->s == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "talloc_strdup failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- DLIST_ADD(*missing_parents, li);
|
|
|
905b4d |
-
|
|
|
905b4d |
- parent = talloc_strdup(mem_ctx, ccdirname);
|
|
|
905b4d |
- if (parent == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "talloc_strdup failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* We'll remove all trailing slashes from the back so that
|
|
|
905b4d |
- * we only pass /some/path to find_ccdir_parent_data, not
|
|
|
905b4d |
- * /some/path */
|
|
|
905b4d |
- do {
|
|
|
905b4d |
- end = strrchr(parent, '/');
|
|
|
905b4d |
- if (end == NULL || end == parent) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "Cannot find parent directory of [%s], / is not allowed.\n",
|
|
|
905b4d |
- ccdirname);
|
|
|
905b4d |
- ret = EINVAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- *end = '\0';
|
|
|
905b4d |
- } while (*(end+1) == '\0');
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = find_ccdir_parent_data(mem_ctx, parent, parent_stat, missing_parents);
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- talloc_free(parent);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-static errno_t
|
|
|
905b4d |
-check_ccache_re(const char *filename, pcre *illegal_re)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = pcre_exec(illegal_re, NULL, filename, strlen(filename),
|
|
|
905b4d |
- 0, 0, NULL, 0);
|
|
|
905b4d |
- if (ret == 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE,
|
|
|
905b4d |
- "Illegal pattern in ccache directory name [%s].\n", filename);
|
|
|
905b4d |
- return EINVAL;
|
|
|
905b4d |
- } else if (ret == PCRE_ERROR_NOMATCH) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_LIBS,
|
|
|
905b4d |
- "Ccache directory name [%s] does not contain "
|
|
|
905b4d |
- "illegal patterns.\n", filename);
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "pcre_exec failed [%d].\n", ret);
|
|
|
905b4d |
- return EFAULT;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t
|
|
|
905b4d |
-create_ccache_dir(const char *ccdirname, pcre *illegal_re,
|
|
|
905b4d |
- uid_t uid, gid_t gid)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- int ret = EFAULT;
|
|
|
905b4d |
- struct stat parent_stat;
|
|
|
905b4d |
- struct string_list *missing_parents = NULL;
|
|
|
905b4d |
- struct string_list *li = NULL;
|
|
|
905b4d |
- mode_t old_umask;
|
|
|
905b4d |
- mode_t new_dir_mode;
|
|
|
905b4d |
- TALLOC_CTX *tmp_ctx = NULL;
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
- if (tmp_ctx == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
- "talloc_new failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (*ccdirname != '/') {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "Only absolute paths are allowed, not [%s] .\n", ccdirname);
|
|
|
905b4d |
- ret = EINVAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (illegal_re != NULL) {
|
|
|
905b4d |
- ret = check_ccache_re(ccdirname, illegal_re);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = find_ccdir_parent_data(tmp_ctx, ccdirname, &parent_stat,
|
|
|
905b4d |
- &missing_parents);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "find_ccdir_parent_data failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = check_parent_stat(&parent_stat, uid);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_FATAL_FAILURE,
|
|
|
905b4d |
- "Check the ownership and permissions of krb5_ccachedir: [%s].\n",
|
|
|
905b4d |
- ccdirname);
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- DLIST_FOR_EACH(li, missing_parents) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
905b4d |
- "Creating directory [%s].\n", li->s);
|
|
|
905b4d |
- new_dir_mode = 0700;
|
|
|
905b4d |
-
|
|
|
905b4d |
- old_umask = umask(0000);
|
|
|
905b4d |
- ret = mkdir(li->s, new_dir_mode);
|
|
|
905b4d |
- umask(old_umask);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- ret = errno;
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "mkdir [%s] failed: [%d][%s].\n", li->s, ret,
|
|
|
905b4d |
- strerror(ret));
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- ret = chown(li->s, uid, gid);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- ret = errno;
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "chown failed [%d][%s].\n", ret, strerror(ret));
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- talloc_free(tmp_ctx);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
|
|
905b4d |
- struct tgt_times *tgtt)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- krb5_error_code kerr;
|
|
|
905b4d |
- krb5_context ctx = NULL;
|
|
|
905b4d |
- krb5_ccache cc = NULL;
|
|
|
905b4d |
- krb5_principal client_princ = NULL;
|
|
|
905b4d |
- krb5_principal server_princ = NULL;
|
|
|
905b4d |
- char *server_name;
|
|
|
905b4d |
- krb5_creds mcred;
|
|
|
905b4d |
- krb5_creds cred;
|
|
|
905b4d |
- const char *realm_name;
|
|
|
905b4d |
- int realm_length;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_init_context(&ctx;;
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_init_context failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_parse_name(ctx, client_name, &client_princ);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- sss_krb5_princ_realm(ctx, client_princ, &realm_name, &realm_length);
|
|
|
905b4d |
-
|
|
|
905b4d |
- server_name = talloc_asprintf(NULL, "krbtgt/%.*s@%.*s",
|
|
|
905b4d |
- realm_length, realm_name,
|
|
|
905b4d |
- realm_length, realm_name);
|
|
|
905b4d |
- if (server_name == NULL) {
|
|
|
905b4d |
- kerr = KRB5_CC_NOMEM;
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_parse_name(ctx, server_name, &server_princ);
|
|
|
905b4d |
- talloc_free(server_name);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_resolve(ctx, ccache_file, &cc);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- memset(&mcred, 0, sizeof(mcred));
|
|
|
905b4d |
- memset(&cred, 0, sizeof(mcred));
|
|
|
905b4d |
-
|
|
|
905b4d |
- mcred.server = server_princ;
|
|
|
905b4d |
- mcred.client = client_princ;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_retrieve_cred(ctx, cc, 0, &mcred, &cred);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_retrieve_cred failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tgtt->authtime = cred.times.authtime;
|
|
|
905b4d |
- tgtt->starttime = cred.times.starttime;
|
|
|
905b4d |
- tgtt->endtime = cred.times.endtime;
|
|
|
905b4d |
- tgtt->renew_till = cred.times.renew_till;
|
|
|
905b4d |
-
|
|
|
905b4d |
- krb5_free_cred_contents(ctx, &cred);
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_close(ctx, cc);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_close failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- cc = NULL;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = 0;
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- if (cc != NULL) {
|
|
|
905b4d |
- krb5_cc_close(ctx, cc);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (client_princ != NULL) {
|
|
|
905b4d |
- krb5_free_principal(ctx, client_princ);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (server_princ != NULL) {
|
|
|
905b4d |
- krb5_free_principal(ctx, server_princ);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (ctx != NULL) {
|
|
|
905b4d |
- krb5_free_context(ctx);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- return EIO;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re,
|
|
|
905b4d |
- uid_t uid, gid_t gid)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- TALLOC_CTX *tmp_ctx = NULL;
|
|
|
905b4d |
- const char *filename;
|
|
|
905b4d |
- char *ccdirname;
|
|
|
905b4d |
- char *end;
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (ccname[0] == '/') {
|
|
|
905b4d |
- filename = ccname;
|
|
|
905b4d |
- } else if (strncmp(ccname, "FILE:", 5) == 0) {
|
|
|
905b4d |
- filename = ccname + 5;
|
|
|
905b4d |
- } else if (strncmp(ccname, "DIR:", 4) == 0) {
|
|
|
905b4d |
- filename = ccname + 4;
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- /* only FILE and DIR types need precreation so far, we ignore any
|
|
|
905b4d |
- * other type */
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
- if (!tmp_ctx) return ENOMEM;
|
|
|
905b4d |
-
|
|
|
905b4d |
- ccdirname = talloc_strdup(tmp_ctx, filename);
|
|
|
905b4d |
- if (ccdirname == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
|
|
|
905b4d |
- ret = ENOMEM;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* We'll remove all trailing slashes from the back so that
|
|
|
905b4d |
- * we only pass /some/path to find_ccdir_parent_data, not
|
|
|
905b4d |
- * /some/path/ */
|
|
|
905b4d |
- do {
|
|
|
905b4d |
- end = strrchr(ccdirname, '/');
|
|
|
905b4d |
- if (end == NULL || end == ccdirname) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find parent directory of [%s], "
|
|
|
905b4d |
- "/ is not allowed.\n", ccdirname);
|
|
|
905b4d |
- ret = EINVAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- *end = '\0';
|
|
|
905b4d |
- } while (*(end+1) == '\0');
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = create_ccache_dir(ccdirname, illegal_re, uid, gid);
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- talloc_free(tmp_ctx);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-
|
|
|
905b4d |
-struct sss_krb5_ccache {
|
|
|
905b4d |
- struct sss_creds *creds;
|
|
|
905b4d |
- krb5_context context;
|
|
|
905b4d |
- krb5_ccache ccache;
|
|
|
905b4d |
-};
|
|
|
905b4d |
-
|
|
|
905b4d |
-static int sss_free_krb5_ccache(void *mem)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- struct sss_krb5_ccache *cc = talloc_get_type(mem, struct sss_krb5_ccache);
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (cc->ccache) {
|
|
|
905b4d |
- krb5_cc_close(cc->context, cc->ccache);
|
|
|
905b4d |
- }
|
|
|
905b4d |
- krb5_free_context(cc->context);
|
|
|
905b4d |
- restore_creds(cc->creds);
|
|
|
905b4d |
- return 0;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-static errno_t sss_open_ccache_as_user(TALLOC_CTX *mem_ctx,
|
|
|
905b4d |
- const char *ccname,
|
|
|
905b4d |
- uid_t uid, gid_t gid,
|
|
|
905b4d |
- struct sss_krb5_ccache **ccache)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- struct sss_krb5_ccache *cc;
|
|
|
905b4d |
- krb5_error_code kerr;
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- cc = talloc_zero(mem_ctx, struct sss_krb5_ccache);
|
|
|
905b4d |
- if (!cc) {
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- talloc_set_destructor((TALLOC_CTX *)cc, sss_free_krb5_ccache);
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = switch_creds(cc, uid, gid, 0, NULL, &cc->creds);
|
|
|
905b4d |
- if (ret) {
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_init_context(&cc->context);
|
|
|
905b4d |
- if (kerr) {
|
|
|
905b4d |
- ret = EIO;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_resolve(cc->context, ccname, &cc->ccache);
|
|
|
905b4d |
- if (kerr == KRB5_FCC_NOFILE || cc->ccache == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_FUNC, "ccache %s is missing or empty\n", ccname);
|
|
|
905b4d |
- ret = ERR_NOT_FOUND;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- } else if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n");
|
|
|
905b4d |
- ret = ERR_INTERNAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- if (ret) {
|
|
|
905b4d |
- talloc_free(cc);
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- *ccache = cc;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-static errno_t sss_destroy_ccache(struct sss_krb5_ccache *cc)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- krb5_error_code kerr;
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_destroy(cc->context, cc->ccache);
|
|
|
905b4d |
- if (kerr) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_destroy failed.\n");
|
|
|
905b4d |
- ret = EIO;
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* krb5_cc_destroy frees cc->ccache in all events */
|
|
|
905b4d |
- cc->ccache = NULL;
|
|
|
905b4d |
-
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- struct sss_krb5_ccache *cc = NULL;
|
|
|
905b4d |
- TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
- if (tmp_ctx == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
|
|
|
905b4d |
- if (ret) {
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sss_destroy_ccache(cc);
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- talloc_free(tmp_ctx);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-
|
|
|
905b4d |
-/* This function is called only as a way to validate that we have the
|
|
|
905b4d |
- * right cache */
|
|
|
905b4d |
-errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
|
|
905b4d |
- const char *ccname, const char *principal)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- struct sss_krb5_ccache *cc = NULL;
|
|
|
905b4d |
- krb5_principal ccprinc = NULL;
|
|
|
905b4d |
- krb5_principal kprinc = NULL;
|
|
|
905b4d |
- krb5_error_code kerr;
|
|
|
905b4d |
- const char *cc_type;
|
|
|
905b4d |
- TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
- if (tmp_ctx == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
|
|
|
905b4d |
- if (ret) {
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- cc_type = krb5_cc_get_type(cc->context, cc->ccache);
|
|
|
905b4d |
-
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
905b4d |
- "Searching for [%s] in cache of type [%s]\n", principal, cc_type);
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_parse_name(cc->context, principal, &kprinc);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
|
|
|
905b4d |
- ret = ERR_INTERNAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_get_principal(cc->context, cc->ccache, &ccprinc);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_get_principal failed.\n");
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (ccprinc) {
|
|
|
905b4d |
- if (krb5_principal_compare(cc->context, kprinc, ccprinc) == TRUE) {
|
|
|
905b4d |
- /* found in the primary ccache */
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
-#ifdef HAVE_KRB5_CC_COLLECTION
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (krb5_cc_support_switch(cc->context, cc_type)) {
|
|
|
905b4d |
-
|
|
|
905b4d |
- krb5_cc_close(cc->context, cc->ccache);
|
|
|
905b4d |
- cc->ccache = NULL;
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_set_default_name(cc->context, ccname);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_MINOR_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- /* try to continue despite failure */
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_cache_match(cc->context, kprinc, &cc->ccache);
|
|
|
905b4d |
- if (kerr == 0) {
|
|
|
905b4d |
- ret = EOK;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_TRACE_INTERNAL, cc->context, kerr);
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
-#endif /* HAVE_KRB5_CC_COLLECTION */
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = ERR_NOT_FOUND;
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- if (cc) {
|
|
|
905b4d |
- krb5_free_principal(cc->context, ccprinc);
|
|
|
905b4d |
- krb5_free_principal(cc->context, kprinc);
|
|
|
905b4d |
- }
|
|
|
905b4d |
- talloc_free(tmp_ctx);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-static errno_t sss_low_level_path_check(const char *ccname)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- const char *filename;
|
|
|
905b4d |
- struct stat buf;
|
|
|
905b4d |
- int ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- if (ccname[0] == '/') {
|
|
|
905b4d |
- filename = ccname;
|
|
|
905b4d |
- } else if (strncmp(ccname, "FILE:", 5) == 0) {
|
|
|
905b4d |
- filename = ccname + 5;
|
|
|
905b4d |
- } else if (strncmp(ccname, "DIR:", 4) == 0) {
|
|
|
905b4d |
- filename = ccname + 4;
|
|
|
905b4d |
- if (filename[0] == ':') filename += 1;
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- /* only FILE and DIR types need file checks so far, we ignore any
|
|
|
905b4d |
- * other type */
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = stat(filename, &buf;;
|
|
|
905b4d |
- if (ret == -1) return errno;
|
|
|
905b4d |
- return EOK;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
|
|
905b4d |
- const char *realm, const char *principal)
|
|
|
905b4d |
-{
|
|
|
905b4d |
- struct sss_krb5_ccache *cc = NULL;
|
|
|
905b4d |
- TALLOC_CTX *tmp_ctx = NULL;
|
|
|
905b4d |
- krb5_principal tgt_princ = NULL;
|
|
|
905b4d |
- krb5_principal princ = NULL;
|
|
|
905b4d |
- char *tgt_name;
|
|
|
905b4d |
- krb5_creds mcred = { 0 };
|
|
|
905b4d |
- krb5_creds cred = { 0 };
|
|
|
905b4d |
- krb5_error_code kerr;
|
|
|
905b4d |
- errno_t ret;
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* first of all verify if the old ccache file/dir exists as we may be
|
|
|
905b4d |
- * trying to verify if an old ccache exists at all. If no file/dir
|
|
|
905b4d |
- * exists bail out immediately otherwise a following krb5_cc_resolve()
|
|
|
905b4d |
- * call may actually create paths and files we do not want to have
|
|
|
905b4d |
- * around */
|
|
|
905b4d |
- ret = sss_low_level_path_check(ccname);
|
|
|
905b4d |
- if (ret) {
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
- if (tmp_ctx == NULL) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
|
|
|
905b4d |
- if (ret) {
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- tgt_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
|
|
|
905b4d |
- if (!tgt_name) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
|
|
|
905b4d |
- ret = ENOMEM;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_parse_name(cc->context, tgt_name, &tgt_princ);
|
|
|
905b4d |
- if (kerr) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL;
|
|
|
905b4d |
- else ret = ERR_INTERNAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_parse_name(cc->context, principal, &princ);
|
|
|
905b4d |
- if (kerr) {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL;
|
|
|
905b4d |
- else ret = ERR_INTERNAL;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- mcred.client = princ;
|
|
|
905b4d |
- mcred.server = tgt_princ;
|
|
|
905b4d |
- mcred.times.endtime = time(NULL);
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_cc_retrieve_cred(cc->context, cc->ccache,
|
|
|
905b4d |
- KRB5_TC_MATCH_TIMES, &mcred, &cred);
|
|
|
905b4d |
- if (kerr) {
|
|
|
905b4d |
- if (kerr == KRB5_CC_NOTFOUND || kerr == KRB5_FCC_NOFILE) {
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_INTERNAL, "TGT not found or expired.\n");
|
|
|
905b4d |
- ret = EINVAL;
|
|
|
905b4d |
- } else {
|
|
|
905b4d |
- KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
|
|
|
905b4d |
- ret = ERR_INTERNAL;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- }
|
|
|
905b4d |
- krb5_free_cred_contents(cc->context, &cred);
|
|
|
905b4d |
-
|
|
|
905b4d |
-done:
|
|
|
905b4d |
- if (tgt_princ) krb5_free_principal(cc->context, tgt_princ);
|
|
|
905b4d |
- if (princ) krb5_free_principal(cc->context, princ);
|
|
|
905b4d |
- talloc_free(tmp_ctx);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
-}
|
|
|
905b4d |
-
|
|
|
905b4d |
-
|
|
|
905b4d |
errno_t get_domain_or_subdomain(struct be_ctx *be_ctx,
|
|
|
905b4d |
char *domain_name,
|
|
|
905b4d |
struct sss_domain_info **dom)
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
|
|
|
905b4d |
index f54a07f7936a361c21ca933026ee753a89fe5808..ce5ce1ebcf6db14579191840600e684d41a2fdbe 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_utils.h
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_utils.h
|
|
|
905b4d |
@@ -42,25 +42,10 @@ errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb,
|
|
|
905b4d |
const char *user,
|
|
|
905b4d |
const char *upn);
|
|
|
905b4d |
|
|
|
905b4d |
-errno_t create_ccache_dir(const char *dirname, pcre *illegal_re,
|
|
|
905b4d |
- uid_t uid, gid_t gid);
|
|
|
905b4d |
-
|
|
|
905b4d |
char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
|
|
|
905b4d |
const char *template, bool file_mode,
|
|
|
905b4d |
bool case_sensitive);
|
|
|
905b4d |
|
|
|
905b4d |
-errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re,
|
|
|
905b4d |
- uid_t uid, gid_t gid);
|
|
|
905b4d |
-errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);
|
|
|
905b4d |
-errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
|
|
|
905b4d |
- const char *ccname, const char *principal);
|
|
|
905b4d |
-errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
|
|
|
905b4d |
- const char *realm, const char *principal);
|
|
|
905b4d |
-
|
|
|
905b4d |
-errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
|
|
|
905b4d |
- struct tgt_times *tgtt);
|
|
|
905b4d |
-
|
|
|
905b4d |
-
|
|
|
905b4d |
errno_t get_domain_or_subdomain(struct be_ctx *be_ctx,
|
|
|
905b4d |
char *domain_name,
|
|
|
905b4d |
struct sss_domain_info **dom);
|
|
|
905b4d |
diff --git a/src/tests/krb5_child-test.c b/src/tests/krb5_child-test.c
|
|
|
905b4d |
index 63caa5f6c97f3e5c0df459b7549e681e51fcc108..09f23d5386e3c70efc5ce54fa199c1a6e8656eec 100644
|
|
|
905b4d |
--- a/src/tests/krb5_child-test.c
|
|
|
905b4d |
+++ b/src/tests/krb5_child-test.c
|
|
|
905b4d |
@@ -37,6 +37,7 @@
|
|
|
905b4d |
#include "providers/krb5/krb5_auth.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_common.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_utils.h"
|
|
|
905b4d |
+#include "providers/krb5/krb5_ccache.h"
|
|
|
905b4d |
|
|
|
905b4d |
extern struct dp_option default_krb5_opts[];
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/tests/krb5_utils-tests.c b/src/tests/krb5_utils-tests.c
|
|
|
905b4d |
index 18d2bd230ab1170da2caf685cead46c1390c0851..52d8a18576b23c627c7ef3358bd34f4b2dbae6f7 100644
|
|
|
905b4d |
--- a/src/tests/krb5_utils-tests.c
|
|
|
905b4d |
+++ b/src/tests/krb5_utils-tests.c
|
|
|
905b4d |
@@ -27,6 +27,7 @@
|
|
|
905b4d |
#include <check.h>
|
|
|
905b4d |
|
|
|
905b4d |
#include "providers/krb5/krb5_utils.h"
|
|
|
905b4d |
+#include "providers/krb5/krb5_ccache.h"
|
|
|
905b4d |
#include "providers/krb5/krb5_auth.h"
|
|
|
905b4d |
#include "tests/common.h"
|
|
|
905b4d |
|
|
|
905b4d |
--
|
|
|
905b4d |
1.9.3
|
|
|
905b4d |
|