diff options
Diffstat (limited to 'src/providers/krb5')
-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 |
4 files changed, 167 insertions, 12 deletions
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) { |