2 Unix SMB/CIFS implementation.
3 kerberos authorization data (PAC) utility library
4 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 static DATA_BLOB
unwrap_pac(DATA_BLOB
*auth_data
)
27 DATA_BLOB pac_contents
;
31 asn1_load(&data
, *auth_data
);
32 asn1_start_tag(&data
, ASN1_SEQUENCE(0));
33 asn1_start_tag(&data
, ASN1_SEQUENCE(0));
34 asn1_start_tag(&data
, ASN1_CONTEXT(0));
35 asn1_read_Integer(&data
, &data_type
);
37 asn1_start_tag(&data
, ASN1_CONTEXT(1));
38 asn1_read_OctetString(&data
, &pac_contents
);
46 static BOOL
pac_io_unknown_type_10(const char *desc
, UNKNOWN_TYPE_10
*type_10
,
47 prs_struct
*ps
, int depth
)
52 prs_debug(ps
, depth
, desc
, "pac_io_unknown_type_10");
55 if (!smb_io_time("unknown_time", &type_10
->unknown_time
, ps
, depth
))
58 if (!prs_uint16("len", ps
, depth
, &type_10
->len
))
61 if (UNMARSHALLING(ps
) && type_10
->len
) {
62 type_10
->username
= PRS_ALLOC_MEM(ps
, uint16
, type_10
->len
);
63 if (!type_10
->username
) {
64 DEBUG(3, ("No memory available\n"));
69 if (!prs_uint16s(True
, "name", ps
, depth
, type_10
->username
,
70 (type_10
->len
/ sizeof(uint16
))))
78 static BOOL
pac_io_krb_sids(const char *desc
, KRB_SID_AND_ATTRS
*sid_and_attr
,
79 prs_struct
*ps
, int depth
)
81 if (NULL
== sid_and_attr
)
84 prs_debug(ps
, depth
, desc
, "pac_io_krb_sids");
87 if (UNMARSHALLING(ps
)) {
88 sid_and_attr
->sid
= PRS_ALLOC_MEM(ps
, DOM_SID2
, 1);
89 if (!sid_and_attr
->sid
) {
90 DEBUG(3, ("No memory available\n"));
95 if(!smb_io_dom_sid2("sid", sid_and_attr
->sid
, ps
, depth
))
102 static BOOL
pac_io_krb_attrs(const char *desc
, KRB_SID_AND_ATTRS
*sid_and_attr
,
103 prs_struct
*ps
, int depth
)
105 if (NULL
== sid_and_attr
)
108 prs_debug(ps
, depth
, desc
, "pac_io_krb_attrs");
111 if (!prs_uint32("sid_ptr", ps
, depth
, &sid_and_attr
->sid_ptr
))
113 if (!prs_uint32("attrs", ps
, depth
, &sid_and_attr
->attrs
))
119 static BOOL
pac_io_krb_sid_and_attr_array(const char *desc
,
120 KRB_SID_AND_ATTR_ARRAY
*array
,
122 prs_struct
*ps
, int depth
)
129 prs_debug(ps
, depth
, desc
, "pac_io_krb_sid_and_attr_array");
133 if (!prs_uint32("count", ps
, depth
, &array
->count
))
136 if (UNMARSHALLING(ps
)) {
137 array
->krb_sid_and_attrs
= PRS_ALLOC_MEM(ps
, KRB_SID_AND_ATTRS
, num
);
138 if (!array
->krb_sid_and_attrs
) {
139 DEBUG(3, ("No memory available\n"));
144 for (i
=0; i
<num
; i
++) {
145 if (!pac_io_krb_attrs(desc
,
146 &array
->krb_sid_and_attrs
[i
],
151 for (i
=0; i
<num
; i
++) {
152 if (!pac_io_krb_sids(desc
,
153 &array
->krb_sid_and_attrs
[i
],
163 static BOOL
pac_io_group_membership(const char *desc
,
164 GROUP_MEMBERSHIP
*membership
,
165 prs_struct
*ps
, int depth
)
167 if (NULL
== membership
)
170 prs_debug(ps
, depth
, desc
, "pac_io_group_membership");
173 if (!prs_uint32("rid", ps
, depth
, &membership
->rid
))
175 if (!prs_uint32("attrs", ps
, depth
, &membership
->attrs
))
182 static BOOL
pac_io_group_membership_array(const char *desc
,
183 GROUP_MEMBERSHIP_ARRAY
*array
,
185 prs_struct
*ps
, int depth
)
192 prs_debug(ps
, depth
, desc
, "pac_io_group_membership_array");
196 if (!prs_uint32("count", ps
, depth
, &array
->count
))
199 if (UNMARSHALLING(ps
)) {
200 array
->group_membership
= PRS_ALLOC_MEM(ps
, GROUP_MEMBERSHIP
, num
);
201 if (!array
->group_membership
) {
202 DEBUG(3, ("No memory available\n"));
207 for (i
=0; i
<num
; i
++) {
208 if (!pac_io_group_membership(desc
,
209 &array
->group_membership
[i
],
219 static BOOL
pac_io_pac_logon_info(const char *desc
, PAC_LOGON_INFO
*info
,
220 prs_struct
*ps
, int depth
)
226 prs_debug(ps
, depth
, desc
, "pac_io_pac_logon_info");
229 if (!prs_uint32("unknown", ps
, depth
, &garbage
))
231 if (!prs_uint32("unknown", ps
, depth
, &garbage
))
233 if (!prs_uint32("bufferlen", ps
, depth
, &garbage
))
235 if (!prs_uint32("bufferlenhi", ps
, depth
, &garbage
))
237 if (!prs_uint32("pointer", ps
, depth
, &garbage
))
240 if (!smb_io_time("logon_time", &info
->logon_time
, ps
, depth
))
242 if (!smb_io_time("logoff_time", &info
->logoff_time
, ps
, depth
))
244 if (!smb_io_time("kickoff_time", &info
->kickoff_time
, ps
, depth
))
246 if (!smb_io_time("pass_last_set_time", &info
->pass_last_set_time
,
249 if (!smb_io_time("pass_can_change_time", &info
->pass_can_change_time
,
252 if (!smb_io_time("pass_must_change_time", &info
->pass_must_change_time
,
256 if (!smb_io_unihdr("hdr_user_name", &info
->hdr_user_name
, ps
, depth
))
258 if (!smb_io_unihdr("hdr_full_name", &info
->hdr_full_name
, ps
, depth
))
260 if (!smb_io_unihdr("hdr_logon_script", &info
->hdr_logon_script
,
263 if (!smb_io_unihdr("hdr_profile_path", &info
->hdr_profile_path
,
266 if (!smb_io_unihdr("hdr_home_dir", &info
->hdr_home_dir
, ps
, depth
))
268 if (!smb_io_unihdr("hdr_dir_drive", &info
->hdr_dir_drive
, ps
, depth
))
271 if (!prs_uint16("logon_count", ps
, depth
, &info
->logon_count
))
273 if (!prs_uint16("reserved12", ps
, depth
, &info
->reserved12
))
275 if (!prs_uint32("user_rid", ps
, depth
, &info
->user_rid
))
277 if (!prs_uint32("group_rid", ps
, depth
, &info
->group_rid
))
279 if (!prs_uint32("group_count", ps
, depth
, &info
->group_count
))
281 /* I haven't seen this contain anything yet, but when it does
282 we will have to make sure we decode the contents in the middle
283 all the unistr2s ... */
284 if (!prs_uint32("group_mem_ptr", ps
, depth
,
285 &info
->group_membership_ptr
))
287 if (!prs_uint32("user_flags", ps
, depth
, &info
->user_flags
))
290 if (!prs_uint32("reserved13.0", ps
, depth
, &info
->reserved13
[0]))
292 if (!prs_uint32("reserved13.1", ps
, depth
, &info
->reserved13
[1]))
294 if (!prs_uint32("reserved13.2", ps
, depth
, &info
->reserved13
[2]))
296 if (!prs_uint32("reserved13.3", ps
, depth
, &info
->reserved13
[3]))
299 if (!smb_io_unihdr("hdr_dom_controller",
300 &info
->hdr_dom_controller
, ps
, depth
))
302 if (!smb_io_unihdr("hdr_dom_name", &info
->hdr_dom_name
, ps
, depth
))
305 /* this should be followed, but just get ptr for now */
306 if (!prs_uint32("ptr_dom_sid", ps
, depth
, &info
->ptr_dom_sid
))
309 if (!prs_uint32("reserved16.0", ps
, depth
, &info
->reserved16
[0]))
311 if (!prs_uint32("reserved16.1", ps
, depth
, &info
->reserved16
[1]))
314 /* might be acb_info */
315 if (!prs_uint32("reserved17", ps
, depth
, &info
->reserved17
))
319 if (!prs_uint32("reserved18.0", ps
, depth
, &info
->reserved18
[0]))
321 if (!prs_uint32("reserved18.1", ps
, depth
, &info
->reserved18
[1]))
323 if (!prs_uint32("reserved18.2", ps
, depth
, &info
->reserved18
[2]))
325 if (!prs_uint32("reserved18.3", ps
, depth
, &info
->reserved18
[3]))
327 if (!prs_uint32("reserved18.4", ps
, depth
, &info
->reserved18
[4]))
329 if (!prs_uint32("reserved18.5", ps
, depth
, &info
->reserved18
[5]))
331 if (!prs_uint32("reserved18.6", ps
, depth
, &info
->reserved18
[6]))
334 if (!prs_uint32("sid_count", ps
, depth
, &info
->sid_count
))
336 if (!prs_uint32("ptr_extra_sids", ps
, depth
, &info
->ptr_extra_sids
))
338 if (!prs_uint32("ptr_res_group_dom_sid", ps
, depth
,
339 &info
->ptr_res_group_dom_sid
))
341 if (!prs_uint32("res_group_count", ps
, depth
, &info
->res_group_count
))
343 if (!prs_uint32("ptr_res_groups", ps
, depth
, &info
->ptr_res_groups
))
346 if(!smb_io_unistr2("uni_user_name", &info
->uni_user_name
,
347 info
->hdr_user_name
.buffer
, ps
, depth
))
349 if(!smb_io_unistr2("uni_full_name", &info
->uni_full_name
,
350 info
->hdr_full_name
.buffer
, ps
, depth
))
352 if(!smb_io_unistr2("uni_logon_script", &info
->uni_logon_script
,
353 info
->hdr_logon_script
.buffer
, ps
, depth
))
355 if(!smb_io_unistr2("uni_profile_path", &info
->uni_profile_path
,
356 info
->hdr_profile_path
.buffer
, ps
, depth
))
358 if(!smb_io_unistr2("uni_home_dir", &info
->uni_home_dir
,
359 info
->hdr_home_dir
.buffer
, ps
, depth
))
361 if(!smb_io_unistr2("uni_dir_drive", &info
->uni_dir_drive
,
362 info
->hdr_dir_drive
.buffer
, ps
, depth
))
365 if (info
->group_membership_ptr
) {
366 if (!pac_io_group_membership_array("group membership",
374 if(!smb_io_unistr2("uni_dom_controller", &info
->uni_dom_controller
,
375 info
->hdr_dom_controller
.buffer
, ps
, depth
))
377 if(!smb_io_unistr2("uni_dom_name", &info
->uni_dom_name
,
378 info
->hdr_dom_name
.buffer
, ps
, depth
))
381 if(info
->ptr_dom_sid
)
382 if(!smb_io_dom_sid2("dom_sid", &info
->dom_sid
, ps
, depth
))
386 if (info
->sid_count
&& info
->ptr_extra_sids
)
387 if (!pac_io_krb_sid_and_attr_array("extra_sids",
393 if (info
->ptr_res_group_dom_sid
)
394 if (!smb_io_dom_sid2("res_group_dom_sid",
395 &info
->res_group_dom_sid
, ps
, depth
))
398 if (info
->ptr_res_groups
)
399 if (!pac_io_group_membership_array("res group membership",
401 info
->res_group_count
,
409 static BOOL
pac_io_pac_signature_data(const char *desc
,
410 PAC_SIGNATURE_DATA
*data
, uint32 length
,
411 prs_struct
*ps
, int depth
)
413 uint32 siglen
= length
- sizeof(uint32
);
417 prs_debug(ps
, depth
, desc
, "pac_io_pac_signature_data");
420 if (!prs_uint32("type", ps
, depth
, &data
->type
))
422 if (UNMARSHALLING(ps
)) {
423 data
->signature
= PRS_ALLOC_MEM(ps
, unsigned char, siglen
);
424 if (!data
->signature
) {
425 DEBUG(3, ("No memory available\n"));
429 if (!prs_uint8s(False
, "signature", ps
, depth
, data
->signature
,siglen
))
435 static BOOL
pac_io_pac_info_hdr_ctr(const char *desc
, PAC_INFO_HDR
*hdr
,
436 prs_struct
*ps
, int depth
)
441 prs_debug(ps
, depth
, desc
, "pac_io_pac_info_hdr_ctr");
447 if (hdr
->offset
!= prs_offset(ps
)) {
448 DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
449 hdr
->offset
, prs_offset(ps
)));
450 prs_set_offset(ps
, hdr
->offset
);
453 if (UNMARSHALLING(ps
) && hdr
->size
> 0) {
454 hdr
->ctr
= PRS_ALLOC_MEM(ps
, PAC_INFO_CTR
, 1);
456 DEBUG(3, ("No memory available\n"));
462 case PAC_TYPE_LOGON_INFO
:
463 DEBUG(5, ("PAC_TYPE_LOGON_INFO\n"));
464 if (UNMARSHALLING(ps
))
465 hdr
->ctr
->pac
.logon_info
= PRS_ALLOC_MEM(ps
, PAC_LOGON_INFO
, 1);
466 if (!hdr
->ctr
->pac
.logon_info
) {
467 DEBUG(3, ("No memory available\n"));
470 if (!pac_io_pac_logon_info(desc
, hdr
->ctr
->pac
.logon_info
,
475 case PAC_TYPE_SERVER_CHECKSUM
:
476 DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n"));
477 if (UNMARSHALLING(ps
))
478 hdr
->ctr
->pac
.srv_cksum
= PRS_ALLOC_MEM(ps
, PAC_SIGNATURE_DATA
, 1);
479 if (!hdr
->ctr
->pac
.srv_cksum
) {
480 DEBUG(3, ("No memory available\n"));
483 if (!pac_io_pac_signature_data(desc
, hdr
->ctr
->pac
.srv_cksum
,
484 hdr
->size
, ps
, depth
))
488 case PAC_TYPE_PRIVSVR_CHECKSUM
:
489 DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n"));
490 if (UNMARSHALLING(ps
))
491 hdr
->ctr
->pac
.privsrv_cksum
= PRS_ALLOC_MEM(ps
, PAC_SIGNATURE_DATA
, 1);
492 if (!hdr
->ctr
->pac
.privsrv_cksum
) {
493 DEBUG(3, ("No memory available\n"));
496 if (!pac_io_pac_signature_data(desc
,
497 hdr
->ctr
->pac
.privsrv_cksum
,
498 hdr
->size
, ps
, depth
))
502 case PAC_TYPE_UNKNOWN_10
:
503 DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n"));
504 if (UNMARSHALLING(ps
))
505 hdr
->ctr
->pac
.type_10
= PRS_ALLOC_MEM(ps
, UNKNOWN_TYPE_10
, 1);
506 if (!hdr
->ctr
->pac
.type_10
) {
507 DEBUG(3, ("No memory available\n"));
510 if (!pac_io_unknown_type_10(desc
, hdr
->ctr
->pac
.type_10
,
516 /* dont' know, so we need to skip it */
517 DEBUG(3, ("unknown PAC type %d\n", hdr
->type
));
518 prs_set_offset(ps
, prs_offset(ps
) + hdr
->size
);
524 static BOOL
pac_io_pac_info_hdr(const char *desc
, PAC_INFO_HDR
*hdr
,
525 prs_struct
*ps
, int depth
)
530 prs_debug(ps
, depth
, desc
, "pac_io_pac_info_hdr");
535 if (!prs_uint32("type", ps
, depth
, &hdr
->type
))
537 if (!prs_uint32("size", ps
, depth
, &hdr
->size
))
539 if (!prs_uint32("offset", ps
, depth
, &hdr
->offset
))
541 if (!prs_uint32("offsethi", ps
, depth
, &hdr
->offsethi
))
547 static BOOL
pac_io_pac_data(const char *desc
, PAC_DATA
*data
,
548 prs_struct
*ps
, int depth
)
555 prs_debug(ps
, depth
, desc
, "pac_io_pac_data");
560 if (!prs_uint32("num_buffers", ps
, depth
, &data
->num_buffers
))
562 if (!prs_uint32("version", ps
, depth
, &data
->version
))
565 if (UNMARSHALLING(ps
) && data
->num_buffers
> 0) {
566 if ((data
->pac_info_hdr_ptr
= PRS_ALLOC_MEM(ps
, PAC_INFO_HDR
, data
->num_buffers
)) == NULL
) {
571 for (i
=0; i
<data
->num_buffers
; i
++) {
572 if (!pac_io_pac_info_hdr(desc
, &data
->pac_info_hdr_ptr
[i
], ps
,
577 for (i
=0; i
<data
->num_buffers
; i
++) {
578 if (!pac_io_pac_info_hdr_ctr(desc
, &data
->pac_info_hdr_ptr
[i
],
586 PAC_DATA
*decode_pac_data(DATA_BLOB
*auth_data
, TALLOC_CTX
*ctx
)
588 DATA_BLOB pac_data_blob
= unwrap_pac(auth_data
);
592 DEBUG(5,("dump_pac_data\n"));
593 prs_init(&ps
, pac_data_blob
.length
, ctx
, UNMARSHALL
);
594 prs_copy_data_in(&ps
, (char *)pac_data_blob
.data
, pac_data_blob
.length
);
595 prs_set_offset(&ps
, 0);
597 data_blob_free(&pac_data_blob
);
599 pac_data
= TALLOC_ZERO_P(ctx
, PAC_DATA
);
600 pac_io_pac_data("pac data", pac_data
, &ps
, 0);