heimdal:lib/krb5: verify_logonname() to handle multi component principal
authorStefan Metzmacher <metze@samba.org>
Wed, 20 May 2015 13:40:58 +0000 (13:40 +0000)
committerStefan Metzmacher <metze@samba.org>
Wed, 20 May 2015 17:29:30 +0000 (19:29 +0200)
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 <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/heimdal/lib/krb5/pac.c

index 9328647a5b3d7cb1632fea779d03a6e9aa277cb2..7c8ba50e9c49fdaed9bd7bef20253c0a543e264a 100644 (file)
@@ -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);
@@ -664,31 +665,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 = strcmp(logon_string, principal_string);
+    if (ret != 0) {
        ret = EINVAL;
-       krb5_set_error_message(context, ret, "PAC logon name mismatch");
+       krb5_set_error_message(context, ret, "PAC logon name [%s] mismatch principal name [%s]",
+                              logon_string, principal_string);
     }
-    krb5_free_principal(context, p2);
+    free(logon_string);
+    free(principal_string);
     return ret;
 out:
     return ret;