2 Unix SMB/CIFS implementation.
3 kerberos authorization data (PAC) utility library
4 Copyright (C) Jim McDonough 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
);
45 static BOOL
pac_io_unknown_type_10(const char *desc
, UNKNOWN_TYPE_10
*type_10
,
46 prs_struct
*ps
, int depth
)
51 prs_debug(ps
, depth
, desc
, "pac_io_unknown_type_10");
54 if (!smb_io_time("unknown_time", &type_10
->unknown_time
, ps
, depth
))
57 if (!prs_uint16("len", ps
, depth
, &type_10
->len
))
60 if (UNMARSHALLING(ps
) && type_10
->len
) {
61 type_10
->username
= (uint16
*) prs_alloc_mem(ps
, type_10
->len
);
62 if (!type_10
->username
) {
63 DEBUG(3, ("No memory available\n"));
68 if (!prs_uint16s(True
, "name", ps
, depth
, type_10
->username
,
69 (type_10
->len
/ sizeof(uint16
))))
77 static BOOL
pac_io_krb_sids(const char *desc
, KRB_SID_AND_ATTRS
*sid_and_attr
,
78 prs_struct
*ps
, int depth
)
80 if (NULL
== sid_and_attr
)
83 prs_debug(ps
, depth
, desc
, "pac_io_krb_sids");
86 if (UNMARSHALLING(ps
)) {
88 (DOM_SID2
* ) prs_alloc_mem(ps
, sizeof(DOM_SID2
));
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
= (KRB_SID_AND_ATTRS
*)
138 prs_alloc_mem(ps
, sizeof(KRB_SID_AND_ATTRS
) * num
);
139 if (!array
->krb_sid_and_attrs
) {
140 DEBUG(3, ("No memory available\n"));
145 for (i
=0; i
<num
; i
++) {
146 if (!pac_io_krb_attrs(desc
,
147 &array
->krb_sid_and_attrs
[i
],
152 for (i
=0; i
<num
; i
++) {
153 if (!pac_io_krb_sids(desc
,
154 &array
->krb_sid_and_attrs
[i
],
164 static BOOL
pac_io_group_membership(const char *desc
,
165 GROUP_MEMBERSHIP
*membership
,
166 prs_struct
*ps
, int depth
)
168 if (NULL
== membership
)
171 prs_debug(ps
, depth
, desc
, "pac_io_group_membership");
174 if (!prs_uint32("rid", ps
, depth
, &membership
->rid
))
176 if (!prs_uint32("attrs", ps
, depth
, &membership
->attrs
))
183 static BOOL
pac_io_group_membership_array(const char *desc
,
184 GROUP_MEMBERSHIP_ARRAY
*array
,
186 prs_struct
*ps
, int depth
)
193 prs_debug(ps
, depth
, desc
, "pac_io_group_membership_array");
197 if (!prs_uint32("count", ps
, depth
, &array
->count
))
200 if (UNMARSHALLING(ps
)) {
201 array
->group_membership
= (GROUP_MEMBERSHIP
*)
202 prs_alloc_mem(ps
, sizeof(GROUP_MEMBERSHIP
) * num
);
203 if (!array
->group_membership
) {
204 DEBUG(3, ("No memory available\n"));
209 for (i
=0; i
<num
; i
++) {
210 if (!pac_io_group_membership(desc
,
211 &array
->group_membership
[i
],
221 static BOOL
pac_io_pac_logon_info(const char *desc
, PAC_LOGON_INFO
*info
,
222 prs_struct
*ps
, int depth
)
228 prs_debug(ps
, depth
, desc
, "pac_io_pac_logon_info");
231 if (!prs_uint32("unknown", ps
, depth
, &garbage
))
233 if (!prs_uint32("unknown", ps
, depth
, &garbage
))
235 if (!prs_uint32("bufferlen", ps
, depth
, &garbage
))
237 if (!prs_uint32("bufferlenhi", ps
, depth
, &garbage
))
239 if (!prs_uint32("pointer", ps
, depth
, &garbage
))
242 if (!smb_io_time("logon_time", &info
->logon_time
, ps
, depth
))
244 if (!smb_io_time("logoff_time", &info
->logoff_time
, ps
, depth
))
246 if (!smb_io_time("kickoff_time", &info
->kickoff_time
, ps
, depth
))
248 if (!smb_io_time("pass_last_set_time", &info
->pass_last_set_time
,
251 if (!smb_io_time("pass_can_change_time", &info
->pass_can_change_time
,
254 if (!smb_io_time("pass_must_change_time", &info
->pass_must_change_time
,
258 if (!smb_io_unihdr("hdr_user_name", &info
->hdr_user_name
, ps
, depth
))
260 if (!smb_io_unihdr("hdr_full_name", &info
->hdr_full_name
, ps
, depth
))
262 if (!smb_io_unihdr("hdr_logon_script", &info
->hdr_logon_script
,
265 if (!smb_io_unihdr("hdr_profile_path", &info
->hdr_profile_path
,
268 if (!smb_io_unihdr("hdr_home_dir", &info
->hdr_home_dir
, ps
, depth
))
270 if (!smb_io_unihdr("hdr_dir_drive", &info
->hdr_dir_drive
, ps
, depth
))
273 if (!prs_uint16("logon_count", ps
, depth
, &info
->logon_count
))
275 if (!prs_uint16("reserved12", ps
, depth
, &info
->reserved12
))
277 if (!prs_uint32("user_rid", ps
, depth
, &info
->user_rid
))
279 if (!prs_uint32("group_rid", ps
, depth
, &info
->group_rid
))
281 if (!prs_uint32("group_count", ps
, depth
, &info
->group_count
))
283 /* I haven't seen this contain anything yet, but when it does
284 we will have to make sure we decode the contents in the middle
285 all the unistr2s ... */
286 if (!prs_uint32("group_mem_ptr", ps
, depth
,
287 &info
->group_membership_ptr
))
289 if (!prs_uint32("user_flags", ps
, depth
, &info
->user_flags
))
292 if (!prs_uint32("reserved13.0", ps
, depth
, &info
->reserved13
[0]))
294 if (!prs_uint32("reserved13.1", ps
, depth
, &info
->reserved13
[1]))
296 if (!prs_uint32("reserved13.2", ps
, depth
, &info
->reserved13
[2]))
298 if (!prs_uint32("reserved13.3", ps
, depth
, &info
->reserved13
[3]))
301 if (!smb_io_unihdr("hdr_dom_controller",
302 &info
->hdr_dom_controller
, ps
, depth
))
304 if (!smb_io_unihdr("hdr_dom_name", &info
->hdr_dom_name
, ps
, depth
))
307 /* this should be followed, but just get ptr for now */
308 if (!prs_uint32("ptr_dom_sid", ps
, depth
, &info
->ptr_dom_sid
))
311 if (!prs_uint32("reserved16.0", ps
, depth
, &info
->reserved16
[0]))
313 if (!prs_uint32("reserved16.1", ps
, depth
, &info
->reserved16
[1]))
316 /* might be acb_info */
317 if (!prs_uint32("reserved17", ps
, depth
, &info
->reserved17
))
321 if (!prs_uint32("reserved18.0", ps
, depth
, &info
->reserved18
[0]))
323 if (!prs_uint32("reserved18.1", ps
, depth
, &info
->reserved18
[1]))
325 if (!prs_uint32("reserved18.2", ps
, depth
, &info
->reserved18
[2]))
327 if (!prs_uint32("reserved18.3", ps
, depth
, &info
->reserved18
[3]))
329 if (!prs_uint32("reserved18.4", ps
, depth
, &info
->reserved18
[4]))
331 if (!prs_uint32("reserved18.5", ps
, depth
, &info
->reserved18
[5]))
333 if (!prs_uint32("reserved18.6", ps
, depth
, &info
->reserved18
[6]))
336 if (!prs_uint32("sid_count", ps
, depth
, &info
->sid_count
))
338 if (!prs_uint32("ptr_extra_sids", ps
, depth
, &info
->ptr_extra_sids
))
340 if (!prs_uint32("ptr_res_group_dom_sid", ps
, depth
,
341 &info
->ptr_res_group_dom_sid
))
343 if (!prs_uint32("res_group_count", ps
, depth
, &info
->res_group_count
))
345 if (!prs_uint32("ptr_res_groups", ps
, depth
, &info
->ptr_res_groups
))
348 if(!smb_io_unistr2("uni_user_name", &info
->uni_user_name
,
349 info
->hdr_user_name
.buffer
, ps
, depth
))
351 if(!smb_io_unistr2("uni_full_name", &info
->uni_full_name
,
352 info
->hdr_full_name
.buffer
, ps
, depth
))
354 if(!smb_io_unistr2("uni_logon_script", &info
->uni_logon_script
,
355 info
->hdr_logon_script
.buffer
, ps
, depth
))
357 if(!smb_io_unistr2("uni_profile_path", &info
->uni_profile_path
,
358 info
->hdr_profile_path
.buffer
, ps
, depth
))
360 if(!smb_io_unistr2("uni_home_dir", &info
->uni_home_dir
,
361 info
->hdr_home_dir
.buffer
, ps
, depth
))
363 if(!smb_io_unistr2("uni_dir_drive", &info
->uni_dir_drive
,
364 info
->hdr_dir_drive
.buffer
, ps
, depth
))
367 if (info
->group_membership_ptr
) {
368 if (!pac_io_group_membership_array("group membership",
376 if(!smb_io_unistr2("uni_dom_controller", &info
->uni_dom_controller
,
377 info
->hdr_dom_controller
.buffer
, ps
, depth
))
379 if(!smb_io_unistr2("uni_dom_name", &info
->uni_dom_name
,
380 info
->hdr_dom_name
.buffer
, ps
, depth
))
383 if(info
->ptr_dom_sid
)
384 if(!smb_io_dom_sid2("dom_sid", &info
->dom_sid
, ps
, depth
))
388 if (info
->sid_count
&& info
->ptr_extra_sids
)
389 if (!pac_io_krb_sid_and_attr_array("extra_sids",
395 if (info
->ptr_res_group_dom_sid
)
396 if (!smb_io_dom_sid2("res_group_dom_sid",
397 &info
->res_group_dom_sid
, ps
, depth
))
400 if (info
->ptr_res_groups
)
401 if (!pac_io_group_membership_array("res group membership",
403 info
->res_group_count
,
411 static BOOL
pac_io_pac_signature_data(const char *desc
,
412 PAC_SIGNATURE_DATA
*data
, uint32 length
,
413 prs_struct
*ps
, int depth
)
415 uint32 siglen
= length
- sizeof(uint32
);
419 prs_debug(ps
, depth
, desc
, "pac_io_pac_signature_data");
422 if (!prs_uint32("type", ps
, depth
, &data
->type
))
424 if (UNMARSHALLING(ps
)) {
425 data
->signature
= prs_alloc_mem(ps
, siglen
);
426 if (!data
->signature
) {
427 DEBUG(3, ("No memory available\n"));
431 if (!prs_uint8s(False
, "signature", ps
, depth
, data
->signature
,siglen
))
437 static BOOL
pac_io_pac_info_hdr_ctr(const char *desc
, PAC_INFO_HDR
*hdr
,
438 prs_struct
*ps
, int depth
)
443 prs_debug(ps
, depth
, desc
, "pac_io_pac_info_hdr_ctr");
449 if (hdr
->offset
!= prs_offset(ps
)) {
450 DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
451 hdr
->offset
, prs_offset(ps
)));
452 prs_set_offset(ps
, hdr
->offset
);
455 if (UNMARSHALLING(ps
) && hdr
->size
> 0) {
456 hdr
->ctr
= (PAC_INFO_CTR
*)
457 prs_alloc_mem(ps
, sizeof(PAC_INFO_CTR
));
459 DEBUG(3, ("No memory available\n"));
465 case PAC_TYPE_LOGON_INFO
:
466 DEBUG(5, ("PAC_TYPE_LOGON_INFO\n"));
467 if (UNMARSHALLING(ps
))
468 hdr
->ctr
->pac
.logon_info
= (PAC_LOGON_INFO
*)
469 prs_alloc_mem(ps
, sizeof(PAC_LOGON_INFO
));
470 if (!hdr
->ctr
->pac
.logon_info
) {
471 DEBUG(3, ("No memory available\n"));
474 if (!pac_io_pac_logon_info(desc
, hdr
->ctr
->pac
.logon_info
,
479 case PAC_TYPE_SERVER_CHECKSUM
:
480 DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n"));
481 if (UNMARSHALLING(ps
))
482 hdr
->ctr
->pac
.srv_cksum
= (PAC_SIGNATURE_DATA
*)
483 prs_alloc_mem(ps
, sizeof(PAC_SIGNATURE_DATA
));
484 if (!hdr
->ctr
->pac
.srv_cksum
) {
485 DEBUG(3, ("No memory available\n"));
488 if (!pac_io_pac_signature_data(desc
, hdr
->ctr
->pac
.srv_cksum
,
489 hdr
->size
, ps
, depth
))
493 case PAC_TYPE_PRIVSVR_CHECKSUM
:
494 DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n"));
495 if (UNMARSHALLING(ps
))
496 hdr
->ctr
->pac
.privsrv_cksum
= (PAC_SIGNATURE_DATA
*)
497 prs_alloc_mem(ps
, sizeof(PAC_SIGNATURE_DATA
));
498 if (!hdr
->ctr
->pac
.privsrv_cksum
) {
499 DEBUG(3, ("No memory available\n"));
502 if (!pac_io_pac_signature_data(desc
,
503 hdr
->ctr
->pac
.privsrv_cksum
,
504 hdr
->size
, ps
, depth
))
508 case PAC_TYPE_UNKNOWN_10
:
509 DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n"));
510 if (UNMARSHALLING(ps
))
511 hdr
->ctr
->pac
.type_10
= (UNKNOWN_TYPE_10
*)
512 prs_alloc_mem(ps
, sizeof(UNKNOWN_TYPE_10
));
513 if (!hdr
->ctr
->pac
.type_10
) {
514 DEBUG(3, ("No memory available\n"));
517 if (!pac_io_unknown_type_10(desc
, hdr
->ctr
->pac
.type_10
,
523 /* dont' know, so we need to skip it */
524 DEBUG(3, ("unknown PAC type %d\n", hdr
->type
));
525 prs_set_offset(ps
, prs_offset(ps
) + hdr
->size
);
531 static BOOL
pac_io_pac_info_hdr(const char *desc
, PAC_INFO_HDR
*hdr
,
532 prs_struct
*ps
, int depth
)
537 prs_debug(ps
, depth
, desc
, "pac_io_pac_info_hdr");
542 if (!prs_uint32("type", ps
, depth
, &hdr
->type
))
544 if (!prs_uint32("size", ps
, depth
, &hdr
->size
))
546 if (!prs_uint32("offset", ps
, depth
, &hdr
->offset
))
548 if (!prs_uint32("offsethi", ps
, depth
, &hdr
->offsethi
))
554 static BOOL
pac_io_pac_data(const char *desc
, PAC_DATA
*data
,
555 prs_struct
*ps
, int depth
)
562 prs_debug(ps
, depth
, desc
, "pac_io_pac_data");
567 if (!prs_uint32("num_buffers", ps
, depth
, &data
->num_buffers
))
569 if (!prs_uint32("version", ps
, depth
, &data
->version
))
572 if (UNMARSHALLING(ps
) && data
->num_buffers
> 0) {
573 if ((data
->pac_info_hdr_ptr
= (PAC_INFO_HDR
*)
574 prs_alloc_mem(ps
, sizeof(PAC_INFO_HDR
) *
575 data
->num_buffers
)) == NULL
) {
580 for (i
=0; i
<data
->num_buffers
; i
++) {
581 if (!pac_io_pac_info_hdr(desc
, &data
->pac_info_hdr_ptr
[i
], ps
,
586 for (i
=0; i
<data
->num_buffers
; i
++) {
587 if (!pac_io_pac_info_hdr_ctr(desc
, &data
->pac_info_hdr_ptr
[i
],
595 PAC_DATA
*decode_pac_data(DATA_BLOB
*auth_data
, TALLOC_CTX
*ctx
)
597 DATA_BLOB pac_data_blob
= unwrap_pac(auth_data
);
601 DEBUG(5,("dump_pac_data\n"));
602 prs_init(&ps
, pac_data_blob
.length
, ctx
, UNMARSHALL
);
603 prs_copy_data_in(&ps
, pac_data_blob
.data
, pac_data_blob
.length
);
604 prs_set_offset(&ps
, 0);
606 pac_data
= (PAC_DATA
*) talloc_zero(ctx
, sizeof(PAC_DATA
));
607 pac_io_pac_data("pac data", pac_data
, &ps
, 0);