diff --git a/third_party/heimdal/kcm/protocol.c b/third_party/heimdal/kcm/protocol.c index 31f17623d01..b5442e45891 100644 --- a/third_party/heimdal/kcm/protocol.c +++ b/third_party/heimdal/kcm/protocol.c @@ -333,9 +333,7 @@ kcm_op_retrieve(krb5_context context, return ret; } - if (disallow_getting_krbtgt && - mcreds.server->name.name_string.len == 2 && - strcmp(mcreds.server->name.name_string.val[0], KRB5_TGS_NAME) == 0) + if (disallow_getting_krbtgt && krb5_principal_is_krbtgt(context, mcreds.server)) { free(name); krb5_free_cred_contents(context, &mcreds); diff --git a/third_party/heimdal/kdc/krb5tgs.c b/third_party/heimdal/kdc/krb5tgs.c index 6ba3efccc4a..af80450c4b0 100644 --- a/third_party/heimdal/kdc/krb5tgs.c +++ b/third_party/heimdal/kdc/krb5tgs.c @@ -962,7 +962,13 @@ tgs_parse_request(astgs_request_t r, goto out; } - if(!get_krbtgt_realm(&ap_req.ticket.sname)){ + if(!krb5_principalname_is_krbtgt(r->context, &ap_req.ticket.sname)){ + /* + * Note: this check is not to be depended upon for security. Nothing + * prevents a client modifying the sname, as it is located in the + * unencrypted part of the ticket. + */ + /* XXX check for ticket.sname == req.sname */ kdc_log(r->context, config, 4, "PA-DATA is not a ticket-granting ticket"); ret = KRB5KDC_ERR_POLICY; /* ? */ @@ -1631,7 +1637,13 @@ server_lookup: goto out; } t = &b->additional_tickets->val[0]; - if(!get_krbtgt_realm(&t->sname)){ + if(!krb5_principalname_is_krbtgt(context, &t->sname)){ + /* + * Note: this check is not to be depended upon for + * security. Nothing prevents a client modifying the sname, as + * it is located in the unencrypted part of the ticket. + */ + kdc_log(context, config, 4, "Additional ticket is not a ticket-granting ticket"); kdc_audit_addreason((kdc_request_t)priv, diff --git a/third_party/heimdal/lib/hdb/common.c b/third_party/heimdal/lib/hdb/common.c index 1c947b3cfc5..f86481dd9ea 100644 --- a/third_party/heimdal/lib/hdb/common.c +++ b/third_party/heimdal/lib/hdb/common.c @@ -1616,7 +1616,7 @@ fetch_it(krb5_context context, if (!db->enable_virtual_hostbased_princs) maxdots = mindots = 0; if (db->enable_virtual_hostbased_princs && comp1 && - strcmp("krbtgt", comp0) != 0 && strcmp(KRB5_WELLKNOWN_NAME, comp0) != 0) { + (comp0 == NULL || (strcmp("krbtgt", comp0) != 0 && strcmp(KRB5_WELLKNOWN_NAME, comp0) != 0))) { char *htmp; if ((host = strdup(comp1)) == NULL) diff --git a/third_party/heimdal/lib/krb5/libkrb5-exports.def.in b/third_party/heimdal/lib/krb5/libkrb5-exports.def.in index 3845cd73601..4870de90d1f 100644 --- a/third_party/heimdal/lib/krb5/libkrb5-exports.def.in +++ b/third_party/heimdal/lib/krb5/libkrb5-exports.def.in @@ -539,6 +539,7 @@ EXPORTS krb5_principal_set_comp_string krb5_principal_set_realm krb5_principal_set_type + krb5_principalname_is_krbtgt krb5_print_address krb5_program_setup krb5_prompter_posix diff --git a/third_party/heimdal/lib/krb5/principal.c b/third_party/heimdal/lib/krb5/principal.c index 4a8e66deb41..33ebd19ffe0 100644 --- a/third_party/heimdal/lib/krb5/principal.c +++ b/third_party/heimdal/lib/krb5/principal.c @@ -1244,6 +1244,20 @@ krb5_principal_is_pku2u(krb5_context context, krb5_const_principal principal) return strcmp(principal->realm, KRB5_PKU2U_REALM_NAME) == 0; } +/** + * Check if the cname part of the principal name is a krbtgt principal + * + * @ingroup krb5_principal + */ + +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL +krb5_principalname_is_krbtgt(krb5_context context, const PrincipalName *p) +{ + return 1 <= p->name_string.len && + p->name_string.len <= 2 && + strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0; +} + /** * Check if the cname part of the principal is a krbtgt principal * @@ -1253,8 +1267,7 @@ krb5_principal_is_pku2u(krb5_context context, krb5_const_principal principal) KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_principal_is_krbtgt(krb5_context context, krb5_const_principal p) { - return p->name.name_string.len == 2 && - strcmp(p->name.name_string.val[0], KRB5_TGS_NAME) == 0; + return krb5_principalname_is_krbtgt(context, &p->name); } /** diff --git a/third_party/heimdal/lib/krb5/test_pac.c b/third_party/heimdal/lib/krb5/test_pac.c index 70da1cb6266..89434ccd09f 100644 --- a/third_party/heimdal/lib/krb5/test_pac.c +++ b/third_party/heimdal/lib/krb5/test_pac.c @@ -823,13 +823,6 @@ t_err(krb5_context context, krb5_err(context, 1, error, "test %s failed in %s", test, func); } -static krb5_boolean -is_krbtgt(const PrincipalName *p) -{ - return (p->name_string.len == 2 && - strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0); -} - static void check_ticket_signature(krb5_context context, const struct test_pac_ticket *tkt) @@ -875,7 +868,9 @@ check_ticket_signature(krb5_context context, if (ret) t_err(context, tkt->name, "_krb5_kdc_pac_ticket_parse", ret); - heim_assert(!is_krbtgt(&ticket.sname) == !!signedticket, "ticket-signature"); + heim_assert(!krb5_principalname_is_krbtgt(context, + &ticket.sname) == !!signedticket, + "ticket-signature"); ret = krb5_pac_verify(context, pac, et.authtime, client, tkt->key, tkt->kdc_key); @@ -932,7 +927,9 @@ check_ticket_signature(krb5_context context, if (ret) t_err(context, tkt->name, "_krb5_kdc_pac_ticket_parse 2", ret); - heim_assert(!is_krbtgt(&ticket.sname) == !!signedticket, "ticket-signature"); + heim_assert(!krb5_principalname_is_krbtgt(context, + &ticket.sname) == !!signedticket, + "ticket-signature"); ret = krb5_pac_verify(context, pac, et.authtime, client, tkt->key, tkt->kdc_key); diff --git a/third_party/heimdal/lib/krb5/version-script.map b/third_party/heimdal/lib/krb5/version-script.map index a81b08fa147..f2cfa3cd3f9 100644 --- a/third_party/heimdal/lib/krb5/version-script.map +++ b/third_party/heimdal/lib/krb5/version-script.map @@ -532,6 +532,7 @@ HEIMDAL_KRB5_2.0 { krb5_principal_is_federated; krb5_principal_is_krbtgt; krb5_principal_is_root_krbtgt; + krb5_principalname_is_krbtgt; krb5_print_address; krb5_program_setup; krb5_prompter_posix;