1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
|
/*
krb5 PAC
Portions obtained from MS-KILE which is Copyright © 2021 Microsoft
Corporation as permitted by the Open Specifications terms
reproduced in IDL_LICENCE.txt
*/
#include "idl_types.h"
import "security.idl", "lsa.idl", "netlogon.idl", "samr.idl";
[
uuid("12345778-1234-abcd-0000-00000000"),
version(0.0),
pointer_default(unique),
helpstring("Active Directory KRB5 PAC"),
helper("../librpc/ndr/ndr_krb5pac.h")
]
interface krb5pac
{
typedef struct {
NTTIME logon_time;
[value(2*strlen_m(account_name))] uint16 size;
[charset(UTF16)] uint8 account_name[size];
} PAC_LOGON_NAME;
typedef [public,flag(NDR_PAHEX)] struct {
uint32 type;
[flag(NDR_REMAINING)] DATA_BLOB signature;
} PAC_SIGNATURE_DATA;
typedef struct {
dom_sid2 *domain_sid;
samr_RidWithAttributeArray groups;
} PAC_DOMAIN_GROUP_MEMBERSHIP;
typedef struct {
netr_SamInfo3 info3;
/*
* On ndr_push:
* Pointers values of info3.sids[*].sid
* should be allocated before the following ones?
* (just the 0x30 0x00 0x02 0x00 value).
*/
PAC_DOMAIN_GROUP_MEMBERSHIP resource_groups;
} PAC_LOGON_INFO;
typedef [bitmap32bit] bitmap {
PAC_CREDENTIAL_NTLM_HAS_LM_HASH = 0x00000001,
PAC_CREDENTIAL_NTLM_HAS_NT_HASH = 0x00000002
} PAC_CREDENTIAL_NTLM_FLAGS;
typedef [public] struct {
[value(0)] uint32 version;
PAC_CREDENTIAL_NTLM_FLAGS flags;
[noprint] samr_Password lm_password;
[noprint] samr_Password nt_password;
} PAC_CREDENTIAL_NTLM_SECPKG;
typedef [public] struct {
lsa_String package_name;
uint32 credential_size;
[size_is(credential_size), noprint] uint8 *credential;
} PAC_CREDENTIAL_SUPPLEMENTAL_SECPKG;
typedef [public] struct {
uint32 credential_count;
[size_is(credential_count)] PAC_CREDENTIAL_SUPPLEMENTAL_SECPKG credentials[*];
} PAC_CREDENTIAL_DATA;
typedef [public] struct {
PAC_CREDENTIAL_DATA *data;
} PAC_CREDENTIAL_DATA_CTR;
typedef [public] struct {
[subcontext(0xFFFFFC01)] PAC_CREDENTIAL_DATA_CTR ctr;
} PAC_CREDENTIAL_DATA_NDR;
typedef [public] struct {
[value(0)] uint32 version;
uint32 encryption_type;
[flag(NDR_REMAINING)] DATA_BLOB encrypted_data;
} PAC_CREDENTIAL_INFO;
typedef struct {
lsa_String proxy_target;
uint32 num_transited_services;
[size_is(num_transited_services)] lsa_String *transited_services;
} PAC_CONSTRAINED_DELEGATION;
typedef [bitmap32bit] bitmap {
PAC_UPN_DNS_FLAG_CONSTRUCTED = 0x00000001,
PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID = 0x00000002
} PAC_UPN_DNS_FLAGS;
typedef struct {
[value(2*strlen_m(samaccountname))] uint16 samaccountname_size;
[relative_short,subcontext(0),subcontext_size(samaccountname_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *samaccountname;
[value(ndr_size_dom_sid(objectsid, ndr->flags))] uint16 objectsid_size;
[relative_short,subcontext(0),subcontext_size(objectsid_size)] dom_sid *objectsid;
} PAC_UPN_DNS_INFO_SAM_NAME_AND_SID;
typedef [nodiscriminant] union {
[case(PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_SAM_NAME_AND_SID sam_name_and_sid;
[default];
} PAC_UPN_DNS_INFO_EX;
typedef struct {
[value(2*strlen_m(upn_name))] uint16 upn_name_size;
[relative_short,subcontext(0),subcontext_size(upn_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *upn_name;
[value(2*strlen_m(dns_domain_name))] uint16 dns_domain_name_size;
[relative_short,subcontext(0),subcontext_size(dns_domain_name_size),flag(NDR_ALIGN8|STR_NOTERM|NDR_REMAINING)] string *dns_domain_name;
PAC_UPN_DNS_FLAGS flags;
[switch_is(flags & PAC_UPN_DNS_FLAG_HAS_SAM_NAME_AND_SID)] PAC_UPN_DNS_INFO_EX ex;
} PAC_UPN_DNS_INFO;
typedef [bitmap32bit] bitmap {
PAC_ATTRIBUTE_FLAG_PAC_WAS_REQUESTED = 0x00000001,
PAC_ATTRIBUTE_FLAG_PAC_WAS_GIVEN_IMPLICITLY = 0x00000002
} PAC_ATTRIBUTE_INFO_FLAGS;
typedef struct {
uint32 flags_length; /* length in bits */
PAC_ATTRIBUTE_INFO_FLAGS flags;
} PAC_ATTRIBUTES_INFO;
typedef struct {
dom_sid sid;
} PAC_REQUESTER_SID;
typedef [public] struct {
PAC_LOGON_INFO *info;
} PAC_LOGON_INFO_CTR;
typedef [public] struct {
PAC_CONSTRAINED_DELEGATION *info;
} PAC_CONSTRAINED_DELEGATION_CTR;
typedef struct {
uint32 rid;
uint32 primary_gid;
dom_sid2 *domain_sid;
samr_RidWithAttributeArray groups;
uint32 sid_count;
[size_is(sid_count)] netr_SidAttr *sids;
uint32 domain_group_count;
[size_is(domain_group_count)] PAC_DOMAIN_GROUP_MEMBERSHIP *domain_groups;
} PAC_DEVICE_INFO;
typedef struct {
PAC_DEVICE_INFO *info;
} PAC_DEVICE_INFO_CTR;
typedef [public,v1_enum] enum {
PAC_TYPE_LOGON_INFO = 1,
PAC_TYPE_CREDENTIAL_INFO = 2,
PAC_TYPE_SRV_CHECKSUM = 6,
PAC_TYPE_KDC_CHECKSUM = 7,
PAC_TYPE_LOGON_NAME = 10,
PAC_TYPE_CONSTRAINED_DELEGATION = 11,
PAC_TYPE_UPN_DNS_INFO = 12,
PAC_TYPE_CLIENT_CLAIMS_INFO = 13,
PAC_TYPE_DEVICE_INFO = 14,
PAC_TYPE_DEVICE_CLAIMS_INFO = 15,
PAC_TYPE_TICKET_CHECKSUM = 16,
PAC_TYPE_ATTRIBUTES_INFO = 17,
PAC_TYPE_REQUESTER_SID = 18,
PAC_TYPE_FULL_CHECKSUM = 19
/*
* Note! when adding new types, adjust the value of PAC_TYPE_END
* to equal one more than the highest supported type.
*/
} PAC_TYPE;
const uint32 PAC_TYPE_BEGIN = 1;
const uint32 PAC_TYPE_END = 20;
const uint32 PAC_TYPE_COUNT = PAC_TYPE_END - PAC_TYPE_BEGIN;
typedef struct {
[flag(NDR_REMAINING)] DATA_BLOB remaining;
} DATA_BLOB_REM;
typedef [public,nodiscriminant,gensize] union {
[case(PAC_TYPE_LOGON_INFO)][subcontext(0xFFFFFC01)] PAC_LOGON_INFO_CTR logon_info;
[case(PAC_TYPE_CREDENTIAL_INFO)] PAC_CREDENTIAL_INFO credential_info;
[case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum;
[case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum;
[case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name;
[case(PAC_TYPE_CONSTRAINED_DELEGATION)][subcontext(0xFFFFFC01)]
PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation;
[case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info;
[case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum;
[case(PAC_TYPE_ATTRIBUTES_INFO)] PAC_ATTRIBUTES_INFO attributes_info;
[case(PAC_TYPE_REQUESTER_SID)] PAC_REQUESTER_SID requester_sid;
/*
* [subcontext(0)] and DATA_BLOB_REM is used as in
* PAC_TYPE_CLIENT_CLAIMS_INFO
* PAC_TYPE_DEVICE_CLAIMS_INFO as Windows will
* sometimes send an empty buffer (presumably to avoid
* the overhead of the header around the claims) if
* there are no claims to send
*/
[case(PAC_TYPE_CLIENT_CLAIMS_INFO)][subcontext(0)] DATA_BLOB_REM client_claims_info;
[case(PAC_TYPE_DEVICE_INFO)][subcontext(0xFFFFFC01)] PAC_DEVICE_INFO_CTR device_info;
[case(PAC_TYPE_DEVICE_CLAIMS_INFO)][subcontext(0)] DATA_BLOB_REM device_claims_info;
[case(PAC_TYPE_FULL_CHECKSUM)] PAC_SIGNATURE_DATA full_checksum;
/* when new PAC info types are added they are supposed to be done
in such a way that they are backwards compatible with existing
servers. This makes it safe to just use a [default] for
unknown types, which lets us ignore the data */
[default] [subcontext(0)] DATA_BLOB_REM unknown;
} PAC_INFO;
typedef [public,nopush,nopull] struct {
PAC_TYPE type;
[value(_ndr_size_PAC_INFO(info, type, LIBNDR_FLAG_ALIGN8))] uint32 _ndr_size;
/*
* We need to have two subcontexts to get the padding right,
* the outer subcontext uses NDR_ROUND(_ndr_size, 8), while
* the inner subcontext only uses _ndr_size.
*
* We do that in non-generated push/pull functions.
*/
[relative,switch_is(type),subcontext(0),subcontext_size(NDR_ROUND(_ndr_size,8)),flag(NDR_ALIGN8)] PAC_INFO *info;
[value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */
} PAC_BUFFER;
typedef [public] struct {
uint32 num_buffers;
uint32 version;
PAC_BUFFER buffers[num_buffers];
} PAC_DATA;
typedef [public] struct {
PAC_TYPE type;
uint32 ndr_size;
[relative,subcontext(0),subcontext_size(NDR_ROUND(ndr_size,8)),flag(NDR_ALIGN8)] DATA_BLOB_REM *info;
[value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */
} PAC_BUFFER_RAW;
typedef [public] struct {
uint32 num_buffers;
uint32 version;
PAC_BUFFER_RAW buffers[num_buffers];
} PAC_DATA_RAW;
const int NETLOGON_GENERIC_KRB5_PAC_VALIDATE = 3;
typedef [public] struct {
[value(NETLOGON_GENERIC_KRB5_PAC_VALIDATE)] uint32 MessageType;
uint32 ChecksumLength;
int32 SignatureType;
uint32 SignatureLength;
[flag(NDR_REMAINING)] DATA_BLOB ChecksumAndSignature;
} PAC_Validate;
/* used for samba3 netsamlogon cache */
typedef [public] struct {
time_t timestamp;
netr_SamInfo3 info3;
} netsamlogoncache_entry;
}
|