hdb: dereference principal aliases in all KDC lookups (#452)

e11abf41 added support in libhdb for always dereferencing principal aliases
during an AS-REQ (where dereferencing refers to enabling alias lookups, and
rewriting the returned entry with the alias name unless canonicalization was
enabled).

Due to the KDC setting HDB_F_FOR_AS_REQ for all lookups from the AS, this
allowed aliases on the TGS itself to be dereferenced during an AS-REQ; however,
on presenting the TGT, the TGS would fail to resolve. Creating an explicit TGS
principal for the aliased realm would work (at least prior to c555ed6a), but
this could be confusing to deploy.

This commit changes enables alias dereferencing when HDB_F_GET_ANY is set,
which essentially means dereference whenever the request is coming from the KDC
(as opposed to, say, kadmin).

We also backout c555ed6a, which changed the TGS to always canonicalize the
server realm, as this breaks serving multiple realms from a single KDC, where
server principals in different realms share a single canonical entry.
HDB_F_CANON is now passed to the backend as a hint only, and per RFC 6806 the
principal name is never changed in TGS replies. (However, for Samba interop,
backends can override this by setting the force-canonicalize HDB flag.)
This commit is contained in:
Luke Howard
2019-01-05 12:36:28 +11:00
parent c6d00f2502
commit 6bb8eaca20
3 changed files with 22 additions and 13 deletions

View File

@@ -130,7 +130,8 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal,
if(ret)
return ret;
ret = hdb_value2entry(context, &value, &entry->entry);
if (ret == ASN1_BAD_ID && (flags & (HDB_F_CANON|HDB_F_FOR_AS_REQ)) == 0) {
/* HDB_F_GET_ANY indicates request originated from KDC (not kadmin) */
if (ret == ASN1_BAD_ID && (flags & (HDB_F_CANON|HDB_F_GET_ANY)) == 0) {
krb5_data_free(&value);
return HDB_ERR_NOENTRY;
} else if (ret == ASN1_BAD_ID) {
@@ -155,7 +156,7 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal,
return ret;
}
if ((flags & HDB_F_FOR_AS_REQ) && (flags & HDB_F_CANON) == 0) {
if ((flags & HDB_F_GET_ANY) && (flags & HDB_F_CANON) == 0) {
krb5_principal tmp;
/* "hard" alias: return the principal the client asked for */
@@ -333,7 +334,8 @@ _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
krb5_data key, value;
int code;
if (entry->entry.flags.do_not_store)
if (entry->entry.flags.do_not_store ||
entry->entry.flags.force_canonicalize)
return HDB_ERR_MISUSE;
/* check if new aliases already is used */
code = hdb_check_aliases(context, db, entry);