kdc: add auth data type for synthetic principals
Add a new authorization data type to indicate a synthetic principal was used, to allow synthetic clients acquired outside of PKINIT (e.g. with GSS-API pre-authentication) to use the TGS. Note: we continue to honor KRB5_AUTHDATA_INITIAL_VERIFIED_CAS to indicate that it is OK for the client to be synthetic, even though it is only an indication that the client *may* have been synthetic.
This commit is contained in:
@@ -1959,6 +1959,23 @@ add_enc_pa_rep(astgs_request_t r)
|
||||
KRB5_PADATA_FX_FAST, NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an authorization data element indicating that a synthetic
|
||||
* principal was used, so that the TGS does not accidentally
|
||||
* synthesize a non-synthetic principal that has since been deleted.
|
||||
*/
|
||||
static krb5_error_code
|
||||
add_synthetic_princ_ad(astgs_request_t r)
|
||||
{
|
||||
krb5_data data;
|
||||
|
||||
krb5_data_zero(&data);
|
||||
|
||||
return _kdc_tkt_add_if_relevant_ad(r->context, &r->et,
|
||||
KRB5_AUTHDATA_SYNTHETIC_PRINC_USED,
|
||||
&data);
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
get_local_tgs(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
@@ -2615,6 +2632,12 @@ _kdc_as_rep(astgs_request_t r)
|
||||
generate_pac(r, skey, krbtgt_key);
|
||||
}
|
||||
|
||||
if (r->client->entry.flags.synthetic) {
|
||||
ret = add_synthetic_princ_ad(r);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
_kdc_log_timestamp(r, "AS-REQ", r->et.authtime,
|
||||
r->et.starttime, r->et.endtime,
|
||||
r->et.renew_till);
|
||||
|
@@ -47,6 +47,30 @@ get_krbtgt_realm(const PrincipalName *p)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* return TRUE if client was a synthetic principal, as indicated by
|
||||
* authorization data
|
||||
*/
|
||||
krb5_boolean
|
||||
_kdc_synthetic_princ_used_p(krb5_context context, krb5_ticket *ticket)
|
||||
{
|
||||
krb5_data synthetic_princ_used;
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = krb5_ticket_get_authorization_data_type(context, ticket,
|
||||
KRB5_AUTHDATA_SYNTHETIC_PRINC_USED,
|
||||
&synthetic_princ_used);
|
||||
if (ret == ENOENT)
|
||||
ret = krb5_ticket_get_authorization_data_type(context, ticket,
|
||||
KRB5_AUTHDATA_INITIAL_VERIFIED_CAS,
|
||||
&synthetic_princ_used);
|
||||
|
||||
if (ret == 0)
|
||||
krb5_data_free(&synthetic_princ_used);
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@@ -1902,25 +1926,9 @@ server_lookup:
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
krb5_data verified_cas;
|
||||
if (_kdc_synthetic_princ_used_p(context, ticket))
|
||||
flags |= HDB_F_SYNTHETIC_OK;
|
||||
|
||||
/*
|
||||
* If the client doesn't exist in the HDB but has a TGT and it's
|
||||
* obtained with PKINIT then we assume it's a synthetic client -- that
|
||||
* is, a client whose name was vouched for by a CA using a PKINIT SAN,
|
||||
* but which doesn't exist in the HDB proper. We'll allow such a
|
||||
* client to do TGT requests even though normally we'd reject all
|
||||
* clients that don't exist in the HDB.
|
||||
*/
|
||||
ret = krb5_ticket_get_authorization_data_type(context, ticket,
|
||||
KRB5_AUTHDATA_INITIAL_VERIFIED_CAS,
|
||||
&verified_cas);
|
||||
if (ret == 0) {
|
||||
krb5_data_free(&verified_cas);
|
||||
flags |= HDB_F_SYNTHETIC_OK;
|
||||
}
|
||||
}
|
||||
ret = db_fetch_client(context, config, flags, cp, cpn, our_realm,
|
||||
&clientdb, &client);
|
||||
if (ret)
|
||||
|
@@ -215,6 +215,7 @@ AUTHDATA-TYPE ::= INTEGER {
|
||||
KRB5-AUTHDATA-SIGNTICKET-OLDER(-17),
|
||||
KRB5-AUTHDATA-SIGNTICKET-OLD(142),
|
||||
KRB5-AUTHDATA-SIGNTICKET(512),
|
||||
KRB5-AUTHDATA-SYNTHETIC-PRINC-USED(513), -- principal was synthetised
|
||||
KRB5-AUTHDATA-AP-OPTIONS(143),
|
||||
-- N.B. these assignments have not been confirmed yet.
|
||||
--
|
||||
|
Reference in New Issue
Block a user