kdc: refactor anonymous checks in KDC
_kdc_is_anon_request() is only used by the AS, so make it static. Centralize anonymous poilcy checks shared between AS and TGS into a shared function, _kdc_check_anon_policy(). When issuing an anonymous ticket, set the ticket flag early and test that rather than re-testing the request.
This commit is contained in:
@@ -116,6 +116,22 @@ is_default_salt_p(const krb5_salt *default_salt, const Key *key)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static krb5_boolean
|
||||
is_anon_request_p(kdc_request_t r)
|
||||
{
|
||||
KDC_REQ_BODY *b = &r->req.req_body;
|
||||
|
||||
/*
|
||||
* Some versions of heimdal use bit 14 instead of 16 for
|
||||
* request_anonymous, as indicated in the anonymous draft prior to
|
||||
* version 11. Bit 14 is assigned to S4U2Proxy, but all S4U2Proxy
|
||||
* requests will have a second ticket; don't consider those anonymous
|
||||
*/
|
||||
return b->kdc_options.request_anonymous ||
|
||||
(b->kdc_options.cname_in_addl_tkt && !b->additional_tickets);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the first appropriate key of `princ' in `ret_key'. Look for
|
||||
* all the etypes in (`etypes', `len'), stopping as soon as we find
|
||||
@@ -437,7 +453,6 @@ static krb5_error_code
|
||||
pa_enc_chal_validate(kdc_request_t r, const PA_DATA *pa)
|
||||
{
|
||||
krb5_data pepper1, pepper2, ts_data;
|
||||
KDC_REQ_BODY *b = &r->req.req_body;
|
||||
int invalidPassword = 0;
|
||||
EncryptedData enc_data;
|
||||
krb5_enctype aenctype;
|
||||
@@ -448,7 +463,7 @@ pa_enc_chal_validate(kdc_request_t r, const PA_DATA *pa)
|
||||
|
||||
heim_assert(r->armor_crypto != NULL, "ENC-CHAL called for non FAST");
|
||||
|
||||
if (_kdc_is_anon_request(b)) {
|
||||
if (is_anon_request_p(r)) {
|
||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
||||
kdc_log(r->context, r->config, 0, "ENC-CHALL doesn't support anon");
|
||||
return ret;
|
||||
@@ -1537,6 +1552,24 @@ _kdc_check_addresses(krb5_context context,
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
krb5_error_code
|
||||
_kdc_check_anon_policy (krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
hdb_entry_ex *client,
|
||||
hdb_entry_ex *server)
|
||||
{
|
||||
if (!config->allow_anonymous){
|
||||
kdc_log(context, config, 0,
|
||||
"Request for anonymous ticket denied by local policy");
|
||||
return KRB5KDC_ERR_POLICY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@@ -1760,12 +1793,11 @@ _kdc_as_rep(kdc_request_t r,
|
||||
*
|
||||
*/
|
||||
|
||||
if (_kdc_is_anonymous(context, r->client_princ)) {
|
||||
if (!_kdc_is_anon_request(b)) {
|
||||
kdc_log(context, config, 0, "Anonymous client w/o anonymous flag");
|
||||
ret = KRB5KDC_ERR_BADOPTION;
|
||||
goto out;
|
||||
}
|
||||
if (_kdc_is_anonymous(context, r->client_princ) &&
|
||||
!is_anon_request_p(r)) {
|
||||
kdc_log(context, config, 0, "Anonymous client w/o anonymous flag");
|
||||
ret = KRB5KDC_ERR_BADOPTION;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1936,7 +1968,7 @@ _kdc_as_rep(kdc_request_t r,
|
||||
* send requre preauth is its required or anon is requested,
|
||||
* anon is today only allowed via preauth mechanisms.
|
||||
*/
|
||||
if (require_preauth_p(r) || _kdc_is_anon_request(b)) {
|
||||
if (require_preauth_p(r) || is_anon_request_p(r)) {
|
||||
ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
|
||||
_kdc_set_e_text(r, "Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ");
|
||||
goto out;
|
||||
@@ -1969,6 +2001,16 @@ _kdc_as_rep(kdc_request_t r,
|
||||
if(ret)
|
||||
goto out;
|
||||
|
||||
if (is_anon_request_p(r)) {
|
||||
ret = _kdc_check_anon_policy(context, config, r->client, r->server);
|
||||
if (ret) {
|
||||
_kdc_set_e_text(r, "Anonymous ticket requests are disabled");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r->et.flags.anonymous = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the best encryption type for the KDC with out regard to
|
||||
* the client since the client never needs to read that data.
|
||||
@@ -1980,8 +2022,7 @@ _kdc_as_rep(kdc_request_t r,
|
||||
if(ret)
|
||||
goto out;
|
||||
|
||||
if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey
|
||||
|| (_kdc_is_anon_request(b) && !config->allow_anonymous)) {
|
||||
if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey) {
|
||||
ret = KRB5KDC_ERR_BADOPTION;
|
||||
_kdc_set_e_text(r, "Bad KDC options");
|
||||
goto out;
|
||||
@@ -2003,7 +2044,7 @@ _kdc_as_rep(kdc_request_t r,
|
||||
ret = copy_Realm(&r->client_princ->realm, &rep.crealm);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (_kdc_is_anon_request(b))
|
||||
if (r->et.flags.anonymous)
|
||||
ret = _kdc_make_anonymous_principalname(&rep.cname);
|
||||
else if (f.canonicalize || r->client->entry.flags.force_canonicalize)
|
||||
ret = _krb5_principal2principalname(&rep.cname, r->client->entry.principal);
|
||||
@@ -2120,9 +2161,6 @@ _kdc_as_rep(kdc_request_t r,
|
||||
}
|
||||
}
|
||||
|
||||
if (_kdc_is_anon_request(b))
|
||||
r->et.flags.anonymous = 1;
|
||||
|
||||
if(b->addresses){
|
||||
ALLOC(r->et.caddr);
|
||||
copy_HostAddresses(b->addresses, r->et.caddr);
|
||||
@@ -2235,7 +2273,7 @@ _kdc_as_rep(kdc_request_t r,
|
||||
}
|
||||
|
||||
/* Add the PAC */
|
||||
if (send_pac_p(context, req) && !_kdc_is_anon_request(b)) {
|
||||
if (send_pac_p(context, req) && !r->et.flags.anonymous) {
|
||||
generate_pac(r, skey);
|
||||
}
|
||||
|
||||
@@ -2430,14 +2468,3 @@ _kdc_tkt_add_if_relevant_ad(krb5_context context,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_boolean
|
||||
_kdc_is_anon_request(const KDC_REQ_BODY *b)
|
||||
{
|
||||
/* some versions of heimdal use bit 14 instead of 16 for
|
||||
request_anonymous, as indicated in the anonymous draft prior to
|
||||
version 11. Bit 14 is assigned to S4U2Proxy, but all S4U2Proxy
|
||||
requests will have a second ticket; don't consider those anonymous */
|
||||
return (b->kdc_options.request_anonymous ||
|
||||
(b->kdc_options.cname_in_addl_tkt && !b->additional_tickets));
|
||||
}
|
||||
|
@@ -506,15 +506,8 @@ check_tgs_flags(krb5_context context,
|
||||
* anonymous KDC option SHOULD be set, but it is not required.
|
||||
* Treat an anonymous TGT as if the anonymous flag was set.
|
||||
*/
|
||||
if (tgt->flags.anonymous || f.request_anonymous) {
|
||||
if (!config->allow_anonymous){
|
||||
kdc_log(context, config, 0,
|
||||
"Request for anonymous ticket");
|
||||
return KRB5KDC_ERR_BADOPTION;
|
||||
}
|
||||
|
||||
if (tgt->flags.anonymous || f.request_anonymous)
|
||||
et->flags.anonymous = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2352,6 +2345,13 @@ server_lookup:
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check local and per-principal anonymous ticket issuance policy */
|
||||
if (tgt->flags.anonymous || b->kdc_options.request_anonymous) {
|
||||
ret = _kdc_check_anon_policy(context, config, client, server);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is an referral, add server referral data to the
|
||||
* auth_data reply .
|
||||
|
Reference in New Issue
Block a user