From 1f04eb2e2617ac05974c21bdac9ebb4781b5a9d9 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 9 Apr 2003 16:48:59 +0000 Subject: Complete what I've seen (and then some)t of the PAC. I haven't seen the rid+attr arrays for group membership, nor sids or the same kind of arrays for resource domains, so I don't know how that will work. Also, the PAC info type 10 is now decoded, but I don't know what it's for. It has an NTTIME, a 16-bit name length, and a username. According to M$, it's not needed, because they didn't doc it... (This used to be commit 28ab8504cf6c181866106e5cc626a5896283d0a9) --- source3/include/authdata.h | 22 ++++++-- source3/libads/authdata.c | 129 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 141 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/include/authdata.h b/source3/include/authdata.h index 1521185a8f..0798b72bdf 100644 --- a/source3/include/authdata.h +++ b/source3/include/authdata.h @@ -27,6 +27,13 @@ #define PAC_TYPE_LOGON_INFO 1 #define PAC_TYPE_SERVER_CHECKSUM 6 #define PAC_TYPE_PRIVSVR_CHECKSUM 7 +#define PAC_TYPE_UNKNOWN_10 10 + +typedef struct unknown_type_10 { + NTTIME unknown_time; + uint16 len; + uint16 *username; /* might not be null terminated, so not UNISTR */ +} UNKNOWN_TYPE_10; typedef struct pac_signature_data { uint32 type; @@ -38,6 +45,11 @@ typedef struct group_membership { uint32 attrs; } GROUP_MEMBERSHIP; +typedef struct group_membership_array { + uint32 count; + GROUP_MEMBERSHIP *group_membership; +} GROUP_MEMBERSHIP_ARRAY; + typedef struct krb_sid_and_attrs { uint32 sid_ptr; uint32 attrs; @@ -93,7 +105,7 @@ typedef struct pac_logon_info { uint32 ptr_res_group_dom_sid; uint32 res_group_count; - uint32 ptr_res_group_sids; + uint32 ptr_res_groups; UNISTR2 uni_user_name; /* user name unicode string header */ UNISTR2 uni_full_name; /* user's full name unicode string header */ @@ -104,12 +116,11 @@ typedef struct pac_logon_info { UNISTR2 uni_dom_controller; UNISTR2 uni_dom_name; DOM_SID2 dom_sid; - /* group membership array needs to go in here. - I've not seen it on the wire */ + GROUP_MEMBERSHIP_ARRAY groups; KRB_SID_AND_ATTR_ARRAY extra_sids; DOM_SID2 res_group_dom_sid; - /* resource group membership array needs to go in here */ - + GROUP_MEMBERSHIP_ARRAY res_groups; + } PAC_LOGON_INFO; typedef struct pac_info_ctr @@ -119,6 +130,7 @@ typedef struct pac_info_ctr PAC_LOGON_INFO *logon_info; PAC_SIGNATURE_DATA *srv_cksum; PAC_SIGNATURE_DATA *privsrv_cksum; + UNKNOWN_TYPE_10 *type_10; } pac; } PAC_INFO_CTR; diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 3d25aec205..c554a02e90 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -42,6 +42,38 @@ static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) return pac_contents; } +static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10, + prs_struct *ps, int depth) +{ + if (NULL == type_10) + return False; + + prs_debug(ps, depth, desc, "pac_io_unknown_type_10"); + depth++; + + if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth)) + return False; + + if (!prs_uint16("len", ps, depth, &type_10->len)) + return False; + + if (UNMARSHALLING(ps) && type_10->len) { + type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len); + if (!type_10->username) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if (!prs_uint16s(True, "name", ps, depth, type_10->username, + (type_10->len / sizeof(uint16)))) + return False; + + return True; + +} + + static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, prs_struct *ps, int depth) { @@ -129,6 +161,63 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc, } +static BOOL pac_io_group_membership(const char *desc, + GROUP_MEMBERSHIP *membership, + prs_struct *ps, int depth) +{ + if (NULL == membership) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership"); + depth++; + + if (!prs_uint32("rid", ps, depth, &membership->rid)) + return False; + if (!prs_uint32("attrs", ps, depth, &membership->attrs)) + return False; + + return True; +} + + +static BOOL pac_io_group_membership_array(const char *desc, + GROUP_MEMBERSHIP_ARRAY *array, + uint32 num, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == array) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership_array"); + depth++; + + + if (!prs_uint32("count", ps, depth, &array->count)) + return False; + + if (UNMARSHALLING(ps)) { + array->group_membership = (GROUP_MEMBERSHIP *) + prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num); + if (!array->group_membership) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + for (i=0; igroup_membership[i], + ps, depth)) + return False; + + } + + return True; + +} + static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { @@ -253,8 +342,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, return False; if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) return False; - if (!prs_uint32("ptr_res_group_sids", ps, depth, - &info->ptr_res_group_sids)) + if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups)) return False; if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, @@ -276,7 +364,14 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, info->hdr_dir_drive.buffer, ps, depth)) return False; - /* the group membership list will need to be handled here */ + if (info->group_membership_ptr) { + if (!pac_io_group_membership_array("group membership", + &info->groups, + info->group_count, + ps, depth)) + return False; + } + if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, info->hdr_dom_controller.buffer, ps, depth)) @@ -290,14 +385,24 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, return False; - if (info->sid_count && info->ptr_extra_sids) { + if (info->sid_count && info->ptr_extra_sids) if (!pac_io_krb_sid_and_attr_array("extra_sids", &info->extra_sids, info->sid_count, ps, depth)) return False; - } + if (info->ptr_res_group_dom_sid) + if (!smb_io_dom_sid2("res_group_dom_sid", + &info->res_group_dom_sid, ps, depth)) + return False; + + if (info->ptr_res_groups) + if (!pac_io_group_membership_array("res group membership", + &info->res_groups, + info->res_group_count, + ps, depth)) + return False; return True; } @@ -400,6 +505,20 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, return False; break; + case PAC_TYPE_UNKNOWN_10: + DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *) + prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10)); + if (!hdr->ctr->pac.type_10) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10, + ps, depth)) + return False; + break; + default: /* dont' know, so we need to skip it */ DEBUG(3, ("unknown PAC type %d\n", hdr->type)); -- cgit