diff options
-rw-r--r-- | src/conf_macros.m4 | 2 | ||||
-rw-r--r-- | src/man/sssd-krb5.5.xml | 11 | ||||
-rw-r--r-- | src/providers/ad/ad_opts.h | 2 | ||||
-rw-r--r-- | src/providers/ipa/ipa_opts.h | 2 | ||||
-rw-r--r-- | src/providers/krb5/krb5_auth.c | 4 | ||||
-rw-r--r-- | src/providers/krb5/krb5_common.c | 99 | ||||
-rw-r--r-- | src/providers/krb5/krb5_opts.h | 2 | ||||
-rw-r--r-- | src/providers/krb5/krb5_utils.c | 74 | ||||
-rw-r--r-- | src/util/util_errors.c | 1 | ||||
-rw-r--r-- | src/util/util_errors.h | 1 |
10 files changed, 182 insertions, 16 deletions
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4 index 1834f3cb..433e99ce 100644 --- a/src/conf_macros.m4 +++ b/src/conf_macros.m4 @@ -278,7 +278,7 @@ AC_DEFUN([WITH_DEFAULT_CCACHE_DIR], AC_DEFUN([WITH_DEFAULT_CCNAME_TEMPLATE], [ AC_ARG_WITH([default-ccname-template], [AC_HELP_STRING([--with-default-ccname-template=CCACHE], - [The default value of krb5_ccname_template [FILE:%d/krb5cc_%U_XXXXXX]] + [The default fallback value of krb5_ccname_template [FILE:%d/krb5cc_%U_XXXXXX]] ) ] ) diff --git a/src/man/sssd-krb5.5.xml b/src/man/sssd-krb5.5.xml index 720f39b7..9b0bfba4 100644 --- a/src/man/sssd-krb5.5.xml +++ b/src/man/sssd-krb5.5.xml @@ -220,7 +220,16 @@ predictable method. </para> <para> - Default: FILE:%d/krb5cc_%U_XXXXXX + The default value for the credential cache name is + sourced from the profile stored in the system wide + krb5.conf configuration file in the [libdefaults] + section. The option name is default_ccache_name. + See krb5.conf(5)'s PARAMETER EXPANSION paragraph + for additional information on the expansion format + defined by krb5.conf. + </para> + <para> + Default: (from libkrb5) </para> </listitem> </varlistentry> diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h index 197b97e2..f3b6cd61 100644 --- a/src/providers/ad/ad_opts.h +++ b/src/providers/ad/ad_opts.h @@ -134,7 +134,7 @@ struct dp_option ad_def_krb5_opts[] = { { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING }, - { "krb5_ccname_template", DP_OPT_STRING, { DEFAULT_CCNAME_TEMPLATE }, NULL_STRING}, + { "krb5_ccname_template", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h index 9babca73..5ec36c55 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -263,7 +263,7 @@ struct dp_option ipa_def_krb5_opts[] = { { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING }, - { "krb5_ccname_template", DP_OPT_STRING, { DEFAULT_CCNAME_TEMPLATE }, NULL_STRING}, + { "krb5_ccname_template", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 506ca520..db0aa936 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -315,7 +315,7 @@ static void krb5_auth_cache_creds(struct krb5_ctx *krb5_ctx, *dp_err = DP_ERR_OFFLINE; } -static errno_t krb5_auth_prepare_ccache_file(struct krb5child_req *kr, +static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr, struct be_ctx *be_ctx, int *pam_status, int *dp_err) { @@ -783,7 +783,7 @@ static void krb5_auth_resolve_done(struct tevent_req *subreq) } } - ret = krb5_auth_prepare_ccache_file(kr, state->be_ctx, + ret = krb5_auth_prepare_ccache_name(kr, state->be_ctx, &state->pam_status, &state->dp_err); if (ret) { goto done; diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index c88eb03f..c7ce574d 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -33,6 +33,11 @@ #include "providers/krb5/krb5_opts.h" #include "providers/krb5/krb5_utils.h" +#ifdef HAVE_KRB5_CC_COLLECTION +/* krb5 profile functions */ +#include <profile.h> +#endif + errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id, const char *env_name) { @@ -86,6 +91,58 @@ done: return ret; } +#ifdef HAVE_KRB5_CC_COLLECTION +/* source default_ccache_name from krb5.conf */ +static errno_t sss_get_system_ccname_template(TALLOC_CTX *mem_ctx, + char **ccname) +{ + krb5_context ctx; + profile_t p; + char *value = NULL; + long ret; + + *ccname = NULL; + + ret = krb5_init_context(&ctx); + if (ret) return ret; + + ret = krb5_get_profile(ctx, &p); + if (ret) goto done; + + ret = profile_get_string(p, "libdefaults", "default_ccache_name", + NULL, NULL, &value); + if (ret) goto done; + + if (!value) { + ret = ERR_NOT_FOUND; + goto done; + } + + *ccname = talloc_strdup(mem_ctx, value); + if (*ccname == NULL) { + ret = ENOMEM; + goto done; + } + + ret = EOK; + +done: + krb5_free_context(ctx); + free(value); + return ret; +} +#else +static errno_t sss_get_system_ccname_template(TALLOC_CTX *mem_ctx, + char **ccname) +{ + DEBUG(SSSDBG_CONF_SETTINGS, + ("Your kerberos library does not support the default_ccache_name " + "option or the profile library. Please use krb5_ccname_template " + "in sssd.conf if you want to change the default\n")); + *ccname = NULL; + return ERR_NOT_FOUND; +} +#endif errno_t check_and_export_options(struct dp_option *opts, struct sss_domain_info *dom, @@ -188,19 +245,45 @@ errno_t check_and_export_options(struct dp_option *opts, "using the KDC or defaults.\n")); } - dummy = dp_opt_get_cstring(opts, KRB5_CCNAME_TMPL); - if (dummy == NULL) { - DEBUG(1, ("Missing credential cache name template.\n")); - ret = EINVAL; - goto done; + ccname = dp_opt_get_string(opts, KRB5_CCNAME_TMPL); + if (ccname != NULL) { + DEBUG(SSSDBG_CONF_SETTINGS, + ("The credential ccache name template has been explicitly set " + "in sssd.conf, it is recommended to set default_ccache_name " + "in krb5.conf instead so that a system default is used\n")); + ccname = talloc_strdup(tmp_ctx, ccname); + if (!ccname) { + ret = ENOMEM; + goto done; + } + } else { + ret = sss_get_system_ccname_template(tmp_ctx, &ccname); + if (ret && ret != ERR_NOT_FOUND) { + goto done; + } + if (ret == ERR_NOT_FOUND) { + /* Use fallback default */ + ccname = talloc_strdup(tmp_ctx, DEFAULT_CCNAME_TEMPLATE); + if (!ccname) { + ret = ENOMEM; + goto done; + } + } + + /* set back in opts */ + 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; + } } - cc_be = sss_krb5_get_type(dummy); + cc_be = sss_krb5_get_type(ccname); switch (cc_be) { case SSS_KRB5_TYPE_FILE: DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type FILE\n")); krb5_ctx->cc_be = &file_cc; - if (dummy[0] != '/') { + if (ccname[0] != '/') { /* FILE:/path/to/cc */ break; } @@ -209,7 +292,7 @@ errno_t check_and_export_options(struct dp_option *opts, "missing an explicit type, but is an absolute " "path specifier. Assuming FILE:\n")); - ccname = talloc_asprintf(tmp_ctx, "FILE:%s", dummy); + ccname = talloc_asprintf(tmp_ctx, "FILE:%s", ccname); if (!ccname) { ret = ENOMEM; goto done; diff --git a/src/providers/krb5/krb5_opts.h b/src/providers/krb5/krb5_opts.h index 400b7e33..db62cc3b 100644 --- a/src/providers/krb5/krb5_opts.h +++ b/src/providers/krb5/krb5_opts.h @@ -30,7 +30,7 @@ struct dp_option default_krb5_opts[] = { { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING }, - { "krb5_ccname_template", DP_OPT_STRING, { DEFAULT_CCNAME_TEMPLATE }, NULL_STRING}, + { "krb5_ccname_template", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c index d82ef47c..dc4c448e 100644 --- a/src/providers/krb5/krb5_utils.c +++ b/src/providers/krb5/krb5_utils.c @@ -157,6 +157,25 @@ done: return ret; } +#define S_EXP_TEMP "{TEMP}" +#define L_EXP_TEMP (sizeof(S_EXP_TEMP) - 1) +#define S_EXP_UID "{uid}" +#define L_EXP_UID (sizeof(S_EXP_UID) - 1) +#define S_EXP_USERID "{USERID}" +#define L_EXP_USERID (sizeof(S_EXP_USERID) - 1) +#define S_EXP_EUID "{euid}" +#define L_EXP_EUID (sizeof(S_EXP_EUID) - 1) +#define S_EXP_NULL "{null}" +#define L_EXP_NULL (sizeof(S_EXP_NULL) - 1) +#define S_EXP_USERNAME "{username}" +#define L_EXP_USERNAME (sizeof(S_EXP_USERNAME) - 1) +#define S_EXP_LIBDIR "{LIBDIR}" +#define L_EXP_LIBDIR (sizeof(S_EXP_LIBDIR) - 1) +#define S_EXP_BINDIR "{BINDIR}" +#define L_EXP_BINDIR (sizeof(S_EXP_BINDIR) - 1) +#define S_EXP_SBINDIR "{SBINDIR}" +#define L_EXP_SBINDIR (sizeof(S_EXP_SBINDIR) - 1) + char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr, const char *template, bool file_mode, bool case_sensitive, bool *private_path) @@ -170,6 +189,8 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr, char *res = NULL; const char *cache_dir_tmpl; TALLOC_CTX *tmp_ctx = NULL; + char action; + bool rewind; *private_path = false; @@ -202,7 +223,11 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr, goto done; } - switch( *n ) { + rewind = true; + action = *n; + while (rewind) { + rewind = false; + switch (action) { case 'u': if (kr->pd->user == NULL) { DEBUG(1, ("Cannot expand user name template " @@ -297,9 +322,56 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr, result = talloc_asprintf_append(result, "%s%d", p, kr->pd->cli_pid); break; + + /* Additional syntax from krb5.conf default_ccache_name */ + case '{': + if (strncmp(n, S_EXP_TEMP, L_EXP_TEMP) == 0) { + /* let the libkrb5 library resolve this */ + result = talloc_asprintf_append(result, "%%"S_EXP_TEMP); + n += L_EXP_TEMP - 1; + } else if (strncmp(n , S_EXP_UID, L_EXP_UID) == 0) { + action = 'U'; + n += L_EXP_UID - 1; + rewind = true; + continue; + } else if (strncmp(n , S_EXP_USERID, L_EXP_USERID) == 0) { + action = 'U'; + n += L_EXP_USERID - 1; + rewind = true; + continue; + } else if (strncmp(n , S_EXP_EUID, L_EXP_EUID) == 0) { + /* SSSD does not distinguish betwen uid and euid, + * so we treat both the same way */ + action = 'U'; + n += L_EXP_EUID - 1; + rewind = true; + continue; + } else if (strncmp(n , S_EXP_NULL, L_EXP_NULL) == 0) { + /* skip immediately */ + n += L_EXP_NULL - 1; + } else if (strncmp(n , S_EXP_USERNAME, L_EXP_USERNAME) == 0) { + action = 'u'; + n += L_EXP_USERNAME - 1; + rewind = true; + continue; + } else if (strncmp(n , S_EXP_LIBDIR, L_EXP_LIBDIR) == 0) { + /* skip, only the libkrb5 library can resolve this */ + result = talloc_asprintf_append(result, "%%"S_EXP_LIBDIR); + n += L_EXP_LIBDIR - 1; + } else if (strncmp(n , S_EXP_BINDIR, L_EXP_BINDIR) == 0) { + /* skip, only the libkrb5 library can resolve this */ + result = talloc_asprintf_append(result, "%%"S_EXP_BINDIR); + n += L_EXP_BINDIR - 1; + } else if (strncmp(n , S_EXP_SBINDIR, L_EXP_SBINDIR) == 0) { + /* skip, only the libkrb5 library can resolve this */ + result = talloc_asprintf_append(result, "%%"S_EXP_SBINDIR); + n += L_EXP_SBINDIR - 1; + } + break; default: DEBUG(1, ("format error, unknown template [%%%c].\n", *n)); goto done; + } } if (result == NULL) { diff --git a/src/util/util_errors.c b/src/util/util_errors.c index 015c5aca..e39e1587 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -48,6 +48,7 @@ struct err_string error_to_str[] = { { "Dynamic DNS update failed" }, /* ERR_DYNDNS_FAILED */ { "Dynamic DNS update timed out" }, /* ERR_DYNDNS_TIMEOUT */ { "Dynamic DNS update not possible while offline" }, /* ERR_DYNDNS_OFFLINE */ + { "Entry not found" }, /* ERR_NOT_FOUND */ }; diff --git a/src/util/util_errors.h b/src/util/util_errors.h index ca447282..8580d6ba 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -70,6 +70,7 @@ enum sssd_errors { ERR_DYNDNS_FAILED, ERR_DYNDNS_TIMEOUT, ERR_DYNDNS_OFFLINE, + ERR_NOT_FOUND, ERR_LAST /* ALWAYS LAST */ }; |