summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2013-08-27 13:36:41 -0400
committerJakub Hrozek <jhrozek@redhat.com>2013-08-28 11:00:03 +0200
commitdcc6877aa2e2dd63a9dc9c411a9c58feaeb36b9a (patch)
treefda3c24e3ec4be05c86b6271e297e8fc0f4cd6a1
parenta524b03792dc8f8dae32bba5a2af8532bc751e86 (diff)
downloadsssd-dcc6877aa2e2dd63a9dc9c411a9c58feaeb36b9a.tar.gz
sssd-dcc6877aa2e2dd63a9dc9c411a9c58feaeb36b9a.tar.xz
sssd-dcc6877aa2e2dd63a9dc9c411a9c58feaeb36b9a.zip
krb5: Fetch ccname template from krb5.conf
In order to use the same defaults in all system daemons that needs to know how to generate or search for ccaches we introduce ode here to take advantage of the new option called default_ccache_name provided by libkrb5. If set this variable we establish the same default for all programs that surce it out of krb5.conf therefore providing a consistent experience across the system. Related: https://fedorahosted.org/sssd/ticket/2036
-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 1834f3cb7..433e99cef 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 720f39b7b..9b0bfba42 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 197b97e22..f3b6cd616 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 9babca73f..5ec36c550 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 506ca520a..db0aa936f 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 c88eb03fa..c7ce574d5 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 400b7e338..db62cc3b2 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 d82ef47c9..dc4c448ef 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 015c5acaf..e39e15870 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 ca4472823..8580d6ba7 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 */
};