summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2012-08-24 10:56:38 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-08-24 18:35:19 +0200
commitd29a9e0bfe54926c057bc1ea3e22269a2f87c15b (patch)
tree86055e8401469e8002d1881a1b162b7f78919c0e
parentb096321a5a02dda0b6b71ba0f9c4d8feacd979e4 (diff)
downloadsssd-d29a9e0bfe54926c057bc1ea3e22269a2f87c15b.tar.gz
sssd-d29a9e0bfe54926c057bc1ea3e22269a2f87c15b.tar.bz2
sssd-d29a9e0bfe54926c057bc1ea3e22269a2f87c15b.zip
Fix fallback in validate_tgt()
To validate a TGT a keytab entry from the client realm is preferred but if none ca be found the last entry should be used. But the entry was freed and zeroed before it could be used. This should also fix the trusted domain use case mentioned in https://fedorahosted.org/sssd/ticket/1396 although a different approach then suggested in the ticket is used.
-rw-r--r--src/providers/krb5/krb5_child.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 817a3d01..7ae184cb 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -695,6 +695,7 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
krb5_kt_cursor cursor;
krb5_keytab_entry entry;
krb5_verify_init_creds_opt opt;
+ krb5_principal validation_princ = NULL;
memset(&keytab, 0, sizeof(keytab));
kerr = krb5_kt_resolve(kr->ctx, kr->keytab, &keytab);
@@ -715,10 +716,15 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
/* We look for the first entry from our realm or take the last one */
memset(&entry, 0, sizeof(entry));
while ((kt_err = krb5_kt_next_entry(kr->ctx, keytab, &entry, &cursor)) == 0) {
- if (krb5_realm_compare(kr->ctx, entry.principal, kr->princ)) {
- DEBUG(SSSDBG_TRACE_INTERNAL,
- ("Found keytab entry with the realm of the credential.\n"));
- break;
+ if (validation_princ != NULL) {
+ krb5_free_principal(kr->ctx, validation_princ);
+ validation_princ = NULL;
+ }
+ kerr = krb5_copy_principal(kr->ctx, entry.principal,
+ &validation_princ);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_copy_principal failed.\n"));
+ goto done;
}
kerr = sss_krb5_free_keytab_entry_contents(kr->ctx, &entry);
@@ -726,6 +732,12 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
DEBUG(1, ("Failed to free keytab entry.\n"));
}
memset(&entry, 0, sizeof(entry));
+
+ if (krb5_realm_compare(kr->ctx, validation_princ, kr->princ)) {
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ ("Found keytab entry with the realm of the credential.\n"));
+ break;
+ }
}
/* Close the keytab here. Even though we're using cursors, the file
@@ -747,7 +759,7 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
/* Get the principal to which the key belongs, for logging purposes. */
principal = NULL;
- kerr = krb5_unparse_name(kr->ctx, entry.principal, &principal);
+ kerr = krb5_unparse_name(kr->ctx, validation_princ, &principal);
if (kerr != 0) {
DEBUG(1, ("internal error parsing principal name, "
"not verifying TGT.\n"));
@@ -757,7 +769,7 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
krb5_verify_init_creds_opt_init(&opt);
- kerr = krb5_verify_init_creds(kr->ctx, kr->creds, entry.principal, keytab,
+ kerr = krb5_verify_init_creds(kr->ctx, kr->creds, validation_princ, keytab,
NULL, &opt);
if (kerr == 0) {
@@ -770,8 +782,8 @@ done:
if (krb5_kt_close(kr->ctx, keytab) != 0) {
DEBUG(1, ("krb5_kt_close failed"));
}
- if (sss_krb5_free_keytab_entry_contents(kr->ctx, &entry) != 0) {
- DEBUG(1, ("Failed to free keytab entry.\n"));
+ if (validation_princ != NULL) {
+ krb5_free_principal(kr->ctx, validation_princ);
}
if (principal != NULL) {
sss_krb5_free_unparsed_name(kr->ctx, principal);