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,
|
armor_client, r->armor_server,
|
||||||
r->armor_server, r->armor_server,
|
r->armor_server, r->armor_server,
|
||||||
&r->armor_key->key, &r->armor_key->key,
|
&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) {
|
if (ret) {
|
||||||
const char *msg = krb5_get_error_message(r->context, ret);
|
const char *msg = krb5_get_error_message(r->context, ret);
|
||||||
|
|
||||||
|
@@ -109,6 +109,8 @@ struct astgs_request_desc {
|
|||||||
Key *armor_key;
|
Key *armor_key;
|
||||||
|
|
||||||
KDCFastState fast;
|
KDCFastState fast;
|
||||||
|
|
||||||
|
uint64_t pac_attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct kx509_req_context_desc {
|
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
|
static uint64_t
|
||||||
check_pa_pac_request(krb5_context context,
|
get_pac_attributes(krb5_context context, KDC_REQ *req)
|
||||||
KDC_REQ *req,
|
|
||||||
krb5_boolean *include_pac)
|
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
PA_PAC_REQUEST pacreq;
|
PA_PAC_REQUEST pacreq;
|
||||||
const PA_DATA *pa;
|
const PA_DATA *pa;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
uint32_t pac_attributes;
|
||||||
*include_pac = TRUE;
|
|
||||||
|
|
||||||
pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);
|
pa = _kdc_find_padata(req, &i, KRB5_PADATA_PA_PAC_REQUEST);
|
||||||
if (pa == NULL)
|
if (pa == NULL)
|
||||||
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
|
return KRB5_PAC_WAS_GIVEN_IMPLICITLY;
|
||||||
|
|
||||||
ret = decode_PA_PAC_REQUEST(pa->padata_value.data,
|
ret = decode_PA_PAC_REQUEST(pa->padata_value.data,
|
||||||
pa->padata_value.length,
|
pa->padata_value.length,
|
||||||
&pacreq,
|
&pacreq,
|
||||||
NULL);
|
NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
|
return KRB5_PAC_WAS_GIVEN_IMPLICITLY;
|
||||||
*include_pac = pacreq.include_pac;
|
|
||||||
|
pac_attributes = pacreq.include_pac ? KRB5_PAC_WAS_REQUESTED : 0;
|
||||||
free_PA_PAC_REQUEST(&pacreq);
|
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;
|
krb5_data data;
|
||||||
uint16_t rodc_id;
|
uint16_t rodc_id;
|
||||||
krb5_principal client;
|
krb5_principal client;
|
||||||
krb5_boolean client_sent_pac_req, pac_request;
|
|
||||||
krb5_const_principal canon_princ = NULL;
|
krb5_const_principal canon_princ = NULL;
|
||||||
|
|
||||||
client_sent_pac_req =
|
r->pac_attributes = get_pac_attributes(r->context, &r->req);
|
||||||
(check_pa_pac_request(r->context, &r->req, &pac_request) == 0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When a PA mech replaces the reply key, the PAC may include the
|
* 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->client,
|
||||||
r->server,
|
r->server,
|
||||||
r->replaced_reply_key ? &r->reply_key : NULL,
|
r->replaced_reply_key ? &r->reply_key : NULL,
|
||||||
client_sent_pac_req ? &pac_request : NULL,
|
r->pac_attributes,
|
||||||
&p);
|
&p);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
_kdc_r_log(r, 4, "PAC generation failed for -- %s",
|
_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,
|
rodc_id,
|
||||||
NULL, /* UPN */
|
NULL, /* UPN */
|
||||||
canon_princ,
|
canon_princ,
|
||||||
|
&r->pac_attributes,
|
||||||
&data);
|
&data);
|
||||||
krb5_free_principal(r->context, client);
|
krb5_free_principal(r->context, client);
|
||||||
krb5_pac_free(r->context, p);
|
krb5_pac_free(r->context, p);
|
||||||
|
@@ -89,7 +89,8 @@ _kdc_check_pac(krb5_context context,
|
|||||||
EncTicketPart *tkt,
|
EncTicketPart *tkt,
|
||||||
krb5_boolean *kdc_issued,
|
krb5_boolean *kdc_issued,
|
||||||
krb5_pac *ppac,
|
krb5_pac *ppac,
|
||||||
krb5_principal *pac_canon_name)
|
krb5_principal *pac_canon_name,
|
||||||
|
uint64_t *pac_attributes)
|
||||||
{
|
{
|
||||||
krb5_pac pac = NULL;
|
krb5_pac pac = NULL;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -129,6 +130,8 @@ _kdc_check_pac(krb5_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pac_attributes)
|
||||||
|
_krb5_pac_get_attributes_info(context, pac, pac_attributes);
|
||||||
} else if (ret == KRB5_PLUGIN_NO_HANDLE) {
|
} else if (ret == KRB5_PLUGIN_NO_HANDLE) {
|
||||||
/*
|
/*
|
||||||
* We can't verify the KDC signatures if the ticket was issued by
|
* 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);
|
krb5_pac_free(context, pac);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (pac_attributes)
|
||||||
|
_krb5_pac_get_attributes_info(context, pac, pac_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Discard the PAC if the plugin didn't handle it */
|
/* 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. */
|
/* The PAC should be the last change to the ticket. */
|
||||||
ret = _krb5_kdc_pac_sign_ticket(r->context, mspac, tgt_name, serverkey,
|
ret = _krb5_kdc_pac_sign_ticket(r->context, mspac, tgt_name, serverkey,
|
||||||
krbtgtkey, rodc_id, add_ticket_sig, &et,
|
krbtgtkey, rodc_id, NULL, r->client_princ,
|
||||||
NULL, r->client_princ);
|
add_ticket_sig, &et, &r->pac_attributes);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1842,7 +1847,7 @@ server_lookup:
|
|||||||
ret = _kdc_check_pac(context, config, user2user_princ, NULL,
|
ret = _kdc_check_pac(context, config, user2user_princ, NULL,
|
||||||
user2user_client, user2user_krbtgt, user2user_krbtgt, user2user_krbtgt,
|
user2user_client, user2user_krbtgt, user2user_krbtgt, user2user_krbtgt,
|
||||||
&uukey->key, &priv->ticket_key->key, &adtkt,
|
&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);
|
_kdc_free_ent(context, user2user_client);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
const char *msg = krb5_get_error_message(context, 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,
|
ret = _kdc_check_pac(context, config, cp, NULL, client, server, krbtgt, krbtgt,
|
||||||
&priv->ticket_key->key, &priv->ticket_key->key, tgt,
|
&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) {
|
if (ret) {
|
||||||
const char *msg = krb5_get_error_message(context, ret);
|
const char *msg = krb5_get_error_message(context, ret);
|
||||||
_kdc_audit_addreason((kdc_request_t)priv, "PAC check failed");
|
_kdc_audit_addreason((kdc_request_t)priv, "PAC check failed");
|
||||||
@@ -2131,7 +2136,7 @@ server_lookup:
|
|||||||
s4u2self_impersonated_client,
|
s4u2self_impersonated_client,
|
||||||
server,
|
server,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
KRB5_PAC_WAS_GIVEN_IMPLICITLY,
|
||||||
&mspac);
|
&mspac);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kdc_log(context, config, 4, "PAC generation failed for -- %s", tpn);
|
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,
|
ret = _kdc_check_pac(context, config, tp, dp, adclient, server, krbtgt, client,
|
||||||
&clientkey->key, &priv->ticket_key->key, &adtkt,
|
&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)
|
if (adclient)
|
||||||
_kdc_free_ent(context, adclient);
|
_kdc_free_ent(context, adclient);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@@ -73,8 +73,8 @@ struct generate_uc {
|
|||||||
hdb_entry_ex *client;
|
hdb_entry_ex *client;
|
||||||
hdb_entry_ex *server;
|
hdb_entry_ex *server;
|
||||||
const krb5_keyblock *reply_key;
|
const krb5_keyblock *reply_key;
|
||||||
|
uint64_t pac_attributes;
|
||||||
krb5_pac *pac;
|
krb5_pac *pac;
|
||||||
const krb5_boolean *pac_request;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static krb5_error_code KRB5_LIB_CALL
|
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->client,
|
||||||
uc->server,
|
uc->server,
|
||||||
uc->reply_key,
|
uc->reply_key,
|
||||||
uc->pac_request,
|
uc->pac_attributes,
|
||||||
uc->pac);
|
uc->pac);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ _kdc_pac_generate(krb5_context context,
|
|||||||
hdb_entry_ex *client,
|
hdb_entry_ex *client,
|
||||||
hdb_entry_ex *server,
|
hdb_entry_ex *server,
|
||||||
const krb5_keyblock *reply_key,
|
const krb5_keyblock *reply_key,
|
||||||
const krb5_boolean *pac_request,
|
uint64_t pac_attributes,
|
||||||
krb5_pac *pac)
|
krb5_pac *pac)
|
||||||
{
|
{
|
||||||
krb5_error_code ret = 0;
|
krb5_error_code ret = 0;
|
||||||
@@ -118,7 +118,7 @@ _kdc_pac_generate(krb5_context context,
|
|||||||
uc.server = server;
|
uc.server = server;
|
||||||
uc.reply_key = reply_key;
|
uc.reply_key = reply_key;
|
||||||
uc.pac = pac;
|
uc.pac = pac;
|
||||||
uc.pac_request = pac_request;
|
uc.pac_attributes = pac_attributes;
|
||||||
|
|
||||||
ret = _krb5_plugin_run_f(context, &windc_plugin_data,
|
ret = _krb5_plugin_run_f(context, &windc_plugin_data,
|
||||||
0, &uc, generate);
|
0, &uc, generate);
|
||||||
|
@@ -57,7 +57,7 @@ typedef krb5_error_code
|
|||||||
struct hdb_entry_ex *, /* client */
|
struct hdb_entry_ex *, /* client */
|
||||||
struct hdb_entry_ex *, /* server */
|
struct hdb_entry_ex *, /* server */
|
||||||
const krb5_keyblock *, /* pk_replykey */
|
const krb5_keyblock *, /* pk_replykey */
|
||||||
const krb5_boolean *, /* pac_request */
|
uint64_t, /* pac_attributes */
|
||||||
krb5_pac *);
|
krb5_pac *);
|
||||||
|
|
||||||
typedef krb5_error_code
|
typedef krb5_error_code
|
||||||
|
@@ -480,4 +480,8 @@ struct krb5_decrypt_tkt_with_subkey_state {
|
|||||||
/* Flag in KRB5_AUTHDATA_AP_OPTIONS */
|
/* Flag in KRB5_AUTHDATA_AP_OPTIONS */
|
||||||
#define KERB_AP_OPTIONS_CBT 0x00004000
|
#define KERB_AP_OPTIONS_CBT 0x00004000
|
||||||
|
|
||||||
|
/* Flag in PAC_ATTRIBUTES_INFO */
|
||||||
|
#define KRB5_PAC_WAS_REQUESTED 0x1
|
||||||
|
#define KRB5_PAC_WAS_GIVEN_IMPLICITLY 0x2
|
||||||
|
|
||||||
#endif /* __KRB5_LOCL_H__ */
|
#endif /* __KRB5_LOCL_H__ */
|
||||||
|
@@ -822,6 +822,7 @@ EXPORTS
|
|||||||
_krb5_get_int
|
_krb5_get_int
|
||||||
_krb5_get_int64
|
_krb5_get_int64
|
||||||
_krb5_pac_sign
|
_krb5_pac_sign
|
||||||
|
_krb5_pac_get_attributes_info
|
||||||
_krb5_pac_get_canon_principal
|
_krb5_pac_get_canon_principal
|
||||||
_krb5_kdc_pac_sign_ticket
|
_krb5_kdc_pac_sign_ticket
|
||||||
_krb5_kdc_pac_ticket_parse
|
_krb5_kdc_pac_ticket_parse
|
||||||
@@ -843,7 +844,6 @@ EXPORTS
|
|||||||
_krb5_expand_path_tokens ;!
|
_krb5_expand_path_tokens ;!
|
||||||
_krb5_make_pa_enc_challenge
|
_krb5_make_pa_enc_challenge
|
||||||
_krb5_validate_pa_enc_challenge
|
_krb5_validate_pa_enc_challenge
|
||||||
_krb5_store_utf8_as_ucs2le_at_offset
|
|
||||||
|
|
||||||
; kinit helper
|
; kinit helper
|
||||||
krb5_get_init_creds_opt_set_pkinit_user_certs
|
krb5_get_init_creds_opt_set_pkinit_user_certs
|
||||||
|
219
lib/krb5/pac.c
219
lib/krb5/pac.c
@@ -55,13 +55,17 @@ struct krb5_pac_data {
|
|||||||
struct PAC_INFO_BUFFER *logon_name;
|
struct PAC_INFO_BUFFER *logon_name;
|
||||||
struct PAC_INFO_BUFFER *upn_dns_info;
|
struct PAC_INFO_BUFFER *upn_dns_info;
|
||||||
struct PAC_INFO_BUFFER *ticket_checksum;
|
struct PAC_INFO_BUFFER *ticket_checksum;
|
||||||
|
struct PAC_INFO_BUFFER *attributes_info;
|
||||||
krb5_data ticket_sign_data;
|
krb5_data ticket_sign_data;
|
||||||
|
|
||||||
/* parsed upn_dns_info, krb5_pac_verify only */
|
/* PAC_UPN_DNS_INFO */
|
||||||
krb5_principal upn_princ;
|
krb5_principal upn_princ;
|
||||||
uint32_t upn_flags;
|
uint32_t upn_flags;
|
||||||
krb5_principal canon_princ;
|
krb5_principal canon_princ;
|
||||||
krb5_data sid;
|
krb5_data sid;
|
||||||
|
|
||||||
|
/* PAC_ATTRIBUTES_INFO */
|
||||||
|
uint64_t pac_attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PAC_ALIGNMENT 8
|
#define PAC_ALIGNMENT 8
|
||||||
@@ -75,8 +79,10 @@ struct krb5_pac_data {
|
|||||||
#define PAC_CONSTRAINED_DELEGATION 11
|
#define PAC_CONSTRAINED_DELEGATION 11
|
||||||
#define PAC_UPN_DNS_INFO 12
|
#define PAC_UPN_DNS_INFO 12
|
||||||
#define PAC_TICKET_CHECKSUM 16
|
#define PAC_TICKET_CHECKSUM 16
|
||||||
|
#define PAC_ATTRIBUTES_INFO 17
|
||||||
|
#define PAC_REQUESTOR_SID 18
|
||||||
|
|
||||||
/* Flag in PAC_UPN_DNS_INFO, _krb5_pac_get_upn_dns_info() */
|
/* Flag in PAC_UPN_DNS_INFO */
|
||||||
#define PAC_EXTRA_LOGON_INFO_FLAGS_UPN_DEFAULTED 0x1
|
#define PAC_EXTRA_LOGON_INFO_FLAGS_UPN_DEFAULTED 0x1
|
||||||
#define PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID 0x2
|
#define PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID 0x2
|
||||||
|
|
||||||
@@ -270,6 +276,14 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
p->ticket_checksum = &p->pac->buffers[i];
|
p->ticket_checksum = &p->pac->buffers[i];
|
||||||
|
} else if (p->pac->buffers[i].type == PAC_ATTRIBUTES_INFO) {
|
||||||
|
if (p->attributes_info) {
|
||||||
|
ret = EINVAL;
|
||||||
|
krb5_set_error_message(context, ret,
|
||||||
|
N_("PAC has multiple attributes info buffers", ""));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
p->attributes_info = &p->pac->buffers[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,14 +649,14 @@ parse_upn_dns_info(krb5_context context,
|
|||||||
const krb5_data *data,
|
const krb5_data *data,
|
||||||
krb5_principal *upn_princ,
|
krb5_principal *upn_princ,
|
||||||
uint32_t *flags,
|
uint32_t *flags,
|
||||||
krb5_principal *sam_name_princ,
|
krb5_principal *canon_princ,
|
||||||
krb5_data *sid)
|
krb5_data *sid)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_storage *sp = NULL;
|
krb5_storage *sp = NULL;
|
||||||
uint16_t upn_length, upn_offset;
|
uint16_t upn_length, upn_offset;
|
||||||
uint16_t dns_domain_name_length, dns_domain_name_offset;
|
uint16_t dns_domain_name_length, dns_domain_name_offset;
|
||||||
uint16_t sam_name_length, sam_name_offset;
|
uint16_t canon_princ_length, canon_princ_offset;
|
||||||
uint16_t sid_length, sid_offset;
|
uint16_t sid_length, sid_offset;
|
||||||
char *upn = NULL;
|
char *upn = NULL;
|
||||||
char *dns_domain_name = NULL;
|
char *dns_domain_name = NULL;
|
||||||
@@ -650,7 +664,7 @@ parse_upn_dns_info(krb5_context context,
|
|||||||
|
|
||||||
*upn_princ = NULL;
|
*upn_princ = NULL;
|
||||||
*flags = 0;
|
*flags = 0;
|
||||||
*sam_name_princ = NULL;
|
*canon_princ = NULL;
|
||||||
krb5_data_zero(sid);
|
krb5_data_zero(sid);
|
||||||
|
|
||||||
sp = krb5_storage_from_readonly_mem((const char *)data->data + upndnsinfo->offset_lo,
|
sp = krb5_storage_from_readonly_mem((const char *)data->data + upndnsinfo->offset_lo,
|
||||||
@@ -667,13 +681,13 @@ parse_upn_dns_info(krb5_context context,
|
|||||||
CHECK(ret, krb5_ret_uint32(sp, flags), out);
|
CHECK(ret, krb5_ret_uint32(sp, flags), out);
|
||||||
|
|
||||||
if (*flags & PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID) {
|
if (*flags & PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID) {
|
||||||
CHECK(ret, krb5_ret_uint16(sp, &sam_name_length), out);
|
CHECK(ret, krb5_ret_uint16(sp, &canon_princ_length), out);
|
||||||
CHECK(ret, krb5_ret_uint16(sp, &sam_name_offset), out);
|
CHECK(ret, krb5_ret_uint16(sp, &canon_princ_offset), out);
|
||||||
CHECK(ret, krb5_ret_uint16(sp, &sid_length), out);
|
CHECK(ret, krb5_ret_uint16(sp, &sid_length), out);
|
||||||
CHECK(ret, krb5_ret_uint16(sp, &sid_offset), out);
|
CHECK(ret, krb5_ret_uint16(sp, &sid_offset), out);
|
||||||
} else {
|
} else {
|
||||||
sam_name_offset = 0;
|
canon_princ_length = canon_princ_offset = 0;
|
||||||
sid_offset = 0;
|
sid_length = sid_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upn_offset) {
|
if (upn_offset) {
|
||||||
@@ -682,9 +696,9 @@ parse_upn_dns_info(krb5_context context,
|
|||||||
}
|
}
|
||||||
CHECK(ret, _krb5_ret_utf8_from_ucs2le_at_offset(sp, dns_domain_name_offset,
|
CHECK(ret, _krb5_ret_utf8_from_ucs2le_at_offset(sp, dns_domain_name_offset,
|
||||||
dns_domain_name_length, &dns_domain_name), out);
|
dns_domain_name_length, &dns_domain_name), out);
|
||||||
if ((*flags & PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID) && sam_name_offset) {
|
if ((*flags & PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID) && canon_princ_offset) {
|
||||||
CHECK(ret, _krb5_ret_utf8_from_ucs2le_at_offset(sp, sam_name_offset,
|
CHECK(ret, _krb5_ret_utf8_from_ucs2le_at_offset(sp, canon_princ_offset,
|
||||||
sam_name_length, &sam_name), out);
|
canon_princ_length, &sam_name), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upn_offset) {
|
if (upn_offset) {
|
||||||
@@ -701,16 +715,16 @@ parse_upn_dns_info(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sam_name_offset) {
|
if (canon_princ_offset) {
|
||||||
ret = krb5_parse_name_flags(context,
|
ret = krb5_parse_name_flags(context,
|
||||||
sam_name,
|
sam_name,
|
||||||
KRB5_PRINCIPAL_PARSE_NO_REALM |
|
KRB5_PRINCIPAL_PARSE_NO_REALM |
|
||||||
KRB5_PRINCIPAL_PARSE_NO_DEF_REALM,
|
KRB5_PRINCIPAL_PARSE_NO_DEF_REALM,
|
||||||
sam_name_princ);
|
canon_princ);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = krb5_principal_set_realm(context, *sam_name_princ, dns_domain_name);
|
ret = krb5_principal_set_realm(context, *canon_princ, dns_domain_name);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -734,6 +748,7 @@ static krb5_error_code
|
|||||||
build_upn_dns_info(krb5_context context,
|
build_upn_dns_info(krb5_context context,
|
||||||
krb5_const_principal upn_princ,
|
krb5_const_principal upn_princ,
|
||||||
krb5_const_principal canon_princ,
|
krb5_const_principal canon_princ,
|
||||||
|
const krb5_data *sid,
|
||||||
krb5_data *upn_dns_info)
|
krb5_data *upn_dns_info)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -779,8 +794,10 @@ build_upn_dns_info(krb5_context context,
|
|||||||
realm = canon_princ->realm;
|
realm = canon_princ->realm;
|
||||||
else if (upn_princ)
|
else if (upn_princ)
|
||||||
realm = upn_princ->realm;
|
realm = upn_princ->realm;
|
||||||
else
|
else {
|
||||||
realm = NULL;
|
ret = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ret = _krb5_store_utf8_as_ucs2le_at_offset(sp, (off_t)-1, realm);
|
ret = _krb5_store_utf8_as_ucs2le_at_offset(sp, (off_t)-1, realm);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -789,17 +806,23 @@ build_upn_dns_info(krb5_context context,
|
|||||||
flags = 0;
|
flags = 0;
|
||||||
if (upn_princ)
|
if (upn_princ)
|
||||||
flags |= PAC_EXTRA_LOGON_INFO_FLAGS_UPN_DEFAULTED;
|
flags |= PAC_EXTRA_LOGON_INFO_FLAGS_UPN_DEFAULTED;
|
||||||
if (canon_princ)
|
if (canon_princ || sid)
|
||||||
flags |= PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID;
|
flags |= PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID;
|
||||||
|
|
||||||
ret = krb5_store_uint32(sp, flags);
|
ret = krb5_store_uint32(sp, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = _krb5_store_utf8_as_ucs2le_at_offset(sp, (off_t)-1,
|
if (flags & PAC_EXTRA_LOGON_INFO_FLAGS_HAS_SAM_NAME_AND_SID) {
|
||||||
canon_princ_name);
|
ret = _krb5_store_utf8_as_ucs2le_at_offset(sp, (off_t)-1,
|
||||||
if (ret)
|
canon_princ_name);
|
||||||
goto out;
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = _krb5_store_data_at_offset(sp, (off_t)-1, sid);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ret = krb5_storage_to_data(sp, upn_dns_info);
|
ret = krb5_storage_to_data(sp, upn_dns_info);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -1054,6 +1077,80 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
parse_attributes_info(krb5_context context,
|
||||||
|
const struct PAC_INFO_BUFFER *attributes_info,
|
||||||
|
const krb5_data *data,
|
||||||
|
uint64_t *pac_attributes)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_storage *sp = NULL;
|
||||||
|
uint32_t flags_length;
|
||||||
|
|
||||||
|
*pac_attributes = 0;
|
||||||
|
|
||||||
|
sp = krb5_storage_from_readonly_mem((const char *)data->data + attributes_info->offset_lo,
|
||||||
|
attributes_info->buffersize);
|
||||||
|
if (sp == NULL)
|
||||||
|
return krb5_enomem(context);
|
||||||
|
|
||||||
|
krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
|
||||||
|
|
||||||
|
ret = krb5_ret_uint32(sp, &flags_length);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (flags_length > 32)
|
||||||
|
ret = krb5_ret_uint64(sp, pac_attributes);
|
||||||
|
else {
|
||||||
|
uint32_t pac_attributes32 = 0;
|
||||||
|
ret = krb5_ret_uint32(sp, &pac_attributes32);
|
||||||
|
*pac_attributes = pac_attributes32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
build_attributes_info(krb5_context context,
|
||||||
|
uint64_t pac_attributes,
|
||||||
|
krb5_data *attributes_info)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_storage *sp = NULL;
|
||||||
|
uint32_t flags_length;
|
||||||
|
|
||||||
|
krb5_data_zero(attributes_info);
|
||||||
|
|
||||||
|
sp = krb5_storage_emem();
|
||||||
|
if (sp == NULL)
|
||||||
|
return krb5_enomem(context);
|
||||||
|
|
||||||
|
krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
|
||||||
|
|
||||||
|
if (pac_attributes == 0)
|
||||||
|
flags_length = 0;
|
||||||
|
else
|
||||||
|
flags_length = 64 - rk_clzll(pac_attributes);
|
||||||
|
if (flags_length < KRB5_PAC_WAS_GIVEN_IMPLICITLY)
|
||||||
|
flags_length = KRB5_PAC_WAS_GIVEN_IMPLICITLY;
|
||||||
|
|
||||||
|
ret = krb5_store_uint32(sp, flags_length);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (flags_length > 32)
|
||||||
|
ret = krb5_store_uint64(sp, pac_attributes);
|
||||||
|
else
|
||||||
|
ret = krb5_store_uint32(sp, (uint32_t)pac_attributes);
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
ret = krb5_storage_to_data(sp, attributes_info);
|
||||||
|
|
||||||
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the PAC.
|
* Verify the PAC.
|
||||||
*
|
*
|
||||||
@@ -1169,12 +1266,19 @@ krb5_pac_verify(krb5_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (pac->canon_princ &&
|
if (principal && pac->canon_princ &&
|
||||||
!krb5_realm_compare(context, principal, pac->canon_princ)) {
|
!krb5_realm_compare(context, principal, pac->canon_princ)) {
|
||||||
return KRB5KRB_AP_ERR_MODIFIED;
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pac->attributes_info) {
|
||||||
|
ret = parse_attributes_info(context, pac->attributes_info, &pac->data,
|
||||||
|
&pac->pac_attributes);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1244,6 +1348,7 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
uint16_t rodc_id,
|
uint16_t rodc_id,
|
||||||
krb5_const_principal upn_princ,
|
krb5_const_principal upn_princ,
|
||||||
krb5_const_principal canon_princ,
|
krb5_const_principal canon_princ,
|
||||||
|
uint64_t *pac_attributes, /* optional */
|
||||||
krb5_data *data)
|
krb5_data *data)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -1256,10 +1361,12 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
size_t i, sz;
|
size_t i, sz;
|
||||||
krb5_data logon, d;
|
krb5_data logon, d;
|
||||||
krb5_data upn_dns_info;
|
krb5_data upn_dns_info;
|
||||||
|
krb5_data attributes_info;
|
||||||
|
|
||||||
krb5_data_zero(&d);
|
krb5_data_zero(&d);
|
||||||
krb5_data_zero(&logon);
|
krb5_data_zero(&logon);
|
||||||
krb5_data_zero(&upn_dns_info);
|
krb5_data_zero(&upn_dns_info);
|
||||||
|
krb5_data_zero(&attributes_info);
|
||||||
|
|
||||||
for (i = 0; i < p->pac->numbuffers; i++) {
|
for (i = 0; i < p->pac->numbuffers; i++) {
|
||||||
if (p->pac->buffers[i].type == PAC_SERVER_CHECKSUM) {
|
if (p->pac->buffers[i].type == PAC_SERVER_CHECKSUM) {
|
||||||
@@ -1312,6 +1419,16 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
N_("PAC has multiple ticket checksums", ""));
|
N_("PAC has multiple ticket checksums", ""));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
} else if (p->pac->buffers[i].type == PAC_ATTRIBUTES_INFO) {
|
||||||
|
if (p->attributes_info == NULL) {
|
||||||
|
p->attributes_info = &p->pac->buffers[i];
|
||||||
|
}
|
||||||
|
if (p->attributes_info != &p->pac->buffers[i]) {
|
||||||
|
ret = KRB5KDC_ERR_BADOPTION;
|
||||||
|
krb5_set_error_message(context, ret,
|
||||||
|
N_("PAC has multiple attributes info buffers", ""));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1325,6 +1442,8 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
num++;
|
num++;
|
||||||
if (p->ticket_sign_data.length != 0 && p->ticket_checksum == NULL)
|
if (p->ticket_sign_data.length != 0 && p->ticket_checksum == NULL)
|
||||||
num++;
|
num++;
|
||||||
|
if (pac_attributes && p->attributes_info == NULL)
|
||||||
|
num++;
|
||||||
|
|
||||||
if (num) {
|
if (num) {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
@@ -1362,6 +1481,11 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
memset(p->ticket_checksum, 0, sizeof(*p->ticket_checksum));
|
memset(p->ticket_checksum, 0, sizeof(*p->ticket_checksum));
|
||||||
p->ticket_checksum->type = PAC_TICKET_CHECKSUM;
|
p->ticket_checksum->type = PAC_TICKET_CHECKSUM;
|
||||||
}
|
}
|
||||||
|
if (pac_attributes && p->attributes_info == NULL) {
|
||||||
|
p->attributes_info = &p->pac->buffers[p->pac->numbuffers++];
|
||||||
|
memset(p->attributes_info, 0, sizeof(*p->attributes_info));
|
||||||
|
p->attributes_info->type = PAC_ATTRIBUTES_INFO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate LOGON NAME */
|
/* Calculate LOGON NAME */
|
||||||
@@ -1374,8 +1498,11 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size);
|
ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size);
|
||||||
|
|
||||||
if (upn_princ || canon_princ)
|
if (ret == 0 && (upn_princ || canon_princ))
|
||||||
ret = build_upn_dns_info(context, upn_princ, canon_princ, &upn_dns_info);
|
ret = build_upn_dns_info(context, upn_princ, canon_princ, NULL, &upn_dns_info);
|
||||||
|
|
||||||
|
if (ret == 0 && pac_attributes)
|
||||||
|
ret = build_attributes_info(context, *pac_attributes, &attributes_info);
|
||||||
|
|
||||||
/* Encode PAC */
|
/* Encode PAC */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -1440,13 +1567,20 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
ret = KRB5KDC_ERR_BADOPTION;
|
ret = KRB5KDC_ERR_BADOPTION;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else if ((upn_princ || canon_princ) &&
|
} else if (upn_dns_info.length != 0 &&
|
||||||
p->pac->buffers[i].type == PAC_UPN_DNS_INFO) {
|
p->pac->buffers[i].type == PAC_UPN_DNS_INFO) {
|
||||||
len = krb5_storage_write(spdata, upn_dns_info.data, upn_dns_info.length);
|
len = krb5_storage_write(spdata, upn_dns_info.data, upn_dns_info.length);
|
||||||
if (upn_dns_info.length != len) {
|
if (upn_dns_info.length != len) {
|
||||||
ret = KRB5KDC_ERR_BADOPTION;
|
ret = KRB5KDC_ERR_BADOPTION;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
} else if (attributes_info.length != 0 &&
|
||||||
|
p->pac->buffers[i].type == PAC_ATTRIBUTES_INFO) {
|
||||||
|
len = krb5_storage_write(spdata, attributes_info.data, attributes_info.length);
|
||||||
|
if (attributes_info.length != len) {
|
||||||
|
ret = KRB5KDC_ERR_BADOPTION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
len = p->pac->buffers[i].buffersize;
|
len = p->pac->buffers[i].buffersize;
|
||||||
ptr = (char *)p->data.data + p->pac->buffers[i].offset_lo;
|
ptr = (char *)p->data.data + p->pac->buffers[i].offset_lo;
|
||||||
@@ -1537,6 +1671,7 @@ _krb5_pac_sign(krb5_context context,
|
|||||||
|
|
||||||
krb5_data_free(&logon);
|
krb5_data_free(&logon);
|
||||||
krb5_data_free(&upn_dns_info);
|
krb5_data_free(&upn_dns_info);
|
||||||
|
krb5_data_free(&attributes_info);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
krb5_storage_free(spdata);
|
krb5_storage_free(spdata);
|
||||||
|
|
||||||
@@ -1545,6 +1680,7 @@ out:
|
|||||||
krb5_data_free(&d);
|
krb5_data_free(&d);
|
||||||
krb5_data_free(&logon);
|
krb5_data_free(&logon);
|
||||||
krb5_data_free(&upn_dns_info);
|
krb5_data_free(&upn_dns_info);
|
||||||
|
krb5_data_free(&attributes_info);
|
||||||
if (sp)
|
if (sp)
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
if (spdata)
|
if (spdata)
|
||||||
@@ -1614,12 +1750,33 @@ _krb5_pac_get_canon_principal(krb5_context context,
|
|||||||
{
|
{
|
||||||
*canon_princ = NULL;
|
*canon_princ = NULL;
|
||||||
|
|
||||||
if (pac->canon_princ == NULL)
|
if (pac->canon_princ == NULL) {
|
||||||
|
krb5_set_error_message(context, ENOENT,
|
||||||
|
"PAC missing UPN DNS info buffer");
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
return krb5_copy_principal(context, pac->canon_princ, canon_princ);
|
return krb5_copy_principal(context, pac->canon_princ, canon_princ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||||
|
_krb5_pac_get_attributes_info(krb5_context context,
|
||||||
|
krb5_pac pac,
|
||||||
|
uint64_t *pac_attributes)
|
||||||
|
{
|
||||||
|
*pac_attributes = 0;
|
||||||
|
|
||||||
|
if (pac->attributes_info == NULL) {
|
||||||
|
krb5_set_error_message(context, ENOENT,
|
||||||
|
"PAC missing attributes info buffer");
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pac_attributes = pac->pac_attributes;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned char single_zero = '\0';
|
static unsigned char single_zero = '\0';
|
||||||
static krb5_data single_zero_pac = { 1, &single_zero };
|
static krb5_data single_zero_pac = { 1, &single_zero };
|
||||||
|
|
||||||
@@ -1747,10 +1904,11 @@ _krb5_kdc_pac_sign_ticket(krb5_context context,
|
|||||||
const krb5_keyblock *server_key,
|
const krb5_keyblock *server_key,
|
||||||
const krb5_keyblock *kdc_key,
|
const krb5_keyblock *kdc_key,
|
||||||
uint16_t rodc_id,
|
uint16_t rodc_id,
|
||||||
|
krb5_const_principal upn,
|
||||||
|
krb5_const_principal canon_name,
|
||||||
krb5_boolean add_ticket_sig,
|
krb5_boolean add_ticket_sig,
|
||||||
EncTicketPart *tkt,
|
EncTicketPart *tkt,
|
||||||
krb5_const_principal upn,
|
uint64_t *pac_attributes) /* optional */
|
||||||
krb5_const_principal canon_name)
|
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_data tkt_data;
|
krb5_data tkt_data;
|
||||||
@@ -1785,7 +1943,8 @@ _krb5_kdc_pac_sign_ticket(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = _krb5_pac_sign(context, pac, tkt->authtime, client, server_key,
|
ret = _krb5_pac_sign(context, pac, tkt->authtime, client, server_key,
|
||||||
kdc_key, rodc_id, upn, canon_name, &rspac);
|
kdc_key, rodc_id, upn, canon_name,
|
||||||
|
pac_attributes, &rspac);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = _kdc_tkt_insert_pac(context, tkt, &rspac);
|
ret = _kdc_tkt_insert_pac(context, tkt, &rspac);
|
||||||
krb5_data_free(&rspac);
|
krb5_data_free(&rspac);
|
||||||
|
@@ -897,7 +897,8 @@ check_ticket_signature(krb5_context context,
|
|||||||
t_err(context, tkt->name, "remove_AuthorizationData", ret);
|
t_err(context, tkt->name, "remove_AuthorizationData", ret);
|
||||||
|
|
||||||
ret = _krb5_kdc_pac_sign_ticket(context, pac, client, tkt->key,
|
ret = _krb5_kdc_pac_sign_ticket(context, pac, client, tkt->key,
|
||||||
tkt->kdc_key, tkt->rodc_id, signedticket, &et);
|
tkt->kdc_key, tkt->rodc_id,
|
||||||
|
NULL, NULL, signedticket, &et, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
t_err(context, tkt->name, "_krb5_kdc_pac_sign_ticket", ret);
|
t_err(context, tkt->name, "_krb5_kdc_pac_sign_ticket", ret);
|
||||||
|
|
||||||
@@ -915,7 +916,8 @@ check_ticket_signature(krb5_context context,
|
|||||||
t_err(context, tkt->name, "remove_AuthorizationData 2", ret);
|
t_err(context, tkt->name, "remove_AuthorizationData 2", ret);
|
||||||
|
|
||||||
ret = _krb5_kdc_pac_sign_ticket(context, pac, client, tkt->key,
|
ret = _krb5_kdc_pac_sign_ticket(context, pac, client, tkt->key,
|
||||||
tkt->kdc_key, tkt->rodc_id, signedticket, &et);
|
tkt->kdc_key, tkt->rodc_id,
|
||||||
|
NULL, NULL, signedticket, &et, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
t_err(context, tkt->name, "_krb5_kdcsignedticketsign_ticket 2", ret);
|
t_err(context, tkt->name, "_krb5_kdcsignedticketsign_ticket 2", ret);
|
||||||
|
|
||||||
@@ -978,7 +980,8 @@ main(int argc, char **argv)
|
|||||||
krb5_err(context, 1, ret, "krb5_pac_verify");
|
krb5_err(context, 1, ret, "krb5_pac_verify");
|
||||||
|
|
||||||
ret = _krb5_pac_sign(context, pac, authtime, p,
|
ret = _krb5_pac_sign(context, pac, authtime, p,
|
||||||
&member_keyblock, &kdc_keyblock, 0, &data);
|
&member_keyblock, &kdc_keyblock, 0, NULL, NULL,
|
||||||
|
NULL, &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "_krb5_pac_sign");
|
krb5_err(context, 1, ret, "_krb5_pac_sign");
|
||||||
|
|
||||||
@@ -1034,7 +1037,8 @@ main(int argc, char **argv)
|
|||||||
free(list);
|
free(list);
|
||||||
|
|
||||||
ret = _krb5_pac_sign(context, pac2, authtime, p,
|
ret = _krb5_pac_sign(context, pac2, authtime, p,
|
||||||
&member_keyblock, &kdc_keyblock, 0, &data);
|
&member_keyblock, &kdc_keyblock, 0,
|
||||||
|
NULL, NULL, NULL, &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "_krb5_pac_sign 4");
|
krb5_err(context, 1, ret, "_krb5_pac_sign 4");
|
||||||
|
|
||||||
@@ -1076,34 +1080,6 @@ main(int argc, char **argv)
|
|||||||
krb5_pac_free(context, pac);
|
krb5_pac_free(context, pac);
|
||||||
krb5_free_principal(context, p2);
|
krb5_free_principal(context, p2);
|
||||||
|
|
||||||
/*
|
|
||||||
* check extra logon info PAC
|
|
||||||
*/
|
|
||||||
ret = krb5_pac_parse(context, extra_logon_info,
|
|
||||||
sizeof(extra_logon_info) - 1, &pac);
|
|
||||||
if (ret)
|
|
||||||
krb5_err(context, 1, ret, "krb5_pac_parse");
|
|
||||||
|
|
||||||
{
|
|
||||||
krb5_principal upn = NULL;
|
|
||||||
uint32_t flags = 0;
|
|
||||||
krb5_principal sam_name = NULL;
|
|
||||||
krb5_data sid;
|
|
||||||
|
|
||||||
krb5_data_zero(&sid);
|
|
||||||
|
|
||||||
ret = _krb5_pac_get_upn_dns_info(context, pac, &upn,
|
|
||||||
&flags, &sam_name, &sid);
|
|
||||||
if (ret)
|
|
||||||
krb5_err(context, 1, ret, "_krb5_pac_get_upn_dns_info");
|
|
||||||
|
|
||||||
krb5_free_principal(context, upn);
|
|
||||||
krb5_free_principal(context, sam_name);
|
|
||||||
krb5_data_free(&sid);
|
|
||||||
}
|
|
||||||
|
|
||||||
krb5_pac_free(context, pac);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test empty free
|
* Test empty free
|
||||||
*/
|
*/
|
||||||
@@ -1161,7 +1137,8 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = _krb5_pac_sign(context, pac, authtime, p,
|
ret = _krb5_pac_sign(context, pac, authtime, p,
|
||||||
&member_keyblock, &kdc_keyblock, 0, &data);
|
&member_keyblock, &kdc_keyblock, 0,
|
||||||
|
NULL, NULL, NULL, &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_err(context, 1, ret, "_krb5_pac_sign");
|
krb5_err(context, 1, ret, "_krb5_pac_sign");
|
||||||
|
|
||||||
@@ -1193,6 +1170,33 @@ main(int argc, char **argv)
|
|||||||
krb5_pac_free(context, pac);
|
krb5_pac_free(context, pac);
|
||||||
krb5_free_principal(context, p);
|
krb5_free_principal(context, p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check extra logon info PAC
|
||||||
|
*/
|
||||||
|
ret = krb5_pac_parse(context, extra_logon_info,
|
||||||
|
sizeof(extra_logon_info) - 1, &pac);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_pac_parse");
|
||||||
|
|
||||||
|
ret = krb5_pac_verify(context, pac, 0, NULL, NULL, NULL);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "krb5_pac_verify");
|
||||||
|
|
||||||
|
ret = krb5_parse_name(context, "c9d801a8_0@EXAMPLE.COM", &p);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "_krb5_pac_get_canon_principal");
|
||||||
|
|
||||||
|
ret = _krb5_pac_get_canon_principal(context, pac, &p2);
|
||||||
|
if (ret)
|
||||||
|
krb5_err(context, 1, ret, "_krb5_pac_get_canon_principal");
|
||||||
|
|
||||||
|
if (!krb5_principal_compare(context, p, p2))
|
||||||
|
krb5_errx(context, 1, "canon principal doesn't match");
|
||||||
|
|
||||||
|
krb5_pac_free(context, pac);
|
||||||
|
krb5_free_principal(context, p);
|
||||||
|
krb5_free_principal(context, p2);
|
||||||
|
|
||||||
/* Test PAC ticket-signature */
|
/* Test PAC ticket-signature */
|
||||||
{
|
{
|
||||||
const struct test_pac_ticket *tkt;
|
const struct test_pac_ticket *tkt;
|
||||||
|
@@ -814,6 +814,7 @@ HEIMDAL_KRB5_2.0 {
|
|||||||
_krb5_get_int;
|
_krb5_get_int;
|
||||||
_krb5_get_int64;
|
_krb5_get_int64;
|
||||||
_krb5_pac_sign;
|
_krb5_pac_sign;
|
||||||
|
_krb5_pac_get_attributes_info;
|
||||||
_krb5_pac_get_canon_principal;
|
_krb5_pac_get_canon_principal;
|
||||||
_krb5_kdc_pac_sign_ticket;
|
_krb5_kdc_pac_sign_ticket;
|
||||||
_krb5_kdc_pac_ticket_parse;
|
_krb5_kdc_pac_ticket_parse;
|
||||||
@@ -833,7 +834,6 @@ HEIMDAL_KRB5_2.0 {
|
|||||||
_krb5_crypto_set_flags;
|
_krb5_crypto_set_flags;
|
||||||
_krb5_make_pa_enc_challenge;
|
_krb5_make_pa_enc_challenge;
|
||||||
_krb5_validate_pa_enc_challenge;
|
_krb5_validate_pa_enc_challenge;
|
||||||
_krb5_store_utf8_as_ucs2le_at_offset;
|
|
||||||
|
|
||||||
# kinit helper
|
# kinit helper
|
||||||
krb5_get_init_creds_opt_set_pkinit_user_certs;
|
krb5_get_init_creds_opt_set_pkinit_user_certs;
|
||||||
|
@@ -23,13 +23,14 @@ pac_generate(void *ctx, krb5_context context,
|
|||||||
struct hdb_entry_ex *client,
|
struct hdb_entry_ex *client,
|
||||||
struct hdb_entry_ex *server,
|
struct hdb_entry_ex *server,
|
||||||
const krb5_keyblock *pk_replykey,
|
const krb5_keyblock *pk_replykey,
|
||||||
const krb5_boolean *pac_request,
|
uint64_t pac_attributes,
|
||||||
krb5_pac *pac)
|
krb5_pac *pac)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_data data;
|
krb5_data data;
|
||||||
|
|
||||||
if (pac_request != NULL && *pac_request == FALSE) {
|
if ((pac_attributes & (KRB5_PAC_WAS_REQUESTED |
|
||||||
|
KRB5_PAC_WAS_GIVEN_IMPLICITLY)) == 0) {
|
||||||
*pac = NULL;
|
*pac = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user