summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-11-17 17:39:38 +0100
committerJakub Hrozek <jhrozek@redhat.com>2014-12-03 14:27:22 +0100
commit3e53a8cd98b9410cd378ad68d8528e2a8d6d4f6a (patch)
treeb19a7cfd81365c55ba262ac87277987ca3382d27 /src/providers
parent664843123793879049459326127c2686f6361106 (diff)
downloadsssd-3e53a8cd98b9410cd378ad68d8528e2a8d6d4f6a.tar.gz
sssd-3e53a8cd98b9410cd378ad68d8528e2a8d6d4f6a.tar.xz
sssd-3e53a8cd98b9410cd378ad68d8528e2a8d6d4f6a.zip
krb5: add copy_ccache_into_memory()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src/providers')
-rw-r--r--src/providers/krb5/krb5_ccache.c110
-rw-r--r--src/providers/krb5/krb5_ccache.h17
2 files changed, 127 insertions, 0 deletions
diff --git a/src/providers/krb5/krb5_ccache.c b/src/providers/krb5/krb5_ccache.c
index 7aa36b744..de6e694a9 100644
--- a/src/providers/krb5/krb5_ccache.c
+++ b/src/providers/krb5/krb5_ccache.c
@@ -667,3 +667,113 @@ errno_t safe_remove_old_ccache_file(const char *old_ccache,
return sss_krb5_cc_destroy(old_ccache, uid, gid);
}
+
+krb5_error_code copy_ccache_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
+ const char *ccache_file,
+ char **_mem_name)
+{
+ krb5_error_code kerr;
+ krb5_ccache ccache;
+ krb5_ccache mem_ccache = NULL;
+ char *ccache_name = NULL;
+ krb5_principal princ = NULL;
+ char *mem_name = NULL;
+ char *sep;
+
+ kerr = krb5_cc_resolve(kctx, ccache_file, &ccache);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "error resolving ccache [%s].\n",
+ ccache_file);
+ return kerr;
+ }
+
+ kerr = krb5_cc_get_full_name(kctx, ccache, &ccache_name);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read name for ccache [%s].\n",
+ ccache_file);
+ goto done;
+ }
+
+ sep = strchr(ccache_name, ':');
+ if (sep == NULL || sep[1] == '\0') {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Ccache name [%s] does not have delimiter[:] .\n", ccache_name);
+ kerr = KRB5KRB_ERR_GENERIC;
+ goto done;
+ }
+
+ if (strncmp(ccache_name, "MEMORY:", sizeof("MEMORY:") -1) == 0) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Ccache [%s] is already memory ccache.\n",
+ ccache_name);
+ *_mem_name = talloc_strdup(mem_ctx, ccache_name);
+ if(*_mem_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ kerr = KRB5KRB_ERR_GENERIC;
+ goto done;
+ }
+ kerr = 0;
+ goto done;
+ }
+ if (strncmp(ccache_name, "FILE:", sizeof("FILE:") -1) == 0) {
+ mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s", sep + 1);
+ if (mem_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+ kerr = KRB5KRB_ERR_GENERIC;
+ goto done;
+ }
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected ccache type for ccache [%s], " \
+ "currently only FILE is supported.\n",
+ ccache_name);
+ kerr = KRB5KRB_ERR_GENERIC;
+ goto done;
+ }
+
+ kerr = krb5_cc_resolve(kctx, mem_name, &mem_ccache);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "error resolving ccache [%s].\n", mem_name);
+ goto done;
+ }
+
+ kerr = krb5_cc_get_principal(kctx, ccache, &princ);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "error reading principal from ccache [%s].\n", ccache_name);
+ goto done;
+ }
+
+ kerr = krb5_cc_initialize(kctx, mem_ccache, princ);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize ccache [%s].\n", mem_name);
+ goto done;
+ }
+
+ kerr = krb5_cc_copy_creds(kctx, ccache, mem_ccache);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to copy ccache [%s] to [%s].\n", ccache_name, mem_name);
+ goto done;
+ }
+
+ *_mem_name = mem_name;
+ kerr = 0;
+
+done:
+ if (kerr != 0) {
+ talloc_free(mem_name);
+ }
+
+ free(ccache_name);
+ krb5_free_principal(kctx, princ);
+
+ if (krb5_cc_close(kctx, ccache) != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_close failed.\n");
+ }
+
+ if (krb5_cc_close(kctx, mem_ccache) != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_close failed.\n");
+ }
+
+ return kerr;
+}
diff --git a/src/providers/krb5/krb5_ccache.h b/src/providers/krb5/krb5_ccache.h
index e47df3665..f3928e644 100644
--- a/src/providers/krb5/krb5_ccache.h
+++ b/src/providers/krb5/krb5_ccache.h
@@ -53,4 +53,21 @@ errno_t safe_remove_old_ccache_file(const char *old_ccache,
const char *new_ccache,
uid_t uid, gid_t gid);
+/**
+ * @brief Copy given ccache into a MEMORY ccache
+ *
+ * @param[in] mem_ctx Talloc memory context the new ccache name should be
+ * allocated on
+ * @param[in] kctx Kerberos context
+ * @param[in] ccache_file Name of existing ccache
+ * @param[out] _mem_name Name of the new MEMORY ccache
+ *
+ * In contrast to MEMORY keytabs MEMORY ccaches can and must be removed
+ * explicitly with krb5_cc_destroy() from the memory. Just calling
+ * krb5_cc_close() will keep the MEMORY ccache in memory even if there are no
+ * open handles for the given MEMORY ccache.
+ */
+krb5_error_code copy_ccache_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
+ const char *ccache_file,
+ char **_mem_name);
#endif /* __KRB5_CCACHE_H__ */