>From 31d9f6c7df59f3c84ea2cbf65d74d653de06ce62 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Wed, 29 May 2013 09:57:38 +0200 Subject: [PATCH 2/3] Every time return directory for krb5 cache collection. Function krb5_cc_get_full_name is called only as a way to validate that, we have the right cache. Instead of returned name, location will be returned from function cc_dir_cache_for_princ. https://fedorahosted.org/sssd/ticket/1936 --- src/providers/krb5/krb5_child.c | 59 ++++++++++++++++++++++++++++++++++++++++- src/providers/krb5/krb5_utils.c | 5 +++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index e9fbfbeafe774bc82f8be4976cc1b5a67a6acc5b..354d280514514e3283ff03ec5d534e24bc00ae36 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -1080,12 +1080,58 @@ done: } +static char * get_ccache_name_by_principal(TALLOC_CTX *mem_ctx, + krb5_context ctx, + krb5_principal principal, + const char *ccname) +{ + krb5_error_code kerr; + krb5_ccache tmp_cc = NULL; + char *tmp_ccname = NULL; + char *ret_ccname = NULL; + + kerr = krb5_cc_set_default_name(ctx, ccname); + if (kerr != 0) { + KRB5_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr); + return NULL; + } + + kerr = krb5_cc_cache_match(ctx, principal, &tmp_cc); + if (kerr != 0) { + KRB5_CHILD_DEBUG(SSSDBG_TRACE_INTERNAL, kerr); + return NULL; + } + + kerr = krb5_cc_get_full_name(ctx, tmp_cc, &tmp_ccname); + if (kerr !=0) { + KRB5_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr); + goto done; + } + + ret_ccname = talloc_strdup(mem_ctx, tmp_ccname); + if (ret_ccname == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed (ENOMEM).\n")); + } + +done: + if (tmp_cc != NULL) { + kerr = krb5_cc_close(ctx, tmp_cc); + if (kerr != 0) { + KRB5_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr); + } + } + krb5_free_string(ctx, tmp_ccname); + + return ret_ccname; +} + static krb5_error_code get_and_save_tgt(struct krb5_req *kr, const char *password) { const char *realm_name; int realm_length; krb5_error_code kerr; + char *cc_name; kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options, @@ -1100,6 +1146,17 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr, DEBUG(SSSDBG_TRACE_FUNC, ("Attempting kinit for realm [%s]\n",realm_name)); + + /* If kr->ccname is cache collection (DIR:/...), we want to work + * directly with file ccache (DIR::/...), but cache collection + * should be returned bactk to back end. + */ + cc_name = get_ccache_name_by_principal(kr->pd, kr->ctx, kr->princ, + kr->ccname); + if (cc_name == NULL) { + cc_name = kr->ccname; + } + kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ, discard_const(password), sss_krb5_prompter, kr, 0, @@ -1134,7 +1191,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, kr->creds ? kr->creds->client : kr->princ, - kr->ccname, kr->creds); + cc_name, kr->creds); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c index 1883d785e6746c45e51c8b0fabe01afbad688d6d..3f16faa7fb238bbb9801029beed66293cd873c15 100644 --- a/src/providers/krb5/krb5_utils.c +++ b/src/providers/krb5/krb5_utils.c @@ -1164,6 +1164,9 @@ cc_dir_cache_for_princ(TALLOC_CTX *mem_ctx, const char *location, return NULL; } + /* This function is called only as a way to validate that, + * we have the right cache + */ krberr = krb5_cc_get_full_name(context, ccache, &name); if (ccache) krb5_cc_close(context, ccache); krb5_free_context(context); @@ -1173,7 +1176,7 @@ cc_dir_cache_for_princ(TALLOC_CTX *mem_ctx, const char *location, return NULL; } - return talloc_strdup(mem_ctx, name); + return talloc_strdup(mem_ctx, location); } errno_t -- 1.8.1.4