diff --git a/packet-dcerpc-wkssvc.c b/packet-dcerpc-wkssvc.c index 23e80bb40d..67a55ca3b7 100644 --- a/packet-dcerpc-wkssvc.c +++ b/packet-dcerpc-wkssvc.c @@ -3,7 +3,7 @@ * Copyright 2001, Tim Potter * Copyright 2003, Richard Sharpe * - * $Id: packet-dcerpc-wkssvc.c,v 1.13 2003/04/29 23:28:36 sharpe Exp $ + * $Id: packet-dcerpc-wkssvc.c,v 1.14 2003/04/30 17:32:07 sharpe Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -48,6 +48,13 @@ static int hf_wkssvc_logged_on_users = -1; static int hf_wkssvc_pref_max = -1; static int hf_wkssvc_enum_handle = -1; static int hf_wkssvc_junk = -1; +static int hf_wkssvc_user_name = -1; +static int hf_wkssvc_num_entries = -1; +static int hf_wkssvc_logon_domain = -1; +static int hf_wkssvc_other_domains = -1; +static int hf_wkssvc_logon_server = -1; +static int hf_wkssvc_entries_read = -1; +static int hf_wkssvc_total_entries = -1; static gint ett_dcerpc_wkssvc = -1; extern const value_string platform_id_vals[]; @@ -261,10 +268,160 @@ static int wkssvc_dissect_netwkstagetinfo_reply(tvbuff_t *tvb, int offset, } /* - * IDL long NetWkstaGetInfo( + * IDL typedef struct { + * IDL [string] [unique] wchar_t *dev; + * IDL } USER_INFO_0; + */ +static int +wkssvc_dissect_USER_INFO_0(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep, + NDR_POINTER_UNIQUE, "User Name", + hf_wkssvc_user_name, 0); + + return offset; +} + +static int +wkssvc_dissect_USER_INFO_0_array(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_USER_INFO_0); + + return offset; +} + +/* + * IDL typedef struct { + * IDL long EntriesRead; + * IDL [size_is(EntriesRead)] [unique] USER_INFO_0 *devs; + * IDL } USER_INFO_0_CONTAINER; + */ +static int +wkssvc_dissect_USER_INFO_0_CONTAINER(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, + hf_wkssvc_num_entries, NULL); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_USER_INFO_0_array, NDR_POINTER_UNIQUE, + "USER_INFO_0 array:", -1); + + return offset; +} + +/* + * IDL typedef struct { + * IDL [string] [unique] wchar_t *user_name; + * IDL [string] [unique] wchar_t *logon_domain; + * IDL [string] [unique] wchar_t *other_domains; + * IDL [string] [unique] wchar_t *logon_server; + * IDL } USER_INFO_1; + */ +static int +wkssvc_dissect_USER_INFO_1(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep, + NDR_POINTER_UNIQUE, "User Name", + hf_wkssvc_user_name, 0); + + offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep, + NDR_POINTER_UNIQUE, "Logon Domain", + hf_wkssvc_logon_domain, 0); + + offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep, + NDR_POINTER_UNIQUE, "Other Domains", + hf_wkssvc_other_domains, 0); + + offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep, + NDR_POINTER_UNIQUE, "Logon Server", + hf_wkssvc_logon_server, 0); + + + return offset; +} +static int +wkssvc_dissect_USER_INFO_1_array(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_USER_INFO_1); + + return offset; +} + +/* + * IDL typedef struct { + * IDL long EntriesRead; + * IDL [size_is(EntriesRead)] [unique] USER_INFO_1 *devs; + * IDL } USER_INFO_1_CONTAINER; + */ +static int +wkssvc_dissect_USER_INFO_1_CONTAINER(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, + hf_wkssvc_num_entries, NULL); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_USER_INFO_1_array, NDR_POINTER_UNIQUE, + "USER_INFO_1 array:", -1); + + return offset; +} + +/* + * IDL typedef [switch_type(long)] union { + * IDL [case(0)] [unique] USER_INFO_0_CONTAINER *dev0; + * IDL [case(1)] [unique] USER_INFO_1_CONTAINER *dev1; + * IDL } CHARDEV_ENUM_UNION; + */ +static int +wkssvc_dissect_USER_ENUM_UNION(tvbuff_t *tvb, int offset, + packet_info *pinfo, proto_tree *tree, + char *drep) +{ + guint32 level; + + ALIGN_TO_4_BYTES; + + offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_wkssvc_info_level, &level); + + switch(level){ + case 0: + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_USER_INFO_0_CONTAINER, + NDR_POINTER_UNIQUE, "USER_INFO_0_CONTAINER:", -1); + break; + case 1: + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_USER_INFO_1_CONTAINER, + NDR_POINTER_UNIQUE, "USER_INFO_1_CONTAINER:", -1); + break; + } + + return offset; +} + +/* + * IDL long NetWkstaEnumUsers( * IDL [in] [string] [unique] wchar_t *ServerName, * IDL [in] long level, - * IDL [out] [ref] WKS_INFO_UNION *wks + * IDL [in] [out] [ref] WKS_USER_ENUM_STRUCT *users, + * IDL [in] long prefmaxlen, + * IDL [out] long *entriesread, + * IDL [out] long *totalentries, + * IDL [in] [out] [ref] *resumehandle * IDL ); */ static int @@ -306,12 +463,25 @@ static int wkssvc_dissect_netwkstaenumusers_reply(tvbuff_t *tvb, int offset, proto_tree *tree, char *drep) { - /* offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, - wkssvc_dissect_WKS_GETINFO_UNION, - NDR_POINTER_REF, "Server Info", -1); + /* There seems to be an info level there first */ + offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, + hf_wkssvc_info_level, 0); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_USER_ENUM_UNION, + NDR_POINTER_REF, "User Info", -1); + + /* Entries read seems to be in the enum array ... */ + + offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, + hf_wkssvc_total_entries, 0); + + offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep, + wkssvc_dissect_ENUM_HANDLE, + NDR_POINTER_UNIQUE, "Enum Handle", -1); offset = dissect_doserror(tvb, offset, pinfo, tree, drep, - hf_wkssvc_rc, NULL);*/ + hf_wkssvc_rc, NULL); return offset; } @@ -363,9 +533,30 @@ proto_register_dcerpc_wkssvc(void) { &hf_wkssvc_enum_handle, { "Enumeration handle", "wkssvc.enum_hnd", FT_BYTES, BASE_HEX, NULL, 0x0, "Enumeration Handle", HFILL}}, + { &hf_wkssvc_user_name, + { "User Name", "wkssvc.user.name", FT_STRING, BASE_NONE, + NULL, 0x0, "User Name", HFILL}}, + { &hf_wkssvc_logon_domain, + { "Logon Domain", "wkssvc.logon.domain", FT_STRING, BASE_NONE, + NULL, 0x0, "Logon Domain", HFILL}}, + { &hf_wkssvc_other_domains, + { "Other Domains", "wkssvc.other.domains", FT_STRING, BASE_NONE, + NULL, 0x0, "Other Domains", HFILL}}, + { &hf_wkssvc_logon_server, + { "Logon Server", "wkssvc.logon.server", FT_STRING, BASE_NONE, + NULL, 0x0, "Logon Server", HFILL}}, { &hf_wkssvc_rc, { "Return code", "srvsvc.rc", FT_UINT32, BASE_HEX, VALS(DOS_errors), 0x0, "Return Code", HFILL}}, + { &hf_wkssvc_num_entries, + { "Num Entries", "wkssvc.num.entries", FT_INT32, + BASE_DEC, NULL, 0x0, "Num Entries", HFILL}}, + { &hf_wkssvc_entries_read, + { "Entries Read", "wkssvc.entries.read", FT_INT32, + BASE_DEC, NULL, 0x0, "Entries Read", HFILL}}, + { &hf_wkssvc_total_entries, + { "Total Entries", "wkssvc.total.entries", FT_INT32, + BASE_DEC, NULL, 0x0, "Total Entries", HFILL}}, }; static gint *ett[] = {