kdc: support for PAC_ATTRIBUTES_INFO
Add PAC_ATTRIBUTES_INFO to the PAC. This info buffer indicates whether the user explicitly requested a PAC be present or absent. Note: this changes the windc plugin ABI.
This commit is contained in:
@@ -848,7 +848,7 @@ _kdc_fast_check_armor_pac(astgs_request_t r)
|
||||
armor_client, r->armor_server,
|
||||
r->armor_server, r->armor_server,
|
||||
&r->armor_key->key, &r->armor_key->key,
|
||||
&r->armor_ticket->ticket, &ad_kdc_issued, &mspac, NULL);
|
||||
&r->armor_ticket->ticket, &ad_kdc_issued, &mspac, NULL, NULL);
|
||||
if (ret) {
|
||||
const char *msg = krb5_get_error_message(r->context, ret);
|
||||
|
||||
|
@@ -109,6 +109,8 @@ struct astgs_request_desc {
|
||||
Key *armor_key;
|
||||
|
||||
KDCFastState fast;
|
||||
|
||||
uint64_t pac_attributes;
|
||||
};
|
||||
|
||||
typedef struct kx509_req_context_desc {
|
||||
|
@@ -1783,34 +1783,33 @@ _kdc_check_anon_policy(astgs_request_t r)
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Determine whether the client requested a PAC be included
|
||||
* or excluded explictly, or whether it doesn't care.
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
check_pa_pac_request(krb5_context context,
|
||||
KDC_REQ *req,
|
||||
krb5_boolean *include_pac)
|
||||
static uint64_t
|
||||
get_pac_attributes(krb5_context context, KDC_REQ *req)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
PA_PAC_REQUEST pacreq;
|
||||
const PA_DATA *pa;
|
||||
int i = 0;
|
||||
|
||||
*include_pac = TRUE;
|
||||
uint32_t pac_attributes;
|
||||
|
||||
pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);
|
||||
if (pa == NULL)
|
||||
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
|
||||
return KRB5_PAC_WAS_GIVEN_IMPLICITLY;
|
||||
|
||||
ret = decode_PA_PAC_REQUEST(pa->padata_value.data,
|
||||
pa->padata_value.length,
|
||||
&pacreq,
|
||||
NULL);
|
||||
if (ret)
|
||||
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
|
||||
*include_pac = pacreq.include_pac;
|
||||
return KRB5_PAC_WAS_GIVEN_IMPLICITLY;
|
||||
|
||||
pac_attributes = pacreq.include_pac ? KRB5_PAC_WAS_REQUESTED : 0;
|
||||
free_PA_PAC_REQUEST(&pacreq);
|
||||
return 0;
|
||||
return pac_attributes;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1825,11 +1824,9 @@ generate_pac(astgs_request_t r, const Key *skey, const Key *tkey)
|
||||
krb5_data data;
|
||||
uint16_t rodc_id;
|
||||
krb5_principal client;
|
||||
krb5_boolean client_sent_pac_req, pac_request;
|
||||
krb5_const_principal canon_princ = NULL;
|
||||
|
||||
client_sent_pac_req =
|
||||
(check_pa_pac_request(r->context, &r->req, &pac_request) == 0);
|
||||
r->pac_attributes = get_pac_attributes(r->context, &r->req);
|
||||
|
||||
/*
|
||||
* When a PA mech replaces the reply key, the PAC may include the
|
||||
@@ -1841,7 +1838,7 @@ generate_pac(astgs_request_t r, const Key *skey, const Key *tkey)
|
||||
r->client,
|
||||
r->server,
|
||||
r->replaced_reply_key ? &r->reply_key : NULL,
|
||||
client_sent_pac_req ? &pac_request : NULL,
|
||||
r->pac_attributes,
|
||||
&p);
|
||||
if (ret) {
|
||||
_kdc_r_log(r, 4, "PAC generation failed for -- %s",
|
||||
@@ -1885,6 +1882,7 @@ generate_pac(astgs_request_t r, const Key *skey, const Key *tkey)
|
||||
rodc_id,
|
||||
NULL, /* UPN */
|
||||
canon_princ,
|
||||
&r->pac_attributes,
|
||||
&data);
|
||||
krb5_free_principal(r->context, client);
|
||||
krb5_pac_free(r->context, p);
|
||||
|
@@ -89,7 +89,8 @@ _kdc_check_pac(krb5_context context,
|
||||
EncTicketPart *tkt,
|
||||
krb5_boolean *kdc_issued,
|
||||
krb5_pac *ppac,
|
||||
krb5_principal *pac_canon_name)
|
||||
krb5_principal *pac_canon_name,
|
||||
uint64_t *pac_attributes)
|
||||
{
|
||||
krb5_pac pac = NULL;
|
||||
krb5_error_code ret;
|
||||
@@ -129,6 +130,8 @@ _kdc_check_pac(krb5_context context,
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (pac_attributes)
|
||||
_krb5_pac_get_attributes_info(context, pac, pac_attributes);
|
||||
} else if (ret == KRB5_PLUGIN_NO_HANDLE) {
|
||||
/*
|
||||
* We can't verify the KDC signatures if the ticket was issued by
|
||||
@@ -150,6 +153,8 @@ _kdc_check_pac(krb5_context context,
|
||||
krb5_pac_free(context, pac);
|
||||
return ret;
|
||||
}
|
||||
if (pac_attributes)
|
||||
_krb5_pac_get_attributes_info(context, pac, pac_attributes);
|
||||
}
|
||||
|
||||
/* Discard the PAC if the plugin didn't handle it */
|
||||
@@ -818,8 +823,8 @@ tgs_make_reply(astgs_request_t r,
|
||||
|
||||
/* The PAC should be the last change to the ticket. */
|
||||
ret = _krb5_kdc_pac_sign_ticket(r->context, mspac, tgt_name, serverkey,
|
||||
krbtgtkey, rodc_id, add_ticket_sig, &et,
|
||||
NULL, r->client_princ);
|
||||
krbtgtkey, rodc_id, NULL, r->client_princ,
|
||||
add_ticket_sig, &et, &r->pac_attributes);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
@@ -1842,7 +1847,7 @@ server_lookup:
|
||||
ret = _kdc_check_pac(context, config, user2user_princ, NULL,
|
||||
user2user_client, user2user_krbtgt, user2user_krbtgt, user2user_krbtgt,
|
||||
&uukey->key, &priv->ticket_key->key, &adtkt,
|
||||
&user2user_kdc_issued, &user2user_pac, NULL);
|
||||
&user2user_kdc_issued, &user2user_pac, NULL, NULL);
|
||||
_kdc_free_ent(context, user2user_client);
|
||||
if (ret) {
|
||||
const char *msg = krb5_get_error_message(context, ret);
|
||||
@@ -1970,7 +1975,7 @@ server_lookup:
|
||||
|
||||
ret = _kdc_check_pac(context, config, cp, NULL, client, server, krbtgt, krbtgt,
|
||||
&priv->ticket_key->key, &priv->ticket_key->key, tgt,
|
||||
&kdc_issued, &mspac, &priv->client_princ);
|
||||
&kdc_issued, &mspac, &priv->client_princ, &priv->pac_attributes);
|
||||
if (ret) {
|
||||
const char *msg = krb5_get_error_message(context, ret);
|
||||
_kdc_audit_addreason((kdc_request_t)priv, "PAC check failed");
|
||||
@@ -2131,7 +2136,7 @@ server_lookup:
|
||||
s4u2self_impersonated_client,
|
||||
server,
|
||||
NULL,
|
||||
NULL,
|
||||
KRB5_PAC_WAS_GIVEN_IMPLICITLY,
|
||||
&mspac);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 4, "PAC generation failed for -- %s", tpn);
|
||||
@@ -2302,7 +2307,7 @@ server_lookup:
|
||||
*/
|
||||
ret = _kdc_check_pac(context, config, tp, dp, adclient, server, krbtgt, client,
|
||||
&clientkey->key, &priv->ticket_key->key, &adtkt,
|
||||
&ad_kdc_issued, &mspac, &priv->client_princ);
|
||||
&ad_kdc_issued, &mspac, &priv->client_princ, &priv->pac_attributes);
|
||||
if (adclient)
|
||||
_kdc_free_ent(context, adclient);
|
||||
if (ret) {
|
||||
|
@@ -73,8 +73,8 @@ struct generate_uc {
|
||||
hdb_entry_ex *client;
|
||||
hdb_entry_ex *server;
|
||||
const krb5_keyblock *reply_key;
|
||||
uint64_t pac_attributes;
|
||||
krb5_pac *pac;
|
||||
const krb5_boolean *pac_request;
|
||||
};
|
||||
|
||||
static krb5_error_code KRB5_LIB_CALL
|
||||
@@ -90,7 +90,7 @@ generate(krb5_context context, const void *plug, void *plugctx, void *userctx)
|
||||
uc->client,
|
||||
uc->server,
|
||||
uc->reply_key,
|
||||
uc->pac_request,
|
||||
uc->pac_attributes,
|
||||
uc->pac);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ _kdc_pac_generate(krb5_context context,
|
||||
hdb_entry_ex *client,
|
||||
hdb_entry_ex *server,
|
||||
const krb5_keyblock *reply_key,
|
||||
const krb5_boolean *pac_request,
|
||||
uint64_t pac_attributes,
|
||||
krb5_pac *pac)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
@@ -118,7 +118,7 @@ _kdc_pac_generate(krb5_context context,
|
||||
uc.server = server;
|
||||
uc.reply_key = reply_key;
|
||||
uc.pac = pac;
|
||||
uc.pac_request = pac_request;
|
||||
uc.pac_attributes = pac_attributes;
|
||||
|
||||
ret = _krb5_plugin_run_f(context, &windc_plugin_data,
|
||||
0, &uc, generate);
|
||||
|
@@ -57,7 +57,7 @@ typedef krb5_error_code
|
||||
struct hdb_entry_ex *, /* client */
|
||||
struct hdb_entry_ex *, /* server */
|
||||
const krb5_keyblock *, /* pk_replykey */
|
||||
const krb5_boolean *, /* pac_request */
|
||||
uint64_t, /* pac_attributes */
|
||||
krb5_pac *);
|
||||
|
||||
typedef krb5_error_code
|
||||
|
Reference in New Issue
Block a user