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
= (uint16
*) prs_alloc_mem(ps
, 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
)) {
89 (DOM_SID2
* ) prs_alloc_mem(ps
, sizeof(DOM_SID2
));
90 if (!sid_and_attr
->sid
) {
91 DEBUG(3, ("No memory available\n"));
96 if(!smb_io_dom_sid2("sid", sid_and_attr
->sid
, ps
, depth
))
103 static BOOL
pac_io_krb_attrs(const char *desc
, KRB_SID_AND_ATTRS
*sid_and_attr
,
104 prs_struct
*ps
, int depth
)
106 if (NULL
== sid_and_attr
)
109 prs_debug(ps
, depth
, desc
, "pac_io_krb_attrs");
112 if (!prs_uint32("sid_ptr", ps
, depth
, &sid_and_attr
->sid_ptr
))
114 if (!prs_uint32("attrs", ps
, depth
, &sid_and_attr
->attrs
))
120 static BOOL
pac_io_krb_sid_and_attr_array(const char *desc
,
121 KRB_SID_AND_ATTR_ARRAY
*array
,
123 prs_struct
*ps
, int depth
)
130 prs_debug(ps
, depth
, desc
, "pac_io_krb_sid_and_attr_array");
134 if (!prs_uint32("count", ps
, depth
, &array
->count
))
137 if (UNMARSHALLING(ps
)) {
138 array
->krb_sid_and_attrs
= (KRB_SID_AND_ATTRS
*)
139 prs_alloc_mem(ps
, sizeof(KRB_SID_AND_ATTRS
) * num
);
140 if (!array
->krb_sid_and_attrs
) {
141 DEBUG(3, ("No memory available\n"));
146 for (i
=0; i
<num
; i
++) {
147 if (!pac_io_krb_attrs(desc
,
148 &array
->krb_sid_and_attrs
[i
],
153 for (i
=0; i
<num
; i
++) {
154 if (!pac_io_krb_sids(desc
,
155 &array
->krb_sid_and_attrs
[i
],
165 static BOOL
pac_io_group_membership(const char *desc
,
166 GROUP_MEMBERSHIP
*membership
,
167 prs_struct
*ps
, int depth
)
169 if (NULL
== membership
)
172 prs_debug(ps
, depth
, desc
, "pac_io_group_membership");
175 if (!prs_uint32("rid", ps
, depth
, &membership
->rid
))
177 if (!prs_uint32("attrs", ps
, depth
, &membership
->attrs
))
184 static BOOL
pac_io_group_membership_array(const char *desc
,
185 GROUP_MEMBERSHIP_ARRAY
*array
,
187 prs_struct
*ps
, int depth
)
194 prs_debug(ps
, depth
, desc
, "pac_io_group_membership_array");
198 if (!prs_uint32("count", ps
, depth
, &array
->count
))
201 if (UNMARSHALLING(ps
)) {
202 array
->group_membership
= (GROUP_MEMBERSHIP
*)
203 prs_alloc_mem(ps
, sizeof(GROUP_MEMBERSHIP
) * num
);
204 if (!array
->group_membership
) {
205 DEBUG(3, ("No memory available\n"));
210 for (i
=0; i
<num
; i
++) {
211 if (!pac_io_group_membership(desc
,
212 &array
->group_membership
[i
],
222 static BOOL
pac_io_pac_logon_info(const char *desc
, PAC_LOGON_INFO
*info
,
223 prs_struct
*ps
, int depth
)
229 prs_debug(ps
, depth
, desc
, "pac_io_pac_logon_info");
232 if (!prs_uint32("unknown", ps
, depth
, &garbage
))
234 if (!prs_uint32("unknown", ps
, depth
, &garbage
))
236 if (!prs_uint32("bufferlen", ps
, depth
, &garbage
))
238 if (!prs_uint32("bufferlenhi", ps
, depth
, &garbage
))
240 if (!prs_uint32("pointer", ps
, depth
, &garbage
))
243 if (!smb_io_time("logon_time", &info
->logon_time
, ps
, depth
))
245 if (!smb_io_time("logoff_time", &info
->logoff_time
, ps
, depth
))
247 if (!smb_io_time("kickoff_time", &info
->kickoff_time
, ps
, depth
))
249 if (!smb_io_time("pass_last_set_time", &info
->pass_last_set_time
,
252 if (!smb_io_time("pass_can_change_time", &info
->pass_can_change_time
,
255 if (!smb_io_time("pass_must_change_time", &info
->pass_must_change_time
,
259 if (!smb_io_unihdr("hdr_user_name", &info
->hdr_user_name
, ps
, depth
))
261 if (!smb_io_unihdr("hdr_full_name", &info
->hdr_full_name
, ps
, depth
))
263 if (!smb_io_unihdr("hdr_logon_script", &info
->hdr_logon_script
,
266 if (!smb_io_unihdr("hdr_profile_path", &info
->hdr_profile_path
,
269 if (!smb_io_unihdr("hdr_home_dir", &info
->hdr_home_dir
, ps
, depth
))
271 if (!smb_io_unihdr("hdr_dir_drive", &info
->hdr_dir_drive
, ps
, depth
))
274 if (!prs_uint16("logon_count", ps
, depth
, &info
->logon_count
))
276 if (!prs_uint16("reserved12", ps
, depth
, &info
->reserved12
))
278 if (!prs_uint32("user_rid", ps
, depth
, &info
->user_rid
))
280 if (!prs_uint32("group_rid", ps
, depth
, &info
->group_rid
))
282 if (!prs_uint32("group_count", ps
, depth
, &info
->group_count
))
284 /* I haven't seen this contain anything yet, but when it does
285 we will have to make sure we decode the contents in the middle
286 all the unistr2s ... */
287 if (!prs_uint32("group_mem_ptr", ps
, depth
,
288 &info
->group_membership_ptr
))
290 if (!prs_uint32("user_flags", ps
, depth
, &info
->user_flags
))
293 if (!prs_uint32("reserved13.0", ps
, depth
, &info
->reserved13
[0]))
295 if (!prs_uint32("reserved13.1", ps
, depth
, &info
->reserved13
[1]))
297 if (!prs_uint32("reserved13.2", ps
, depth
, &info
->reserved13
[2]))
299 if (!prs_uint32("reserved13.3", ps
, depth
, &info
->reserved13
[3]))
302 if (!smb_io_unihdr("hdr_dom_controller",
303 &info
->hdr_dom_controller
, ps
, depth
))
305 if (!smb_io_unihdr("hdr_dom_name", &info
->hdr_dom_name
, ps
, depth
))
308 /* this should be followed, but just get ptr for now */
309 if (!prs_uint32("ptr_dom_sid", ps
, depth
, &info
->ptr_dom_sid
))
312 if (!prs_uint32("reserved16.0", ps
, depth
, &info
->reserved16
[0]))
314 if (!prs_uint32("reserved16.1", ps
, depth
, &info
->reserved16
[1]))
317 /* might be acb_info */
318 if (!prs_uint32("reserved17", ps
, depth
, &info
->reserved17
))
322 if (!prs_uint32("reserved18.0", ps
, depth
, &info
->reserved18
[0]))
324 if (!prs_uint32("reserved18.1", ps
, depth
, &info
->reserved18
[1]))
326 if (!prs_uint32("reserved18.2", ps
, depth
, &info
->reserved18
[2]))
328 if (!prs_uint32("reserved18.3", ps
, depth
, &info
->reserved18
[3]))
330 if (!prs_uint32("reserved18.4", ps
, depth
, &info
->reserved18
[4]))
332 if (!prs_uint32("reserved18.5", ps
, depth
, &info
->reserved18
[5]))
334 if (!prs_uint32("reserved18.6", ps
, depth
, &info
->reserved18
[6]))
337 if (!prs_uint32("sid_count", ps
, depth
, &info
->sid_count
))
339 if (!prs_uint32("ptr_extra_sids", ps
, depth
, &info
->ptr_extra_sids
))
341 if (!prs_uint32("ptr_res_group_dom_sid", ps
, depth
,
342 &info
->ptr_res_group_dom_sid
))
344 if (!prs_uint32("res_group_count", ps
, depth
, &info
->res_group_count
))
346 if (!prs_uint32("ptr_res_groups", ps
, depth
, &info
->ptr_res_groups
))
349 if(!smb_io_unistr2("uni_user_name", &info
->uni_user_name
,
350 info
->hdr_user_name
.buffer
, ps
, depth
))
352 if(!smb_io_unistr2("uni_full_name", &info
->uni_full_name
,
353 info
->hdr_full_name
.buffer
, ps
, depth
))
355 if(!smb_io_unistr2("uni_logon_script", &info
->uni_logon_script
,
356 info
->hdr_logon_script
.buffer
, ps
, depth
))
358 if(!smb_io_unistr2("uni_profile_path", &info
->uni_profile_path
,
359 info
->hdr_profile_path
.buffer
, ps
, depth
))
361 if(!smb_io_unistr2("uni_home_dir", &info
->uni_home_dir
,
362 info
->hdr_home_dir
.buffer
, ps
, depth
))
364 if(!smb_io_unistr2("uni_dir_drive", &info
->uni_dir_drive
,
365 info
->hdr_dir_drive
.buffer
, ps
, depth
))
368 if (info
->group_membership_ptr
) {
369 if (!pac_io_group_membership_array("group membership",
377 if(!smb_io_unistr2("uni_dom_controller", &info
->uni_dom_controller
,
378 info
->hdr_dom_controller
.buffer
, ps
, depth
))
380 if(!smb_io_unistr2("uni_dom_name", &info
->uni_dom_name
,
381 info
->hdr_dom_name
.buffer
, ps
, depth
))
384 if(info
->ptr_dom_sid
)
385 if(!smb_io_dom_sid2("dom_sid", &info
->dom_sid
, ps
, depth
))
389 if (info
->sid_count
&& info
->ptr_extra_sids
)
390 if (!pac_io_krb_sid_and_attr_array("extra_sids",
396 if (info
->ptr_res_group_dom_sid
)
397 if (!smb_io_dom_sid2("res_group_dom_sid",
398 &info
->res_group_dom_sid
, ps
, depth
))
401 if (info
->ptr_res_groups
)
402 if (!pac_io_group_membership_array("res group membership",
404 info
->res_group_count
,
412 static BOOL
pac_io_pac_signature_data(const char *desc
,
413 PAC_SIGNATURE_DATA
*data
, uint32 length
,
414 prs_struct
*ps
, int depth
)
416 uint32 siglen
= length
- sizeof(uint32
);
420 prs_debug(ps
, depth
, desc
, "pac_io_pac_signature_data");
423 if (!prs_uint32("type", ps
, depth
, &data
->type
))
425 if (UNMARSHALLING(ps
)) {
426 data
->signature
= (unsigned char *)prs_alloc_mem(ps
, siglen
);
427 if (!data
->signature
) {
428 DEBUG(3, ("No memory available\n"));
432 if (!prs_uint8s(False
, "signature", ps
, depth
, data
->signature
,siglen
))
438 static BOOL
pac_io_pac_info_hdr_ctr(const char *desc
, PAC_INFO_HDR
*hdr
,
439 prs_struct
*ps
, int depth
)
444 prs_debug(ps
, depth
, desc
, "pac_io_pac_info_hdr_ctr");
450 if (hdr
->offset
!= prs_offset(ps
)) {
451 DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
452 hdr
->offset
, prs_offset(ps
)));
453 prs_set_offset(ps
, hdr
->offset
);
456 if (UNMARSHALLING(ps
) && hdr
->size
> 0) {
457 hdr
->ctr
= (PAC_INFO_CTR
*)
458 prs_alloc_mem(ps
, sizeof(PAC_INFO_CTR
));
460 DEBUG(3, ("No memory available\n"));
466 case PAC_TYPE_LOGON_INFO
:
467 DEBUG(5, ("PAC_TYPE_LOGON_INFO\n"));
468 if (UNMARSHALLING(ps
))
469 hdr
->ctr
->pac
.logon_info
= (PAC_LOGON_INFO
*)
470 prs_alloc_mem(ps
, sizeof(PAC_LOGON_INFO
));
471 if (!hdr
->ctr
->pac
.logon_info
) {
472 DEBUG(3, ("No memory available\n"));
475 if (!pac_io_pac_logon_info(desc
, hdr
->ctr
->pac
.logon_info
,
480 case PAC_TYPE_SERVER_CHECKSUM
:
481 DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n"));
482 if (UNMARSHALLING(ps
))
483 hdr
->ctr
->pac
.srv_cksum
= (PAC_SIGNATURE_DATA
*)
484 prs_alloc_mem(ps
, sizeof(PAC_SIGNATURE_DATA
));
485 if (!hdr
->ctr
->pac
.srv_cksum
) {
486 DEBUG(3, ("No memory available\n"));
489 if (!pac_io_pac_signature_data(desc
, hdr
->ctr
->pac
.srv_cksum
,
490 hdr
->size
, ps
, depth
))
494 case PAC_TYPE_PRIVSVR_CHECKSUM
:
495 DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n"));
496 if (UNMARSHALLING(ps
))
497 hdr
->ctr
->pac
.privsrv_cksum
= (PAC_SIGNATURE_DATA
*)
498 prs_alloc_mem(ps
, sizeof(PAC_SIGNATURE_DATA
));
499 if (!hdr
->ctr
->pac
.privsrv_cksum
) {
500 DEBUG(3, ("No memory available\n"));
503 if (!pac_io_pac_signature_data(desc
,
504 hdr
->ctr
->pac
.privsrv_cksum
,
505 hdr
->size
, ps
, depth
))
509 case PAC_TYPE_UNKNOWN_10
:
510 DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n"));
511 if (UNMARSHALLING(ps
))
512 hdr
->ctr
->pac
.type_10
= (UNKNOWN_TYPE_10
*)
513 prs_alloc_mem(ps
, sizeof(UNKNOWN_TYPE_10
));
514 if (!hdr
->ctr
->pac
.type_10
) {
515 DEBUG(3, ("No memory available\n"));
518 if (!pac_io_unknown_type_10(desc
, hdr
->ctr
->pac
.type_10
,
524 /* dont' know, so we need to skip it */
525 DEBUG(3, ("unknown PAC type %d\n", hdr
->type
));
526 prs_set_offset(ps
, prs_offset(ps
) + hdr
->size
);
532 static BOOL
pac_io_pac_info_hdr(const char *desc
, PAC_INFO_HDR
*hdr
,
533 prs_struct
*ps
, int depth
)
538 prs_debug(ps
, depth
, desc
, "pac_io_pac_info_hdr");
543 if (!prs_uint32("type", ps
, depth
, &hdr
->type
))
545 if (!prs_uint32("size", ps
, depth
, &hdr
->size
))
547 if (!prs_uint32("offset", ps
, depth
, &hdr
->offset
))
549 if (!prs_uint32("offsethi", ps
, depth
, &hdr
->offsethi
))
555 static BOOL
pac_io_pac_data(const char *desc
, PAC_DATA
*data
,
556 prs_struct
*ps
, int depth
)
563 prs_debug(ps
, depth
, desc
, "pac_io_pac_data");
568 if (!prs_uint32("num_buffers", ps
, depth
, &data
->num_buffers
))
570 if (!prs_uint32("version", ps
, depth
, &data
->version
))
573 if (UNMARSHALLING(ps
) && data
->num_buffers
> 0) {
574 if ((data
->pac_info_hdr_ptr
= (PAC_INFO_HDR
*)
575 prs_alloc_mem(ps
, sizeof(PAC_INFO_HDR
) *
576 data
->num_buffers
)) == NULL
) {
581 for (i
=0; i
<data
->num_buffers
; i
++) {
582 if (!pac_io_pac_info_hdr(desc
, &data
->pac_info_hdr_ptr
[i
], ps
,
587 for (i
=0; i
<data
->num_buffers
; i
++) {
588 if (!pac_io_pac_info_hdr_ctr(desc
, &data
->pac_info_hdr_ptr
[i
],
596 PAC_DATA
*decode_pac_data(DATA_BLOB
*auth_data
, TALLOC_CTX
*ctx
)
598 DATA_BLOB pac_data_blob
= unwrap_pac(auth_data
);
602 DEBUG(5,("dump_pac_data\n"));
603 prs_init(&ps
, pac_data_blob
.length
, ctx
, UNMARSHALL
);
604 prs_copy_data_in(&ps
, (char *)pac_data_blob
.data
, pac_data_blob
.length
);
605 prs_set_offset(&ps
, 0);
607 data_blob_free(&pac_data_blob
);
609 pac_data
= (PAC_DATA
*) talloc_zero(ctx
, sizeof(PAC_DATA
));
610 pac_io_pac_data("pac data", pac_data
, &ps
, 0);