summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/conf_macros.m42
-rw-r--r--src/man/sssd-krb5.5.xml11
-rw-r--r--src/providers/ad/ad_opts.h2
-rw-r--r--src/providers/ipa/ipa_opts.h2
-rw-r--r--src/providers/krb5/krb5_auth.c4
-rw-r--r--src/providers/krb5/krb5_common.c99
-rw-r--r--src/providers/krb5/krb5_opts.h2
-rw-r--r--src/providers/krb5/krb5_utils.c74
-rw-r--r--src/util/util_errors.c1
-rw-r--r--src/util/util_errors.h1
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 */
};