From 0317255b5329e4ff3e1aa4a86b52b60d30f4614b Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 18 May 2020 15:23:16 +0300 Subject: [PATCH] ipa-kdb: add UPN_DNS_INFO PAC structure UPN_DNS_INFO structure contains the client's user principal name (UPN) and a fully qualified domain name. It is used to provide the UPN and the FQDN that corresponds to the client of the ticket. The structure is defined in MS-PAC section 2.10. MS-KILE specification says in the section 3.3.5.6.4.5 that KDCs should return this buffer. It further clarifies in section 3.3.5.2 that if the user account object has no userPrincipalName attribute, UPN_DNS_INFO should be constructed by concatenating user name, the "@" symbol, and the DNS name of the domain. IPA users don't really have userPrincipalName attribute. Instead, we always construct their account names in LOGON Info3 structure by unparsing the canonical principal name without realm, meaning that user principal can be recovered by concatenating the account name and the realm (domain). Unless the account name and unparsed client principal name are different or the primary Info3 gid (group RID) is the one for machine accounts, mark the UPN as constructed. Related: https://pagure.io/freeipa/issue/8319 Signed-off-by: Alexander Bokovoy Reviewed-By: Isaac Boukris Reviewed-By: Florence Blanc-Renaud --- daemons/ipa-kdb/ipa_kdb_mspac.c | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index 615a23e95..255628612 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -805,6 +805,8 @@ static krb5_error_code ipadb_get_pac(krb5_context kcontext, union PAC_INFO pac_info; krb5_error_code kerr; enum ndr_err_code ndr_err; + union PAC_INFO pac_upn; + char *principal = NULL; /* When no client entry is there, we cannot generate MS-PAC */ if (!client) { @@ -879,6 +881,46 @@ static krb5_error_code ipadb_get_pac(krb5_context kcontext, kerr = krb5_pac_add_buffer(kcontext, *pac, KRB5_PAC_LOGON_INFO, &data); + /* == Package UPN_DNS_LOGON_INFO == */ + memset(&pac_upn, 0, sizeof(pac_upn)); + kerr = krb5_unparse_name(kcontext, client->princ, &principal); + if (kerr) { + goto done; + } + + pac_upn.upn_dns_info.upn_name = talloc_strdup(tmpctx, principal); + krb5_free_unparsed_name(kcontext, principal); + if (pac_upn.upn_dns_info.upn_name == NULL) { + kerr = KRB5_KDB_INTERNAL_ERROR; + goto done; + } + + pac_upn.upn_dns_info.dns_domain_name = talloc_strdup(tmpctx, ipactx->realm); + if (pac_upn.upn_dns_info.dns_domain_name == NULL) { + kerr = KRB5_KDB_INTERNAL_ERROR; + goto done; + } + + /* IPA user principals are all constructed */ + if ((pac_info.logon_info.info->info3.base.rid != 515) || + (pac_info.logon_info.info->info3.base.rid != 516)) { + pac_upn.upn_dns_info.flags |= PAC_UPN_DNS_FLAG_CONSTRUCTED; + } + + ndr_err = ndr_push_union_blob(&pac_data, tmpctx, &pac_upn, + PAC_TYPE_UPN_DNS_INFO, + (ndr_push_flags_fn_t)ndr_push_PAC_INFO); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + kerr = KRB5_KDB_INTERNAL_ERROR; + goto done; + } + + data.magic = KV5M_DATA; + data.data = (char *)pac_data.data; + data.length = pac_data.length; + + kerr = krb5_pac_add_buffer(kcontext, *pac, KRB5_PAC_UPN_DNS_INFO, &data); + done: ldap_msgfree(results); talloc_free(tmpctx);