summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2011-12-20 16:13:59 -0500
committerStephen Gallagher <sgallagh@redhat.com>2011-12-22 10:37:47 -0500
commitcbe8cbd9ebecdd4aec8830748dadb3721f6cdd70 (patch)
treedbd659d134335e58006335036106ebaf9dd62320
parentdc09a9a7fbb812937f90f030e45fbccee7057e21 (diff)
downloadsssd-cbe8cbd9ebecdd4aec8830748dadb3721f6cdd70.tar.gz
sssd-cbe8cbd9ebecdd4aec8830748dadb3721f6cdd70.tar.xz
sssd-cbe8cbd9ebecdd4aec8830748dadb3721f6cdd70.zip
Add compatibility layer for Heimdal Kerberos implementation
-rw-r--r--src/external/krb5.m410
-rw-r--r--src/providers/krb5/krb5_child.c10
-rw-r--r--src/providers/krb5/krb5_utils.c10
-rw-r--r--src/providers/ldap/ldap_child.c5
-rw-r--r--src/util/sss_krb5.c70
-rw-r--r--src/util/sss_krb5.h15
6 files changed, 99 insertions, 21 deletions
diff --git a/src/external/krb5.m4 b/src/external/krb5.m4
index 40d632ce5..a8707c6e1 100644
--- a/src/external/krb5.m4
+++ b/src/external/krb5.m4
@@ -37,13 +37,21 @@ SAVE_LIBS=$LIBS
CFLAGS="$CFLAGS $KRB5_CFLAGS"
LIBS="$LIBS $KRB5_LIBS"
AC_CHECK_HEADERS([krb5.h krb5/krb5.h])
+AC_CHECK_TYPES([krb5_ticket_times, krb5_times], [], [],
+ [[#include <krb5.h>]])
AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc krb5_get_error_message \
krb5_free_unparsed_name \
krb5_get_init_creds_opt_set_expire_callback \
krb5_get_init_creds_opt_set_fast_ccache_name \
krb5_get_init_creds_opt_set_fast_flags \
krb5_get_init_creds_opt_set_canonicalize \
- krb5_unparse_name_flags])
+ krb5_unparse_name_flags \
+ krb5_get_init_creds_opt_set_change_password_prompt \
+ krb5_free_keytab_entry_contents \
+ krb5_kt_free_entry \
+ krb5_princ_realm \
+ krb5_get_time_offsets \
+ krb5_principal_get_realm])
CFLAGS=$SAVE_CFLAGS
LIBS=$SAVE_LIBS
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 297e3a763..c83179b4b 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -530,7 +530,7 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
break;
}
- kerr = krb5_free_keytab_entry_contents(kr->ctx, &entry);
+ kerr = sss_krb5_free_keytab_entry_contents(kr->ctx, &entry);
if (kerr != 0) {
DEBUG(1, ("Failed to free keytab entry.\n"));
}
@@ -578,7 +578,7 @@ done:
if (krb5_kt_close(kr->ctx, keytab) != 0) {
DEBUG(1, ("krb5_kt_close failed"));
}
- if (krb5_free_keytab_entry_contents(kr->ctx, &entry) != 0) {
+ if (sss_krb5_free_keytab_entry_contents(kr->ctx, &entry) != 0) {
DEBUG(1, ("Failed to free keytab entry.\n"));
}
if (principal != NULL) {
@@ -1194,7 +1194,7 @@ static int krb5_cleanup(void *ptr)
static krb5_error_code get_tgt_times(krb5_context ctx, const char *ccname,
krb5_principal server_principal,
krb5_principal client_principal,
- krb5_ticket_times *tgtt)
+ sss_krb5_ticket_times *tgtt)
{
krb5_error_code krberr;
krb5_ccache ccache = NULL;
@@ -1247,7 +1247,7 @@ static krb5_error_code check_fast_ccache(krb5_context ctx, const char *primary,
krb5_error_code kerr;
char *ccname;
char *server_name;
- krb5_ticket_times tgtt;
+ sss_krb5_ticket_times tgtt;
krb5_keytab keytab = NULL;
krb5_principal client_princ = NULL;
krb5_principal server_princ = NULL;
@@ -1420,6 +1420,7 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline)
goto failed;
}
+#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT
/* A prompter is used to catch messages about when a password will
* expired. The library shall not use the prompter to ask for a new password
* but shall return KRB5KDC_ERR_KEY_EXP. */
@@ -1428,6 +1429,7 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline)
KRB5_DEBUG(1, kerr);
goto failed;
}
+#endif
lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME);
if (lifetime_str == NULL) {
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index 2957598cc..c97d58e7c 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -431,6 +431,8 @@ errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
char *server_name;
krb5_creds mcred;
krb5_creds cred;
+ const char *realm_name;
+ int realm_length;
kerr = krb5_init_context(&ctx);
if (kerr != 0) {
@@ -444,11 +446,11 @@ errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
goto done;
}
+ sss_krb5_princ_realm(ctx, client_princ, &realm_name, &realm_length);
+
server_name = talloc_asprintf(NULL, "krbtgt/%.*s@%.*s",
- krb5_princ_realm(ctx, client_princ)->length,
- krb5_princ_realm(ctx, client_princ)->data,
- krb5_princ_realm(ctx, client_princ)->length,
- krb5_princ_realm(ctx, client_princ)->data);
+ realm_length, realm_name,
+ realm_length, realm_name);
if (server_name == NULL) {
kerr = KRB5_CC_NOMEM;
DEBUG(1, ("talloc_asprintf failed.\n"));
diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c
index 160cc1ce4..05aadde90 100644
--- a/src/providers/ldap/ldap_child.c
+++ b/src/providers/ldap/ldap_child.c
@@ -287,6 +287,7 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
goto done;
}
+#ifdef HAVE_KRB5_GET_TIME_OFFSETS
krberr = krb5_get_time_offsets(context, &kdc_time_offset, &kdc_time_offset_usec);
if (krberr) {
DEBUG(2, ("Failed to get KDC time offset: %s\n",
@@ -297,6 +298,10 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
kdc_time_offset++;
}
}
+#else
+ /* If we don't have this function, just assume no offset */
+ kdc_time_offset = 0;
+#endif
krberr = 0;
*ccname_out = ccname;
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index 3311ef542..fe76afc52 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -44,6 +44,8 @@ errno_t select_principal_from_keytab(TALLOC_CTX *mem_ctx,
int i = 0;
errno_t ret;
char *principal_string;
+ const char *realm_name;
+ int realm_len;
/**
* Priority of lookup:
@@ -164,9 +166,11 @@ errno_t select_principal_from_keytab(TALLOC_CTX *mem_ctx,
}
if (_realm) {
+ sss_krb5_princ_realm(krb_ctx, client_princ,
+ &realm_name,
+ &realm_len);
*_realm = talloc_asprintf(mem_ctx, "%.*s",
- krb5_princ_realm(ctx, client_princ)->length,
- krb5_princ_realm(ctx, client_princ)->data);
+ realm_len, realm_name);
if (!*_realm) {
DEBUG(1, ("talloc_asprintf failed"));
if (_principal) talloc_zfree(*_principal);
@@ -322,7 +326,7 @@ int sss_krb5_verify_keytab_ex(const char *principal, const char *keytab_name,
found = true;
}
free(kt_principal);
- krberr = krb5_free_keytab_entry_contents(context, &entry);
+ krberr = sss_krb5_free_keytab_entry_contents(context, &entry);
if (krberr) {
/* This should never happen. The API docs for this function
* specify only success for this function
@@ -378,18 +382,19 @@ static bool match_principal(krb5_context ctx,
const char *pattern_primary,
const char *pattern_realm)
{
- krb5_data *realm_data;
char *primary = NULL;
char *primary_str = NULL;
int primary_str_len = 0;
int tmp_len;
int len_diff;
+ const char *realm_name;
+ int realm_len;
int mode = MODE_NORMAL;
TALLOC_CTX *tmp_ctx;
bool ret = false;
- realm_data = krb5_princ_realm(ctx, principal);
+ sss_krb5_princ_realm(ctx, principal, &realm_name, &realm_len);
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) {
@@ -425,8 +430,8 @@ static bool match_principal(krb5_context ctx,
}
}
- if (!pattern_realm || (realm_data->length == strlen(pattern_realm) &&
- strncmp(realm_data->data, pattern_realm, realm_data->length) == 0)) {
+ if (!pattern_realm || (realm_len == strlen(pattern_realm) &&
+ strncmp(realm_name, pattern_realm, realm_len) == 0)) {
DEBUG(7, ("Principal matched to the sample (%s@%s).\n", pattern_primary,
pattern_realm));
ret = true;
@@ -466,7 +471,7 @@ krb5_error_code find_principal_in_keytab(krb5_context ctx,
break;
}
- kerr = krb5_free_keytab_entry_contents(ctx, &entry);
+ kerr = sss_krb5_free_keytab_entry_contents(ctx, &entry);
if (kerr != 0) {
DEBUG(1, ("Failed to free keytab entry.\n"));
}
@@ -504,7 +509,7 @@ krb5_error_code find_principal_in_keytab(krb5_context ctx,
kerr = 0;
done:
- kerr_d = krb5_free_keytab_entry_contents(ctx, &entry);
+ kerr_d = sss_krb5_free_keytab_entry_contents(ctx, &entry);
if (kerr_d != 0) {
DEBUG(1, ("Failed to free keytab entry.\n"));
}
@@ -917,9 +922,50 @@ cleanup:
void sss_krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt *opts,
int canonicalize)
{
-#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CANONICALIZE
- return krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize);
+ /* FIXME: The extra check for HAVE_KRB5_TICKET_TIMES is a workaround due to Heimdal
+ * defining krb5_get_init_creds_opt_set_canonicalize() with a different set of
+ * arguments. We should use a better configure check in the future.
+ */
+#if defined(HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CANONICALIZE) && defined(HAVE_KRB5_TICKET_TIMES)
+ krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize);
#else
- DEBUG(SSSDBG_OP_FAILURE, ("Kerberos principal canonicalization is not avaliable!\n"));
+ DEBUG(SSSDBG_OP_FAILURE, ("Kerberos principal canonicalization is not available!\n"));
#endif
}
+
+#ifdef HAVE_KRB5_PRINCIPAL_GET_REALM
+void sss_krb5_princ_realm(krb5_context context, krb5_const_principal princ,
+ const char **realm, int *len)
+{
+ *realm = krb5_principal_get_realm(context, princ);
+ *len = strlen(*realm);
+}
+#else
+void sss_krb5_princ_realm(krb5_context context, krb5_const_principal princ,
+ const char **realm, int *len)
+{
+ const krb5_data *data;
+
+ data = krb5_princ_realm(context, princ);
+ if (data) {
+ *realm = data->data;
+ *len = data->length;
+ }
+}
+#endif
+
+#ifdef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS
+krb5_error_code
+sss_krb5_free_keytab_entry_contents(krb5_context context,
+ krb5_keytab_entry *entry)
+{
+ return krb5_free_keytab_entry_contents(context, entry);
+}
+#else
+krb5_error_code
+sss_krb5_free_keytab_entry_contents(krb5_context context,
+ krb5_keytab_entry *entry)
+{
+ return krb5_kt_free_entry(context, entry);
+}
+#endif
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
index 039b79af0..52e6c5d48 100644
--- a/src/util/sss_krb5.h
+++ b/src/util/sss_krb5.h
@@ -115,4 +115,19 @@ sss_krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal
void sss_krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt *opts,
int canonicalize);
+/* === Compatibility routines for the Heimdal Kerberos implementation === */
+
+void sss_krb5_princ_realm(krb5_context context, krb5_const_principal princ,
+ const char **realm, int *len);
+
+krb5_error_code
+sss_krb5_free_keytab_entry_contents(krb5_context context,
+ krb5_keytab_entry *entry);
+
+#ifdef HAVE_KRB5_TICKET_TIMES
+typedef krb5_ticket_times sss_krb5_ticket_times;
+#elif HAVE_KRB5_TIMES
+typedef krb5_times sss_krb5_ticket_times;
+#endif
+
#endif /* __SSS_KRB5_H__ */