diff options
Diffstat (limited to 'src/providers/krb5')
-rw-r--r-- | src/providers/krb5/krb5_child.c | 45 | ||||
-rw-r--r-- | src/providers/krb5/krb5_common.c | 12 | ||||
-rw-r--r-- | src/providers/krb5/krb5_common.h | 2 |
3 files changed, 55 insertions, 4 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 1ed63f6b..fcd108aa 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -1221,7 +1221,8 @@ done: return krberr; } -static krb5_error_code check_fast_ccache(krb5_context ctx, const char *realm, +static krb5_error_code check_fast_ccache(krb5_context ctx, const char *primary, + const char *realm, const char *keytab_name, TALLOC_CTX *mem_ctx, char **fast_ccname) @@ -1260,7 +1261,7 @@ static krb5_error_code check_fast_ccache(krb5_context ctx, const char *realm, goto done; } - kerr = find_principal_in_keytab(ctx, keytab, NULL, realm, &client_princ); + kerr = find_principal_in_keytab(ctx, keytab, primary, realm, &client_princ); if (kerr != 0) { DEBUG(1, ("find_principal_in_keytab failed.\n")); goto done; @@ -1322,6 +1323,11 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) krb5_error_code kerr = 0; char *lifetime_str; char *use_fast_str; + char *tmp_str; + krb5_data *realm_data; + krb5_principal fast_princ_struct; + char *fast_principal = NULL; + const char *fast_principal_realm = NULL; krb5_deltat lifetime; kr->krb5_ctx = talloc_zero(kr, struct krb5_child_ctx); @@ -1443,7 +1449,40 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) DEBUG(9, ("Not using FAST.\n")); } else if (strcasecmp(use_fast_str, "try") == 0 || strcasecmp(use_fast_str, "demand") == 0) { - kerr = check_fast_ccache(kr->ctx, kr->krb5_ctx->realm, kr->keytab, + + tmp_str = getenv(SSSD_KRB5_FAST_PRINCIPAL); + if (!tmp_str) { + fast_principal = NULL; + fast_principal_realm = kr->krb5_ctx->realm; + } else { + kerr = krb5_parse_name(kr->ctx, tmp_str, &fast_princ_struct); + if (kerr) { + DEBUG(1, ("krb5_parse_name failed.\n")); + goto failed; + } + kerr = krb5_unparse_name_flags(kr->ctx, fast_princ_struct, + KRB5_PRINCIPAL_UNPARSE_NO_REALM, + &tmp_str); + if (kerr) { + DEBUG(1, ("krb5_unparse_name_flags failed.\n")); + goto failed; + } + fast_principal = talloc_strdup(kr, tmp_str); + if (!fast_principal) { + DEBUG(1, ("talloc_strdup failed.\n")); + kerr = KRB5KRB_ERR_GENERIC; + goto failed; + } + free(tmp_str); + realm_data = krb5_princ_realm(kr->ctx, fast_princ_struct); + fast_principal_realm = talloc_asprintf(kr, "%.*s", realm_data->length, realm_data->data); + if (!fast_principal_realm) { + DEBUG(1, ("talloc_asprintf failed.\n")); + goto failed; + } + } + + kerr = check_fast_ccache(kr->ctx, fast_principal, fast_principal_realm, kr->keytab, kr, &kr->fast_ccname); if (kerr != 0) { DEBUG(1, ("check_fast_ccache failed.\n")); diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index 434fc7fb..ca37ba7d 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -44,7 +44,8 @@ struct dp_option default_krb5_opts[] = { { "krb5_renewable_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_renew_interval", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER }, - { "krb5_use_fast", DP_OPT_STRING, NULL_STRING, NULL_STRING } + { "krb5_use_fast", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING } }; errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id, @@ -109,6 +110,7 @@ errno_t check_and_export_options(struct dp_option *opts, const char *realm; const char *dummy; char *use_fast_str; + char *fast_principal; realm = dp_opt_get_cstring(opts, KRB5_REALM); if (realm == NULL) { @@ -155,6 +157,14 @@ errno_t check_and_export_options(struct dp_option *opts, ret = setenv(SSSD_KRB5_USE_FAST, use_fast_str, 1); if (ret != EOK) { DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_USE_FAST)); + } else { + fast_principal = dp_opt_get_string(opts, KRB5_FAST_PRINCIPAL); + if (fast_principal != NULL) { + ret = setenv(SSSD_KRB5_FAST_PRINCIPAL, fast_principal, 1); + if (ret != EOK) { + DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_FAST_PRINCIPAL)); + } + } } } } diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h index c65ff74b..d1a90c85 100644 --- a/src/providers/krb5/krb5_common.h +++ b/src/providers/krb5/krb5_common.h @@ -38,6 +38,7 @@ #define SSSD_KRB5_RENEWABLE_LIFETIME "SSSD_KRB5_RENEWABLE_LIFETIME" #define SSSD_KRB5_LIFETIME "SSSD_KRB5_LIFETIME" #define SSSD_KRB5_USE_FAST "SSSD_KRB5_USE_FAST" +#define SSSD_KRB5_FAST_PRINCIPAL "SSSD_KRB5_FAST_PRINCIPAL" #define KDCINFO_TMPL PUBCONF_PATH"/kdcinfo.%s" #define KPASSWDINFO_TMPL PUBCONF_PATH"/kpasswdinfo.%s" @@ -59,6 +60,7 @@ enum krb5_opts { KRB5_LIFETIME, KRB5_RENEW_INTERVAL, KRB5_USE_FAST, + KRB5_FAST_PRINCIPAL, KRB5_OPTS }; |