From ae4d222f586b7e93800b902b6823ab3a3978ff54 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 May 2015 13:40:58 +0000 Subject: [PATCH] lib/krb5: verify_logonname() to handle multi component principal FreeIPA can generate tickets with a client principal of 'host/hostname.example.com'. verify_logonname() should just verify the principal name in the PAC_LOGON_NAME is the same as the principal of the client principal (without realm) of the ticket. Samba commit b7cc8c1187ff967e44587cd0d09185330378f366 break this. We try to compare ['host']['hostname.example.com'] with ['host/hostname.example.com]' (as we interpret it as enterprise principal) this fail if we don't compare them as strings. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11142 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- lib/krb5/pac.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/krb5/pac.c b/lib/krb5/pac.c index 72da58dc7..9b03dfc79 100644 --- a/lib/krb5/pac.c +++ b/lib/krb5/pac.c @@ -595,11 +595,12 @@ verify_logonname(krb5_context context, krb5_const_principal principal) { krb5_error_code ret; - krb5_principal p2; uint32_t time1, time2; krb5_storage *sp; uint16_t len; - char *s; + char *s = NULL; + char *principal_string = NULL; + char *logon_string = NULL; sp = krb5_storage_from_readonly_mem((const char *)data->data + logon_name->offset_lo, logon_name->buffersize); @@ -670,31 +671,36 @@ verify_logonname(krb5_context context, return ret; } u8len += 1; /* Add space for NUL */ - s = malloc(u8len); - if (s == NULL) { + logon_string = malloc(u8len); + if (logon_string == NULL) { free(ucs2); return krb5_enomem(context); } - ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len); + ret = wind_ucs2utf8(ucs2, ucs2len, logon_string, &u8len); free(ucs2); if (ret) { - free(s); + free(logon_string); krb5_set_error_message(context, ret, "Failed to convert to UTF-8"); return ret; } } - ret = krb5_parse_name_flags(context, s, - KRB5_PRINCIPAL_PARSE_NO_REALM | - KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p2); - free(s); - if (ret) + ret = krb5_unparse_name_flags(context, principal, + KRB5_PRINCIPAL_UNPARSE_NO_REALM | + KRB5_PRINCIPAL_UNPARSE_DISPLAY, + &principal_string); + if (ret) { + free(logon_string); return ret; - - if (krb5_principal_compare_any_realm(context, principal, p2) != TRUE) { - ret = EINVAL; - krb5_set_error_message(context, ret, "PAC logon name mismatch"); } - krb5_free_principal(context, p2); + + ret = strcmp(logon_string, principal_string); + if (ret != 0) { + ret = EINVAL; + krb5_set_error_message(context, ret, "PAC logon name [%s] mismatch principal name [%s]", + logon_string, principal_string); + } + free(logon_string); + free(principal_string); return ret; out: return ret;