1 /* packet-dcerpc-netlogon.c
2  * Routines for SMB \PIPE\NETLOGON packet disassembly
3  * Copyright 2001,2003 Tim Potter <tpot@samba.org>
4  *  2002 structure and command dissectors by Ronnie Sahlberg
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 #include "config.h"
14 
15 
16 #include <epan/packet.h>
17 #include <epan/expert.h>
18 #include <wsutil/wsgcrypt.h>
19 #include <wsutil/wslog.h>
20 
21 /* for dissect_mscldap_string */
22 #include "packet-ldap.h"
23 #include "packet-dcerpc.h"
24 #include "packet-dcerpc-nt.h"
25 #include "packet-dcerpc-netlogon.h"
26 #include "packet-windows-common.h"
27 #include "packet-dcerpc-lsa.h"
28 #include "packet-ntlmssp.h"
29 /* for keytab format */
30 #include <epan/asn1.h>
31 #include "packet-kerberos.h"
32 /* for routines to read the keytab file */
33 #include "read_keytab_file.h"
34 /* for decoding */
35 
36 void proto_register_dcerpc_netlogon(void);
37 void proto_reg_handoff_dcerpc_netlogon(void);
38 
39 #ifdef DEBUG_NETLOGON
40 #include <stdio.h>
41 #define debugprintf(...) fprintf(stderr,__VA_ARGS__)
printnbyte(const guint8 * tab,int nb,const char * txt,const char * txt2)42 static void printnbyte(const guint8* tab,int nb,const char* txt,const char* txt2)
43 {
44     int i=0;
45     debugprintf("%s ",txt);
46     for(i=0;i<nb;i++)
47     {
48         debugprintf("%02X ",*(tab+i));
49     }
50     debugprintf("%s",txt2);
51 }
52 #else
53 #define debugprintf(...)
printnbyte(const guint8 * tab _U_,int nb _U_,const char * txt _U_,const char * txt2 _U_)54 static void printnbyte(const guint8* tab _U_,int nb _U_,const char* txt _U_,const char* txt2 _U_) {}
55 #endif
56 
57 #define NETLOGON_FLAG_80000000 0x80000000
58 #define NETLOGON_FLAG_40000000 0x40000000
59 #define NETLOGON_FLAG_20000000 0x20000000
60 #define NETLOGON_FLAG_10000000 0x10000000
61 #define NETLOGON_FLAG_8000000   0x8000000
62 #define NETLOGON_FLAG_4000000   0x4000000
63 #define NETLOGON_FLAG_2000000   0x2000000
64 #define NETLOGON_FLAG_AES       0x1000000
65 #define NETLOGON_FLAG_800000     0x800000
66 #define NETLOGON_FLAG_400000     0x400000
67 #define NETLOGON_FLAG_200000     0x200000
68 #define NETLOGON_FLAG_100000     0x100000
69 #define NETLOGON_FLAG_80000       0x80000
70 #define NETLOGON_FLAG_40000       0x40000
71 #define NETLOGON_FLAG_20000       0x20000
72 #define NETLOGON_FLAG_10000       0x10000
73 #define NETLOGON_FLAG_8000         0x8000
74 #define NETLOGON_FLAG_STRONGKEY    0x4000
75 #define NETLOGON_FLAG_2000         0x2000
76 #define NETLOGON_FLAG_1000         0x1000
77 #define NETLOGON_FLAG_800           0x800
78 #define NETLOGON_FLAG_400           0x400
79 #define NETLOGON_FLAG_200           0x200
80 #define NETLOGON_FLAG_100           0x100
81 #define NETLOGON_FLAG_80             0x80
82 #define NETLOGON_FLAG_40             0x40
83 #define NETLOGON_FLAG_20             0x20
84 #define NETLOGON_FLAG_10             0x10
85 #define NETLOGON_FLAG_8               0x8
86 #define NETLOGON_FLAG_4               0x4
87 #define NETLOGON_FLAG_2               0x2
88 #define NETLOGON_FLAG_1               0x1
89 
90 static wmem_map_t *netlogon_auths=NULL;
91 #if 0
92 static wmem_map_t *schannel_auths;
93 #endif
94 static gint hf_netlogon_TrustedDomainName_string = -1;
95 static gint hf_netlogon_UserName_string = -1;
96 static gint DomainInfo_sid = -1;
97 static gint DnsDomainInfo_sid = -1;
98 static gint DnsDomainInfo_domain_guid = -1;
99 static gint DnsDomainInfo_dns_domain = -1;
100 static gint DnsDomainInfo_dns_forest = -1;
101 static gint DnsDomainInfo_name = -1;
102 static int hf_client_challenge = -1;
103 static int hf_server_rid = -1;
104 static int hf_server_challenge = -1;
105 static int hf_client_credential = -1;
106 static int hf_server_credential = -1;
107 static int proto_dcerpc_netlogon = -1;
108 static int hf_netlogon_logon_dnslogondomainname = -1;
109 static int hf_netlogon_logon_upn = -1;
110 static int hf_netlogon_group_attrs_mandatory = -1;
111 static int hf_netlogon_group_attrs_enabled_by_default = -1;
112 static int hf_netlogon_group_attrs_enabled = -1;
113 static int hf_netlogon_opnum = -1;
114 static int hf_netlogon_data_length = -1;
115 static int hf_netlogon_extraflags = -1;
116 static int hf_netlogon_extra_flags_root_forest = -1;
117 static int hf_netlogon_trust_flags_dc_firsthop = -1;
118 static int hf_netlogon_trust_flags_rodc_to_dc = -1;
119 static int hf_netlogon_trust_flags_rodc_ntlm = -1;
120 static int hf_netlogon_package_name = -1;
121 static int hf_netlogon_rc = -1;
122 static int hf_netlogon_dos_rc = -1;
123 static int hf_netlogon_werr_rc = -1;
124 static int hf_netlogon_len = -1;
125 static int hf_netlogon_sensitive_data_flag = -1;
126 static int hf_netlogon_sensitive_data_len = -1;
127 static int hf_netlogon_sensitive_data = -1;
128 static int hf_netlogon_security_information = -1;
129 static int hf_netlogon_dummy = -1;
130 static int hf_netlogon_neg_flags = -1;
131 /* static int hf_netlogon_neg_flags_80000000 = -1; */
132 static int hf_netlogon_neg_flags_40000000 = -1;
133 static int hf_netlogon_neg_flags_20000000 = -1;
134 /* static int hf_netlogon_neg_flags_10000000 = -1; */
135 /* static int hf_netlogon_neg_flags_8000000 = -1; */
136 /* static int hf_netlogon_neg_flags_4000000 = -1; */
137 /* static int hf_netlogon_neg_flags_2000000 = -1; */
138 static int hf_netlogon_neg_flags_1000000 = -1;
139 /* static int hf_netlogon_neg_flags_800000 = -1; */
140 /* static int hf_netlogon_neg_flags_400000 = -1; */
141 static int hf_netlogon_neg_flags_200000 = -1;
142 static int hf_netlogon_neg_flags_100000 = -1;
143 static int hf_netlogon_neg_flags_80000 = -1;
144 static int hf_netlogon_neg_flags_40000 = -1;
145 static int hf_netlogon_neg_flags_20000 = -1;
146 static int hf_netlogon_neg_flags_10000 = -1;
147 static int hf_netlogon_neg_flags_8000 = -1;
148 static int hf_netlogon_neg_flags_4000 = -1;
149 static int hf_netlogon_neg_flags_2000 = -1;
150 static int hf_netlogon_neg_flags_1000 = -1;
151 static int hf_netlogon_neg_flags_800 = -1;
152 static int hf_netlogon_neg_flags_400 = -1;
153 static int hf_netlogon_neg_flags_200 = -1;
154 static int hf_netlogon_neg_flags_100 = -1;
155 static int hf_netlogon_neg_flags_80 = -1;
156 static int hf_netlogon_neg_flags_40 = -1;
157 static int hf_netlogon_neg_flags_20 = -1;
158 static int hf_netlogon_neg_flags_10 = -1;
159 static int hf_netlogon_neg_flags_8 = -1;
160 static int hf_netlogon_neg_flags_4 = -1;
161 static int hf_netlogon_neg_flags_2 = -1;
162 static int hf_netlogon_neg_flags_1 = -1;
163 static int hf_netlogon_minworkingsetsize = -1;
164 static int hf_netlogon_maxworkingsetsize = -1;
165 static int hf_netlogon_pagedpoollimit = -1;
166 static int hf_netlogon_pagefilelimit = -1;
167 static int hf_netlogon_timelimit = -1;
168 static int hf_netlogon_nonpagedpoollimit = -1;
169 /* static int hf_netlogon_pac_size = -1; */
170 /* static int hf_netlogon_pac_data = -1; */
171 /* static int hf_netlogon_auth_size = -1; */
172 /* static int hf_netlogon_auth_data = -1; */
173 static int hf_netlogon_cipher_len = -1;
174 static int hf_netlogon_cipher_maxlen = -1;
175 static int hf_netlogon_cipher_current_data = -1;
176 static int hf_netlogon_cipher_current_set_time = -1;
177 static int hf_netlogon_cipher_old_data = -1;
178 static int hf_netlogon_cipher_old_set_time = -1;
179 static int hf_netlogon_priv = -1;
180 static int hf_netlogon_privilege_entries = -1;
181 static int hf_netlogon_privilege_control = -1;
182 static int hf_netlogon_privilege_name = -1;
183 static int hf_netlogon_systemflags = -1;
184 static int hf_netlogon_pdc_connection_status = -1;
185 static int hf_netlogon_tc_connection_status = -1;
186 static int hf_netlogon_restart_state = -1;
187 static int hf_netlogon_attrs = -1;
188 static int hf_netlogon_lsapolicy_len = -1;
189 /* static int hf_netlogon_lsapolicy_referentid = -1; */
190 /* static int hf_netlogon_lsapolicy_pointer = -1; */
191 static int hf_netlogon_count = -1;
192 static int hf_netlogon_entries = -1;
193 static int hf_netlogon_minpasswdlen = -1;
194 static int hf_netlogon_passwdhistorylen = -1;
195 static int hf_netlogon_level16 = -1;
196 static int hf_netlogon_validation_level = -1;
197 static int hf_netlogon_reference = -1;
198 static int hf_netlogon_next_reference = -1;
199 static int hf_netlogon_timestamp = -1;
200 static int hf_netlogon_level = -1;
201 static int hf_netlogon_challenge = -1;
202 static int hf_netlogon_reserved = -1;
203 static int hf_netlogon_audit_retention_period = -1;
204 static int hf_netlogon_auditing_mode = -1;
205 static int hf_netlogon_max_audit_event_count = -1;
206 static int hf_netlogon_event_audit_option = -1;
207 static int hf_netlogon_unknown_string = -1;
208 static int hf_netlogon_trust_extension = -1;
209 static int hf_netlogon_trust_max = -1;
210 static int hf_netlogon_trust_offset = -1;
211 static int hf_netlogon_trust_len = -1;
212 static int hf_netlogon_dummy_string = -1;
213 static int hf_netlogon_dummy_string2 = -1;
214 static int hf_netlogon_dummy_string3 = -1;
215 static int hf_netlogon_dummy_string4 = -1;
216 static int hf_netlogon_dummy_string5 = -1;
217 static int hf_netlogon_dummy_string6 = -1;
218 static int hf_netlogon_dummy_string7 = -1;
219 static int hf_netlogon_dummy_string8 = -1;
220 static int hf_netlogon_dummy_string9 = -1;
221 static int hf_netlogon_dummy_string10 = -1;
222 static int hf_netlogon_unknown_short = -1;
223 static int hf_netlogon_unknown_long = -1;
224 static int hf_netlogon_dummy1_long = -1;
225 static int hf_netlogon_dummy2_long = -1;
226 static int hf_netlogon_dummy3_long = -1;
227 static int hf_netlogon_dummy4_long = -1;
228 static int hf_netlogon_dummy5_long = -1;
229 static int hf_netlogon_dummy6_long = -1;
230 static int hf_netlogon_dummy7_long = -1;
231 static int hf_netlogon_dummy8_long = -1;
232 static int hf_netlogon_dummy9_long = -1;
233 static int hf_netlogon_dummy10_long = -1;
234 static int hf_netlogon_unknown_char = -1;
235 static int hf_netlogon_logon_time = -1;
236 static int hf_netlogon_logoff_time = -1;
237 static int hf_netlogon_last_logoff_time = -1;
238 static int hf_netlogon_kickoff_time = -1;
239 static int hf_netlogon_pwd_age = -1;
240 static int hf_netlogon_pwd_last_set_time = -1;
241 static int hf_netlogon_pwd_can_change_time = -1;
242 static int hf_netlogon_pwd_must_change_time = -1;
243 static int hf_netlogon_nt_chal_resp = -1;
244 static int hf_netlogon_lm_chal_resp = -1;
245 static int hf_netlogon_credential = -1;
246 static int hf_netlogon_acct_name = -1;
247 static int hf_netlogon_acct_desc = -1;
248 static int hf_netlogon_group_desc = -1;
249 static int hf_netlogon_full_name = -1;
250 static int hf_netlogon_comment = -1;
251 static int hf_netlogon_parameters = -1;
252 static int hf_netlogon_logon_script = -1;
253 static int hf_netlogon_profile_path = -1;
254 static int hf_netlogon_home_dir = -1;
255 static int hf_netlogon_dir_drive = -1;
256 static int hf_netlogon_logon_count = -1;
257 static int hf_netlogon_logon_count16 = -1;
258 static int hf_netlogon_bad_pw_count = -1;
259 static int hf_netlogon_bad_pw_count16 = -1;
260 static int hf_netlogon_user_rid = -1;
261 static int hf_netlogon_alias_rid = -1;
262 static int hf_netlogon_group_rid = -1;
263 static int hf_netlogon_logon_srv = -1;
264 /* static int hf_netlogon_principal = -1; */
265 static int hf_netlogon_logon_dom = -1;
266 static int hf_netlogon_resourcegroupcount = -1;
267 static int hf_netlogon_accountdomaingroupcount = -1;
268 static int hf_netlogon_domaingroupcount = -1;
269 static int hf_netlogon_membership_domains_count = -1;
270 static int hf_netlogon_downlevel_domain_name = -1;
271 static int hf_netlogon_dns_domain_name = -1;
272 static int hf_netlogon_ad_client_dns_name = -1;
273 static int hf_netlogon_domain_name = -1;
274 static int hf_netlogon_domain_create_time = -1;
275 static int hf_netlogon_domain_modify_time = -1;
276 static int hf_netlogon_modify_count = -1;
277 static int hf_netlogon_db_modify_time = -1;
278 static int hf_netlogon_db_create_time = -1;
279 static int hf_netlogon_oem_info = -1;
280 static int hf_netlogon_serial_number = -1;
281 static int hf_netlogon_num_rids = -1;
282 static int hf_netlogon_num_trusts = -1;
283 static int hf_netlogon_num_controllers = -1;
284 static int hf_netlogon_num_sid = -1;
285 static int hf_netlogon_computer_name = -1;
286 static int hf_netlogon_site_name = -1;
287 static int hf_netlogon_trusted_dc_name = -1;
288 static int hf_netlogon_dc_name = -1;
289 static int hf_netlogon_dc_site_name = -1;
290 static int hf_netlogon_dns_forest_name = -1;
291 static int hf_netlogon_dc_address = -1;
292 static int hf_netlogon_dc_address_type = -1;
293 static int hf_netlogon_client_site_name = -1;
294 static int hf_netlogon_workstation = -1;
295 static int hf_netlogon_workstation_site_name = -1;
296 static int hf_netlogon_os_version = -1;
297 static int hf_netlogon_workstation_os = -1;
298 static int hf_netlogon_workstation_flags = -1;
299 static int hf_netlogon_supportedenctypes = -1;
300 
301 static int hf_netlogon_workstations = -1;
302 static int hf_netlogon_workstation_fqdn = -1;
303 static int hf_netlogon_group_name = -1;
304 static int hf_netlogon_alias_name = -1;
305 static int hf_netlogon_country = -1;
306 static int hf_netlogon_codepage = -1;
307 static int hf_netlogon_flags = -1;
308 static int hf_netlogon_trust_attribs = -1;
309 static int hf_netlogon_trust_attribs_non_transitive = -1;
310 static int hf_netlogon_trust_attribs_uplevel_only = -1;
311 static int hf_netlogon_trust_attribs_quarantined_domain = -1;
312 static int hf_netlogon_trust_attribs_forest_transitive = -1;
313 static int hf_netlogon_trust_attribs_cross_organization = -1;
314 static int hf_netlogon_trust_attribs_within_forest = -1;
315 static int hf_netlogon_trust_attribs_treat_as_external = -1;
316 static int hf_netlogon_trust_type = -1;
317 static int hf_netlogon_trust_flags = -1;
318 static int hf_netlogon_trust_flags_inbound = -1;
319 static int hf_netlogon_trust_flags_outbound = -1;
320 static int hf_netlogon_trust_flags_in_forest = -1;
321 static int hf_netlogon_trust_flags_native_mode = -1;
322 static int hf_netlogon_trust_flags_primary = -1;
323 static int hf_netlogon_trust_flags_tree_root = -1;
324 static int hf_netlogon_trust_parent_index = -1;
325 static int hf_netlogon_user_account_control = -1;
326 static int hf_netlogon_user_account_control_dont_require_preauth = -1;
327 static int hf_netlogon_user_account_control_use_des_key_only = -1;
328 static int hf_netlogon_user_account_control_not_delegated = -1;
329 static int hf_netlogon_user_account_control_trusted_for_delegation = -1;
330 static int hf_netlogon_user_account_control_smartcard_required = -1;
331 static int hf_netlogon_user_account_control_encrypted_text_password_allowed = -1;
332 static int hf_netlogon_user_account_control_account_auto_locked = -1;
333 static int hf_netlogon_user_account_control_dont_expire_password = -1;
334 static int hf_netlogon_user_account_control_server_trust_account = -1;
335 static int hf_netlogon_user_account_control_workstation_trust_account = -1;
336 static int hf_netlogon_user_account_control_interdomain_trust_account = -1;
337 static int hf_netlogon_user_account_control_mns_logon_account = -1;
338 static int hf_netlogon_user_account_control_normal_account = -1;
339 static int hf_netlogon_user_account_control_temp_duplicate_account = -1;
340 static int hf_netlogon_user_account_control_password_not_required = -1;
341 static int hf_netlogon_user_account_control_home_directory_required = -1;
342 static int hf_netlogon_user_account_control_account_disabled = -1;
343 static int hf_netlogon_user_flags = -1;
344 static int hf_netlogon_user_flags_extra_sids = -1;
345 static int hf_netlogon_user_flags_resource_groups = -1;
346 static int hf_netlogon_auth_flags = -1;
347 static int hf_netlogon_pwd_expired = -1;
348 static int hf_netlogon_nt_pwd_present = -1;
349 static int hf_netlogon_lm_pwd_present = -1;
350 static int hf_netlogon_code = -1;
351 static int hf_netlogon_database_id = -1;
352 static int hf_netlogon_sync_context = -1;
353 static int hf_netlogon_max_size = -1;
354 static int hf_netlogon_max_log_size = -1;
355 static int hf_netlogon_dns_host = -1;
356 static int hf_netlogon_acct_expiry_time = -1;
357 static int hf_netlogon_encrypted_lm_owf_password = -1;
358 static int hf_netlogon_lm_owf_password = -1;
359 static int hf_netlogon_nt_owf_password = -1;
360 static int hf_netlogon_param_ctrl = -1;
361 static int hf_netlogon_logon_id = -1;
362 static int hf_netlogon_num_deltas = -1;
363 static int hf_netlogon_user_session_key = -1;
364 static int hf_netlogon_blob_size = -1;
365 static int hf_netlogon_blob = -1;
366 static int hf_netlogon_logon_attempts = -1;
367 static int hf_netlogon_authoritative = -1;
368 static int hf_netlogon_secure_channel_type = -1;
369 static int hf_netlogon_logonsrv_handle = -1;
370 static int hf_netlogon_delta_type = -1;
371 static int hf_netlogon_get_dcname_request_flags = -1;
372 static int hf_netlogon_get_dcname_request_flags_force_rediscovery = -1;
373 static int hf_netlogon_get_dcname_request_flags_directory_service_required = -1;
374 static int hf_netlogon_get_dcname_request_flags_directory_service_preferred = -1;
375 static int hf_netlogon_get_dcname_request_flags_gc_server_required = -1;
376 static int hf_netlogon_get_dcname_request_flags_pdc_required = -1;
377 static int hf_netlogon_get_dcname_request_flags_background_only = -1;
378 static int hf_netlogon_get_dcname_request_flags_ip_required = -1;
379 static int hf_netlogon_get_dcname_request_flags_kdc_required = -1;
380 static int hf_netlogon_get_dcname_request_flags_timeserv_required = -1;
381 static int hf_netlogon_get_dcname_request_flags_writable_required = -1;
382 static int hf_netlogon_get_dcname_request_flags_good_timeserv_preferred = -1;
383 static int hf_netlogon_get_dcname_request_flags_avoid_self = -1;
384 static int hf_netlogon_get_dcname_request_flags_only_ldap_needed = -1;
385 static int hf_netlogon_get_dcname_request_flags_is_flat_name = -1;
386 static int hf_netlogon_get_dcname_request_flags_is_dns_name = -1;
387 static int hf_netlogon_get_dcname_request_flags_return_dns_name = -1;
388 static int hf_netlogon_get_dcname_request_flags_return_flat_name = -1;
389 static int hf_netlogon_dc_flags = -1;
390 static int hf_netlogon_dc_flags_pdc_flag = -1;
391 static int hf_netlogon_dc_flags_gc_flag = -1;
392 static int hf_netlogon_dc_flags_ldap_flag = -1;
393 static int hf_netlogon_dc_flags_ds_flag = -1;
394 static int hf_netlogon_dc_flags_kdc_flag = -1;
395 static int hf_netlogon_dc_flags_timeserv_flag = -1;
396 static int hf_netlogon_dc_flags_closest_flag = -1;
397 static int hf_netlogon_dc_flags_writable_flag = -1;
398 static int hf_netlogon_dc_flags_good_timeserv_flag = -1;
399 static int hf_netlogon_dc_flags_ndnc_flag = -1;
400 static int hf_netlogon_dc_flags_dns_controller_flag = -1;
401 static int hf_netlogon_dc_flags_dns_domain_flag = -1;
402 static int hf_netlogon_dc_flags_dns_forest_flag = -1;
403 /* static int hf_netlogon_dnsdomaininfo = -1; */
404 static int hf_netlogon_s4u2proxytarget = -1;
405 static int hf_netlogon_transitedlistsize = -1;
406 static int hf_netlogon_transited_service = -1;
407 static int hf_netlogon_logon_duration = -1;
408 static int hf_netlogon_time_created = -1;
409 
410 static gint ett_nt_counted_longs_as_string = -1;
411 static gint ett_dcerpc_netlogon = -1;
412 static gint ett_group_attrs = -1;
413 static gint ett_user_flags = -1;
414 static gint ett_user_account_control = -1;
415 static gint ett_QUOTA_LIMITS = -1;
416 static gint ett_IDENTITY_INFO = -1;
417 static gint ett_DELTA_ENUM = -1;
418 static gint ett_authenticate_flags = -1;
419 static gint ett_CYPHER_VALUE = -1;
420 static gint ett_UNICODE_MULTI = -1;
421 static gint ett_DOMAIN_CONTROLLER_INFO = -1;
422 static gint ett_UNICODE_STRING_512 = -1;
423 static gint ett_TYPE_50 = -1;
424 static gint ett_TYPE_52 = -1;
425 static gint ett_DELTA_ID_UNION = -1;
426 static gint ett_TYPE_44 = -1;
427 static gint ett_DELTA_UNION = -1;
428 static gint ett_LM_OWF_PASSWORD = -1;
429 static gint ett_NT_OWF_PASSWORD = -1;
430 static gint ett_GROUP_MEMBERSHIP = -1;
431 static gint ett_BLOB = -1;
432 static gint ett_DS_DOMAIN_TRUSTS = -1;
433 static gint ett_LSA_POLICY_INFO = -1;
434 static gint ett_DOMAIN_TRUST_INFO = -1;
435 static gint ett_trust_flags = -1;
436 static gint ett_trust_attribs = -1;
437 static gint ett_get_dcname_request_flags = -1;
438 static gint ett_dc_flags = -1;
439 static gint ett_wstr_LOGON_IDENTITY_INFO_string = -1;
440 static gint ett_domain_group_memberships = -1;
441 static gint ett_domains_group_memberships = -1;
442 
443 static expert_field ei_netlogon_auth_nthash = EI_INIT;
444 static expert_field ei_netlogon_session_key = EI_INIT;
445 
446 typedef struct _netlogon_auth_vars {
447     guint64 client_challenge;
448     guint64 server_challenge;
449     md4_pass nthash;
450     int auth_fd_num;
451     guint8  session_key[16];
452     guint8  encryption_key[16];
453     guint8  sequence[16];
454     guint32 flags;
455     guint64 seq;
456     guint64 confounder;
457     guint8 private_type;
458     gboolean can_decrypt;
459     char* client_name;
460     int start;
461     int next_start;
462     struct _netlogon_auth_vars *next;
463 } netlogon_auth_vars;
464 
465 typedef struct _seen_packet {
466     gboolean isseen;
467     guint32 num;
468 } seen_packet;
469 
470 static seen_packet seen;
471 
472 static e_guid_t uuid_dcerpc_netlogon = {
473     0x12345678, 0x1234, 0xabcd,
474     { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0xcf, 0xfb }
475 };
476 
477 static guint16 ver_dcerpc_netlogon = 1;
478 
dissect_dcerpc_8bytes(tvbuff_t * tvb,gint offset,packet_info * pinfo _U_,proto_tree * tree,guint8 * drep,int hfindex,guint64 * pdata)479 static gint dissect_dcerpc_8bytes (tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
480                                    proto_tree *tree, guint8 *drep,
481                                    int hfindex, guint64 *pdata)
482 {
483     guint64 data;
484 
485     data = ((drep[0] & DREP_LITTLE_ENDIAN)
486             ? tvb_get_letoh64 (tvb, offset)
487             : tvb_get_ntoh64 (tvb, offset));
488 
489     /* These fields are FT_BYTES, hence the byte order doesn't matter */
490     if (tree) {
491         proto_tree_add_item(tree, hfindex, tvb, offset, 8, ENC_NA);
492     }
493     if (pdata)
494         *pdata = data;
495     return offset+8;
496 }
497 
498 static const true_false_string user_account_control_dont_require_preauth= {
499     "This account DOESN'T_REQUIRE_PREAUTHENTICATION",
500     "This account REQUIRES preauthentication",
501 };
502 static const true_false_string user_account_control_use_des_key_only= {
503     "This account must USE_DES_KEY_ONLY for passwords",
504     "This account does NOT have to use_des_key_only",
505 };
506 static const true_false_string user_account_control_not_delegated= {
507     "This account is NOT_DELEGATED",
508     "This might have been delegated",
509 };
510 static const true_false_string user_account_control_trusted_for_delegation= {
511     "This account is TRUSTED_FOR_DELEGATION",
512     "This account is NOT trusted_for_delegation",
513 };
514 static const true_false_string user_account_control_smartcard_required= {
515     "This account REQUIRES_SMARTCARD to authenticate",
516     "This account does NOT require_smartcard to authenticate",
517 };
518 static const true_false_string user_account_control_encrypted_text_password_allowed= {
519     "This account allows ENCRYPTED_TEXT_PASSWORD",
520     "This account does NOT allow encrypted_text_password",
521 };
522 static const true_false_string user_account_control_account_auto_locked= {
523     "This account is AUTO_LOCKED",
524     "This account is NOT auto_locked",
525 };
526 static const true_false_string user_account_control_dont_expire_password= {
527     "This account DOESN'T_EXPIRE_PASSWORDs",
528     "This account might expire_passwords",
529 };
530 static const true_false_string user_account_control_server_trust_account= {
531     "This account is a SERVER_TRUST_ACCOUNT",
532     "This account is NOT a server_trust_account",
533 };
534 static const true_false_string user_account_control_workstation_trust_account= {
535     "This account is a WORKSTATION_TRUST_ACCOUNT",
536     "This account is NOT a workstation_trust_account",
537 };
538 static const true_false_string user_account_control_interdomain_trust_account= {
539     "This account is an INTERDOMAIN_TRUST_ACCOUNT",
540     "This account is NOT an interdomain_trust_account",
541 };
542 static const true_false_string user_account_control_mns_logon_account= {
543     "This account is a MNS_LOGON_ACCOUNT",
544     "This account is NOT a mns_logon_account",
545 };
546 static const true_false_string user_account_control_normal_account= {
547     "This account is a NORMAL_ACCOUNT",
548     "This account is NOT a normal_account",
549 };
550 static const true_false_string user_account_control_temp_duplicate_account= {
551     "This account is a TEMP_DUPLICATE_ACCOUNT",
552     "This account is NOT a temp_duplicate_account",
553 };
554 static const true_false_string user_account_control_password_not_required= {
555     "This account REQUIRES_NO_PASSWORD",
556     "This account REQUIRES a password",
557 };
558 static const true_false_string user_account_control_home_directory_required= {
559     "This account REQUIRES_HOME_DIRECTORY",
560     "This account does NOT require_home_directory",
561 };
562 static const true_false_string user_account_control_account_disabled= {
563     "This account is DISABLED",
564     "This account is NOT disabled",
565 };
566 
567 typedef struct _netlogon_auth_key {
568     /*
569      * For now we only match the client and server ip
570      * addresses, as keys can be used across tcp connections.
571      *
572      * Also note that ServerChallenge and ServerAuthenticate
573      * can be on different tcp connections!
574      *
575      * TODO:
576      * * We could have a challenge table indexed by client, server
577      *   and computer name
578      * * A good ServerAuthenticate could fill a session key table
579      *   indexed by computer name.
580      * * A DCERPC bind/alter context could lookup the session key table
581      *   and copy the session key to the DCERPC connection/auth_context.
582      */
583     address client;
584     address server;
585 } netlogon_auth_key;
586 
587 static gint
netlogon_auth_equal(gconstpointer k1,gconstpointer k2)588 netlogon_auth_equal (gconstpointer k1, gconstpointer k2)
589 {
590     const netlogon_auth_key *key1 = (const netlogon_auth_key *)k1;
591     const netlogon_auth_key *key2 = (const netlogon_auth_key *)k2;
592 
593     return (addresses_equal(&key1->client,&key2->client) && addresses_equal(&key1->server,&key2->server));
594 }
595 
596 static guint
netlogon_auth_hash(gconstpointer k)597 netlogon_auth_hash (gconstpointer k)
598 {
599     const netlogon_auth_key *key1 = (const netlogon_auth_key *)k;
600     guint hash_val1 = 0;
601 
602     hash_val1 = add_address_to_hash(hash_val1, &key1->client);
603     hash_val1 = add_address_to_hash(hash_val1, &key1->server);
604     return hash_val1;
605 }
606 static int
netlogon_dissect_EXTRA_FLAGS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)607 netlogon_dissect_EXTRA_FLAGS(tvbuff_t *tvb, int offset,
608                              packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
609 {
610     guint32 mask;
611     static int * const extraflags[] = {
612         &hf_netlogon_extra_flags_root_forest,
613         &hf_netlogon_trust_flags_dc_firsthop,
614         &hf_netlogon_trust_flags_rodc_to_dc,
615         &hf_netlogon_trust_flags_rodc_ntlm,
616         NULL
617     };
618 
619     if(di->conformant_run){
620         /*just a run to handle conformant arrays, nothing to dissect */
621         return offset;
622     }
623 
624     offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep,
625                               -1, &mask);
626 
627     proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_extraflags, ett_trust_flags, extraflags, mask, BMT_NO_APPEND);
628     return offset;
629 }
630 
631 struct LOGON_INFO_STATE;
632 
633 struct LOGON_INFO_STATE_CB {
634     struct LOGON_INFO_STATE *state;
635     ntlmssp_blob     *response;
636     const guint8     **name_ptr;
637     int              name_levels;
638 };
639 
640 struct LOGON_INFO_STATE {
641     packet_info      *pinfo;
642     proto_tree       *tree;
643     guint8           server_challenge[8];
644     ntlmssp_blob     nt_response;
645     ntlmssp_blob     lm_response;
646     ntlmssp_header_t ntlmssph;
647     struct LOGON_INFO_STATE_CB domain_cb, acct_cb, host_cb, nt_cb, lm_cb;
648 };
649 
dissect_LOGON_INFO_STATE_finish(struct LOGON_INFO_STATE * state)650 static void dissect_LOGON_INFO_STATE_finish(struct LOGON_INFO_STATE *state)
651 {
652     if (state->ntlmssph.acct_name != NULL &&
653         state->nt_response.length >= 24 &&
654         state->lm_response.length >= 24)
655     {
656         if (state->ntlmssph.domain_name == NULL) {
657                 state->ntlmssph.domain_name = "";
658         }
659         if (state->ntlmssph.host_name == NULL) {
660                 state->ntlmssph.host_name = "";
661         }
662 
663         ntlmssp_create_session_key(state->pinfo,
664                                    state->tree,
665                                    &state->ntlmssph,
666                                    0, /* NTLMSSP_ flags */
667                                    state->server_challenge,
668                                    NULL, /* encryptedsessionkey */
669                                    &state->nt_response,
670                                    &state->lm_response);
671     }
672 }
673 
dissect_ndr_lm_nt_byte_array(packet_info * pinfo,proto_tree * tree,proto_item * item _U_,dcerpc_info * di,tvbuff_t * tvb,int start_offset,int end_offset,void * callback_args)674 static void dissect_ndr_lm_nt_byte_array(packet_info *pinfo,
675                                          proto_tree *tree,
676                                          proto_item *item _U_,
677                                          dcerpc_info *di,
678                                          tvbuff_t *tvb,
679                                          int start_offset,
680                                          int end_offset,
681                                          void *callback_args)
682 {
683     struct LOGON_INFO_STATE_CB *cb_ref = (struct LOGON_INFO_STATE_CB *)callback_args;
684     struct LOGON_INFO_STATE *state = NULL;
685     int offset = start_offset;
686     guint64 tmp;
687     guint16 len;
688 
689     if (cb_ref == NULL) {
690         return;
691     }
692     state = cb_ref->state;
693 
694     if (di->conformant_run) {
695         /* just a run to handle conformant arrays, no scalars to dissect */
696         return;
697     }
698 
699     /* NDR array header */
700     ALIGN_TO_5_BYTES
701     if (di->call_data->flags & DCERPC_IS_NDR64) {
702         offset += 3 * 8;
703     } else {
704         offset += 3 * 4;
705     }
706 
707     tmp = end_offset - offset;
708     if (tmp > NTLMSSP_BLOB_MAX_SIZE) {
709         tmp = NTLMSSP_BLOB_MAX_SIZE;
710     }
711     len = (guint16)tmp;
712     cb_ref->response->length = len;
713     cb_ref->response->contents = (guint8 *)tvb_memdup(pinfo->pool, tvb, offset, len);
714     if (len > 24) {
715         dissect_ntlmv2_response(tvb, pinfo, tree, offset, len);
716     }
717 
718     dissect_LOGON_INFO_STATE_finish(state);
719 }
720 
721 static int
dissect_ndr_lm_nt_hash_cb(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_index,dcerpc_callback_fnct_t * callback,void * callback_args)722 dissect_ndr_lm_nt_hash_cb(tvbuff_t *tvb, int offset,
723                           packet_info *pinfo, proto_tree *tree,
724                           dcerpc_info *di, guint8 *drep, int hf_index,
725                           dcerpc_callback_fnct_t *callback,
726                           void *callback_args)
727 {
728     guint16 len, size;
729 
730     /* Structure starts with short, but is aligned for longs */
731 
732     ALIGN_TO_4_BYTES;
733 
734     if (di->conformant_run)
735         return offset;
736 
737 #if 0
738     struct {
739         short len;
740         short size;
741         [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
742     } HASH;
743 
744 #endif
745 
746     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
747                                 hf_nt_cs_len, &len);
748 
749     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
750                                 hf_nt_cs_size, &size);
751 
752     offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, di, drep,
753                                     dissect_ndr_byte_array, NDR_POINTER_UNIQUE,
754                                     "Bytes Array", hf_index, callback, callback_args);
755 
756     return offset;
757 }
758 
759 static int
dissect_ndr_lm_nt_hash_helper(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_index,struct LOGON_INFO_STATE_CB * cb_ref)760 dissect_ndr_lm_nt_hash_helper(tvbuff_t *tvb, int offset,
761                               packet_info *pinfo, proto_tree *tree,
762                               dcerpc_info *di, guint8 *drep, int hf_index,
763                               struct LOGON_INFO_STATE_CB *cb_ref)
764 {
765     proto_tree *subtree;
766 
767     subtree = proto_tree_add_subtree(
768             tree, tvb, offset, 0, ett_LM_OWF_PASSWORD, NULL,
769             proto_registrar_get_name(hf_index));
770 
771     return dissect_ndr_lm_nt_hash_cb(
772         tvb, offset, pinfo, subtree, di, drep, hf_index,
773         dissect_ndr_lm_nt_byte_array, cb_ref);
774 }
775 
776 static int
netlogon_dissect_USER_ACCOUNT_CONTROL(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)777 netlogon_dissect_USER_ACCOUNT_CONTROL(tvbuff_t *tvb, int offset,
778                                       packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
779 {
780     guint32 mask;
781     static int * const uac[] = {
782         &hf_netlogon_user_account_control_dont_require_preauth,
783         &hf_netlogon_user_account_control_use_des_key_only,
784         &hf_netlogon_user_account_control_not_delegated,
785         &hf_netlogon_user_account_control_trusted_for_delegation,
786         &hf_netlogon_user_account_control_smartcard_required,
787         &hf_netlogon_user_account_control_encrypted_text_password_allowed,
788         &hf_netlogon_user_account_control_account_auto_locked,
789         &hf_netlogon_user_account_control_dont_expire_password,
790         &hf_netlogon_user_account_control_server_trust_account,
791         &hf_netlogon_user_account_control_workstation_trust_account,
792         &hf_netlogon_user_account_control_interdomain_trust_account,
793         &hf_netlogon_user_account_control_mns_logon_account,
794         &hf_netlogon_user_account_control_normal_account,
795         &hf_netlogon_user_account_control_temp_duplicate_account,
796         &hf_netlogon_user_account_control_password_not_required,
797         &hf_netlogon_user_account_control_home_directory_required,
798         &hf_netlogon_user_account_control_account_disabled,
799         NULL
800     };
801 
802     if(di->conformant_run){
803         /*just a run to handle conformant arrays, nothing to dissect */
804         return offset;
805     }
806 
807     offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep,
808                               -1, &mask);
809 
810     proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_user_account_control, ett_user_account_control, uac, mask, BMT_NO_APPEND);
811 
812     return offset;
813 }
814 
815 
816 static int
netlogon_dissect_LOGONSRV_HANDLE(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)817 netlogon_dissect_LOGONSRV_HANDLE(tvbuff_t *tvb, int offset,
818                                  packet_info *pinfo, proto_tree *tree,
819                                  dcerpc_info *di, guint8 *drep)
820 {
821     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
822                                           NDR_POINTER_UNIQUE, "Server Handle",
823                                           hf_netlogon_logonsrv_handle, 0);
824 
825     return offset;
826 }
827 
828 /*
829  * IDL typedef struct {
830  * IDL    [unique][string] wchar_t *effective_name;
831  * IDL    long priv;
832  * IDL    long auth_flags;
833  * IDL    long logon_count;
834  * IDL    long bad_pw_count;
835  * IDL    long last_logon;
836  * IDL    long last_logoff;
837  * IDL    long logoff_time;
838  * IDL    long kickoff_time;
839  * IDL    long password_age;
840  * IDL    long pw_can_change;
841  * IDL    long pw_must_change;
842  * IDL    [unique][string] wchar_t *computer;
843  * IDL    [unique][string] wchar_t *domain;
844  * IDL    [unique][string] wchar_t *script_path;
845  * IDL    long reserved;
846  */
847 static int
netlogon_dissect_VALIDATION_UAS_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)848 netlogon_dissect_VALIDATION_UAS_INFO(tvbuff_t *tvb, int offset,
849                                      packet_info *pinfo, proto_tree *tree,
850                                      dcerpc_info *di, guint8 *drep)
851 {
852     if(di->conformant_run){
853         /*just a run to handle conformant arrays, nothing to dissect */
854         return offset;
855     }
856 
857     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
858                                           NDR_POINTER_UNIQUE, "Effective Account",
859                                           hf_netlogon_acct_name, 0);
860 
861     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
862                                 hf_netlogon_priv, NULL);
863 
864     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
865                                 hf_netlogon_auth_flags, NULL);
866 
867     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
868                                 hf_netlogon_logon_count, NULL);
869 
870     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
871                                 hf_netlogon_bad_pw_count, NULL);
872 
873 
874     offset = dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_netlogon_logon_time, NULL);
875 
876     offset = dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_netlogon_last_logoff_time, NULL);
877 
878     offset = dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_netlogon_logoff_time, NULL);
879 
880     offset = dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_netlogon_kickoff_time, NULL);
881 
882     offset = dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_netlogon_pwd_age, NULL);
883 
884     offset = dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_netlogon_pwd_can_change_time, NULL);
885 
886     offset = dissect_ndr_time_t(tvb, offset, pinfo, tree, di, drep, hf_netlogon_pwd_must_change_time, NULL);
887 
888     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
889                                           NDR_POINTER_UNIQUE, "Computer", hf_netlogon_computer_name, 0);
890 
891     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
892                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_domain_name, 0);
893 
894     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
895                                           NDR_POINTER_UNIQUE, "Script", hf_netlogon_logon_script, 0);
896 
897     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
898                                 hf_netlogon_reserved, NULL);
899 
900     return offset;
901 }
902 
903 /*
904  * IDL long NetrLogonUasLogon(
905  * IDL      [in][unique][string] wchar_t *ServerName,
906  * IDL      [in][ref][string] wchar_t *UserName,
907  * IDL      [in][ref][string] wchar_t *Workstation,
908  * IDL      [out][unique] VALIDATION_UAS_INFO *info
909  * IDL );
910  */
911 static int
netlogon_dissect_netrlogonuaslogon_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)912 netlogon_dissect_netrlogonuaslogon_rqst(tvbuff_t *tvb, int offset,
913                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
914 {
915     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
916                                               pinfo, tree, di, drep);
917 
918     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
919                                           NDR_POINTER_REF, "Account", hf_netlogon_acct_name, CB_STR_COL_INFO);
920 
921     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
922                                           NDR_POINTER_REF, "Workstation", hf_netlogon_workstation, 0);
923 
924     return offset;
925 }
926 
927 
928 static int
netlogon_dissect_netrlogonuaslogon_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)929 netlogon_dissect_netrlogonuaslogon_reply(tvbuff_t *tvb, int offset,
930                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
931 {
932     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
933                                  netlogon_dissect_VALIDATION_UAS_INFO, NDR_POINTER_UNIQUE,
934                                  "VALIDATION_UAS_INFO", -1);
935 
936     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
937                               hf_netlogon_dos_rc, NULL);
938 
939     return offset;
940 }
941 
942 /*
943  * IDL typedef struct {
944  * IDL   long duration;
945  * IDL   short logon_count;
946  * IDL } LOGOFF_UAS_INFO;
947  */
948 static int
netlogon_dissect_LOGOFF_UAS_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)949 netlogon_dissect_LOGOFF_UAS_INFO(tvbuff_t *tvb, int offset,
950                                  packet_info *pinfo, proto_tree *tree,
951                                  dcerpc_info *di, guint8 *drep)
952 {
953     guint32 duration;
954 
955     if(di->conformant_run){
956         /*just a run to handle conformant arrays, nothing to dissect */
957         return offset;
958     }
959 
960     duration = tvb_get_guint32(tvb, offset, DREP_ENC_INTEGER(drep));
961     proto_tree_add_uint_format_value(tree, hf_netlogon_logon_duration, tvb, offset, 4, duration, "unknown time format");
962     offset+= 4;
963 
964     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
965                                 hf_netlogon_logon_count16, NULL);
966 
967     return offset;
968 }
969 
970 /*
971  * IDL long NetrLogonUasLogoff(
972  * IDL      [in][unique][string] wchar_t *ServerName,
973  * IDL      [in][ref][string] wchar_t *UserName,
974  * IDL      [in][ref][string] wchar_t *Workstation,
975  * IDL      [out][ref] LOGOFF_UAS_INFO *info
976  * IDL );
977  */
978 static int
netlogon_dissect_netrlogonuaslogoff_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)979 netlogon_dissect_netrlogonuaslogoff_rqst(tvbuff_t *tvb, int offset,
980                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
981 {
982     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
983                                               pinfo, tree, di, drep);
984 
985     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
986                                           NDR_POINTER_REF, "Account", hf_netlogon_acct_name, CB_STR_COL_INFO);
987 
988     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
989                                           NDR_POINTER_REF, "Workstation", hf_netlogon_workstation, 0);
990 
991     return offset;
992 }
993 
994 
995 static int
netlogon_dissect_netrlogonuaslogoff_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)996 netlogon_dissect_netrlogonuaslogoff_reply(tvbuff_t *tvb, int offset,
997                                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
998 {
999     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1000                                  netlogon_dissect_LOGOFF_UAS_INFO, NDR_POINTER_REF,
1001                                  "LOGOFF_UAS_INFO", -1);
1002 
1003     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
1004                               hf_netlogon_dos_rc, NULL);
1005 
1006     return offset;
1007 }
1008 
1009 static int
netlogon_dissect_BYTE_byte(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1010 netlogon_dissect_BYTE_byte(tvbuff_t *tvb, int offset,
1011                            packet_info *pinfo, proto_tree *tree,
1012                            dcerpc_info *di, guint8 *drep)
1013 {
1014     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
1015                                hf_netlogon_unknown_char, NULL);
1016 
1017     return offset;
1018 }
1019 
1020 static int
netlogon_dissect_BYTE_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1021 netlogon_dissect_BYTE_array(tvbuff_t *tvb, int offset,
1022                             packet_info *pinfo, proto_tree *tree,
1023                             dcerpc_info *di, guint8 *drep)
1024 {
1025     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
1026                                  netlogon_dissect_BYTE_byte);
1027 
1028     return offset;
1029 }
1030 
1031 
cb_wstr_LOGON_IDENTITY_INFO(packet_info * pinfo,proto_tree * tree,proto_item * item,dcerpc_info * di,tvbuff_t * tvb,int start_offset,int end_offset,void * callback_args)1032 static void cb_wstr_LOGON_IDENTITY_INFO(packet_info *pinfo, proto_tree *tree,
1033                                         proto_item *item, dcerpc_info *di,
1034                                         tvbuff_t *tvb,
1035                                         int start_offset, int end_offset,
1036                                         void *callback_args)
1037 {
1038     dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
1039     struct LOGON_INFO_STATE_CB *cb_ref =
1040        (struct LOGON_INFO_STATE_CB *)callback_args;
1041     struct LOGON_INFO_STATE *state = cb_ref->state;
1042 
1043     cb_wstr_postprocess(pinfo, tree, item, di, tvb, start_offset, end_offset,
1044                         GINT_TO_POINTER(cb_ref->name_levels));
1045 
1046     if (*cb_ref->name_ptr == NULL) {
1047         *cb_ref->name_ptr = (const guint8 *)dcv->private_data;
1048     }
1049 
1050     dissect_LOGON_INFO_STATE_finish(state);
1051 }
1052 
1053 static int
dissect_ndr_wstr_LOGON_IDENTITY_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_index,int levels,struct LOGON_INFO_STATE_CB * cb_ref)1054 dissect_ndr_wstr_LOGON_IDENTITY_INFO(tvbuff_t *tvb, int offset,
1055                                      packet_info *pinfo, proto_tree *tree,
1056                                      dcerpc_info *di, guint8 *drep,
1057                                      int hf_index, int levels,
1058                                      struct LOGON_INFO_STATE_CB *cb_ref)
1059 {
1060     proto_item *item = NULL;
1061     proto_tree *subtree = NULL;
1062 
1063     if (cb_ref == NULL) {
1064           return dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1065                                             hf_index, levels);
1066     }
1067 
1068     subtree = proto_tree_add_subtree(tree, tvb, offset, 0,
1069                                      ett_wstr_LOGON_IDENTITY_INFO_string, &item,
1070                                      proto_registrar_get_name(hf_index));
1071 
1072     /*
1073      * Add 2 levels, so that the string gets attached to the
1074      * "Character Array" top-level item and to the top-level item
1075      * added above.
1076      */
1077     cb_ref->name_levels = 2 + levels;
1078     cb_ref->name_levels |= CB_STR_SAVE;
1079     return dissect_ndr_counted_string_cb(tvb, offset, pinfo, subtree, di, drep,
1080                                          hf_index, cb_wstr_LOGON_IDENTITY_INFO, cb_ref);
1081 }
1082 
1083 /*
1084  * IDL typedef struct {
1085  * IDL   UNICODESTRING LogonDomainName;
1086  * IDL   long ParameterControl;
1087  * IDL   uint64 LogonID;
1088  * IDL   UNICODESTRING UserName;
1089  * IDL   UNICODESTRING Workstation;
1090  * IDL } LOGON_IDENTITY_INFO;
1091  */
1092 static int
netlogon_dissect_LOGON_IDENTITY_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep,struct LOGON_INFO_STATE * state)1093 netlogon_dissect_LOGON_IDENTITY_INFO(tvbuff_t *tvb, int offset,
1094                                      packet_info *pinfo, proto_tree *parent_tree,
1095                                      dcerpc_info *di, guint8 *drep,
1096                                      struct LOGON_INFO_STATE *state)
1097 {
1098     struct LOGON_INFO_STATE_CB *domain_cb = NULL;
1099     struct LOGON_INFO_STATE_CB *acct_cb = NULL;
1100     struct LOGON_INFO_STATE_CB *host_cb = NULL;
1101     proto_item *item=NULL;
1102     proto_tree *tree=NULL;
1103     int old_offset=offset;
1104 
1105     if (state != NULL) {
1106         domain_cb = &state->domain_cb;
1107         acct_cb = &state->acct_cb;
1108         host_cb = &state->host_cb;
1109     }
1110 
1111     if(parent_tree){
1112         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
1113                                    ett_IDENTITY_INFO, &item, "IDENTITY_INFO:");
1114     }
1115 
1116     /* XXX: It would be nice to get the domain and account name
1117        displayed in COL_INFO. */
1118 
1119     offset = dissect_ndr_wstr_LOGON_IDENTITY_INFO(tvb, offset, pinfo, tree, di, drep,
1120                                                   hf_netlogon_logon_dom, 0, domain_cb);
1121 
1122     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1123                                 hf_netlogon_param_ctrl, NULL);
1124 
1125     offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, di, drep,
1126                                  hf_netlogon_logon_id, NULL);
1127 
1128     offset = dissect_ndr_wstr_LOGON_IDENTITY_INFO(tvb, offset, pinfo, tree, di, drep,
1129                                                   hf_netlogon_acct_name, 1, acct_cb);
1130 
1131     offset = dissect_ndr_wstr_LOGON_IDENTITY_INFO(tvb, offset, pinfo, tree, di, drep,
1132                                                   hf_netlogon_workstation, 0, host_cb);
1133 
1134 #ifdef REMOVED
1135     /* NetMon does not recognize these bytes. I'll comment them out until someone complains */
1136     /* XXX 8 extra bytes here */
1137     /* there were 8 extra bytes, either here or in NETWORK_INFO that does not match
1138        the idl file. Could be a bug in either the NETLOGON implementation or in the
1139        idl file.
1140     */
1141     offset = netlogon_dissect_8_unknown_bytes(tvb, offset, pinfo, tree, di, drep);
1142 #endif
1143 
1144     proto_item_set_len(item, offset-old_offset);
1145     return offset;
1146 }
1147 
1148 
1149 /*
1150  * IDL typedef struct {
1151  * IDL   char password[16];
1152  * IDL } LM_OWF_PASSWORD;
1153  */
1154 static int
netlogon_dissect_LM_OWF_PASSWORD(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep _U_)1155 netlogon_dissect_LM_OWF_PASSWORD(tvbuff_t *tvb, int offset,
1156                                  packet_info *pinfo _U_, proto_tree *parent_tree,
1157                                  dcerpc_info *di, guint8 *drep _U_)
1158 {
1159     proto_item *item=NULL;
1160     proto_tree *tree=NULL;
1161 
1162     if(di->conformant_run){
1163         /*just a run to handle conformant arrays, nothing to dissect.*/
1164         return offset;
1165     }
1166 
1167     if(parent_tree){
1168         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16,
1169                                    ett_LM_OWF_PASSWORD, &item, "LM_OWF_PASSWORD:");
1170     }
1171 
1172     proto_tree_add_item(tree, hf_netlogon_lm_owf_password, tvb, offset, 16,
1173                         ENC_NA);
1174     offset += 16;
1175 
1176     return offset;
1177 }
1178 
1179 /*
1180  * IDL typedef struct {
1181  * IDL   char password[16];
1182  * IDL } NT_OWF_PASSWORD;
1183  */
1184 static int
netlogon_dissect_NT_OWF_PASSWORD(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep _U_)1185 netlogon_dissect_NT_OWF_PASSWORD(tvbuff_t *tvb, int offset,
1186                                  packet_info *pinfo _U_, proto_tree *parent_tree,
1187                                  dcerpc_info *di, guint8 *drep _U_)
1188 {
1189     proto_item *item=NULL;
1190     proto_tree *tree=NULL;
1191 
1192     if(di->conformant_run){
1193         /*just a run to handle conformant arrays, nothing to dissect.*/
1194         return offset;
1195     }
1196 
1197     if(parent_tree){
1198         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 16,
1199                                    ett_NT_OWF_PASSWORD, &item, "NT_OWF_PASSWORD:");
1200     }
1201 
1202     proto_tree_add_item(tree, hf_netlogon_nt_owf_password, tvb, offset, 16,
1203                         ENC_NA);
1204     offset += 16;
1205 
1206     return offset;
1207 }
1208 
1209 
1210 /*
1211  * IDL typedef struct {
1212  * IDL   LOGON_IDENTITY_INFO identity_info;
1213  * IDL   LM_OWF_PASSWORD lmpassword;
1214  * IDL   NT_OWF_PASSWORD ntpassword;
1215  * IDL } INTERACTIVE_INFO;
1216  */
1217 static int
netlogon_dissect_INTERACTIVE_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1218 netlogon_dissect_INTERACTIVE_INFO(tvbuff_t *tvb, int offset,
1219                                   packet_info *pinfo, proto_tree *tree,
1220                                   dcerpc_info *di, guint8 *drep)
1221 {
1222     offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
1223                                                   pinfo, tree, di, drep,
1224                                                   NULL);
1225 
1226     offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
1227                                               pinfo, tree, di, drep);
1228 
1229     offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
1230                                               pinfo, tree, di, drep);
1231 
1232     return offset;
1233 }
1234 
1235 /*
1236  * IDL typedef struct {
1237  * IDL   char chl[8];
1238  * IDL } CHALLENGE;
1239  */
1240 static int
netlogon_dissect_CHALLENGE(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,dcerpc_info * di,guint8 * drep _U_)1241 netlogon_dissect_CHALLENGE(tvbuff_t *tvb, int offset,
1242                            packet_info *pinfo _U_, proto_tree *tree,
1243                            dcerpc_info *di, guint8 *drep _U_)
1244 {
1245     if(di->conformant_run){
1246         /*just a run to handle conformant arrays, nothing to dissect.*/
1247         return offset;
1248     }
1249 
1250     proto_tree_add_item(tree, hf_netlogon_challenge, tvb, offset, 8,
1251                         ENC_NA);
1252     offset += 8;
1253 
1254     return offset;
1255 }
1256 
1257 static int
netlogon_dissect_NETWORK_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1258 netlogon_dissect_NETWORK_INFO(tvbuff_t *tvb, int offset,
1259                               packet_info *pinfo, proto_tree *tree,
1260                               dcerpc_info *di, guint8 *drep)
1261 {
1262     struct LOGON_INFO_STATE *state =
1263         (struct LOGON_INFO_STATE *)di->private_data;
1264     int              last_offset;
1265     struct LOGON_INFO_STATE_CB *nt_cb = NULL;
1266     struct LOGON_INFO_STATE_CB *lm_cb = NULL;
1267 
1268     if (state == NULL) {
1269         state = wmem_new0(pinfo->pool, struct LOGON_INFO_STATE);
1270         state->ntlmssph = (ntlmssp_header_t) { .type = NTLMSSP_AUTH, };
1271         state->domain_cb.state = state;
1272         state->domain_cb.name_ptr = &state->ntlmssph.domain_name;
1273         state->acct_cb.state = state;
1274         state->acct_cb.name_ptr = &state->ntlmssph.acct_name;
1275         state->host_cb.state = state;
1276         state->host_cb.name_ptr = &state->ntlmssph.host_name;
1277         state->nt_cb.state = state;
1278         state->nt_cb.response = &state->nt_response;
1279         state->lm_cb.state = state;
1280         state->lm_cb.response = &state->lm_response;
1281         di->private_data = state;
1282     }
1283     state->pinfo = pinfo;
1284     state->tree = tree;
1285 
1286     offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
1287                                                   pinfo, tree, di, drep,
1288                                                   state);
1289     last_offset = offset;
1290     offset = netlogon_dissect_CHALLENGE(tvb, offset,
1291                                         pinfo, tree, di, drep);
1292     if (offset == (last_offset + 8)) {
1293         tvb_memcpy(tvb, state->server_challenge, last_offset, 8);
1294         nt_cb = &state->nt_cb;
1295         lm_cb = &state->lm_cb;
1296     }
1297     offset = dissect_ndr_lm_nt_hash_helper(tvb,offset,pinfo, tree, di, drep,
1298                                            hf_netlogon_nt_chal_resp,
1299                                            nt_cb);
1300     offset = dissect_ndr_lm_nt_hash_helper(tvb,offset,pinfo, tree, di, drep,
1301                                            hf_netlogon_lm_chal_resp,
1302                                            lm_cb);
1303     return offset;
1304 }
1305 
1306 
1307 /*
1308  * IDL typedef struct {
1309  * IDL   LOGON_IDENTITY_INFO logon_info;
1310  * IDL   LM_OWF_PASSWORD lmpassword;
1311  * IDL   NT_OWF_PASSWORD ntpassword;
1312  * IDL } SERVICE_INFO;
1313  */
1314 static int
netlogon_dissect_SERVICE_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1315 netlogon_dissect_SERVICE_INFO(tvbuff_t *tvb, int offset,
1316                               packet_info *pinfo, proto_tree *tree,
1317                               dcerpc_info *di, guint8 *drep)
1318 {
1319     offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
1320                                                   pinfo, tree, di, drep,
1321                                                   NULL);
1322 
1323     offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
1324                                               pinfo, tree, di, drep);
1325 
1326     offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
1327                                               pinfo, tree, di, drep);
1328 
1329     return offset;
1330 }
1331 
1332 static int
netlogon_dissect_GENERIC_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1333 netlogon_dissect_GENERIC_INFO(tvbuff_t *tvb, int offset,
1334                               packet_info *pinfo, proto_tree *tree,
1335                               dcerpc_info *di, guint8 *drep)
1336 {
1337     offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
1338                                                   pinfo, tree, di, drep,
1339                                                   NULL);
1340 
1341     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1342                                         hf_netlogon_package_name, 0|CB_STR_SAVE);
1343 
1344     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1345                                 hf_netlogon_data_length, NULL);
1346 
1347     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1348                                  netlogon_dissect_BYTE_array, NDR_POINTER_REF,
1349                                  "Logon Data", -1);
1350     return offset;
1351 }
1352 /*
1353  * IDL typedef [switch_type(short)] union {
1354  * IDL    [case(1)][unique] INTERACTIVE_INFO *iinfo;
1355  * IDL    [case(2)][unique] NETWORK_INFO *ninfo;
1356  * IDL    [case(3)][unique] SERVICE_INFO *sinfo;
1357  * IDL } LEVEL;
1358  */
1359 static int
netlogon_dissect_LEVEL(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1360 netlogon_dissect_LEVEL(tvbuff_t *tvb, int offset,
1361                        packet_info *pinfo, proto_tree *tree,
1362                        dcerpc_info *di, guint8 *drep)
1363 {
1364     guint16 level = 0;
1365 
1366     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
1367                                 hf_netlogon_level16, &level);
1368     ALIGN_TO_4_BYTES;
1369     switch(level){
1370     case 1:
1371         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1372                                      netlogon_dissect_INTERACTIVE_INFO, NDR_POINTER_UNIQUE,
1373                                      "INTERACTIVE_INFO:", -1);
1374         break;
1375     case 2:
1376         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1377                                      netlogon_dissect_NETWORK_INFO, NDR_POINTER_UNIQUE,
1378                                      "NETWORK_INFO:", -1);
1379         break;
1380     case 3:
1381         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1382                                      netlogon_dissect_SERVICE_INFO, NDR_POINTER_UNIQUE,
1383                                      "SERVICE_INFO:", -1);
1384         break;
1385     case 4:
1386         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1387                                      netlogon_dissect_GENERIC_INFO, NDR_POINTER_UNIQUE,
1388                                      "GENERIC_INFO:", -1);
1389         break;
1390     case 5:
1391         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1392                                      netlogon_dissect_INTERACTIVE_INFO, NDR_POINTER_UNIQUE,
1393                                      "INTERACTIVE_TRANSITIVE_INFO:", -1);
1394         break;
1395     case 6:
1396         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1397                                      netlogon_dissect_NETWORK_INFO, NDR_POINTER_UNIQUE,
1398                                      "NETWORK_TRANSITIVE_INFO", -1);
1399         break;
1400     case 7:
1401         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1402                                      netlogon_dissect_SERVICE_INFO, NDR_POINTER_UNIQUE,
1403                                      "SERVICE_TRANSITIVE_INFO", -1);
1404         break;
1405     }
1406     return offset;
1407 }
1408 
1409 /*
1410  * IDL typedef struct {
1411  * IDL   char cred[8];
1412  * IDL } CREDENTIAL;
1413  */
1414 static int
netlogon_dissect_CREDENTIAL(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,dcerpc_info * di,guint8 * drep _U_)1415 netlogon_dissect_CREDENTIAL(tvbuff_t *tvb, int offset,
1416                             packet_info *pinfo _U_, proto_tree *tree,
1417                             dcerpc_info *di, guint8 *drep _U_)
1418 {
1419     if(di->conformant_run){
1420         /*just a run to handle conformant arrays, nothing to dissect.*/
1421         return offset;
1422     }
1423 
1424     proto_tree_add_item(tree, hf_netlogon_credential, tvb, offset, 8,
1425                         ENC_NA);
1426     offset += 8;
1427 
1428     return offset;
1429 }
1430 
1431 
1432 /*
1433  * IDL typedef struct {
1434  * IDL   CREDENTIAL cred;
1435  * IDL   long timestamp;
1436  * IDL } AUTHENTICATOR;
1437  */
1438 static int
netlogon_dissect_AUTHENTICATOR(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1439 netlogon_dissect_AUTHENTICATOR(tvbuff_t *tvb, int offset,
1440                                packet_info *pinfo, proto_tree *tree,
1441                                dcerpc_info *di, guint8 *drep)
1442 {
1443     if(di->conformant_run){
1444         /*just a run to handle conformant arrays, nothing to dissect */
1445         return offset;
1446     }
1447 
1448     offset = netlogon_dissect_CREDENTIAL(tvb, offset,
1449                                          pinfo, tree, di, drep);
1450 
1451     /*
1452      * XXX - this appears to be a UNIX time_t in some credentials, but
1453      * appears to be random junk in other credentials.
1454      * For example, it looks like a UNIX time_t in "credential"
1455      * AUTHENTICATORs, but like random junk in "return_authenticator"
1456      * AUTHENTICATORs.
1457      */
1458     ALIGN_TO_4_BYTES;
1459     proto_tree_add_item(tree, hf_netlogon_timestamp, tvb, offset, 4, ENC_TIME_SECS|ENC_LITTLE_ENDIAN);
1460     offset+= 4;
1461 
1462     return offset;
1463 }
1464 
1465 
1466 static const true_false_string group_attrs_mandatory = {
1467     "The MANDATORY bit is SET",
1468     "The mandatory bit is NOT set",
1469 };
1470 static const true_false_string group_attrs_enabled_by_default = {
1471     "The ENABLED_BY_DEFAULT bit is SET",
1472     "The enabled_by_default bit is NOT set",
1473 };
1474 static const true_false_string group_attrs_enabled = {
1475     "The enabled bit is SET",
1476     "The enabled bit is NOT set",
1477 };
1478 static int
netlogon_dissect_GROUP_MEMBERSHIP_ATTRIBUTES(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)1479 netlogon_dissect_GROUP_MEMBERSHIP_ATTRIBUTES(tvbuff_t *tvb, int offset,
1480                                              packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
1481 {
1482     guint32 mask;
1483     static int * const attr[] = {
1484         &hf_netlogon_group_attrs_enabled,
1485         &hf_netlogon_group_attrs_enabled_by_default,
1486         &hf_netlogon_group_attrs_mandatory,
1487         NULL
1488     };
1489 
1490     if(di->conformant_run){
1491         /*just a run to handle conformant arrays, nothing to dissect */
1492         return offset;
1493     }
1494 
1495     offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep,
1496                               -1, &mask);
1497 
1498     proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_attrs, ett_group_attrs, attr, mask, BMT_NO_APPEND);
1499     return offset;
1500 }
1501 
1502 /*
1503  * IDL typedef struct {
1504  * IDL   long user_id;
1505  * IDL   long attributes;
1506  * IDL } GROUP_MEMBERSHIP;
1507  */
1508 static int
netlogon_dissect_GROUP_MEMBERSHIP(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)1509 netlogon_dissect_GROUP_MEMBERSHIP(tvbuff_t *tvb, int offset,
1510                                   packet_info *pinfo, proto_tree *parent_tree,
1511                                   dcerpc_info *di, guint8 *drep)
1512 {
1513     proto_item *item=NULL;
1514     proto_tree *tree=NULL;
1515 
1516     if(parent_tree){
1517         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
1518                                    ett_GROUP_MEMBERSHIP, &item, "GROUP_MEMBERSHIP:");
1519     }
1520 
1521     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1522                                 hf_netlogon_group_rid, NULL);
1523 
1524     offset = netlogon_dissect_GROUP_MEMBERSHIP_ATTRIBUTES(tvb, offset,
1525                                                           pinfo, tree, di, drep);
1526 
1527     return offset;
1528 }
1529 
1530 static int
netlogon_dissect_GROUP_MEMBERSHIP_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1531 netlogon_dissect_GROUP_MEMBERSHIP_ARRAY(tvbuff_t *tvb, int offset,
1532                                         packet_info *pinfo, proto_tree *tree,
1533                                         dcerpc_info *di, guint8 *drep)
1534 {
1535     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
1536                                  netlogon_dissect_GROUP_MEMBERSHIP);
1537 
1538     return offset;
1539 }
1540 
1541 /*
1542  * IDL typedef struct {
1543  * IDL   char user_session_key[16];
1544  * IDL } USER_SESSION_KEY;
1545  */
1546 static int
netlogon_dissect_USER_SESSION_KEY(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,dcerpc_info * di,guint8 * drep _U_)1547 netlogon_dissect_USER_SESSION_KEY(tvbuff_t *tvb, int offset,
1548                                   packet_info *pinfo _U_, proto_tree *tree,
1549                                   dcerpc_info *di, guint8 *drep _U_)
1550 {
1551     if(di->conformant_run){
1552         /*just a run to handle conformant arrays, nothing to dissect.*/
1553         return offset;
1554     }
1555 
1556     proto_tree_add_item(tree, hf_netlogon_user_session_key, tvb, offset, 16,
1557                         ENC_NA);
1558     offset += 16;
1559 
1560     return offset;
1561 }
1562 
1563 
1564 
1565 static const true_false_string user_flags_extra_sids= {
1566     "The EXTRA_SIDS bit is SET",
1567     "The extra_sids is NOT set",
1568 };
1569 static const true_false_string user_flags_resource_groups= {
1570     "The RESOURCE_GROUPS bit is SET",
1571     "The resource_groups is NOT set",
1572 };
1573 static int
netlogon_dissect_USER_FLAGS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)1574 netlogon_dissect_USER_FLAGS(tvbuff_t *tvb, int offset,
1575                             packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
1576 {
1577     guint32 mask;
1578     static int * const flags[] = {
1579         &hf_netlogon_user_flags_resource_groups,
1580         &hf_netlogon_user_flags_extra_sids,
1581         NULL
1582     };
1583 
1584     if(di->conformant_run){
1585         /*just a run to handle conformant arrays, nothing to dissect */
1586         return offset;
1587     }
1588 
1589     offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep,
1590                               -1, &mask);
1591 
1592     proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_user_flags, ett_user_flags, flags, mask, BMT_NO_APPEND);
1593     return offset;
1594 }
1595 
1596 static int
netlogon_dissect_GROUP_MEMBERSHIPS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_count,const char * array_name)1597 netlogon_dissect_GROUP_MEMBERSHIPS(tvbuff_t *tvb, int offset,
1598                                    packet_info *pinfo, proto_tree *tree,
1599                                    dcerpc_info *di, guint8 *drep,
1600                                    int hf_count, const char *array_name)
1601 {
1602     guint32 rgc;
1603 
1604     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1605                                 hf_count, &rgc);
1606 
1607     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1608                                  netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
1609                                  array_name, -1);
1610 
1611     return offset;
1612 }
1613 
1614 static int
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep,int hf_count,const char * name)1615 netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS(tvbuff_t *tvb, int offset,
1616                         packet_info *pinfo, proto_tree *parent_tree,
1617                         dcerpc_info *di, guint8 *drep,
1618                         int hf_count, const char *name)
1619 {
1620         proto_item *item=NULL;
1621         proto_tree *tree=NULL;
1622         int old_offset=offset;
1623 
1624         if(parent_tree){
1625                 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
1626                                               ett_domain_group_memberships,
1627                                               &item, name);
1628         }
1629 
1630         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
1631 
1632         offset = netlogon_dissect_GROUP_MEMBERSHIPS(tvb, offset,
1633                                                     pinfo, tree,
1634                                                     di, drep,
1635                                                     hf_count,
1636                                                     "GroupIDs");
1637 
1638         proto_item_set_len(item, offset-old_offset);
1639         return offset;
1640 }
1641 
1642 static int
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS_WRAPPER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1643 netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS_WRAPPER(tvbuff_t *tvb, int offset,
1644                         packet_info *pinfo, proto_tree *tree,
1645                         dcerpc_info *di, guint8 *drep)
1646 {
1647         return netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS(tvb, offset,
1648                                                          pinfo, tree,
1649                                                          di, drep,
1650                                                          hf_netlogon_domaingroupcount,
1651                                                          "DomainGroupIDs");
1652 }
1653 
1654 static int
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIP_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1655 netlogon_dissect_DOMAIN_GROUP_MEMBERSHIP_ARRAY(tvbuff_t *tvb, int offset,
1656                                         packet_info *pinfo, proto_tree *tree,
1657                                         dcerpc_info *di, guint8 *drep)
1658 {
1659     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
1660                                  netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS_WRAPPER);
1661 
1662     return offset;
1663 }
1664 
1665 static int
netlogon_dissect_DOMAINS_GROUP_MEMBERSHIPS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep,int hf_count,const char * name)1666 netlogon_dissect_DOMAINS_GROUP_MEMBERSHIPS(tvbuff_t *tvb, int offset,
1667                         packet_info *pinfo, proto_tree *parent_tree,
1668                         dcerpc_info *di, guint8 *drep,
1669                         int hf_count, const char *name)
1670 {
1671         proto_item *item=NULL;
1672         proto_tree *tree=NULL;
1673         int old_offset=offset;
1674         guint32 rgc;
1675 
1676         if(parent_tree){
1677                 tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
1678                                               ett_domains_group_memberships,
1679                                               &item, name);
1680         }
1681 
1682         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1683                                     hf_count, &rgc);
1684 
1685         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1686                                      netlogon_dissect_DOMAIN_GROUP_MEMBERSHIP_ARRAY,
1687                                      NDR_POINTER_UNIQUE,
1688                                      name, -1);
1689 
1690         proto_item_set_len(item, offset-old_offset);
1691         return offset;
1692 }
1693 
1694 /*
1695  * IDL typedef struct {
1696  * IDL   uint64 LogonTime;
1697  * IDL   uint64 LogoffTime;
1698  * IDL   uint64 KickOffTime;
1699  * IDL   uint64 PasswdLastSet;
1700  * IDL   uint64 PasswdCanChange;
1701  * IDL   uint64 PasswdMustChange;
1702  * IDL   unicodestring effectivename;
1703  * IDL   unicodestring fullname;
1704  * IDL   unicodestring logonscript;
1705  * IDL   unicodestring profilepath;
1706  * IDL   unicodestring homedirectory;
1707  * IDL   unicodestring homedirectorydrive;
1708  * IDL   short LogonCount;
1709  * IDL   short BadPasswdCount;
1710  * IDL   long userid;
1711  * IDL   long primarygroup;
1712  * IDL   long groupcount;
1713  * IDL   [unique][size_is(groupcount)] GROUP_MEMBERSHIP *groupids;
1714  * IDL   long userflags;
1715  * IDL   USER_SESSION_KEY key;
1716  * IDL   unicodestring logonserver;
1717  * IDL   unicodestring domainname;
1718  * IDL   [unique] SID logondomainid;
1719  * IDL   long expansionroom[2];
1720  * IDL   long useraccountcontrol;
1721  * IDL   long expansionroom[7];
1722  * IDL } VALIDATION_SAM_INFO;
1723  */
1724 static int
netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1725 netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
1726                                      packet_info *pinfo, proto_tree *tree,
1727                                      dcerpc_info *di, guint8 *drep)
1728 {
1729 
1730     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1731                                    hf_netlogon_logon_time);
1732 
1733     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1734                                    hf_netlogon_logoff_time);
1735 
1736     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1737                                    hf_netlogon_kickoff_time);
1738 
1739     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1740                                    hf_netlogon_pwd_last_set_time);
1741 
1742     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1743                                    hf_netlogon_pwd_can_change_time);
1744 
1745     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1746                                    hf_netlogon_pwd_must_change_time);
1747 
1748     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1749                                         hf_netlogon_acct_name, 0);
1750 
1751     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1752                                         hf_netlogon_full_name, 0);
1753 
1754     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1755                                         hf_netlogon_logon_script, 0);
1756 
1757     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1758                                         hf_netlogon_profile_path, 0);
1759 
1760     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1761                                         hf_netlogon_home_dir, 0);
1762 
1763     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1764                                         hf_netlogon_dir_drive, 0);
1765 
1766     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
1767                                 hf_netlogon_logon_count16, NULL);
1768 
1769     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
1770                                 hf_netlogon_bad_pw_count16, NULL);
1771 
1772     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1773                                 hf_netlogon_user_rid, NULL);
1774 
1775     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1776                                 hf_netlogon_group_rid, NULL);
1777 
1778     offset = netlogon_dissect_GROUP_MEMBERSHIPS(tvb, offset,
1779                               pinfo, tree, di, drep,
1780                               hf_netlogon_num_rids,
1781                               "GroupIDs");
1782 
1783     offset = netlogon_dissect_USER_FLAGS(tvb, offset,
1784                                          pinfo, tree, di, drep);
1785 
1786     offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
1787                                                pinfo, tree, di, drep);
1788 
1789     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1790                                         hf_netlogon_logon_srv, 0);
1791 
1792     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1793                                         hf_netlogon_logon_dom, 0);
1794 
1795     offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
1796 
1797     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1798                                 hf_netlogon_dummy1_long, NULL);
1799 
1800     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1801                                 hf_netlogon_dummy2_long, NULL);
1802 
1803     offset = netlogon_dissect_USER_ACCOUNT_CONTROL(tvb, offset,
1804                                                    pinfo, tree, di, drep);
1805 
1806     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1807                                 hf_netlogon_dummy4_long, NULL);
1808 
1809     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1810                                 hf_netlogon_dummy5_long, NULL);
1811 
1812     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1813                                 hf_netlogon_dummy6_long, NULL);
1814 
1815     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1816                                 hf_netlogon_dummy7_long, NULL);
1817 
1818     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1819                                 hf_netlogon_dummy8_long, NULL);
1820 
1821     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1822                                 hf_netlogon_dummy9_long, NULL);
1823 
1824     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1825                                 hf_netlogon_dummy10_long, NULL);
1826 
1827     return offset;
1828 }
1829 
1830 
1831 
1832 /*
1833  * IDL typedef struct {
1834  * IDL   uint64 LogonTime;
1835  * IDL   uint64 LogoffTime;
1836  * IDL   uint64 KickOffTime;
1837  * IDL   uint64 PasswdLastSet;
1838  * IDL   uint64 PasswdCanChange;
1839  * IDL   uint64 PasswdMustChange;
1840  * IDL   unicodestring effectivename;
1841  * IDL   unicodestring fullname;
1842  * IDL   unicodestring logonscript;
1843  * IDL   unicodestring profilepath;
1844  * IDL   unicodestring homedirectory;
1845  * IDL   unicodestring homedirectorydrive;
1846  * IDL   short LogonCount;
1847  * IDL   short BadPasswdCount;
1848  * IDL   long userid;
1849  * IDL   long primarygroup;
1850  * IDL   long groupcount;
1851  * IDL   [unique] GROUP_MEMBERSHIP *groupids;
1852  * IDL   long userflags;
1853  * IDL   USER_SESSION_KEY key;
1854  * IDL   unicodestring logonserver;
1855  * IDL   unicodestring domainname;
1856  * IDL   [unique] SID logondomainid;
1857  * IDL   long expansionroom[2];
1858  * IDL   long useraccountcontrol;
1859  * IDL   long expansionroom[7];
1860  * IDL   long sidcount;
1861  * IDL   [unique] SID_AND_ATTRIBS;
1862  * IDL } VALIDATION_SAM_INFO2;
1863  */
1864 static int
netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1865 netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
1866                                       packet_info *pinfo, proto_tree *tree,
1867                                       dcerpc_info *di, guint8 *drep)
1868 {
1869     offset = netlogon_dissect_VALIDATION_SAM_INFO(tvb,offset,pinfo,tree,di,drep);
1870 #if 0
1871     int i;
1872 
1873     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1874                                    hf_netlogon_logon_time);
1875 
1876     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1877                                    hf_netlogon_logoff_time);
1878 
1879     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1880                                    hf_netlogon_kickoff_time);
1881 
1882     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1883                                    hf_netlogon_pwd_last_set_time);
1884 
1885     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1886                                    hf_netlogon_pwd_can_change_time);
1887 
1888     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
1889                                    hf_netlogon_pwd_must_change_time);
1890 
1891     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1892                                         hf_netlogon_acct_name, 0);
1893 
1894     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1895                                         hf_netlogon_full_name, 0);
1896 
1897     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1898                                         hf_netlogon_logon_script, 0);
1899 
1900     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1901                                         hf_netlogon_profile_path, 0);
1902 
1903     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1904                                         hf_netlogon_home_dir, 0);
1905 
1906     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1907                                         hf_netlogon_dir_drive, 0);
1908 
1909     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
1910                                 hf_netlogon_logon_count16, NULL);
1911 
1912     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
1913                                 hf_netlogon_bad_pw_count16, NULL);
1914 
1915     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1916                                 hf_netlogon_user_rid, NULL);
1917 
1918     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1919                                 hf_netlogon_group_rid, NULL);
1920 
1921     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1922                                 hf_netlogon_num_rids, NULL);
1923 
1924     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1925                                  netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
1926                                  "GROUP_MEMBERSHIP_ARRAY", -1);
1927 
1928     offset = netlogon_dissect_USER_FLAGS(tvb, offset,
1929                                          pinfo, tree, di, drep);
1930 
1931     offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
1932                                                pinfo, tree, di, drep);
1933 
1934     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1935                                         hf_netlogon_logon_srv, 0);
1936 
1937     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1938                                         hf_netlogon_logon_dom, 0);
1939 
1940     offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
1941 
1942     for(i=0;i<2;i++){
1943         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1944                                     hf_netlogon_unknown_long, NULL);
1945     }
1946     offset = netlogon_dissect_USER_ACCOUNT_CONTROL(tvb, offset,
1947                                                    pinfo, tree, di, drep);
1948 
1949     for(i=0;i<7;i++){
1950         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1951                                     hf_netlogon_unknown_long, NULL);
1952     }
1953 #endif
1954     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1955                                 hf_netlogon_num_sid, NULL);
1956 
1957     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
1958                                  dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
1959                                  "SID_AND_ATTRIBUTES_ARRAY:", -1);
1960 
1961     return offset;
1962 }
1963 
1964 
1965 static int
netlogon_dissect_VALIDATION_SAM_INFO4(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1966 netlogon_dissect_VALIDATION_SAM_INFO4(tvbuff_t *tvb, int offset,
1967                                       packet_info *pinfo, proto_tree *tree,
1968                                       dcerpc_info *di, guint8 *drep)
1969 {
1970     offset = netlogon_dissect_VALIDATION_SAM_INFO2(tvb,offset,pinfo,tree,di,drep);
1971 
1972     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1973                                         hf_netlogon_logon_dnslogondomainname, 0);
1974 
1975     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1976                                         hf_netlogon_logon_upn, 0);
1977 
1978     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1979                                         hf_netlogon_dummy_string, 0);
1980 
1981     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1982                                         hf_netlogon_dummy_string2, 0);
1983 
1984     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1985                                         hf_netlogon_dummy_string3, 0);
1986 
1987     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1988                                         hf_netlogon_dummy_string4, 0);
1989 
1990     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1991                                         hf_netlogon_dummy_string5, 0);
1992 
1993     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1994                                         hf_netlogon_dummy_string6, 0);
1995 
1996     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
1997                                         hf_netlogon_dummy_string7, 0);
1998 
1999     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2000                                         hf_netlogon_dummy_string8, 0);
2001 
2002     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2003                                         hf_netlogon_dummy_string9, 0);
2004 
2005     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2006                                         hf_netlogon_dummy_string10, 0);
2007     return offset;
2008 }
2009 
2010 /*
2011  * IDL typedef struct {
2012  * IDL   uint64 LogonTime;
2013  * IDL   uint64 LogoffTime;
2014  * IDL   uint64 KickOffTime;
2015  * IDL   uint64 PasswdLastSet;
2016  * IDL   uint64 PasswdCanChange;
2017  * IDL   uint64 PasswdMustChange;
2018  * IDL   unicodestring effectivename;
2019  * IDL   unicodestring fullname;
2020  * IDL   unicodestring logonscript;
2021  * IDL   unicodestring profilepath;
2022  * IDL   unicodestring homedirectory;
2023  * IDL   unicodestring homedirectorydrive;
2024  * IDL   short LogonCount;
2025  * IDL   short BadPasswdCount;
2026  * IDL   long userid;
2027  * IDL   long primarygroup;
2028  * IDL   long groupcount;
2029  * IDL   [unique] GROUP_MEMBERSHIP *groupids;
2030  * IDL   long userflags;
2031  * IDL   USER_SESSION_KEY key;
2032  * IDL   unicodestring logonserver;
2033  * IDL   unicodestring domainname;
2034  * IDL   [unique] SID logondomainid;
2035  * IDL   long expansionroom[2];
2036  * IDL   long useraccountcontrol;
2037  * IDL   long expansionroom[7];
2038  * IDL   long sidcount;
2039  * IDL   [unique] SID_AND_ATTRIBS;
2040  * IDL   [unique] SID resourcegroupdomainsid;
2041  * IDL   long resourcegroupcount;
2042  qqq
2043  * IDL } PAC_LOGON_INFO;
2044  */
2045 int
netlogon_dissect_PAC_LOGON_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2046 netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
2047                                 packet_info *pinfo, proto_tree *tree,
2048                                 dcerpc_info *di, guint8 *drep)
2049 {
2050     offset = netlogon_dissect_VALIDATION_SAM_INFO(tvb,offset,pinfo,tree,di, drep);
2051 #if 0
2052     int i;
2053 
2054     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
2055                                    hf_netlogon_logon_time);
2056 
2057     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
2058                                    hf_netlogon_logoff_time);
2059 
2060     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
2061                                    hf_netlogon_kickoff_time);
2062 
2063     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
2064                                    hf_netlogon_pwd_last_set_time);
2065 
2066     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
2067                                    hf_netlogon_pwd_can_change_time);
2068 
2069     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
2070                                    hf_netlogon_pwd_must_change_time);
2071 
2072     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2073                                         hf_netlogon_acct_name, 0);
2074 
2075     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2076                                         hf_netlogon_full_name, 0);
2077 
2078     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2079                                         hf_netlogon_logon_script, 0);
2080 
2081     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2082                                         hf_netlogon_profile_path, 0);
2083 
2084     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2085                                         hf_netlogon_home_dir, 0);
2086 
2087     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2088                                         hf_netlogon_dir_drive, 0);
2089 
2090     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2091                                 hf_netlogon_logon_count16, NULL);
2092 
2093     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2094                                 hf_netlogon_bad_pw_count16, NULL);
2095 
2096     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2097                                 hf_netlogon_user_rid, NULL);
2098 
2099     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2100                                 hf_netlogon_group_rid, NULL);
2101 
2102     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2103                                 hf_netlogon_num_rids, NULL);
2104 
2105     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2106                                  netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
2107                                  "GROUP_MEMBERSHIP_ARRAY", -1);
2108 
2109     offset = netlogon_dissect_USER_FLAGS(tvb, offset,
2110                                          pinfo, tree, di, drep);
2111 
2112     offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
2113                                                pinfo, tree, di, drep);
2114 
2115     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2116                                         hf_netlogon_logon_srv, 0);
2117 
2118     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2119                                         hf_netlogon_logon_dom, 0);
2120 
2121     offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
2122 
2123     for(i=0;i<2;i++){
2124         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2125                                     hf_netlogon_unknown_long, NULL);
2126     }
2127     offset = netlogon_dissect_USER_ACCOUNT_CONTROL(tvb, offset,
2128                                                    pinfo, tree, di, drep);
2129 
2130     for(i=0;i<7;i++){
2131         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2132                                     hf_netlogon_unknown_long, NULL);
2133     }
2134 #endif
2135 
2136     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2137                                 hf_netlogon_num_sid, NULL);
2138 
2139     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2140                                  dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
2141                                  "SID_AND_ATTRIBUTES_ARRAY:", -1);
2142 
2143     offset = netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS(tvb, offset,
2144                               pinfo, tree, di, drep,
2145                               hf_netlogon_resourcegroupcount,
2146                               "ResourceGroupIDs");
2147 
2148     return offset;
2149 }
2150 
2151 static int
netlogon_dissect_S4U_Transited_Service_name(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2152 netlogon_dissect_S4U_Transited_Service_name(tvbuff_t *tvb, int offset,
2153                                              packet_info *pinfo, proto_tree *tree,
2154                                              dcerpc_info *di, guint8 *drep)
2155 {
2156     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2157                                         hf_netlogon_transited_service, 1);
2158 
2159     return offset;
2160 }
2161 
2162 static int
netlogon_dissect_S4U_Transited_Services_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2163 netlogon_dissect_S4U_Transited_Services_array(tvbuff_t *tvb, int offset,
2164                                               packet_info *pinfo, proto_tree *tree,
2165                                               dcerpc_info *di, guint8 *drep)
2166 {
2167     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
2168                                  netlogon_dissect_S4U_Transited_Service_name);
2169 
2170     return offset;
2171 }
2172 
2173 int
netlogon_dissect_PAC_S4U_DELEGATION_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2174 netlogon_dissect_PAC_S4U_DELEGATION_INFO(tvbuff_t *tvb, int offset,
2175                                             packet_info *pinfo, proto_tree *tree,
2176                                             dcerpc_info *di, guint8 *drep)
2177 {
2178     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2179                                         hf_netlogon_s4u2proxytarget, 0);
2180 
2181     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2182                                 hf_netlogon_transitedlistsize, NULL);
2183 
2184     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2185                                  netlogon_dissect_S4U_Transited_Services_array, NDR_POINTER_UNIQUE,
2186                                  "S4UTransitedServices", -1);
2187 
2188     return offset;
2189 }
2190 
2191 /*
2192  * IDL typedef struct {
2193  * IDL   long UserId;
2194  * IDL   long PrimaryGroupId;
2195  * IDL   SID AccountDomainId;
2196  * IDL   long AccountGroupCount;
2197  * IDL   [size_is(AccountGroupCount)] PGROUP_MEMBERSHIP AccountGroupIds;
2198  * IDL   ULONG SidCount;
2199  * IDL   [size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;
2200  * IDL   ULONG DomainGroupCount;
2201  * IDL   [size_is(DomainGroupCount)] PDOMAIN_GROUP_MEMBERSHIP DomainGroup;
2202  * IDL } PAC_DEVICE_INFO;
2203  */
2204 int
netlogon_dissect_PAC_DEVICE_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2205 netlogon_dissect_PAC_DEVICE_INFO(tvbuff_t *tvb, int offset,
2206                                  packet_info *pinfo, proto_tree *tree,
2207                                  dcerpc_info *di, guint8 *drep)
2208 {
2209     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2210                                 hf_netlogon_user_rid, NULL);
2211 
2212     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2213                                 hf_netlogon_group_rid, NULL);
2214 
2215     offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
2216 
2217     offset = netlogon_dissect_GROUP_MEMBERSHIPS(tvb, offset,
2218                               pinfo, tree, di, drep,
2219                               hf_netlogon_accountdomaingroupcount,
2220                               "AccountDomainGroupIds");
2221 
2222     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2223                                 hf_netlogon_num_sid, NULL);
2224 
2225     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2226                                  dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
2227                                  "ExtraSids:SID_AND_ATTRIBUTES_ARRAY:", -1);
2228 
2229     offset = netlogon_dissect_DOMAINS_GROUP_MEMBERSHIPS(tvb, offset,
2230                               pinfo, tree, di, drep,
2231                               hf_netlogon_membership_domains_count,
2232                               "ExtraDomain Membership Array");
2233 
2234     return offset;
2235 }
2236 
2237 #if 0
2238 static int
2239 netlogon_dissect_PAC(tvbuff_t *tvb, int offset,
2240                      packet_info *pinfo, proto_tree *tree,
2241                      dcerpc_info *di, guint8 *drep _U_)
2242 {
2243     guint32 pac_size;
2244 
2245     if(di->conformant_run){
2246         return offset;
2247     }
2248 
2249     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2250                                 hf_netlogon_pac_size, &pac_size);
2251 
2252     proto_tree_add_item(tree, hf_netlogon_pac_data, tvb, offset, pac_size,
2253                         ENC_NA);
2254     offset += pac_size;
2255 
2256     return offset;
2257 }
2258 
2259 static int
2260 netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
2261                       packet_info *pinfo, proto_tree *tree,
2262                       dcerpc_info *di, guint8 *drep _U_)
2263 {
2264     guint32 auth_size;
2265 
2266     if(di->conformant_run){
2267         return offset;
2268     }
2269 
2270     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2271                                 hf_netlogon_auth_size, &auth_size);
2272 
2273     proto_tree_add_item(tree, hf_netlogon_auth_data, tvb, offset, auth_size,
2274                         ENC_NA);
2275     offset += auth_size;
2276 
2277     return offset;
2278 }
2279 #endif
2280 
2281 static int
netlogon_dissect_VALIDATION_GENERIC_INFO2(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2282 netlogon_dissect_VALIDATION_GENERIC_INFO2 (tvbuff_t *tvb, int offset,
2283                                            packet_info *pinfo, proto_tree *tree,
2284                                            dcerpc_info *di, guint8 *drep)
2285 {
2286     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2287                                 hf_netlogon_data_length, NULL);
2288 
2289     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2290                                  netlogon_dissect_BYTE_array, NDR_POINTER_REF,
2291                                  "Validation Data", -1);
2292 
2293     return offset;
2294 }
2295 /*
2296  * IDL typedef struct {
2297  * IDL   long pac_size
2298  * IDL   [unique][size_is(pac_size)] char *pac;
2299  * IDL   UNICODESTRING logondomain;
2300  * IDL   UNICODESTRING logonserver;
2301  * IDL   UNICODESTRING principalname;
2302  * IDL   long auth_size;
2303  * IDL   [unique][size_is(auth_size)] char *auth;
2304  * IDL   USER_SESSION_KEY user_session_key;
2305  * IDL   long expansionroom[2];
2306  * IDL   long useraccountcontrol;
2307  * IDL   long expansionroom[7];
2308  * IDL   UNICODESTRING dummy1;
2309  * IDL   UNICODESTRING dummy2;
2310  * IDL   UNICODESTRING dummy3;
2311  * IDL   UNICODESTRING dummy4;
2312  * IDL } VALIDATION_PAC_INFO;
2313  */
2314 #if 0 /* Not used (anymore ?) */
2315 static int
2316 netlogon_dissect_VALIDATION_PAC_INFO(tvbuff_t *tvb, int offset,
2317                                      packet_info *pinfo, proto_tree *tree,
2318                                      dcerpc_info *di, guint8 *drep)
2319 {
2320     int i;
2321 
2322     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2323                                 hf_netlogon_pac_size, NULL);
2324 
2325     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2326                                  netlogon_dissect_PAC, NDR_POINTER_UNIQUE, "PAC:", -1);
2327 
2328     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2329                                         hf_netlogon_logon_dom, 0);
2330 
2331     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2332                                         hf_netlogon_logon_srv, 0);
2333 
2334     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2335                                         hf_netlogon_principal, 0);
2336 
2337     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2338                                 hf_netlogon_auth_size, NULL);
2339 
2340     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2341                                  netlogon_dissect_AUTH, NDR_POINTER_UNIQUE, "AUTH:", -1);
2342 
2343     offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
2344                                                pinfo, tree, di, drep);
2345 
2346     for(i=0;i<2;i++){
2347         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2348                                     hf_netlogon_unknown_long, NULL);
2349     }
2350     offset = netlogon_dissect_USER_ACCOUNT_CONTROL(tvb, offset,
2351                                                    pinfo, tree, di, drep);
2352 
2353     for(i=0;i<7;i++){
2354         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2355                                     hf_netlogon_unknown_long, NULL);
2356     }
2357 
2358     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2359                                         hf_netlogon_dummy, 0);
2360 
2361     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2362                                         hf_netlogon_dummy, 0);
2363 
2364     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2365                                         hf_netlogon_dummy, 0);
2366 
2367     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2368                                         hf_netlogon_dummy, 0);
2369 
2370     return offset;
2371 }
2372 #endif
2373 
2374 /*
2375  * IDL typedef [switch_type(short)] union {
2376  * IDL    [case(1)][unique] VALIDATION_UAS *uas;
2377  * IDL    [case(2)][unique] VALIDATION_SAM_INFO *sam;
2378  * IDL    [case(3)][unique] VALIDATION_SAM_INFO2 *sam2;
2379  * IDL    [case(4)][unique] VALIDATION_GENERIC_INFO *generic;
2380  * IDL    [case(5)][unique] VALIDATION_GENERIC_INFO *generic2;
2381  * IDL    [case(5)][unique] VALIDATION_GENERIC_INFO *generic2;
2382  * IDL    [case(6)][unique] VALIDATION_SAM_INFO4 *sam4;
2383  * IDL } VALIDATION;
2384  */
2385 static int
netlogon_dissect_VALIDATION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2386 netlogon_dissect_VALIDATION(tvbuff_t *tvb, int offset,
2387                             packet_info *pinfo, proto_tree *tree,
2388                             dcerpc_info *di, guint8 *drep)
2389 {
2390     guint16 level = 0;
2391 
2392     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2393                                 hf_netlogon_validation_level, &level);
2394 
2395     ALIGN_TO_4_BYTES;
2396     switch(level){
2397     case 1:
2398         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2399                                      netlogon_dissect_VALIDATION_UAS_INFO, NDR_POINTER_UNIQUE,
2400                                      "VALIDATION_UAS_INFO:", -1);
2401         break;
2402     case 2:
2403         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2404                                      netlogon_dissect_VALIDATION_SAM_INFO, NDR_POINTER_UNIQUE,
2405                                      "VALIDATION_SAM_INFO:", -1);
2406         break;
2407     case 3:
2408         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2409                                      netlogon_dissect_VALIDATION_SAM_INFO2, NDR_POINTER_UNIQUE,
2410                                      "VALIDATION_SAM_INFO2:", -1);
2411         break;
2412     case 4:
2413         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2414                                      netlogon_dissect_VALIDATION_GENERIC_INFO2, NDR_POINTER_UNIQUE,
2415                                      "VALIDATION_INFO:", -1);
2416         break;
2417     case 5:
2418         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2419                                      netlogon_dissect_VALIDATION_GENERIC_INFO2, NDR_POINTER_UNIQUE,
2420                                      "VALIDATION_INFO2:", -1);
2421         break;
2422     case 6:
2423         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2424                                      netlogon_dissect_VALIDATION_SAM_INFO4, NDR_POINTER_UNIQUE,
2425                                      "VALIDATION_SAM_INFO4:", -1);
2426         break;
2427     }
2428     return offset;
2429 }
2430 /*
2431  * IDL long NetrLogonSamLogonWithFlags(
2432  * IDL      [in][unique][string] wchar_t *ServerName,
2433  * IDL      [in][unique][string] wchar_t *Workstation,
2434  * IDL      [in][unique] AUTHENTICATOR *credential,
2435  * IDL      [in][out][unique] AUTHENTICATOR *returnauthenticator,
2436  * IDL      [in] short LogonLevel,
2437  * IDL      [in][ref] LOGON_LEVEL *logonlevel,
2438  * IDL      [in] short ValidationLevel,
2439  * IDL      [out][ref] VALIDATION *validation,
2440  * IDL      [out][ref] boolean Authorative
2441  * IDL      [in][out] unsigned long ExtraFlags
2442  * IDL );
2443  */
2444 static int
netlogon_dissect_netrlogonsamlogonflags_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2445 netlogon_dissect_netrlogonsamlogonflags_rqst(tvbuff_t *tvb, int offset,
2446                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2447 {
2448     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
2449                                               pinfo, tree, di, drep);
2450 
2451     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2452                                           NDR_POINTER_UNIQUE, "Computer Name",
2453                                           hf_netlogon_computer_name, 0);
2454 
2455     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2456                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2457                                  "AUTHENTICATOR: credential", -1);
2458 
2459     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2460                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2461                                  "AUTHENTICATOR: return_authenticator", -1);
2462 
2463     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2464                                 hf_netlogon_level16, NULL);
2465 
2466     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2467                                  netlogon_dissect_LEVEL, NDR_POINTER_REF,
2468                                  "LEVEL: LogonLevel", -1);
2469 
2470     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2471                                 hf_netlogon_validation_level, NULL);
2472 
2473     offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, di, drep);
2474 
2475     return offset;
2476 }
2477 
2478 static int
netlogon_dissect_netrlogonsamlogonflags_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2479 netlogon_dissect_netrlogonsamlogonflags_reply(tvbuff_t *tvb, int offset,
2480                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2481 {
2482     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2483                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2484                                  "AUTHENTICATOR: return_authenticator", -1);
2485 
2486     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2487                                  netlogon_dissect_VALIDATION, NDR_POINTER_REF,
2488                                  "VALIDATION:", -1);
2489 
2490     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
2491                                hf_netlogon_authoritative, NULL);
2492 
2493     offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, di, drep);
2494 
2495     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
2496                               hf_netlogon_rc, NULL);
2497 
2498     return offset;
2499 }
2500 
2501 
2502 
2503 /*
2504  * IDL long NetrLogonSamLogon(
2505  * IDL      [in][unique][string] wchar_t *ServerName,
2506  * IDL      [in][unique][string] wchar_t *Workstation,
2507  * IDL      [in][unique] AUTHENTICATOR *credential,
2508  * IDL      [in][out][unique] AUTHENTICATOR *returnauthenticator,
2509  * IDL      [in] short LogonLevel,
2510  * IDL      [in][ref] LOGON_LEVEL *logonlevel,
2511  * IDL      [in] short ValidationLevel,
2512  * IDL      [out][ref] VALIDATION *validation,
2513  * IDL      [out][ref] boolean Authorative
2514  * IDL );
2515  */
2516 static int
netlogon_dissect_netrlogonsamlogon_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2517 netlogon_dissect_netrlogonsamlogon_rqst(tvbuff_t *tvb, int offset,
2518                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2519 {
2520     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
2521                                               pinfo, tree, di, drep);
2522 
2523     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2524                                           NDR_POINTER_UNIQUE, "Computer Name",
2525                                           hf_netlogon_computer_name, 0);
2526 
2527     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2528                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2529                                  "AUTHENTICATOR: credential", -1);
2530 
2531     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2532                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2533                                  "AUTHENTICATOR: return_authenticator", -1);
2534 
2535     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2536                                 hf_netlogon_level16, NULL);
2537 
2538     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2539                                  netlogon_dissect_LEVEL, NDR_POINTER_REF,
2540                                  "LEVEL: LogonLevel", -1);
2541 
2542     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2543                                 hf_netlogon_validation_level, NULL);
2544 
2545     return offset;
2546 }
2547 
2548 static int
netlogon_dissect_netrlogonsamlogon_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2549 netlogon_dissect_netrlogonsamlogon_reply(tvbuff_t *tvb, int offset,
2550                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2551 {
2552     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2553                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2554                                  "AUTHENTICATOR: return_authenticator", -1);
2555 
2556     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2557                                  netlogon_dissect_VALIDATION, NDR_POINTER_REF,
2558                                  "VALIDATION:", -1);
2559 
2560     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
2561                                hf_netlogon_authoritative, NULL);
2562 
2563     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
2564                               hf_netlogon_rc, NULL);
2565 
2566     return offset;
2567 }
2568 
2569 
2570 /*
2571  * IDL long NetrLogonSamLogoff(
2572  * IDL      [in][unique][string] wchar_t *ServerName,
2573  * IDL      [in][unique][string] wchar_t *ComputerName,
2574  * IDL      [in][unique] AUTHENTICATOR credential,
2575  * IDL      [in][unique] AUTHENTICATOR return_authenticator,
2576  * IDL      [in] short logon_level,
2577  * IDL      [in][ref] LEVEL logoninformation
2578  * IDL );
2579  */
2580 static int
netlogon_dissect_netrlogonsamlogoff_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2581 netlogon_dissect_netrlogonsamlogoff_rqst(tvbuff_t *tvb, int offset,
2582                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2583 {
2584     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
2585                                               pinfo, tree, di, drep);
2586 
2587     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2588                                           NDR_POINTER_UNIQUE, "Computer Name",
2589                                           hf_netlogon_computer_name, 0);
2590 
2591     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2592                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2593                                  "AUTHENTICATOR: credential", -1);
2594 
2595     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2596                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2597                                  "AUTHENTICATOR: return_authenticator", -1);
2598 
2599     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2600                                 hf_netlogon_level16, NULL);
2601 
2602     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2603                                  netlogon_dissect_LEVEL, NDR_POINTER_REF,
2604                                  "LEVEL: logoninformation", -1);
2605 
2606     return offset;
2607 }
2608 static int
netlogon_dissect_netrlogonsamlogoff_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2609 netlogon_dissect_netrlogonsamlogoff_reply(tvbuff_t *tvb, int offset,
2610                                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2611 {
2612 
2613     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2614                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
2615                                  "AUTHENTICATOR: return_authenticator", -1);
2616 
2617     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
2618                               hf_netlogon_rc, NULL);
2619 
2620     return offset;
2621 }
2622 
generate_hash_key(packet_info * pinfo,unsigned char is_server,netlogon_auth_key * key)2623 static void generate_hash_key(packet_info *pinfo,unsigned char is_server,netlogon_auth_key *key)
2624 {
2625     if(is_server) {
2626         copy_address_shallow(&key->server,&pinfo->src);
2627         copy_address_shallow(&key->client,&pinfo->dst);
2628     }
2629     else {
2630         copy_address_shallow(&key->server,&pinfo->dst);
2631         copy_address_shallow(&key->client,&pinfo->src);
2632     }
2633 
2634 }
2635 
2636 /*
2637  * IDL long NetrServerReqChallenge(
2638  * IDL      [in][unique][string] wchar_t *ServerName,
2639  * IDL      [in][ref][string] wchar_t *ComputerName,
2640  * IDL      [in][ref] CREDENTIAL client_credential,
2641  * IDL      [out][ref] CREDENTIAL server_credential
2642  * IDL );
2643  */
2644 static int
netlogon_dissect_netrserverreqchallenge_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2645 netlogon_dissect_netrserverreqchallenge_rqst(tvbuff_t *tvb, int offset,
2646                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2647 {
2648     /*int oldoffset = offset;*/
2649     netlogon_auth_vars *vars;
2650     netlogon_auth_vars *existing_vars;
2651     netlogon_auth_key key;
2652     guint8 tab[8] = { 0,0,0,0,0,0,0,0};
2653     dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
2654 
2655     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset, pinfo, tree, di, drep);
2656     offset = dissect_ndr_pointer_cb(
2657         tvb, offset, pinfo, tree, di, drep,
2658         dissect_ndr_wchar_cvstring, NDR_POINTER_REF,
2659         "Computer Name", hf_netlogon_computer_name,
2660         cb_wstr_postprocess,
2661         GINT_TO_POINTER(CB_STR_COL_INFO |CB_STR_SAVE | 1));
2662 
2663     debugprintf("1)Len %d offset %d txt %s\n",(int) strlen((char *)dcv->private_data),offset,(char*)dcv->private_data);
2664     vars = wmem_new0(wmem_file_scope(), netlogon_auth_vars);
2665     vars->client_name = wmem_strdup(wmem_file_scope(), (const guint8 *)dcv->private_data);
2666     debugprintf("2)Len %d offset %d txt %s\n",(int) strlen((char *)dcv->private_data),offset,vars->client_name);
2667 
2668     offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
2669                                    hf_client_challenge,&vars->client_challenge);
2670     memcpy(tab,&vars->client_challenge,8);
2671 
2672     vars->start = pinfo->num;
2673     vars->next_start = -1;
2674     vars->next = NULL;
2675 
2676     generate_hash_key(pinfo,0,&key);
2677     existing_vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths, &key);
2678     if (!existing_vars) {
2679         netlogon_auth_key *k = (netlogon_auth_key *)wmem_memdup(wmem_file_scope(), &key, sizeof(netlogon_auth_key));
2680         copy_address_wmem(wmem_file_scope(), &k->client, &key.client);
2681         copy_address_wmem(wmem_file_scope(), &k->server, &key.server);
2682         debugprintf("Adding initial vars with this start packet = %d\n",vars->start);
2683         wmem_map_insert(netlogon_auths, k, vars);
2684     }
2685     else {
2686         while(existing_vars->next != NULL && existing_vars->start < vars->start) {
2687             debugprintf("Looping to find existing vars ...\n");
2688             existing_vars = existing_vars->next;
2689         }
2690         if(existing_vars->next != NULL || existing_vars->start == vars->start) {
2691             debugprintf("It seems that I already record this vars start packet = %d\n",vars->start);
2692             wmem_free(wmem_file_scope(), vars);
2693         }
2694         else {
2695             debugprintf("Adding a new entry with this start packet = %d\n",vars->start);
2696             existing_vars->next_start = pinfo->num;
2697             existing_vars->next = vars;
2698         }
2699     }
2700     return offset;
2701 }
2702 
2703 static int
netlogon_dissect_netrserverreqchallenge_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2704 netlogon_dissect_netrserverreqchallenge_reply(tvbuff_t *tvb, int offset,
2705                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2706 {
2707     netlogon_auth_vars *vars;
2708     netlogon_auth_key key;
2709     guint64 server_challenge;
2710 
2711     generate_hash_key(pinfo,1,&key);
2712     vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths,(gconstpointer*) &key);
2713 
2714     offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
2715                                    hf_server_challenge, &server_challenge);
2716     /*offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2717       netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
2718       "CREDENTIAL: server credential", -1);*/
2719 
2720     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
2721                               hf_netlogon_rc, NULL);
2722     if(vars != NULL) {
2723         while(vars !=NULL && vars->next_start != -1 && vars->next_start < (int)pinfo->num )
2724         {
2725             vars = vars->next;
2726             debugprintf("looping challenge reply... %d %d \n", vars->next_start, pinfo->num);
2727         }
2728         if(vars == NULL)
2729         {
2730             debugprintf("Something strange happened while searching for challenge_reply\n");
2731         }
2732         else
2733         {
2734             vars->server_challenge = server_challenge;
2735         }
2736     }
2737 /*
2738   else
2739   {
2740   debugprintf("Vars not found in challenge reply\n");
2741   }
2742 */
2743     return offset;
2744 }
2745 
2746 
2747 static int
netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2748 netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvbuff_t *tvb, int offset,
2749                                               packet_info *pinfo, proto_tree *tree,
2750                                               dcerpc_info *di, guint8 *drep)
2751 {
2752     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
2753                                 hf_netlogon_secure_channel_type, NULL);
2754 
2755     return offset;
2756 }
2757 
2758 
2759 /*
2760  * IDL long NetrServerAuthenticate(
2761  * IDL      [in][unique][string] wchar_t *ServerName,
2762  * IDL      [in][ref][string] wchar_t *UserName,
2763  * IDL      [in] short secure_challenge_type,
2764  * IDL      [in][ref][string] wchar_t *ComputerName,
2765  * IDL      [in][ref] CREDENTIAL client_challenge,
2766  * IDL      [out][ref] CREDENTIAL server_challenge
2767  * IDL );
2768  */
2769 static int
netlogon_dissect_netrserverauthenticate_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2770 netlogon_dissect_netrserverauthenticate_rqst(tvbuff_t *tvb, int offset,
2771                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2772 {
2773     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
2774                                               pinfo, tree, di, drep);
2775 
2776     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2777                                           NDR_POINTER_REF, "User Name", hf_netlogon_acct_name, CB_STR_COL_INFO);
2778 
2779     offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
2780                                                            pinfo, tree, di, drep);
2781 
2782     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2783                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, CB_STR_COL_INFO);
2784 
2785     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2786                                  netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
2787                                  "CREDENTIAL: client challenge", -1);
2788 
2789     return offset;
2790 }
2791 static int
2792 netlogon_dissect_netrserverauthenticate023_reply(tvbuff_t *tvb, int offset,
2793                                                  packet_info *pinfo,
2794                                                  proto_tree *tree,
2795                                                  dcerpc_info *di,
2796                                                  guint8 *drep,
2797                                                  int version);
2798 static int
netlogon_dissect_netrserverauthenticate_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2799 netlogon_dissect_netrserverauthenticate_reply(tvbuff_t *tvb, int offset,
2800                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2801 {
2802     return netlogon_dissect_netrserverauthenticate023_reply(tvb,offset,pinfo,tree,di,drep,0);
2803 }
2804 
2805 
2806 
2807 /*
2808  * IDL typedef struct {
2809  * IDL   char encrypted_password[16];
2810  * IDL } ENCRYPTED_LM_OWF_PASSWORD;
2811  */
2812 static int
netlogon_dissect_ENCRYPTED_LM_OWF_PASSWORD(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,dcerpc_info * di,guint8 * drep _U_)2813 netlogon_dissect_ENCRYPTED_LM_OWF_PASSWORD(tvbuff_t *tvb, int offset,
2814                                            packet_info *pinfo _U_, proto_tree *tree,
2815                                            dcerpc_info *di, guint8 *drep _U_)
2816 {
2817     if(di->conformant_run){
2818         /*just a run to handle conformant arrays, nothing to dissect.*/
2819         return offset;
2820     }
2821 
2822     proto_tree_add_item(tree, hf_netlogon_encrypted_lm_owf_password, tvb, offset, 16,
2823                         ENC_NA);
2824     offset += 16;
2825 
2826     return offset;
2827 }
2828 
2829 /*
2830  * IDL long NetrServerPasswordSet(
2831  * IDL      [in][unique][string] wchar_t *ServerName,
2832  * IDL      [in][ref][string] wchar_t *UserName,
2833  * IDL      [in] short secure_challenge_type,
2834  * IDL      [in][ref][string] wchar_t *ComputerName,
2835  * IDL      [in][ref] AUTHENTICATOR credential,
2836  * IDL      [in][ref] LM_OWF_PASSWORD UasNewPassword,
2837  * IDL      [out][ref] AUTHENTICATOR return_authenticator
2838  * IDL );
2839  */
2840 static int
netlogon_dissect_netrserverpasswordset_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2841 netlogon_dissect_netrserverpasswordset_rqst(tvbuff_t *tvb, int offset,
2842                                             packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2843 {
2844     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
2845                                               pinfo, tree, di, drep);
2846 
2847     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2848                                           NDR_POINTER_REF, "User Name", hf_netlogon_acct_name, 0);
2849 
2850     offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
2851                                                            pinfo, tree, di, drep);
2852 
2853     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2854                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
2855 
2856     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2857                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
2858                                  "AUTHENTICATOR: credential", -1);
2859 
2860     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2861                                  netlogon_dissect_ENCRYPTED_LM_OWF_PASSWORD, NDR_POINTER_REF,
2862                                  "ENCRYPTED_LM_OWF_PASSWORD: hashed_pwd", -1);
2863 
2864     return offset;
2865 }
2866 static int
netlogon_dissect_netrserverpasswordset_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2867 netlogon_dissect_netrserverpasswordset_reply(tvbuff_t *tvb, int offset,
2868                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2869 {
2870     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2871                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
2872                                  "AUTHENTICATOR: return_authenticator", -1);
2873 
2874     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
2875                               hf_netlogon_rc, NULL);
2876 
2877     return offset;
2878 }
2879 
2880 
2881 /*
2882  * IDL typedef struct {
2883  * IDL   [unique][string] wchar_t *UserName;
2884  * IDL   UNICODESTRING dummy1;
2885  * IDL   UNICODESTRING dummy2;
2886  * IDL   UNICODESTRING dummy3;
2887  * IDL   UNICODESTRING dummy4;
2888  * IDL   long dummy5;
2889  * IDL   long dummy6;
2890  * IDL   long dummy7;
2891  * IDL   long dummy8;
2892  * IDL } DELTA_DELETE_USER;
2893  */
2894 static int
netlogon_dissect_DELTA_DELETE_USER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2895 netlogon_dissect_DELTA_DELETE_USER(tvbuff_t *tvb, int offset,
2896                                    packet_info *pinfo, proto_tree *tree,
2897                                    dcerpc_info *di, guint8 *drep)
2898 {
2899     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
2900                                           NDR_POINTER_UNIQUE, "Account Name", hf_netlogon_acct_name, 0);
2901 
2902     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2903                                         hf_netlogon_dummy, 0);
2904 
2905     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2906                                         hf_netlogon_dummy, 0);
2907 
2908     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2909                                         hf_netlogon_dummy, 0);
2910 
2911     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
2912                                         hf_netlogon_dummy, 0);
2913 
2914     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2915                                 hf_netlogon_reserved, NULL);
2916 
2917     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2918                                 hf_netlogon_reserved, NULL);
2919 
2920     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2921                                 hf_netlogon_reserved, NULL);
2922 
2923     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2924                                 hf_netlogon_reserved, NULL);
2925 
2926     return offset;
2927 }
2928 
2929 
2930 /*
2931  * IDL typedef struct {
2932  * IDL   bool SensitiveDataFlag;
2933  * IDL   long DataLength;
2934  * IDL   [unique][size_is(DataLength)] char *SensitiveData;
2935  * IDL } USER_PRIVATE_INFO;
2936  */
2937 static int
netlogon_dissect_SENSITIVE_DATA(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2938 netlogon_dissect_SENSITIVE_DATA(tvbuff_t *tvb, int offset,
2939                                 packet_info *pinfo, proto_tree *tree,
2940                                 dcerpc_info *di, guint8 *drep)
2941 {
2942     guint32 data_len;
2943 
2944     if(di->conformant_run){
2945         /*just a run to handle conformant arrays, nothing to dissect */
2946         return offset;
2947     }
2948 
2949     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2950                                 hf_netlogon_sensitive_data_len, &data_len);
2951 
2952     proto_tree_add_item(tree, hf_netlogon_sensitive_data, tvb, offset,
2953                         data_len, ENC_NA);
2954     offset += data_len;
2955 
2956     return offset;
2957 }
2958 static int
netlogon_dissect_USER_PRIVATE_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2959 netlogon_dissect_USER_PRIVATE_INFO(tvbuff_t *tvb, int offset,
2960                                    packet_info *pinfo, proto_tree *tree,
2961                                    dcerpc_info *di, guint8 *drep)
2962 {
2963     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
2964                                hf_netlogon_sensitive_data_flag, NULL);
2965 
2966     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2967                                 hf_netlogon_sensitive_data_len, NULL);
2968 
2969     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
2970                                  netlogon_dissect_SENSITIVE_DATA, NDR_POINTER_UNIQUE,
2971                                  "SENSITIVE_DATA", -1);
2972 
2973     return offset;
2974 }
2975 
2976 /*
2977  * IDL typedef struct {
2978  * IDL   UNICODESTRING UserName;
2979  * IDL   UNICODESTRING FullName;
2980  * IDL   long UserID;
2981  * IDL   long PrimaryGroupID;
2982  * IDL   UNICODESTRING HomeDir;
2983  * IDL   UNICODESTRING HomeDirDrive;
2984  * IDL   UNICODESTRING LogonScript;
2985  * IDL   UNICODESTRING Comment;
2986  * IDL   UNICODESTRING Workstations;
2987  * IDL   NTTIME LastLogon;
2988  * IDL   NTTIME LastLogoff;
2989  * IDL   LOGON_HOURS logonhours;
2990  * IDL   short BadPwCount;
2991  * IDL   short LogonCount;
2992  * IDL   NTTIME PwLastSet;
2993  * IDL   NTTIME AccountExpires;
2994  * IDL   long AccountControl;
2995  * IDL   LM_OWF_PASSWORD lmpw;
2996  * IDL   NT_OWF_PASSWORD ntpw;
2997  * IDL   bool NTPwPresent;
2998  * IDL   bool LMPwPresent;
2999  * IDL   bool PwExpired;
3000  * IDL   UNICODESTRING UserComment;
3001  * IDL   UNICODESTRING Parameters;
3002  * IDL   short CountryCode;
3003  * IDL   short CodePage;
3004  * IDL   USER_PRIVATE_INFO user_private_info;
3005  * IDL   long SecurityInformation;
3006  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3007  * IDL   UNICODESTRING dummy1;
3008  * IDL   UNICODESTRING dummy2;
3009  * IDL   UNICODESTRING dummy3;
3010  * IDL   UNICODESTRING dummy4;
3011  * IDL   long dummy5;
3012  * IDL   long dummy6;
3013  * IDL   long dummy7;
3014  * IDL   long dummy8;
3015  * IDL } DELTA_USER;
3016  */
3017 static int
netlogon_dissect_DELTA_USER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3018 netlogon_dissect_DELTA_USER(tvbuff_t *tvb, int offset,
3019                             packet_info *pinfo, proto_tree *tree,
3020                             dcerpc_info *di, guint8 *drep)
3021 {
3022     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3023                                         hf_netlogon_acct_name, 3);
3024 
3025     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3026                                         hf_netlogon_full_name, 0);
3027 
3028     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3029                                 hf_netlogon_user_rid, NULL);
3030 
3031     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3032                                 hf_netlogon_group_rid, NULL);
3033 
3034     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3035                                         hf_netlogon_home_dir, 0);
3036 
3037     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3038                                         hf_netlogon_dir_drive, 0);
3039 
3040     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3041                                         hf_netlogon_logon_script, 0);
3042 
3043     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3044                                         hf_netlogon_acct_desc, 0);
3045 
3046     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3047                                         hf_netlogon_workstations, 0);
3048 
3049     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3050                                    hf_netlogon_logon_time);
3051 
3052     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3053                                    hf_netlogon_logoff_time);
3054 
3055     offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, di, drep);
3056 
3057     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
3058                                 hf_netlogon_bad_pw_count16, NULL);
3059 
3060     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
3061                                 hf_netlogon_logon_count16, NULL);
3062 
3063     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3064                                    hf_netlogon_pwd_last_set_time);
3065 
3066     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3067                                    hf_netlogon_acct_expiry_time);
3068 
3069     offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, di, drep);
3070 
3071     offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
3072                                               pinfo, tree, di, drep);
3073 
3074     offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
3075                                               pinfo, tree, di, drep);
3076 
3077     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
3078                                hf_netlogon_nt_pwd_present, NULL);
3079 
3080     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
3081                                hf_netlogon_lm_pwd_present, NULL);
3082 
3083     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
3084                                hf_netlogon_pwd_expired, NULL);
3085 
3086     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3087                                         hf_netlogon_comment, 0);
3088 
3089     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3090                                         hf_netlogon_parameters, 0);
3091 
3092     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
3093                                 hf_netlogon_country, NULL);
3094 
3095     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
3096                                 hf_netlogon_codepage, NULL);
3097 
3098     offset = netlogon_dissect_USER_PRIVATE_INFO(tvb, offset, pinfo, tree,
3099                                                 di, drep);
3100 
3101     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3102                                 hf_netlogon_security_information, NULL);
3103 
3104     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3105 
3106     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3107                                         hf_netlogon_dummy, 0);
3108 
3109     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3110                                         hf_netlogon_dummy, 0);
3111 
3112     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3113                                         hf_netlogon_dummy, 0);
3114 
3115     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3116                                         hf_netlogon_dummy, 0);
3117 
3118     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3119                                 hf_netlogon_reserved, NULL);
3120 
3121     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3122                                 hf_netlogon_reserved, NULL);
3123 
3124     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3125                                 hf_netlogon_reserved, NULL);
3126 
3127     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3128                                 hf_netlogon_reserved, NULL);
3129 
3130     return offset;
3131 }
3132 
3133 
3134 /*
3135  * IDL typedef struct {
3136  * IDL   UNICODESTRING DomainName;
3137  * IDL   UNICODESTRING OEMInfo;
3138  * IDL   NTTIME forcedlogoff;
3139  * IDL   short minpasswdlen;
3140  * IDL   short passwdhistorylen;
3141  * IDL   NTTIME pwd_must_change_time;
3142  * IDL   NTTIME pwd_can_change_time;
3143  * IDL   NTTIME domain_modify_time;
3144  * IDL   NTTIME domain_create_time;
3145  * IDL   long SecurityInformation;
3146  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3147  * IDL   UNICODESTRING dummy1;
3148  * IDL   UNICODESTRING dummy2;
3149  * IDL   UNICODESTRING dummy3;
3150  * IDL   UNICODESTRING dummy4;
3151  * IDL   long dummy5;
3152  * IDL   long dummy6;
3153  * IDL   long dummy7;
3154  * IDL   long dummy8;
3155  * IDL } DELTA_DOMAIN;
3156  */
3157 static int
netlogon_dissect_DELTA_DOMAIN(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3158 netlogon_dissect_DELTA_DOMAIN(tvbuff_t *tvb, int offset,
3159                               packet_info *pinfo, proto_tree *tree,
3160                               dcerpc_info *di, guint8 *drep)
3161 {
3162     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3163                                         hf_netlogon_domain_name, 3);
3164 
3165     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3166                                         hf_netlogon_oem_info, 0);
3167 
3168     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3169                                    hf_netlogon_kickoff_time);
3170 
3171     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
3172                                 hf_netlogon_minpasswdlen, NULL);
3173 
3174     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
3175                                 hf_netlogon_passwdhistorylen, NULL);
3176 
3177     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3178                                    hf_netlogon_pwd_must_change_time);
3179 
3180     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3181                                    hf_netlogon_pwd_can_change_time);
3182 
3183     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3184                                    hf_netlogon_domain_modify_time);
3185 
3186     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3187                                    hf_netlogon_domain_create_time);
3188 
3189     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3190                                 hf_netlogon_security_information, NULL);
3191 
3192     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3193 
3194     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3195                                         hf_netlogon_dummy, 0);
3196 
3197     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3198                                         hf_netlogon_dummy, 0);
3199 
3200     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3201                                         hf_netlogon_dummy, 0);
3202 
3203     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3204                                         hf_netlogon_dummy, 0);
3205 
3206     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3207                                 hf_netlogon_reserved, NULL);
3208 
3209     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3210                                 hf_netlogon_reserved, NULL);
3211 
3212     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3213                                 hf_netlogon_reserved, NULL);
3214 
3215     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3216                                 hf_netlogon_reserved, NULL);
3217 
3218     return offset;
3219 }
3220 
3221 
3222 /*
3223  * IDL typedef struct {
3224  * IDL   UNICODESTRING groupname;
3225  * IDL   GROUP_MEMBERSHIP group_membership;
3226  * IDL   UNICODESTRING comment;
3227  * IDL   long SecurityInformation;
3228  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3229  * IDL   UNICODESTRING dummy1;
3230  * IDL   UNICODESTRING dummy2;
3231  * IDL   UNICODESTRING dummy3;
3232  * IDL   UNICODESTRING dummy4;
3233  * IDL   long dummy5;
3234  * IDL   long dummy6;
3235  * IDL   long dummy7;
3236  * IDL   long dummy8;
3237  * IDL } DELTA_GROUP;
3238  */
3239 static int
netlogon_dissect_DELTA_GROUP(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3240 netlogon_dissect_DELTA_GROUP(tvbuff_t *tvb, int offset,
3241                              packet_info *pinfo, proto_tree *tree,
3242                              dcerpc_info *di, guint8 *drep)
3243 {
3244     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3245                                         hf_netlogon_group_name, 3);
3246 
3247     offset = netlogon_dissect_GROUP_MEMBERSHIP(tvb, offset,
3248                                                pinfo, tree, di, drep);
3249 
3250     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3251                                         hf_netlogon_group_desc, 0);
3252 
3253     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3254                                 hf_netlogon_security_information, NULL);
3255 
3256     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3257 
3258     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3259                                         hf_netlogon_dummy, 0);
3260 
3261     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3262                                         hf_netlogon_dummy, 0);
3263 
3264     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3265                                         hf_netlogon_dummy, 0);
3266 
3267     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3268                                         hf_netlogon_dummy, 0);
3269 
3270     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3271                                 hf_netlogon_reserved, NULL);
3272 
3273     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3274                                 hf_netlogon_reserved, NULL);
3275 
3276     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3277                                 hf_netlogon_reserved, NULL);
3278 
3279     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3280                                 hf_netlogon_reserved, NULL);
3281 
3282     return offset;
3283 }
3284 
3285 
3286 /*
3287  * IDL typedef struct {
3288  * IDL   UNICODESTRING OldName;
3289  * IDL   UNICODESTRING NewName;
3290  * IDL   UNICODESTRING dummy1;
3291  * IDL   UNICODESTRING dummy2;
3292  * IDL   UNICODESTRING dummy3;
3293  * IDL   UNICODESTRING dummy4;
3294  * IDL   long dummy5;
3295  * IDL   long dummy6;
3296  * IDL   long dummy7;
3297  * IDL   long dummy8;
3298  * IDL } DELTA_RENAME;
3299  */
3300 static int
netlogon_dissect_DELTA_RENAME(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3301 netlogon_dissect_DELTA_RENAME(tvbuff_t *tvb, int offset,
3302                               packet_info *pinfo, proto_tree *tree,
3303                               dcerpc_info *di, guint8 *drep)
3304 {
3305     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3306                                         di->hf_index, 0);
3307 
3308     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3309                                         di->hf_index, 0);
3310 
3311     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3312                                         hf_netlogon_dummy, 0);
3313 
3314     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3315                                         hf_netlogon_dummy, 0);
3316 
3317     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3318                                         hf_netlogon_dummy, 0);
3319 
3320     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3321                                         hf_netlogon_dummy, 0);
3322 
3323     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3324                                 hf_netlogon_reserved, NULL);
3325 
3326     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3327                                 hf_netlogon_reserved, NULL);
3328 
3329     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3330                                 hf_netlogon_reserved, NULL);
3331 
3332     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3333                                 hf_netlogon_reserved, NULL);
3334 
3335     return offset;
3336 }
3337 
3338 
3339 static int
netlogon_dissect_RID(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3340 netlogon_dissect_RID(tvbuff_t *tvb, int offset,
3341                      packet_info *pinfo, proto_tree *tree,
3342                      dcerpc_info *di, guint8 *drep)
3343 {
3344     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3345                                 hf_netlogon_user_rid, NULL);
3346 
3347     return offset;
3348 }
3349 
3350 static int
netlogon_dissect_RID_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3351 netlogon_dissect_RID_array(tvbuff_t *tvb, int offset,
3352                            packet_info *pinfo, proto_tree *tree,
3353                            dcerpc_info *di, guint8 *drep)
3354 {
3355     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
3356                                  netlogon_dissect_RID);
3357 
3358     return offset;
3359 }
3360 
3361 static int
netlogon_dissect_ATTRIB(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3362 netlogon_dissect_ATTRIB(tvbuff_t *tvb, int offset,
3363                         packet_info *pinfo, proto_tree *tree,
3364                         dcerpc_info *di, guint8 *drep)
3365 {
3366     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3367                                 hf_netlogon_attrs, NULL);
3368 
3369     return offset;
3370 }
3371 
3372 static int
netlogon_dissect_ATTRIB_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3373 netlogon_dissect_ATTRIB_array(tvbuff_t *tvb, int offset,
3374                               packet_info *pinfo, proto_tree *tree,
3375                               dcerpc_info *di, guint8 *drep)
3376 {
3377     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
3378                                  netlogon_dissect_ATTRIB);
3379 
3380     return offset;
3381 }
3382 
3383 /*
3384  * IDL typedef struct {
3385  * IDL   [unique][size_is(num_rids)] long *rids;
3386  * IDL   [unique][size_is(num_rids)] long *attribs;
3387  * IDL   long num_rids;
3388  * IDL   long dummy1;
3389  * IDL   long dummy2;
3390  * IDL   long dummy3;
3391  * IDL   long dummy4;
3392  * IDL } DELTA_GROUP_MEMBER;
3393  */
3394 static int
netlogon_dissect_DELTA_GROUP_MEMBER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3395 netlogon_dissect_DELTA_GROUP_MEMBER(tvbuff_t *tvb, int offset,
3396                                     packet_info *pinfo, proto_tree *tree,
3397                                     dcerpc_info *di, guint8 *drep)
3398 {
3399     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
3400                                  netlogon_dissect_RID_array, NDR_POINTER_UNIQUE,
3401                                  "RIDs:", -1);
3402 
3403     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
3404                                  netlogon_dissect_ATTRIB_array, NDR_POINTER_UNIQUE,
3405                                  "Attribs:", -1);
3406 
3407     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3408                                 hf_netlogon_num_rids, NULL);
3409 
3410     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3411                                 hf_netlogon_reserved, NULL);
3412 
3413     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3414                                 hf_netlogon_reserved, NULL);
3415 
3416     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3417                                 hf_netlogon_reserved, NULL);
3418 
3419     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3420                                 hf_netlogon_reserved, NULL);
3421 
3422     return offset;
3423 }
3424 
3425 
3426 /*
3427  * IDL typedef struct {
3428  * IDL   UNICODESTRING alias_name;
3429  * IDL   long rid;
3430  * IDL   long SecurityInformation;
3431  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3432  * IDL   UNICODESTRING dummy1;
3433  * IDL   UNICODESTRING dummy2;
3434  * IDL   UNICODESTRING dummy3;
3435  * IDL   UNICODESTRING dummy4;
3436  * IDL   long dummy5;
3437  * IDL   long dummy6;
3438  * IDL   long dummy7;
3439  * IDL   long dummy8;
3440  * IDL } DELTA_ALIAS;
3441  */
3442 static int
netlogon_dissect_DELTA_ALIAS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3443 netlogon_dissect_DELTA_ALIAS(tvbuff_t *tvb, int offset,
3444                              packet_info *pinfo, proto_tree *tree,
3445                              dcerpc_info *di, guint8 *drep)
3446 {
3447     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3448                                         hf_netlogon_alias_name, 0);
3449 
3450     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3451                                 hf_netlogon_alias_rid, NULL);
3452 
3453     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3454                                 hf_netlogon_security_information, NULL);
3455 
3456     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3457 
3458     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3459                                         hf_netlogon_dummy, 0);
3460 
3461     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3462                                         hf_netlogon_dummy, 0);
3463 
3464     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3465                                         hf_netlogon_dummy, 0);
3466 
3467     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3468                                         hf_netlogon_dummy, 0);
3469 
3470     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3471                                 hf_netlogon_reserved, NULL);
3472 
3473     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3474                                 hf_netlogon_reserved, NULL);
3475 
3476     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3477                                 hf_netlogon_reserved, NULL);
3478 
3479     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3480                                 hf_netlogon_reserved, NULL);
3481 
3482     return offset;
3483 }
3484 
3485 
3486 /*
3487  * IDL typedef struct {
3488  * IDL   [unique] SID_ARRAY sids;
3489  * IDL   long dummy1;
3490  * IDL   long dummy2;
3491  * IDL   long dummy3;
3492  * IDL   long dummy4;
3493  * IDL } DELTA_ALIAS_MEMBER;
3494  */
3495 static int
netlogon_dissect_DELTA_ALIAS_MEMBER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3496 netlogon_dissect_DELTA_ALIAS_MEMBER(tvbuff_t *tvb, int offset,
3497                                     packet_info *pinfo, proto_tree *tree,
3498                                     dcerpc_info *di, guint8 *drep)
3499 {
3500     offset = dissect_ndr_nt_PSID_ARRAY(tvb, offset, pinfo, tree, di, drep);
3501 
3502     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3503                                 hf_netlogon_reserved, NULL);
3504 
3505     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3506                                 hf_netlogon_reserved, NULL);
3507 
3508     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3509                                 hf_netlogon_reserved, NULL);
3510 
3511     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3512                                 hf_netlogon_reserved, NULL);
3513 
3514     return offset;
3515 }
3516 
3517 
3518 static int
netlogon_dissect_EVENT_AUDIT_OPTION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3519 netlogon_dissect_EVENT_AUDIT_OPTION(tvbuff_t *tvb, int offset,
3520                                     packet_info *pinfo, proto_tree *tree,
3521                                     dcerpc_info *di, guint8 *drep)
3522 {
3523     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3524                                 hf_netlogon_event_audit_option, NULL);
3525 
3526     return offset;
3527 }
3528 
3529 static int
netlogon_dissect_EVENT_AUDIT_OPTIONS_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3530 netlogon_dissect_EVENT_AUDIT_OPTIONS_ARRAY(tvbuff_t *tvb, int offset,
3531                                            packet_info *pinfo, proto_tree *tree,
3532                                            dcerpc_info *di, guint8 *drep)
3533 {
3534     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
3535                                  netlogon_dissect_EVENT_AUDIT_OPTION);
3536 
3537     return offset;
3538 }
3539 
3540 
3541 /*
3542  * IDL typedef struct {
3543  * IDL   long pagedpoollimit;
3544  * IDL   long nonpagedpoollimit;
3545  * IDL   long minimumworkingsetsize;
3546  * IDL   long maximumworkingsetsize;
3547  * IDL   long pagefilelimit;
3548  * IDL   NTTIME timelimit;
3549  * IDL } QUOTA_LIMITS;
3550  */
3551 static int
netlogon_dissect_QUOTA_LIMITS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)3552 netlogon_dissect_QUOTA_LIMITS(tvbuff_t *tvb, int offset,
3553                               packet_info *pinfo, proto_tree *parent_tree,
3554                               dcerpc_info *di, guint8 *drep)
3555 {
3556     proto_item *item=NULL;
3557     proto_tree *tree=NULL;
3558     int old_offset=offset;
3559 
3560     if(parent_tree){
3561         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
3562                                    ett_QUOTA_LIMITS, &item, "QUOTA_LIMTS:");
3563     }
3564 
3565     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3566                                 hf_netlogon_pagedpoollimit, NULL);
3567 
3568     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3569                                 hf_netlogon_nonpagedpoollimit, NULL);
3570 
3571     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3572                                 hf_netlogon_minworkingsetsize, NULL);
3573 
3574     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3575                                 hf_netlogon_maxworkingsetsize, NULL);
3576 
3577     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3578                                 hf_netlogon_pagefilelimit, NULL);
3579 
3580     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3581                                    hf_netlogon_timelimit);
3582 
3583     proto_item_set_len(item, offset-old_offset);
3584     return offset;
3585 }
3586 
3587 
3588 /*
3589  * IDL typedef struct {
3590  * IDL   long maxlogsize;
3591  * IDL   NTTIME auditretentionperiod;
3592  * IDL   bool auditingmode;
3593  * IDL   long maxauditeventcount;
3594  * IDL   [unique][size_is(maxauditeventcount)] long *eventauditoptions;
3595  * IDL   UNICODESTRING primarydomainname;
3596  * IDL   [unique] SID *sid;
3597  * IDL   QUOTA_LIMITS quota_limits;
3598  * IDL   NTTIME db_modify_time;
3599  * IDL   NTTIME db_create_time;
3600  * IDL   long SecurityInformation;
3601  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3602  * IDL   UNICODESTRING dummy1;
3603  * IDL   UNICODESTRING dummy2;
3604  * IDL   UNICODESTRING dummy3;
3605  * IDL   UNICODESTRING dummy4;
3606  * IDL   long dummy5;
3607  * IDL   long dummy6;
3608  * IDL   long dummy7;
3609  * IDL   long dummy8;
3610  * IDL } DELTA_POLICY;
3611  */
3612 static int
netlogon_dissect_DELTA_POLICY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3613 netlogon_dissect_DELTA_POLICY(tvbuff_t *tvb, int offset,
3614                               packet_info *pinfo, proto_tree *tree,
3615                               dcerpc_info *di, guint8 *drep)
3616 {
3617     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3618                                 hf_netlogon_max_log_size, NULL);
3619 
3620     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3621                                    hf_netlogon_audit_retention_period);
3622 
3623     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
3624                                hf_netlogon_auditing_mode, NULL);
3625 
3626     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3627                                 hf_netlogon_max_audit_event_count, NULL);
3628 
3629     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
3630                                  netlogon_dissect_EVENT_AUDIT_OPTIONS_ARRAY, NDR_POINTER_UNIQUE,
3631                                  "Event Audit Options:", -1);
3632 
3633     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3634                                         hf_netlogon_domain_name, 0);
3635 
3636     offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
3637 
3638     offset = netlogon_dissect_QUOTA_LIMITS(tvb, offset,
3639                                            pinfo, tree, di, drep);
3640 
3641     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3642                                    hf_netlogon_db_modify_time);
3643 
3644     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3645                                    hf_netlogon_db_create_time);
3646 
3647     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3648                                 hf_netlogon_security_information, NULL);
3649 
3650     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3651 
3652     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3653                                         hf_netlogon_dummy, 0);
3654 
3655     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3656                                         hf_netlogon_dummy, 0);
3657 
3658     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3659                                         hf_netlogon_dummy, 0);
3660 
3661     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3662                                         hf_netlogon_dummy, 0);
3663 
3664     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3665                                 hf_netlogon_reserved, NULL);
3666 
3667     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3668                                 hf_netlogon_reserved, NULL);
3669 
3670     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3671                                 hf_netlogon_reserved, NULL);
3672 
3673     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3674                                 hf_netlogon_reserved, NULL);
3675 
3676     return offset;
3677 }
3678 
3679 
3680 static int
netlogon_dissect_CONTROLLER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3681 netlogon_dissect_CONTROLLER(tvbuff_t *tvb, int offset,
3682                             packet_info *pinfo, proto_tree *tree,
3683                             dcerpc_info *di, guint8 *drep)
3684 {
3685     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3686                                         hf_netlogon_dc_name, 0);
3687 
3688     return offset;
3689 }
3690 
3691 static int
netlogon_dissect_CONTROLLER_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3692 netlogon_dissect_CONTROLLER_ARRAY(tvbuff_t *tvb, int offset,
3693                                   packet_info *pinfo, proto_tree *tree,
3694                                   dcerpc_info *di, guint8 *drep)
3695 {
3696     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
3697                                  netlogon_dissect_CONTROLLER);
3698 
3699     return offset;
3700 }
3701 
3702 
3703 /*
3704  * IDL typedef struct {
3705  * IDL   UNICODESTRING DomainName;
3706  * IDL   long num_controllers;
3707  * IDL   [unique][size_is(num_controllers)] UNICODESTRING *controller_names;
3708  * IDL   long SecurityInformation;
3709  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3710  * IDL   UNICODESTRING dummy1;
3711  * IDL   UNICODESTRING dummy2;
3712  * IDL   UNICODESTRING dummy3;
3713  * IDL   UNICODESTRING dummy4;
3714  * IDL   long dummy5;
3715  * IDL   long dummy6;
3716  * IDL   long dummy7;
3717  * IDL   long dummy8;
3718  * IDL } DELTA_TRUSTED_DOMAINS;
3719  */
3720 static int
netlogon_dissect_DELTA_TRUSTED_DOMAINS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3721 netlogon_dissect_DELTA_TRUSTED_DOMAINS(tvbuff_t *tvb, int offset,
3722                                        packet_info *pinfo, proto_tree *tree,
3723                                        dcerpc_info *di, guint8 *drep)
3724 {
3725     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3726                                         hf_netlogon_domain_name, 0);
3727 
3728     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3729                                 hf_netlogon_num_controllers, NULL);
3730 
3731     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
3732                                  netlogon_dissect_CONTROLLER_ARRAY, NDR_POINTER_UNIQUE,
3733                                  "Domain Controllers:", -1);
3734 
3735     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3736                                 hf_netlogon_security_information, NULL);
3737 
3738     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3739 
3740     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3741                                         hf_netlogon_dummy, 0);
3742 
3743     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3744                                         hf_netlogon_dummy, 0);
3745 
3746     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3747                                         hf_netlogon_dummy, 0);
3748 
3749     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3750                                         hf_netlogon_dummy, 0);
3751 
3752     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3753                                 hf_netlogon_reserved, NULL);
3754 
3755     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3756                                 hf_netlogon_reserved, NULL);
3757 
3758     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3759                                 hf_netlogon_reserved, NULL);
3760 
3761     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3762                                 hf_netlogon_reserved, NULL);
3763 
3764     return offset;
3765 }
3766 
3767 
3768 static int
netlogon_dissect_PRIV_ATTR(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3769 netlogon_dissect_PRIV_ATTR(tvbuff_t *tvb, int offset,
3770                            packet_info *pinfo, proto_tree *tree,
3771                            dcerpc_info *di, guint8 *drep)
3772 {
3773     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3774                                 hf_netlogon_attrs, NULL);
3775 
3776     return offset;
3777 }
3778 
3779 static int
netlogon_dissect_PRIV_ATTR_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3780 netlogon_dissect_PRIV_ATTR_ARRAY(tvbuff_t *tvb, int offset,
3781                                  packet_info *pinfo, proto_tree *tree,
3782                                  dcerpc_info *di, guint8 *drep)
3783 {
3784     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
3785                                  netlogon_dissect_PRIV_ATTR);
3786 
3787     return offset;
3788 }
3789 
3790 static int
netlogon_dissect_PRIV_NAME(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3791 netlogon_dissect_PRIV_NAME(tvbuff_t *tvb, int offset,
3792                            packet_info *pinfo, proto_tree *tree,
3793                            dcerpc_info *di, guint8 *drep)
3794 {
3795     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3796                                         hf_netlogon_privilege_name, 1);
3797 
3798     return offset;
3799 }
3800 
3801 static int
netlogon_dissect_PRIV_NAME_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3802 netlogon_dissect_PRIV_NAME_ARRAY(tvbuff_t *tvb, int offset,
3803                                  packet_info *pinfo, proto_tree *tree,
3804                                  dcerpc_info *di, guint8 *drep)
3805 {
3806     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
3807                                  netlogon_dissect_PRIV_NAME);
3808 
3809     return offset;
3810 }
3811 
3812 
3813 
3814 /*
3815  * IDL typedef struct {
3816  * IDL   long privilegeentries;
3817  * IDL   long provolegecontrol;
3818  * IDL   [unique][size_is(privilege_entries)] long *privilege_attrib;
3819  * IDL   [unique][size_is(privilege_entries)] UNICODESTRING *privilege_name;
3820  * IDL   QUOTALIMITS quotalimits;
3821  * IDL   long SecurityInformation;
3822  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3823  * IDL   UNICODESTRING dummy1;
3824  * IDL   UNICODESTRING dummy2;
3825  * IDL   UNICODESTRING dummy3;
3826  * IDL   UNICODESTRING dummy4;
3827  * IDL   long dummy5;
3828  * IDL   long dummy6;
3829  * IDL   long dummy7;
3830  * IDL   long dummy8;
3831  * IDL } DELTA_ACCOUNTS;
3832  */
3833 static int
netlogon_dissect_DELTA_ACCOUNTS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3834 netlogon_dissect_DELTA_ACCOUNTS(tvbuff_t *tvb, int offset,
3835                                 packet_info *pinfo, proto_tree *tree,
3836                                 dcerpc_info *di, guint8 *drep)
3837 {
3838     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3839                                 hf_netlogon_privilege_entries, NULL);
3840 
3841     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3842                                 hf_netlogon_privilege_control, NULL);
3843 
3844     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
3845                                  netlogon_dissect_PRIV_ATTR_ARRAY, NDR_POINTER_UNIQUE,
3846                                  "PRIV_ATTR_ARRAY:", -1);
3847 
3848     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
3849                                  netlogon_dissect_PRIV_NAME_ARRAY, NDR_POINTER_UNIQUE,
3850                                  "PRIV_NAME_ARRAY:", -1);
3851 
3852     offset = netlogon_dissect_QUOTA_LIMITS(tvb, offset,
3853                                            pinfo, tree, di, drep);
3854 
3855     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3856                                 hf_netlogon_systemflags, NULL);
3857 
3858     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3859                                 hf_netlogon_security_information, NULL);
3860 
3861     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3862 
3863     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3864                                         hf_netlogon_dummy, 0);
3865 
3866     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3867                                         hf_netlogon_dummy, 0);
3868 
3869     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3870                                         hf_netlogon_dummy, 0);
3871 
3872     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3873                                         hf_netlogon_dummy, 0);
3874 
3875     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3876                                 hf_netlogon_reserved, NULL);
3877 
3878     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3879                                 hf_netlogon_reserved, NULL);
3880 
3881     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3882                                 hf_netlogon_reserved, NULL);
3883 
3884     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3885                                 hf_netlogon_reserved, NULL);
3886 
3887     return offset;
3888 }
3889 
3890 /*
3891  * IDL typedef struct {
3892  * IDL   long len;
3893  * IDL   long maxlen;
3894  * IDL   [unique][size_is(maxlen)][length_is(len)] char *cipher_data;
3895  * IDL } CIPHER_VALUE;
3896  */
3897 static int
netlogon_dissect_CIPHER_VALUE_DATA(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3898 netlogon_dissect_CIPHER_VALUE_DATA(tvbuff_t *tvb, int offset,
3899                                    packet_info *pinfo, proto_tree *tree,
3900                                    dcerpc_info *di, guint8 *drep)
3901 {
3902     guint32 data_len;
3903 
3904     if(di->conformant_run){
3905         /*just a run to handle conformant arrays, nothing to dissect */
3906         return offset;
3907     }
3908 
3909     offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
3910                                  hf_netlogon_cipher_maxlen, NULL);
3911 
3912     /* skip offset */
3913     offset += 4;
3914 
3915     offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
3916                                  hf_netlogon_cipher_len, &data_len);
3917 
3918     proto_tree_add_item(tree, di->hf_index, tvb, offset,
3919                         data_len, ENC_NA);
3920     offset += data_len;
3921 
3922     return offset;
3923 }
3924 static int
netlogon_dissect_CIPHER_VALUE(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep,const char * name,int hf_index)3925 netlogon_dissect_CIPHER_VALUE(tvbuff_t *tvb, int offset,
3926                               packet_info *pinfo, proto_tree *parent_tree,
3927                               dcerpc_info *di, guint8 *drep, const char *name, int hf_index)
3928 {
3929     proto_item *item=NULL;
3930     proto_tree *tree=NULL;
3931     int old_offset=offset;
3932 
3933     if(parent_tree){
3934         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
3935                                    ett_CYPHER_VALUE, &item, name);
3936     }
3937 
3938     offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
3939                                  hf_netlogon_cipher_len, NULL);
3940 
3941     offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
3942                                  hf_netlogon_cipher_maxlen, NULL);
3943 
3944     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
3945                                  netlogon_dissect_CIPHER_VALUE_DATA, NDR_POINTER_UNIQUE,
3946                                  name, hf_index);
3947 
3948     proto_item_set_len(item, offset-old_offset);
3949     return offset;
3950 }
3951 
3952 /*
3953  * IDL typedef struct {
3954  * IDL   CIPHER_VALUE current_cipher;
3955  * IDL   NTTIME current_cipher_set_time;
3956  * IDL   CIPHER_VALUE old_cipher;
3957  * IDL   NTTIME old_cipher_set_time;
3958  * IDL   long SecurityInformation;
3959  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
3960  * IDL   UNICODESTRING dummy1;
3961  * IDL   UNICODESTRING dummy2;
3962  * IDL   UNICODESTRING dummy3;
3963  * IDL   UNICODESTRING dummy4;
3964  * IDL   long dummy5;
3965  * IDL   long dummy6;
3966  * IDL   long dummy7;
3967  * IDL   long dummy8;
3968  * IDL } DELTA_SECRET;
3969  */
3970 static int
netlogon_dissect_DELTA_SECRET(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3971 netlogon_dissect_DELTA_SECRET(tvbuff_t *tvb, int offset,
3972                               packet_info *pinfo, proto_tree *tree,
3973                               dcerpc_info *di, guint8 *drep)
3974 {
3975     offset = netlogon_dissect_CIPHER_VALUE(tvb, offset,
3976                                            pinfo, tree, di, drep,
3977                                            "CIPHER_VALUE: current cipher value",
3978                                            hf_netlogon_cipher_current_data);
3979 
3980     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3981                                    hf_netlogon_cipher_current_set_time);
3982 
3983     offset = netlogon_dissect_CIPHER_VALUE(tvb, offset,
3984                                            pinfo, tree, di, drep,
3985                                            "CIPHER_VALUE: old cipher value",
3986                                            hf_netlogon_cipher_old_data);
3987 
3988     offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep,
3989                                    hf_netlogon_cipher_old_set_time);
3990 
3991     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3992                                 hf_netlogon_security_information, NULL);
3993 
3994     offset = lsarpc_dissect_sec_desc_buf(tvb, offset, pinfo, tree, di, drep);
3995 
3996     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
3997                                         hf_netlogon_dummy, 0);
3998 
3999     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
4000                                         hf_netlogon_dummy, 0);
4001 
4002     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
4003                                         hf_netlogon_dummy, 0);
4004 
4005     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
4006                                         hf_netlogon_dummy, 0);
4007 
4008     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4009                                 hf_netlogon_reserved, NULL);
4010 
4011     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4012                                 hf_netlogon_reserved, NULL);
4013 
4014     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4015                                 hf_netlogon_reserved, NULL);
4016 
4017     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4018                                 hf_netlogon_reserved, NULL);
4019 
4020     return offset;
4021 }
4022 
4023 /*
4024  * IDL typedef struct {
4025  * IDL   long low_value;
4026  * IDL   long high_value;
4027  * } MODIFIED_COUNT;
4028  */
4029 static int
netlogon_dissect_MODIFIED_COUNT(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4030 netlogon_dissect_MODIFIED_COUNT(tvbuff_t *tvb, int offset,
4031                                 packet_info *pinfo, proto_tree *tree,
4032                                 dcerpc_info *di, guint8 *drep)
4033 {
4034     offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, di, drep,
4035                                  hf_netlogon_modify_count, NULL);
4036 
4037     return offset;
4038 }
4039 
4040 
4041 #define DT_DELTA_DOMAIN                  1
4042 #define DT_DELTA_GROUP                   2
4043 #define DT_DELTA_DELETE_GROUP            3
4044 #define DT_DELTA_RENAME_GROUP            4
4045 #define DT_DELTA_USER                    5
4046 #define DT_DELTA_DELETE_USER             6
4047 #define DT_DELTA_RENAME_USER             7
4048 #define DT_DELTA_GROUP_MEMBER            8
4049 #define DT_DELTA_ALIAS                   9
4050 #define DT_DELTA_DELETE_ALIAS           10
4051 #define DT_DELTA_RENAME_ALIAS           11
4052 #define DT_DELTA_ALIAS_MEMBER           12
4053 #define DT_DELTA_POLICY                 13
4054 #define DT_DELTA_TRUSTED_DOMAINS        14
4055 #define DT_DELTA_DELETE_TRUST           15
4056 #define DT_DELTA_ACCOUNTS               16
4057 #define DT_DELTA_DELETE_ACCOUNT         17
4058 #define DT_DELTA_SECRET                 18
4059 #define DT_DELTA_DELETE_SECRET          19
4060 #define DT_DELTA_DELETE_GROUP2          20
4061 #define DT_DELTA_DELETE_USER2           21
4062 #define DT_MODIFIED_COUNT               22
4063 
4064 static const value_string delta_type_vals[] = {
4065     { DT_DELTA_DOMAIN,          "Domain" },
4066     { DT_DELTA_GROUP,           "Group" },
4067     { DT_DELTA_DELETE_GROUP,    "Delete Group" },
4068     { DT_DELTA_RENAME_GROUP,    "Rename Group" },
4069     { DT_DELTA_USER,            "User" },
4070     { DT_DELTA_DELETE_USER,     "Delete User" },
4071     { DT_DELTA_RENAME_USER,     "Rename User" },
4072     { DT_DELTA_GROUP_MEMBER,    "Group Member" },
4073     { DT_DELTA_ALIAS,           "Alias" },
4074     { DT_DELTA_DELETE_ALIAS,    "Delete Alias" },
4075     { DT_DELTA_RENAME_ALIAS,    "Rename Alias" },
4076     { DT_DELTA_ALIAS_MEMBER,    "Alias Member" },
4077     { DT_DELTA_POLICY,          "Policy" },
4078     { DT_DELTA_TRUSTED_DOMAINS, "Trusted Domains" },
4079     { DT_DELTA_DELETE_TRUST,    "Delete Trust" },
4080     { DT_DELTA_ACCOUNTS,        "Accounts" },
4081     { DT_DELTA_DELETE_ACCOUNT,  "Delete Account" },
4082     { DT_DELTA_SECRET,          "Secret" },
4083     { DT_DELTA_DELETE_SECRET,   "Delete Secret" },
4084     { DT_DELTA_DELETE_GROUP2,   "Delete Group2" },
4085     { DT_DELTA_DELETE_USER2,    "Delete User2" },
4086     { DT_MODIFIED_COUNT,        "Modified Count" },
4087     { 0, NULL }
4088 };
4089 /*
4090  * IDL typedef [switch_type(short)] union {
4091  * IDL   [case(1)][unique] DELTA_DOMAIN *domain;
4092  * IDL   [case(2)][unique] DELTA_GROUP *group;
4093  * IDL   [case(3)][unique] rid only ;
4094  * IDL   [case(4)][unique] DELTA_RENAME_GROUP *rename_group;
4095  * IDL   [case(5)][unique] DELTA_USER *user;
4096  * IDL   [case(6)][unique] rid only ;
4097  * IDL   [case(7)][unique] DELTA_RENAME_USER *rename_user;
4098  * IDL   [case(8)][unique] DELTA_GROUP_MEMBER *group_member;
4099  * IDL   [case(9)][unique] DELTA_ALIAS *alias;
4100  * IDL   [case(10)][unique] rid only ;
4101  * IDL   [case(11)][unique] DELTA_RENAME_ALIAS *alias;
4102  * IDL   [case(12)][unique] DELTA_ALIAS_MEMBER *alias_member;
4103  * IDL   [case(13)][unique] DELTA_POLICY *policy;
4104  * IDL   [case(14)][unique] DELTA_TRUSTED_DOMAINS *trusted_domains;
4105  * IDL   [case(15)][unique] PSID ;
4106  * IDL   [case(16)][unique] DELTA_ACCOUNTS *accounts;
4107  * IDL   [case(17)][unique] PSID ;
4108  * IDL   [case(18)][unique] DELTA_SECRET *secret;
4109  * IDL   [case(19)][unique] string;
4110  * IDL   [case(20)][unique] DELTA_DELETE_GROUP2 *delete_group;
4111  * IDL   [case(21)][unique] DELTA_DELETE_USER2 *delete_user;
4112  * IDL   [case(22)][unique] MODIFIED_COUNT *modified_count;
4113  * IDL } DELTA_UNION;
4114  */
4115 static int
netlogon_dissect_DELTA_UNION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)4116 netlogon_dissect_DELTA_UNION(tvbuff_t *tvb, int offset,
4117                              packet_info *pinfo, proto_tree *parent_tree,
4118                              dcerpc_info *di, guint8 *drep)
4119 {
4120     proto_item *item=NULL;
4121     proto_tree *tree=NULL;
4122     int old_offset=offset;
4123     guint16 level = 0;
4124 
4125     if(parent_tree){
4126         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
4127                                    ett_DELTA_UNION, &item, "DELTA_UNION:");
4128     }
4129 
4130     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
4131                                 hf_netlogon_delta_type, &level);
4132 
4133     ALIGN_TO_4_BYTES;
4134     switch(level){
4135     case 1:
4136         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4137                                      netlogon_dissect_DELTA_DOMAIN, NDR_POINTER_UNIQUE,
4138                                      "DELTA_DOMAIN:", -1);
4139         break;
4140     case 2:
4141         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4142                                      netlogon_dissect_DELTA_GROUP, NDR_POINTER_UNIQUE,
4143                                      "DELTA_GROUP:", -1);
4144         break;
4145     case 4:
4146         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4147                                      netlogon_dissect_DELTA_RENAME, NDR_POINTER_UNIQUE,
4148                                      "DELTA_RENAME_GROUP:", hf_netlogon_group_name);
4149         break;
4150     case 5:
4151         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4152                                      netlogon_dissect_DELTA_USER, NDR_POINTER_UNIQUE,
4153                                      "DELTA_USER:", -1);
4154         break;
4155     case 7:
4156         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4157                                      netlogon_dissect_DELTA_RENAME, NDR_POINTER_UNIQUE,
4158                                      "DELTA_RENAME_USER:", hf_netlogon_acct_name);
4159         break;
4160     case 8:
4161         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4162                                      netlogon_dissect_DELTA_GROUP_MEMBER, NDR_POINTER_UNIQUE,
4163                                      "DELTA_GROUP_MEMBER:", -1);
4164         break;
4165     case 9:
4166         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4167                                      netlogon_dissect_DELTA_ALIAS, NDR_POINTER_UNIQUE,
4168                                      "DELTA_ALIAS:", -1);
4169         break;
4170     case 11:
4171         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4172                                      netlogon_dissect_DELTA_RENAME, NDR_POINTER_UNIQUE,
4173                                      "DELTA_RENAME_ALIAS:", hf_netlogon_alias_name);
4174         break;
4175     case 12:
4176         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4177                                      netlogon_dissect_DELTA_ALIAS_MEMBER, NDR_POINTER_UNIQUE,
4178                                      "DELTA_ALIAS_MEMBER:", -1);
4179         break;
4180     case 13:
4181         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4182                                      netlogon_dissect_DELTA_POLICY, NDR_POINTER_UNIQUE,
4183                                      "DELTA_POLICY:", -1);
4184         break;
4185     case 14:
4186         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4187                                      netlogon_dissect_DELTA_TRUSTED_DOMAINS, NDR_POINTER_UNIQUE,
4188                                      "DELTA_TRUSTED_DOMAINS:", -1);
4189         break;
4190     case 16:
4191         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4192                                      netlogon_dissect_DELTA_ACCOUNTS, NDR_POINTER_UNIQUE,
4193                                      "DELTA_ACCOUNTS:", -1);
4194         break;
4195     case 18:
4196         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4197                                      netlogon_dissect_DELTA_SECRET, NDR_POINTER_UNIQUE,
4198                                      "DELTA_SECRET:", -1);
4199         break;
4200     case 20:
4201         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4202                                      netlogon_dissect_DELTA_DELETE_USER, NDR_POINTER_UNIQUE,
4203                                      "DELTA_DELETE_GROUP:", -1);
4204         break;
4205     case 21:
4206         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4207                                      netlogon_dissect_DELTA_DELETE_USER, NDR_POINTER_UNIQUE,
4208                                      "DELTA_DELETE_USER:", -1);
4209         break;
4210     case 22:
4211         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4212                                      netlogon_dissect_MODIFIED_COUNT, NDR_POINTER_UNIQUE,
4213                                      "MODIFIED_COUNT:", -1);
4214         break;
4215     }
4216 
4217     proto_item_set_len(item, offset-old_offset);
4218     return offset;
4219 }
4220 
4221 
4222 
4223 /* IDL XXX must verify this one, especially 13-19
4224  * IDL typedef [switch_type(short)] union {
4225  * IDL   [case(1)] long rid;
4226  * IDL   [case(2)] long rid;
4227  * IDL   [case(3)] long rid;
4228  * IDL   [case(4)] long rid;
4229  * IDL   [case(5)] long rid;
4230  * IDL   [case(6)] long rid;
4231  * IDL   [case(7)] long rid;
4232  * IDL   [case(8)] long rid;
4233  * IDL   [case(9)] long rid;
4234  * IDL   [case(10)] long rid;
4235  * IDL   [case(11)] long rid;
4236  * IDL   [case(12)] long rid;
4237  * IDL   [case(13)] [unique] SID *sid;
4238  * IDL   [case(14)] [unique] SID *sid;
4239  * IDL   [case(15)] [unique] SID *sid;
4240  * IDL   [case(16)] [unique] SID *sid;
4241  * IDL   [case(17)] [unique] SID *sid;
4242  * IDL   [case(18)] [unique][string] wchar_t *Name ;
4243  * IDL   [case(19)] [unique][string] wchar_t *Name ;
4244  * IDL   [case(20)] long rid;
4245  * IDL   [case(21)] long rid;
4246  * IDL } DELTA_ID_UNION;
4247  */
4248 static int
netlogon_dissect_DELTA_ID_UNION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)4249 netlogon_dissect_DELTA_ID_UNION(tvbuff_t *tvb, int offset,
4250                                 packet_info *pinfo, proto_tree *parent_tree,
4251                                 dcerpc_info *di, guint8 *drep)
4252 {
4253     proto_item *item=NULL;
4254     proto_tree *tree=NULL;
4255     int old_offset=offset;
4256     guint16 level = 0;
4257 
4258     if(parent_tree){
4259         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
4260                                    ett_DELTA_ID_UNION, &item, "DELTA_ID_UNION:");
4261     }
4262 
4263     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
4264                                 hf_netlogon_delta_type, &level);
4265 
4266     ALIGN_TO_4_BYTES;
4267     switch(level){
4268     case 1:
4269         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4270                                     hf_netlogon_group_rid, NULL);
4271         break;
4272     case 2:
4273         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4274                                     hf_netlogon_user_rid, NULL);
4275         break;
4276     case 3:
4277         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4278                                     hf_netlogon_user_rid, NULL);
4279         break;
4280     case 4:
4281         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4282                                     hf_netlogon_user_rid, NULL);
4283         break;
4284     case 5:
4285         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4286                                     hf_netlogon_user_rid, NULL);
4287         break;
4288     case 6:
4289         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4290                                     hf_netlogon_user_rid, NULL);
4291         break;
4292     case 7:
4293         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4294                                     hf_netlogon_user_rid, NULL);
4295         break;
4296     case 8:
4297         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4298                                     hf_netlogon_user_rid, NULL);
4299         break;
4300     case 9:
4301         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4302                                     hf_netlogon_user_rid, NULL);
4303         break;
4304     case 10:
4305         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4306                                     hf_netlogon_user_rid, NULL);
4307         break;
4308     case 11:
4309         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4310                                     hf_netlogon_user_rid, NULL);
4311         break;
4312     case 12:
4313         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4314                                     hf_netlogon_user_rid, NULL);
4315         break;
4316     case 13:
4317         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
4318         break;
4319     case 14:
4320         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
4321         break;
4322     case 15:
4323         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
4324         break;
4325     case 16:
4326         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
4327         break;
4328     case 17:
4329         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
4330         break;
4331     case 18:
4332         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo,
4333                                               tree, di, drep, NDR_POINTER_UNIQUE, "unknown",
4334                                               hf_netlogon_unknown_string, 0);
4335         break;
4336     case 19:
4337         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo,
4338                                               tree, di, drep, NDR_POINTER_UNIQUE, "unknown",
4339                                               hf_netlogon_unknown_string, 0);
4340         break;
4341     case 20:
4342         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4343                                     hf_netlogon_user_rid, NULL);
4344         break;
4345     case 21:
4346         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4347                                     hf_netlogon_user_rid, NULL);
4348         break;
4349     }
4350 
4351     proto_item_set_len(item, offset-old_offset);
4352     return offset;
4353 }
4354 
4355 /*
4356  * IDL typedef struct {
4357  * IDL   short delta_type;
4358  * IDL   DELTA_ID_UNION delta_id_union;
4359  * IDL   DELTA_UNION delta_union;
4360  * IDL } DELTA_ENUM;
4361  */
4362 static int
netlogon_dissect_DELTA_ENUM(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)4363 netlogon_dissect_DELTA_ENUM(tvbuff_t *tvb, int offset,
4364                             packet_info *pinfo, proto_tree *parent_tree,
4365                             dcerpc_info *di, guint8 *drep)
4366 {
4367     proto_item *item=NULL;
4368     proto_tree *tree=NULL;
4369     int old_offset=offset;
4370     guint16 type;
4371 
4372     if(parent_tree){
4373         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
4374                                    ett_DELTA_ENUM, &item, "DELTA_ENUM:");
4375     }
4376 
4377     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
4378                                 hf_netlogon_delta_type, &type);
4379 
4380     proto_item_append_text(item, "%s", val_to_str(
4381                                type, delta_type_vals, "Unknown"));
4382 
4383     offset = netlogon_dissect_DELTA_ID_UNION(tvb, offset,
4384                                              pinfo, tree, di, drep);
4385 
4386     offset = netlogon_dissect_DELTA_UNION(tvb, offset,
4387                                           pinfo, tree, di, drep);
4388 
4389     proto_item_set_len(item, offset-old_offset);
4390     return offset;
4391 }
4392 
4393 static int
netlogon_dissect_DELTA_ENUM_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4394 netlogon_dissect_DELTA_ENUM_array(tvbuff_t *tvb, int offset,
4395                                   packet_info *pinfo, proto_tree *tree,
4396                                   dcerpc_info *di, guint8 *drep)
4397 {
4398     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
4399                                  netlogon_dissect_DELTA_ENUM);
4400 
4401     return offset;
4402 }
4403 
4404 /*
4405  * IDL typedef struct {
4406  * IDL   long num_deltas;
4407  * IDL   [unique][size_is(num_deltas)] DELTA_ENUM *delta_enum;
4408  * IDL } DELTA_ENUM_ARRAY;
4409  */
4410 static int
netlogon_dissect_DELTA_ENUM_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4411 netlogon_dissect_DELTA_ENUM_ARRAY(tvbuff_t *tvb, int offset,
4412                                   packet_info *pinfo, proto_tree *tree,
4413                                   dcerpc_info *di, guint8 *drep)
4414 {
4415     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4416                                 hf_netlogon_num_deltas, NULL);
4417 
4418     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4419                                  netlogon_dissect_DELTA_ENUM_array, NDR_POINTER_UNIQUE,
4420                                  "DELTA_ENUM: deltas", -1);
4421 
4422     return offset;
4423 }
4424 
4425 
4426 /*
4427  * IDL long NetrDatabaseDeltas(
4428  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
4429  * IDL      [in][string][ref] wchar_t *computername,
4430  * IDL      [in][ref] AUTHENTICATOR credential,
4431  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
4432  * IDL      [in] long database_id,
4433  * IDL      [in][out][ref] MODIFIED_COUNT domain_modify_count,
4434  * IDL      [in] long preferredmaximumlength,
4435  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
4436  * IDL );
4437  */
4438 static int
netlogon_dissect_netrdatabasedeltas_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4439 netlogon_dissect_netrdatabasedeltas_rqst(tvbuff_t *tvb, int offset,
4440                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4441 {
4442     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4443                                           NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
4444 
4445     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4446                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
4447 
4448     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4449                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4450                                  "AUTHENTICATOR: credential", -1);
4451 
4452     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4453                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4454                                  "AUTHENTICATOR: return_authenticator", -1);
4455 
4456     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4457                                 hf_netlogon_database_id, NULL);
4458 
4459     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4460                                  netlogon_dissect_MODIFIED_COUNT, NDR_POINTER_REF,
4461                                  "MODIFIED_COUNT: domain modified count", -1);
4462 
4463     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4464                                 hf_netlogon_max_size, NULL);
4465 
4466     return offset;
4467 }
4468 static int
netlogon_dissect_netrdatabasedeltas_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4469 netlogon_dissect_netrdatabasedeltas_reply(tvbuff_t *tvb, int offset,
4470                                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4471 {
4472     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4473                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4474                                  "AUTHENTICATOR: return_authenticator", -1);
4475 
4476     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4477                                  netlogon_dissect_MODIFIED_COUNT, NDR_POINTER_REF,
4478                                  "MODIFIED_COUNT: domain modified count", -1);
4479 
4480     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4481                                  netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
4482                                  "DELTA_ENUM_ARRAY: deltas", -1);
4483 
4484     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
4485                               hf_netlogon_rc, NULL);
4486 
4487     return offset;
4488 }
4489 
4490 
4491 /*
4492  * IDL long NetrDatabaseSync(
4493  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
4494  * IDL      [in][string][ref] wchar_t *computername,
4495  * IDL      [in][ref] AUTHENTICATOR credential,
4496  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
4497  * IDL      [in] long database_id,
4498  * IDL      [in][out][ref] long sync_context,
4499  * IDL      [in] long preferredmaximumlength,
4500  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
4501  * IDL );
4502  */
4503 static int
netlogon_dissect_netrdatabasesync_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4504 netlogon_dissect_netrdatabasesync_rqst(tvbuff_t *tvb, int offset,
4505                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4506 {
4507     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4508                                           NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
4509 
4510     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4511                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
4512 
4513     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4514                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4515                                  "AUTHENTICATOR: credential", -1);
4516 
4517     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4518                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4519                                  "AUTHENTICATOR: return_authenticator", -1);
4520 
4521     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4522                                 hf_netlogon_database_id, NULL);
4523 
4524     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4525                                 hf_netlogon_sync_context, NULL);
4526 
4527     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4528                                 hf_netlogon_max_size, NULL);
4529 
4530     return offset;
4531 }
4532 
4533 
4534 static int
netlogon_dissect_netrdatabasesync_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4535 netlogon_dissect_netrdatabasesync_reply(tvbuff_t *tvb, int offset,
4536                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4537 {
4538     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4539                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4540                                  "AUTHENTICATOR: return_authenticator", -1);
4541 
4542     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4543                                 hf_netlogon_sync_context, NULL);
4544 
4545     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4546                                  netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
4547                                  "DELTA_ENUM_ARRAY: deltas", -1);
4548 
4549     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
4550                               hf_netlogon_rc, NULL);
4551 
4552     return offset;
4553 }
4554 
4555 /*
4556  * IDL typedef struct {
4557  * IDL   char computer_name[16];
4558  * IDL   long timecreated;
4559  * IDL   long serial_number;
4560  * IDL } UAS_INFO_0;
4561  */
4562 static int
netlogon_dissect_UAS_INFO_0(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4563 netlogon_dissect_UAS_INFO_0(tvbuff_t *tvb, int offset,
4564                             packet_info *pinfo, proto_tree *tree,
4565                             dcerpc_info *di, guint8 *drep)
4566 {
4567     guint32 time_created;
4568     if(di->conformant_run){
4569         /*just a run to handle conformant arrays, nothing to dissect */
4570         return offset;
4571     }
4572 
4573     proto_tree_add_item(tree, hf_netlogon_computer_name, tvb, offset, 16, ENC_ASCII|ENC_NA);
4574     offset += 16;
4575 
4576     time_created = tvb_get_guint32(tvb, offset, DREP_ENC_INTEGER(drep));
4577     proto_tree_add_uint_format_value(tree, hf_netlogon_time_created, tvb, offset, 4, time_created, "unknown time format");
4578     offset+= 4;
4579 
4580     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4581                                 hf_netlogon_serial_number, NULL);
4582 
4583     return offset;
4584 }
4585 
4586 
4587 /*
4588  * IDL long NetrAccountDeltas(
4589  * IDL      [in][string][unique] wchar_t *logonserver,
4590  * IDL      [in][string][ref] wchar_t *computername,
4591  * IDL      [in][ref] AUTHENTICATOR credential,
4592  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
4593  * IDL      [out][ref][size_is(count_returned)] char *Buffer,
4594  * IDL      [out][ref] long count_returned,
4595  * IDL      [out][ref] long total_entries,
4596  * IDL      [in][out][ref] UAS_INFO_0 recordid,
4597  * IDL      [in][long] count,
4598  * IDL      [in][long] level,
4599  * IDL      [in][long] buffersize,
4600  * IDL );
4601  */
4602 static int
netlogon_dissect_netraccountdeltas_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4603 netlogon_dissect_netraccountdeltas_rqst(tvbuff_t *tvb, int offset,
4604                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4605 {
4606     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
4607                                               pinfo, tree, di, drep);
4608 
4609     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4610                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
4611 
4612     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4613                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4614                                  "AUTHENTICATOR: credential", -1);
4615 
4616     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4617                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4618                                  "AUTHENTICATOR: return_authenticator", -1);
4619 
4620     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4621                                  netlogon_dissect_UAS_INFO_0, NDR_POINTER_REF,
4622                                  "UAS_INFO_0: RecordID", -1);
4623 
4624     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4625                                 hf_netlogon_count, NULL);
4626 
4627     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4628                                 hf_netlogon_level, NULL);
4629 
4630     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4631                                 hf_netlogon_max_size, NULL);
4632 
4633     return offset;
4634 }
4635 static int
netlogon_dissect_netraccountdeltas_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4636 netlogon_dissect_netraccountdeltas_reply(tvbuff_t *tvb, int offset,
4637                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4638 {
4639     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4640                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4641                                  "AUTHENTICATOR: return_authenticator", -1);
4642 
4643     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4644                                  netlogon_dissect_BYTE_array, NDR_POINTER_REF,
4645                                  "BYTE_array: Buffer", -1);
4646 
4647     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4648                                 hf_netlogon_count, NULL);
4649 
4650     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4651                                 hf_netlogon_entries, NULL);
4652 
4653     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4654                                  netlogon_dissect_UAS_INFO_0, NDR_POINTER_REF,
4655                                  "UAS_INFO_0: RecordID", -1);
4656 
4657     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
4658                               hf_netlogon_rc, NULL);
4659 
4660     return offset;
4661 }
4662 
4663 
4664 /*
4665  * IDL long NetrAccountSync(
4666  * IDL      [in][string][unique] wchar_t *logonserver,
4667  * IDL      [in][string][ref] wchar_t *computername,
4668  * IDL      [in][ref] AUTHENTICATOR credential,
4669  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
4670  * IDL      [out][ref][size_is(count_returned)] char *Buffer,
4671  * IDL      [out][ref] long count_returned,
4672  * IDL      [out][ref] long total_entries,
4673  * IDL      [out][ref] long next_reference,
4674  * IDL      [in][long] reference,
4675  * IDL      [in][long] level,
4676  * IDL      [in][long] buffersize,
4677  * IDL      [in][out][ref] UAS_INFO_0 recordid,
4678  * IDL );
4679  */
4680 static int
netlogon_dissect_netraccountsync_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4681 netlogon_dissect_netraccountsync_rqst(tvbuff_t *tvb, int offset,
4682                                       packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4683 {
4684     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
4685                                               pinfo, tree, di, drep);
4686 
4687     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4688                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
4689 
4690     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4691                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4692                                  "AUTHENTICATOR: credential", -1);
4693 
4694     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4695                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4696                                  "AUTHENTICATOR: return_authenticator", -1);
4697 
4698     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4699                                 hf_netlogon_reference, NULL);
4700 
4701     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4702                                 hf_netlogon_level, NULL);
4703 
4704     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4705                                 hf_netlogon_max_size, NULL);
4706 
4707     return offset;
4708 }
4709 static int
netlogon_dissect_netraccountsync_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4710 netlogon_dissect_netraccountsync_reply(tvbuff_t *tvb, int offset,
4711                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4712 {
4713     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4714                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4715                                  "AUTHENTICATOR: return_authenticator", -1);
4716 
4717     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4718                                  netlogon_dissect_BYTE_array, NDR_POINTER_REF,
4719                                  "BYTE_array: Buffer", -1);
4720 
4721     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4722                                 hf_netlogon_count, NULL);
4723 
4724     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4725                                 hf_netlogon_entries, NULL);
4726 
4727     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4728                                 hf_netlogon_next_reference, NULL);
4729 
4730     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4731                                  netlogon_dissect_UAS_INFO_0, NDR_POINTER_REF,
4732                                  "UAS_INFO_0: RecordID", -1);
4733 
4734     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
4735                               hf_netlogon_rc, NULL);
4736 
4737     return offset;
4738 }
4739 
4740 
4741 /*
4742  * IDL long NetrGetDcName(
4743  * IDL    [in][ref][string] wchar_t *logon_server,
4744  * IDL    [in][unique][string] wchar_t *domainname,
4745  * IDL    [out][unique][string] wchar_t *dcname,
4746  * IDL };
4747  */
4748 static int
netlogon_dissect_netrgetdcname_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4749 netlogon_dissect_netrgetdcname_rqst(tvbuff_t *tvb, int offset,
4750                                     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4751 {
4752     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4753                                           NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
4754 
4755     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4756                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_domain_name, 0);
4757 
4758     return offset;
4759 }
4760 static int
netlogon_dissect_netrgetdcname_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4761 netlogon_dissect_netrgetdcname_reply(tvbuff_t *tvb, int offset,
4762                                      packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4763 {
4764     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4765                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_dc_name, 0);
4766 
4767     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
4768                               hf_netlogon_rc, NULL);
4769 
4770     return offset;
4771 }
4772 
4773 
4774 
4775 /*
4776  * IDL typedef struct {
4777  * IDL   long flags;
4778  * IDL   long pdc_connection_status;
4779  * IDL } NETLOGON_INFO_1;
4780  */
4781 static int
netlogon_dissect_NETLOGON_INFO_1(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4782 netlogon_dissect_NETLOGON_INFO_1(tvbuff_t *tvb, int offset,
4783                                  packet_info *pinfo, proto_tree *tree,
4784                                  dcerpc_info *di, guint8 *drep)
4785 {
4786     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4787                                 hf_netlogon_flags, NULL);
4788 
4789     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4790                                 hf_netlogon_pdc_connection_status, NULL);
4791 
4792     return offset;
4793 }
4794 
4795 
4796 /*
4797  * IDL typedef struct {
4798  * IDL   long flags;
4799  * IDL   long pdc_connection_status;
4800  * IDL   [unique][string] wchar_t trusted_dc_name;
4801  * IDL   long tc_connection_status;
4802  * IDL } NETLOGON_INFO_2;
4803  */
4804 static int
netlogon_dissect_NETLOGON_INFO_2(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4805 netlogon_dissect_NETLOGON_INFO_2(tvbuff_t *tvb, int offset,
4806                                  packet_info *pinfo, proto_tree *tree,
4807                                  dcerpc_info *di, guint8 *drep)
4808 {
4809     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4810                                 hf_netlogon_flags, NULL);
4811 
4812     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4813                                 hf_netlogon_pdc_connection_status, NULL);
4814 
4815     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4816                                           NDR_POINTER_UNIQUE, "Trusted DC Name",
4817                                           hf_netlogon_trusted_dc_name, 0);
4818 
4819     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4820                                 hf_netlogon_tc_connection_status, NULL);
4821 
4822     return offset;
4823 }
4824 
4825 
4826 /*
4827  * IDL typedef struct {
4828  * IDL   long flags;
4829  * IDL   long logon_attempts;
4830  * IDL   long reserved;
4831  * IDL   long reserved;
4832  * IDL   long reserved;
4833  * IDL   long reserved;
4834  * IDL   long reserved;
4835  * IDL } NETLOGON_INFO_3;
4836  */
4837 static int
netlogon_dissect_NETLOGON_INFO_3(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4838 netlogon_dissect_NETLOGON_INFO_3(tvbuff_t *tvb, int offset,
4839                                  packet_info *pinfo, proto_tree *tree,
4840                                  dcerpc_info *di, guint8 *drep)
4841 {
4842     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4843                                 hf_netlogon_flags, NULL);
4844 
4845     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4846                                 hf_netlogon_logon_attempts, NULL);
4847 
4848     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4849                                 hf_netlogon_reserved, NULL);
4850 
4851     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4852                                 hf_netlogon_reserved, NULL);
4853 
4854     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4855                                 hf_netlogon_reserved, NULL);
4856 
4857     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4858                                 hf_netlogon_reserved, NULL);
4859 
4860     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4861                                 hf_netlogon_reserved, NULL);
4862 
4863     return offset;
4864 }
4865 
4866 
4867 /*
4868  * IDL typedef [switch_type(long)] union {
4869  * IDL   [case(1)] [unique] NETLOGON_INFO_1 *i1;
4870  * IDL   [case(2)] [unique] NETLOGON_INFO_2 *i2;
4871  * IDL   [case(3)] [unique] NETLOGON_INFO_3 *i3;
4872  * IDL } CONTROL_QUERY_INFORMATION;
4873  */
4874 static int
netlogon_dissect_CONTROL_QUERY_INFORMATION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4875 netlogon_dissect_CONTROL_QUERY_INFORMATION(tvbuff_t *tvb, int offset,
4876                                            packet_info *pinfo, proto_tree *tree,
4877                                            dcerpc_info *di, guint8 *drep)
4878 {
4879     guint32 level = 0;
4880 
4881     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4882                                 hf_netlogon_level, &level);
4883 
4884     ALIGN_TO_4_BYTES;
4885     switch(level){
4886     case 1:
4887         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4888                                      netlogon_dissect_NETLOGON_INFO_1, NDR_POINTER_UNIQUE,
4889                                      "NETLOGON_INFO_1:", -1);
4890         break;
4891     case 2:
4892         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4893                                      netlogon_dissect_NETLOGON_INFO_2, NDR_POINTER_UNIQUE,
4894                                      "NETLOGON_INFO_2:", -1);
4895         break;
4896     case 3:
4897         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4898                                      netlogon_dissect_NETLOGON_INFO_3, NDR_POINTER_UNIQUE,
4899                                      "NETLOGON_INFO_3:", -1);
4900         break;
4901     }
4902 
4903     return offset;
4904 }
4905 
4906 
4907 /*
4908  * IDL long NetrLogonControl(
4909  * IDL      [in][string][unique] wchar_t *logonserver,
4910  * IDL      [in] long function_code,
4911  * IDL      [in] long level,
4912  * IDL      [out][ref] CONTROL_QUERY_INFORMATION
4913  * IDL );
4914  */
4915 static int
netlogon_dissect_netrlogoncontrol_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4916 netlogon_dissect_netrlogoncontrol_rqst(tvbuff_t *tvb, int offset,
4917                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4918 {
4919     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
4920                                               pinfo, tree, di, drep);
4921 
4922     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4923                                 hf_netlogon_code, NULL);
4924 
4925     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4926                                 hf_netlogon_level, NULL);
4927 
4928     return offset;
4929 }
4930 static int
netlogon_dissect_netrlogoncontrol_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4931 netlogon_dissect_netrlogoncontrol_reply(tvbuff_t *tvb, int offset,
4932                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4933 {
4934     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
4935                                  netlogon_dissect_CONTROL_QUERY_INFORMATION, NDR_POINTER_REF,
4936                                  "CONTROL_QUERY_INFORMATION:", -1);
4937 
4938     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
4939                               hf_netlogon_dos_rc, NULL);
4940 
4941     return offset;
4942 }
4943 
4944 
4945 /*
4946  * IDL long NetrGetAnyDCName(
4947  * IDL    [in][unique][string] wchar_t *logon_server,
4948  * IDL    [in][unique][string] wchar_t *domainname,
4949  * IDL    [out][unique][string] wchar_t *dcname,
4950  * IDL };
4951  */
4952 static int
netlogon_dissect_netrgetanydcname_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4953 netlogon_dissect_netrgetanydcname_rqst(tvbuff_t *tvb, int offset,
4954                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4955 {
4956     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4957                                           NDR_POINTER_UNIQUE, "Server Handle",
4958                                           hf_netlogon_logonsrv_handle, 0);
4959 
4960     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4961                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_domain_name, 0);
4962 
4963     return offset;
4964 }
4965 static int
netlogon_dissect_netrgetanydcname_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4966 netlogon_dissect_netrgetanydcname_reply(tvbuff_t *tvb, int offset,
4967                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4968 {
4969     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
4970                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_dc_name, 0);
4971 
4972     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
4973                               hf_netlogon_dos_rc, NULL);
4974 
4975     return offset;
4976 }
4977 
4978 
4979 /*
4980  * IDL typedef [switch_type(long)] union {
4981  * IDL   [case(5)] [unique][string] wchar_t *unknown;
4982  * IDL   [case(6)] [unique][string] wchar_t *unknown;
4983  * IDL   [case(0xfffe)] long unknown;
4984  * IDL   [case(7)] [unique][string] wchar_t *unknown;
4985  * IDL } CONTROL_DATA_INFORMATION;
4986  */
4987 /* XXX
4988  * According to muddle this is what CONTROL_DATA_INFORMATION is supposed
4989  * to look like. However NetMon does not recognize any such informationlevels.
4990  *
4991  * I'll leave it as CONTROL_DATA_INFORMATION with no informationlevels
4992  * until someone has any source of better authority to call upon.
4993  */
4994 static int
netlogon_dissect_CONTROL_DATA_INFORMATION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4995 netlogon_dissect_CONTROL_DATA_INFORMATION(tvbuff_t *tvb, int offset,
4996                                           packet_info *pinfo, proto_tree *tree,
4997                                           dcerpc_info *di, guint8 *drep)
4998 {
4999     guint32 level = 0;
5000 
5001     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5002                                 hf_netlogon_level, &level);
5003 
5004     ALIGN_TO_4_BYTES;
5005     switch(level){
5006     case 5:
5007         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo,
5008                                               tree, di, drep, NDR_POINTER_UNIQUE, "Trusted Domain Name",
5009                                               hf_netlogon_TrustedDomainName_string, 0);
5010         break;
5011     case 6:
5012         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo,
5013                                               tree, di, drep, NDR_POINTER_UNIQUE, "Trusted Domain Name",
5014                                               hf_netlogon_TrustedDomainName_string, 0);
5015         break;
5016     case 0xfffe:
5017         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5018                                     hf_netlogon_unknown_long, NULL);
5019         break;
5020     case 8:
5021         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo,
5022                                               tree, di, drep, NDR_POINTER_UNIQUE, "UserName",
5023                                               hf_netlogon_UserName_string, 0);
5024         break;
5025     }
5026 
5027     return offset;
5028 }
5029 
5030 
5031 /*
5032  * IDL long NetrLogonControl2(
5033  * IDL      [in][string][unique] wchar_t *logonserver,
5034  * IDL      [in] long function_code,
5035  * IDL      [in] long level,
5036  * IDL      [in][ref] CONTROL_DATA_INFORMATION *data,
5037  * IDL      [out][ref] CONTROL_QUERY_INFORMATION *query
5038  * IDL );
5039  */
5040 static int
netlogon_dissect_netrlogoncontrol2_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5041 netlogon_dissect_netrlogoncontrol2_rqst(tvbuff_t *tvb, int offset,
5042                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5043 {
5044     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5045                                               pinfo, tree, di, drep);
5046 
5047     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5048                                 hf_netlogon_code, NULL);
5049 
5050     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5051                                 hf_netlogon_level, NULL);
5052 
5053     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5054                                  netlogon_dissect_CONTROL_DATA_INFORMATION, NDR_POINTER_REF,
5055                                  "CONTROL_DATA_INFORMATION: ", -1);
5056 
5057     return offset;
5058 }
5059 
5060 static int
netlogon_dissect_netrlogoncontrol2_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5061 netlogon_dissect_netrlogoncontrol2_reply(tvbuff_t *tvb, int offset,
5062                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5063 {
5064     guint32 status;
5065 
5066     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5067                                  netlogon_dissect_CONTROL_QUERY_INFORMATION, NDR_POINTER_REF,
5068                                  "CONTROL_QUERY_INFORMATION:", -1);
5069 
5070     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf_netlogon_werr_rc, &status);
5071 
5072     if (status != 0)
5073         col_append_fstr(pinfo->cinfo, COL_INFO, ", Error: %s", val_to_str_ext(status, &WERR_errors_ext, "Unknown WERR error 0x%08x"));
5074 
5075 
5076     return offset;
5077 }
5078 
5079 
5080 
5081 
5082 /*
5083  * IDL long NetrDatabaseSync2(
5084  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
5085  * IDL      [in][string][ref] wchar_t *computername,
5086  * IDL      [in][ref] AUTHENTICATOR credential,
5087  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
5088  * IDL      [in] long database_id,
5089  * IDL      [in] short restart_state,
5090  * IDL      [in][out][ref] long *sync_context,
5091  * IDL      [in] long preferredmaximumlength,
5092  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
5093  * IDL );
5094  */
5095 static int
netlogon_dissect_netrdatabasesync2_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5096 netlogon_dissect_netrdatabasesync2_rqst(tvbuff_t *tvb, int offset,
5097                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5098 {
5099     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5100                                           NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
5101 
5102     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5103                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
5104 
5105     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5106                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5107                                  "AUTHENTICATOR: credential", -1);
5108 
5109     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5110                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5111                                  "AUTHENTICATOR: return_authenticator", -1);
5112 
5113     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5114                                 hf_netlogon_database_id, NULL);
5115 
5116     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
5117                                 hf_netlogon_restart_state, NULL);
5118 
5119     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5120                                 hf_netlogon_sync_context, NULL);
5121 
5122     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5123                                 hf_netlogon_max_size, NULL);
5124 
5125     return offset;
5126 }
5127 
5128 static int
netlogon_dissect_netrdatabasesync2_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5129 netlogon_dissect_netrdatabasesync2_reply(tvbuff_t *tvb, int offset,
5130                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5131 {
5132     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5133                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5134                                  "AUTHENTICATOR: return_authenticator", -1);
5135 
5136     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5137                                 hf_netlogon_sync_context, NULL);
5138 
5139     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5140                                  netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
5141                                  "DELTA_ENUM_ARRAY: deltas", -1);
5142 
5143     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
5144                               hf_netlogon_rc, NULL);
5145 
5146     return offset;
5147 }
5148 
5149 
5150 /*
5151  * IDL long NetrDatabaseRedo(
5152  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
5153  * IDL      [in][string][ref] wchar_t *computername,
5154  * IDL      [in][ref] AUTHENTICATOR credential,
5155  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
5156  * IDL      [in][ref][size_is(change_log_entry_size)] char *change_log_entry,
5157  * IDL      [in] long change_log_entry_size,
5158  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
5159  * IDL );
5160  */
5161 static int
netlogon_dissect_netrdatabaseredo_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5162 netlogon_dissect_netrdatabaseredo_rqst(tvbuff_t *tvb, int offset,
5163                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5164 {
5165     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5166                                           NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
5167 
5168     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5169                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
5170 
5171     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5172                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5173                                  "AUTHENTICATOR: credential", -1);
5174 
5175     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5176                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5177                                  "AUTHENTICATOR: return_authenticator", -1);
5178 
5179     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5180                                  netlogon_dissect_BYTE_array, NDR_POINTER_REF,
5181                                  "Change log entry: ", -1);
5182 
5183     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5184                                 hf_netlogon_max_log_size, NULL);
5185 
5186     return offset;
5187 }
5188 
5189 static int
netlogon_dissect_netrdatabaseredo_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5190 netlogon_dissect_netrdatabaseredo_reply(tvbuff_t *tvb, int offset,
5191                                         packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5192 {
5193     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5194                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5195                                  "AUTHENTICATOR: return_authenticator", -1);
5196 
5197     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5198                                  netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
5199                                  "DELTA_ENUM_ARRAY: deltas", -1);
5200 
5201     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
5202                               hf_netlogon_rc, NULL);
5203 
5204     return offset;
5205 }
5206 
5207 
5208 /*
5209  * IDL long NetrLogonControl2Ex(
5210  * IDL      [in][string][unique] wchar_t *logonserver,
5211  * IDL      [in] long function_code,
5212  * IDL      [in] long level,
5213  * IDL      [in][ref] CONTROL_DATA_INFORMATION *data,
5214  * IDL      [out][ref] CONTROL_QUERY_INFORMATION *query
5215  * IDL );
5216  */
5217 static int
netlogon_dissect_netrlogoncontrol2ex_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5218 netlogon_dissect_netrlogoncontrol2ex_rqst(tvbuff_t *tvb, int offset,
5219                                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5220 {
5221     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5222                                               pinfo, tree, di, drep);
5223 
5224     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5225                                 hf_netlogon_code, NULL);
5226 
5227     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5228                                 hf_netlogon_level, NULL);
5229 
5230     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5231                                  netlogon_dissect_CONTROL_DATA_INFORMATION, NDR_POINTER_REF,
5232                                  "CONTROL_DATA_INFORMATION: ", -1);
5233 
5234     return offset;
5235 }
5236 static int
netlogon_dissect_netrlogoncontrol2ex_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5237 netlogon_dissect_netrlogoncontrol2ex_reply(tvbuff_t *tvb, int offset,
5238                                            packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5239 {
5240     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5241                                  netlogon_dissect_CONTROL_QUERY_INFORMATION, NDR_POINTER_REF,
5242                                  "CONTROL_QUERY_INFORMATION:", -1);
5243 
5244     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
5245                               hf_netlogon_dos_rc, NULL);
5246 
5247     return offset;
5248 }
5249 
5250 
5251 
5252 
5253 static const value_string trust_type_vals[] = {
5254     { 1, "NT4 Domain" },
5255     { 2, "AD Domain" },
5256     { 3, "MIT Kerberos realm" },
5257     { 4, "DCE realm" },
5258     { 0, NULL }
5259 };
5260 
5261 #define DS_INET_ADDRESS         1
5262 #define DS_NETBIOS_ADDRESS      2
5263 
5264 static const value_string dc_address_types[] = {
5265     { DS_INET_ADDRESS,    "IP/DNS name" },
5266     { DS_NETBIOS_ADDRESS, "NetBIOS name" },
5267     { 0, NULL}
5268 };
5269 
5270 
5271 #define RQ_ROOT_FOREST              0x0001
5272 #define RQ_DC_XFOREST               0x0002
5273 #define RQ_RODC_DIF_DOMAIN          0x0004
5274 #define RQ_NTLM_FROM_RODC           0x0008
5275 
5276 #define DS_DOMAIN_IN_FOREST         0x0001
5277 #define DS_DOMAIN_DIRECT_OUTBOUND   0x0002
5278 #define DS_DOMAIN_TREE_ROOT         0x0004
5279 #define DS_DOMAIN_PRIMARY           0x0008
5280 #define DS_DOMAIN_NATIVE_MODE       0x0010
5281 #define DS_DOMAIN_DIRECT_INBOUND    0x0020
5282 
5283 static const true_false_string trust_inbound = {
5284     "There is a DIRECT INBOUND trust for the servers domain",
5285     "There is NO direct inbound trust for the servers domain"
5286 };
5287 static const true_false_string trust_outbound = {
5288     "There is a DIRECT OUTBOUND trust for this domain",
5289     "There is NO direct outbound trust for this domain"
5290 };
5291 static const true_false_string trust_in_forest = {
5292     "The domain is a member IN the same FOREST as the queried server",
5293     "The domain is NOT a member of the queried servers domain"
5294 };
5295 static const true_false_string trust_native_mode = {
5296     "The primary domain is a NATIVE MODE w2k domain",
5297     "The primary is NOT a native mode w2k domain"
5298 };
5299 static const true_false_string trust_primary = {
5300     "The domain is the PRIMARY domain of the queried server",
5301     "The domain is NOT the primary domain of the queried server"
5302 };
5303 static const true_false_string trust_tree_root = {
5304     "The domain is the ROOT of a domain TREE",
5305     "The domain is NOT a root of a domain tree"
5306 };
5307 
5308 
5309 static int
netlogon_dissect_DOMAIN_TRUST_FLAGS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)5310 netlogon_dissect_DOMAIN_TRUST_FLAGS(tvbuff_t *tvb, int offset,
5311                                     packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
5312 {
5313     guint32 mask;
5314     static int * const flags[] = {
5315         &hf_netlogon_trust_flags_inbound,
5316         &hf_netlogon_trust_flags_native_mode,
5317         &hf_netlogon_trust_flags_primary,
5318         &hf_netlogon_trust_flags_tree_root,
5319         &hf_netlogon_trust_flags_outbound,
5320         &hf_netlogon_trust_flags_in_forest,
5321         NULL
5322     };
5323 
5324     if(di->conformant_run){
5325         /*just a run to handle conformant arrays, nothing to dissect */
5326         return offset;
5327     }
5328 
5329     offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep,
5330                               -1, &mask);
5331 
5332     proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_trust_flags, ett_trust_flags, flags, mask, BMT_NO_APPEND);
5333     return offset;
5334 }
5335 
5336 
5337 
5338 static const true_false_string trust_attribs_non_transitive = {
5339     "This is a NON TRANSITIVE trust relation",
5340     "This is a normal trust"
5341 };
5342 static const true_false_string trust_attribs_uplevel_only = {
5343     "This is an UPLEVEL ONLY trust relation",
5344     "This is a normal trust"
5345 };
5346 static const true_false_string trust_attribs_quarantined_domain = {
5347     "This is a QUARANTINED DOMAIN (so don't expect lookupsids to work)",
5348     "This is a normal trust"
5349 };
5350 static const true_false_string trust_attribs_forest_transitive = {
5351     "This is a FOREST TRANSITIVE trust",
5352     "This is a normal trust"
5353 };
5354 static const true_false_string trust_attribs_cross_organization = {
5355     "This is a CROSS ORGANIZATION trust",
5356     "This is a normal trust"
5357 };
5358 static const true_false_string trust_attribs_within_forest = {
5359     "This is a WITHIN FOREST trust",
5360     "This is a normal trust"
5361 };
5362 static const true_false_string trust_attribs_treat_as_external = {
5363     "TREAT this trust AS an EXTERNAL trust",
5364     "This is a normal trust"
5365 };
5366 
5367 static int
netlogon_dissect_DOMAIN_TRUST_ATTRIBS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)5368 netlogon_dissect_DOMAIN_TRUST_ATTRIBS(tvbuff_t *tvb, int offset,
5369                                       packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
5370 {
5371     guint32 mask;
5372     static int * const attr[] = {
5373         &hf_netlogon_trust_attribs_treat_as_external,
5374         &hf_netlogon_trust_attribs_within_forest,
5375         &hf_netlogon_trust_attribs_cross_organization,
5376         &hf_netlogon_trust_attribs_forest_transitive,
5377         &hf_netlogon_trust_attribs_quarantined_domain,
5378         &hf_netlogon_trust_attribs_uplevel_only,
5379         &hf_netlogon_trust_attribs_non_transitive,
5380         NULL
5381     };
5382 
5383     if(di->conformant_run){
5384         /*just a run to handle conformant arrays, nothing to dissect */
5385         return offset;
5386     }
5387 
5388     offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep,
5389                                 -1, &mask);
5390 
5391     proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_trust_attribs, ett_trust_attribs, attr, mask, BMT_NO_APPEND);
5392     return offset;
5393 }
5394 
5395 
5396 #define DS_FORCE_REDISCOVERY            0x00000001
5397 #define DS_DIRECTORY_SERVICE_REQUIRED   0x00000010
5398 #define DS_DIRECTORY_SERVICE_PREFERRED  0x00000020
5399 #define DS_GC_SERVER_REQUIRED           0x00000040
5400 #define DS_PDC_REQUIRED                 0x00000080
5401 #define DS_BACKGROUND_ONLY              0x00000100
5402 #define DS_IP_REQUIRED                  0x00000200
5403 #define DS_KDC_REQUIRED                 0x00000400
5404 #define DS_TIMESERV_REQUIRED            0x00000800
5405 #define DS_WRITABLE_REQUIRED            0x00001000
5406 #define DS_GOOD_TIMESERV_PREFERRED      0x00002000
5407 #define DS_AVOID_SELF                   0x00004000
5408 #define DS_ONLY_LDAP_NEEDED             0x00008000
5409 #define DS_IS_FLAT_NAME                 0x00010000
5410 #define DS_IS_DNS_NAME                  0x00020000
5411 #define DS_RETURN_DNS_NAME              0x40000000
5412 #define DS_RETURN_FLAT_NAME             0x80000000
5413 
5414 static const true_false_string get_dcname_request_flags_force_rediscovery = {
5415     "FORCE REDISCOVERY of any cached data",
5416     "You may return cached data"
5417 };
5418 static const true_false_string get_dcname_request_flags_directory_service_required = {
5419     "DIRECTORY SERVICE is REQUIRED on the server",
5420     "We do NOT require directory service servers"
5421 };
5422 static const true_false_string get_dcname_request_flags_directory_service_preferred = {
5423     "DIRECTORY SERVICE servers are PREFERRED",
5424     "We do NOT have a preference for directory service servers"
5425 };
5426 static const true_false_string get_dcname_request_flags_gc_server_required = {
5427     "GC SERVER is REQUIRED",
5428     "gc server is NOT required"
5429 };
5430 static const true_false_string get_dcname_request_flags_pdc_required = {
5431     "PDC SERVER is REQUIRED",
5432     "pdc server is NOT required"
5433 };
5434 static const true_false_string get_dcname_request_flags_background_only = {
5435     "Only return cached data, even if it has expired",
5436     "Return cached data unless it has expired"
5437 };
5438 static const true_false_string get_dcname_request_flags_ip_required = {
5439     "IP address is REQUIRED",
5440     "ip address is NOT required"
5441 };
5442 static const true_false_string get_dcname_request_flags_kdc_required = {
5443     "KDC server is REQUIRED",
5444     "kdc server is NOT required"
5445 };
5446 static const true_false_string get_dcname_request_flags_timeserv_required = {
5447     "TIMESERV service is REQUIRED",
5448     "timeserv service is NOT required"
5449 };
5450 static const true_false_string get_dcname_request_flags_writable_required = {
5451     "the returned dc MUST be WRITEABLE",
5452     "a read-only dc may be returned"
5453 };
5454 static const true_false_string get_dcname_request_flags_good_timeserv_preferred = {
5455     "GOOD TIMESERV servers are PREFERRED",
5456     "we do NOT have a preference for good timeserv servers"
5457 };
5458 static const true_false_string get_dcname_request_flags_avoid_self = {
5459     "do NOT return self as dc; return someone else",
5460     "you may return yourSELF as the dc"
5461 };
5462 static const true_false_string get_dcname_request_flags_only_ldap_needed = {
5463     "we ONLY NEED LDAP; you don't have to return a dc",
5464     "we need a normal dc; an ldap only server will not do"
5465 };
5466 static const true_false_string get_dcname_request_flags_is_flat_name = {
5467     "the name we specify is a NetBIOS name",
5468     "the name we specify is NOT a NetBIOS name"
5469 };
5470 static const true_false_string get_dcname_request_flags_is_dns_name = {
5471     "the name we specify is a DNS name",
5472     "the name we specify is NOT a dns name"
5473 };
5474 static const true_false_string get_dcname_request_flags_return_dns_name = {
5475     "return a DNS name",
5476     "you may return a NON-dns name"
5477 };
5478 static const true_false_string get_dcname_request_flags_return_flat_name = {
5479     "return a NetBIOS name",
5480     "you may return a NON-NetBIOS name"
5481 };
5482 static int
netlogon_dissect_GET_DCNAME_REQUEST_FLAGS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)5483 netlogon_dissect_GET_DCNAME_REQUEST_FLAGS(tvbuff_t *tvb, int offset,
5484                                           packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
5485 {
5486     guint32 mask;
5487     static int * const flags[] = {
5488         &hf_netlogon_get_dcname_request_flags_return_flat_name,
5489         &hf_netlogon_get_dcname_request_flags_return_dns_name,
5490         &hf_netlogon_get_dcname_request_flags_is_flat_name,
5491         &hf_netlogon_get_dcname_request_flags_is_dns_name,
5492         &hf_netlogon_get_dcname_request_flags_only_ldap_needed,
5493         &hf_netlogon_get_dcname_request_flags_avoid_self,
5494         &hf_netlogon_get_dcname_request_flags_good_timeserv_preferred,
5495         &hf_netlogon_get_dcname_request_flags_writable_required,
5496         &hf_netlogon_get_dcname_request_flags_timeserv_required,
5497         &hf_netlogon_get_dcname_request_flags_kdc_required,
5498         &hf_netlogon_get_dcname_request_flags_ip_required,
5499         &hf_netlogon_get_dcname_request_flags_background_only,
5500         &hf_netlogon_get_dcname_request_flags_pdc_required,
5501         &hf_netlogon_get_dcname_request_flags_gc_server_required,
5502         &hf_netlogon_get_dcname_request_flags_directory_service_preferred,
5503         &hf_netlogon_get_dcname_request_flags_directory_service_required,
5504         &hf_netlogon_get_dcname_request_flags_force_rediscovery,
5505         NULL
5506     };
5507 
5508     if(di->conformant_run){
5509         /*just a run to handle conformant arrays, nothing to dissect */
5510         return offset;
5511     }
5512 
5513     offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &mask);
5514 
5515     proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_get_dcname_request_flags, ett_get_dcname_request_flags, flags, mask, BMT_NO_APPEND);
5516     return offset;
5517 }
5518 
5519 
5520 
5521 #define DS_PDC_FLAG             0x00000001
5522 #define DS_GC_FLAG              0x00000004
5523 #define DS_LDAP_FLAG            0x00000008
5524 #define DS_DS_FLAG              0x00000010
5525 #define DS_KDC_FLAG             0x00000020
5526 #define DS_TIMESERV_FLAG        0x00000040
5527 #define DS_CLOSEST_FLAG         0x00000080
5528 #define DS_WRITABLE_FLAG        0x00000100
5529 #define DS_GOOD_TIMESERV_FLAG   0x00000200
5530 #define DS_NDNC_FLAG            0x00000400
5531 #define DS_DNS_CONTROLLER_FLAG  0x20000000
5532 #define DS_DNS_DOMAIN_FLAG      0x40000000
5533 #define DS_DNS_FOREST_FLAG      0x80000000
5534 
5535 static const true_false_string dc_flags_pdc_flag = {
5536     "this is the PDC of the domain",
5537     "this is NOT the pdc of the domain"
5538 };
5539 static const true_false_string dc_flags_gc_flag = {
5540     "this is the GC of the forest",
5541     "this is NOT the gc of the forest"
5542 };
5543 static const true_false_string dc_flags_ldap_flag = {
5544     "this is an LDAP server",
5545     "this is NOT an ldap server"
5546 };
5547 static const true_false_string dc_flags_ds_flag = {
5548     "this is a DS server",
5549     "this is NOT a ds server"
5550 };
5551 static const true_false_string dc_flags_kdc_flag = {
5552     "this is a KDC server",
5553     "this is NOT a kdc server"
5554 };
5555 static const true_false_string dc_flags_timeserv_flag = {
5556     "this is a TIMESERV server",
5557     "this is NOT a timeserv server"
5558 };
5559 static const true_false_string dc_flags_closest_flag = {
5560     "this is the CLOSEST server",
5561     "this is NOT the closest server"
5562 };
5563 static const true_false_string dc_flags_writable_flag = {
5564     "this server has a WRITABLE ds database",
5565     "this server has a READ-ONLY ds database"
5566 };
5567 static const true_false_string dc_flags_good_timeserv_flag = {
5568     "this server is a GOOD TIMESERV server",
5569     "this is NOT a good timeserv server"
5570 };
5571 static const true_false_string dc_flags_ndnc_flag = {
5572     "NDNC is set",
5573     "ndnc is NOT set"
5574 };
5575 static const true_false_string dc_flags_dns_controller_flag = {
5576     "DomainControllerName is a DNS name",
5577     "DomainControllerName is NOT a dns name"
5578 };
5579 static const true_false_string dc_flags_dns_domain_flag = {
5580     "DomainName is a DNS name",
5581     "DomainName is NOT a dns name"
5582 };
5583 static const true_false_string dc_flags_dns_forest_flag = {
5584     "DnsForestName is a DNS name",
5585     "DnsForestName is NOT a dns name"
5586 };
5587 static int
netlogon_dissect_DC_FLAGS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)5588 netlogon_dissect_DC_FLAGS(tvbuff_t *tvb, int offset,
5589                           packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
5590 {
5591     guint32 mask;
5592     proto_item *item;
5593     static int * const flags[] = {
5594         &hf_netlogon_dc_flags_dns_forest_flag,
5595         &hf_netlogon_dc_flags_dns_domain_flag,
5596         &hf_netlogon_dc_flags_dns_controller_flag,
5597         &hf_netlogon_dc_flags_ndnc_flag,
5598         &hf_netlogon_dc_flags_good_timeserv_flag,
5599         &hf_netlogon_dc_flags_writable_flag,
5600         &hf_netlogon_dc_flags_closest_flag,
5601         &hf_netlogon_dc_flags_timeserv_flag,
5602         &hf_netlogon_dc_flags_kdc_flag,
5603         &hf_netlogon_dc_flags_ds_flag,
5604         &hf_netlogon_dc_flags_ldap_flag,
5605         &hf_netlogon_dc_flags_gc_flag,
5606         &hf_netlogon_dc_flags_pdc_flag,
5607         NULL
5608     };
5609 
5610     if(di->conformant_run){
5611         /*just a run to handle conformant arrays, nothing to dissect */
5612         return offset;
5613     }
5614 
5615     offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &mask);
5616 
5617     item = proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset-4, hf_netlogon_dc_flags, ett_dc_flags, flags, mask, BMT_NO_APPEND);
5618     if (mask==0x0000ffff)
5619         proto_item_append_text(item, "  PING (mask==0x0000ffff)");
5620 
5621     return offset;
5622 }
5623 
5624 
5625 
5626 static int
netlogon_dissect_pointer_long(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5627 netlogon_dissect_pointer_long(tvbuff_t *tvb, int offset,
5628                               packet_info *pinfo, proto_tree *tree,
5629                               dcerpc_info *di, guint8 *drep)
5630 {
5631     offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
5632                                  di->hf_index, NULL);
5633     return offset;
5634 }
5635 
5636 #if 0
5637 static int
5638 netlogon_dissect_pointer_char(tvbuff_t *tvb, int offset,
5639                               packet_info *pinfo, proto_tree *tree,
5640                               dcerpc_info *di, guint8 *drep)
5641 {
5642     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
5643                                di->hf_index, NULL);
5644     return offset;
5645 }
5646 #endif
5647 
5648 static int
netlogon_dissect_UNICODE_MULTI_byte(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5649 netlogon_dissect_UNICODE_MULTI_byte(tvbuff_t *tvb, int offset,
5650                                     packet_info *pinfo, proto_tree *tree,
5651                                     dcerpc_info *di, guint8 *drep)
5652 {
5653     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
5654                                hf_netlogon_unknown_char, NULL);
5655 
5656     return offset;
5657 }
5658 
5659 static int
netlogon_dissect_UNICODE_MULTI_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5660 netlogon_dissect_UNICODE_MULTI_array(tvbuff_t *tvb, int offset,
5661                                      packet_info *pinfo, proto_tree *tree,
5662                                      dcerpc_info *di, guint8 *drep)
5663 {
5664     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
5665                                  netlogon_dissect_UNICODE_MULTI_byte);
5666 
5667     return offset;
5668 }
5669 
5670 static int
netlogon_dissect_UNICODE_MULTI(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)5671 netlogon_dissect_UNICODE_MULTI(tvbuff_t *tvb, int offset,
5672                                packet_info *pinfo, proto_tree *parent_tree,
5673                                dcerpc_info *di, guint8 *drep)
5674 {
5675     proto_item *item=NULL;
5676     proto_tree *tree=NULL;
5677     int old_offset=offset;
5678 
5679     if(parent_tree){
5680         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
5681                                    ett_UNICODE_MULTI, &item, "UNICODE_MULTI:");
5682     }
5683 
5684     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5685                                 hf_netlogon_len, NULL);
5686 
5687     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
5688                                  netlogon_dissect_UNICODE_MULTI_array, NDR_POINTER_UNIQUE,
5689                                  "unknown", hf_netlogon_unknown_string);
5690 
5691     proto_item_set_len(item, offset-old_offset);
5692     return offset;
5693 }
5694 
5695 static int
netlogon_dissect_DOMAIN_CONTROLLER_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)5696 netlogon_dissect_DOMAIN_CONTROLLER_INFO(tvbuff_t *tvb, int offset,
5697                                         packet_info *pinfo, proto_tree *parent_tree,
5698                                         dcerpc_info *di, guint8 *drep)
5699 {
5700     proto_item *item=NULL;
5701     proto_tree *tree=NULL;
5702     int old_offset=offset;
5703 
5704     if(parent_tree){
5705         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
5706                                    ett_DOMAIN_CONTROLLER_INFO, &item, "DOMAIN_CONTROLLER_INFO:");
5707     }
5708 
5709     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5710                                           NDR_POINTER_UNIQUE, "DC Name", hf_netlogon_dc_name, 0);
5711 
5712     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5713                                           NDR_POINTER_UNIQUE, "DC Address", hf_netlogon_dc_address, 0);
5714 
5715     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5716                                 hf_netlogon_dc_address_type, NULL);
5717 
5718     offset = dissect_nt_GUID(tvb, offset,
5719                              pinfo, tree, di, drep);
5720 
5721     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5722                                           NDR_POINTER_UNIQUE, "Logon Domain", hf_netlogon_logon_dom, 0);
5723 
5724     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5725                                           NDR_POINTER_UNIQUE, "DNS Forest", hf_netlogon_dns_forest_name, 0);
5726 
5727     offset = netlogon_dissect_DC_FLAGS(tvb, offset, pinfo, tree, di, drep);
5728 
5729     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5730                                           NDR_POINTER_UNIQUE, "DC Site", hf_netlogon_dc_site_name, 0);
5731 
5732     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5733                                           NDR_POINTER_UNIQUE, "Client Site",
5734                                           hf_netlogon_client_site_name, 0);
5735 
5736     proto_item_set_len(item, offset-old_offset);
5737     return offset;
5738 }
5739 
5740 
5741 
5742 static int
dissect_ndr_trust_extension(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5743 dissect_ndr_trust_extension(tvbuff_t *tvb, int offset,
5744                             packet_info *pinfo, proto_tree *tree,
5745                             dcerpc_info *di, guint8 *drep)
5746 {
5747     guint32 len,max;
5748 
5749     if(di->conformant_run){
5750         return offset;
5751     }
5752     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5753                                 hf_netlogon_trust_max, &max);
5754 
5755     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5756                                 hf_netlogon_trust_offset, NULL);
5757 
5758     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5759                                 hf_netlogon_trust_len, &len);
5760 
5761     if( max * 2 == 16 ) {
5762         offset = netlogon_dissect_DOMAIN_TRUST_FLAGS(tvb, offset, pinfo, tree, di, drep);
5763 
5764         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5765                                     hf_netlogon_trust_parent_index, NULL);
5766 
5767         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5768                                     hf_netlogon_trust_type, NULL);
5769 
5770         offset = netlogon_dissect_DOMAIN_TRUST_ATTRIBS(tvb, offset, pinfo, tree, di, drep);
5771     }
5772     /* else do something scream shout .... */
5773 
5774     return offset;
5775 }
5776 
5777 static int
netlogon_dissect_BLOB_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5778 netlogon_dissect_BLOB_array(tvbuff_t *tvb, int offset,
5779                             packet_info *pinfo, proto_tree *tree,
5780                             dcerpc_info *di, guint8 *drep)
5781 {
5782     guint32 len;
5783 
5784     if(di->conformant_run){
5785         return offset;
5786     }
5787 
5788     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5789                                 hf_netlogon_blob_size, &len);
5790 
5791     proto_tree_add_item(tree, hf_netlogon_blob, tvb, offset, len,
5792                         ENC_NA);
5793     offset += len;
5794 
5795     return offset;
5796 }
5797 
5798 static int
dissect_ndr_ulongs_as_counted_string(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_index)5799 dissect_ndr_ulongs_as_counted_string(tvbuff_t *tvb, int offset,
5800                                      packet_info *pinfo, proto_tree *tree,
5801                                      dcerpc_info *di, guint8 *drep, int hf_index)
5802 {
5803     guint16 len, size;
5804     gboolean add_subtree = TRUE; /* Manage room for evolution*/
5805     proto_item *item;
5806     proto_tree *subtree = tree;
5807 
5808     if (add_subtree) {
5809 
5810         subtree = proto_tree_add_subtree(
5811             tree, tvb, offset, 0, ett_nt_counted_longs_as_string, &item,
5812             proto_registrar_get_name(hf_index));
5813     }
5814     /* Structure starts with short, but is aligned for longs */
5815     ALIGN_TO_4_BYTES;
5816 
5817     if (di->conformant_run)
5818         return offset;
5819 
5820     /*
5821       struct {
5822       short len;
5823       short size;
5824       [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
5825       } UNICODE_STRING;
5826 
5827     */
5828 
5829     offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, di, drep,
5830                                 hf_nt_cs_len, &len);
5831     offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, di, drep,
5832                                 hf_nt_cs_size, &size);
5833     offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, subtree, di, drep,
5834                                     dissect_ndr_trust_extension, NDR_POINTER_UNIQUE,
5835                                     "Buffer", hf_index,NULL,NULL);
5836     return offset;
5837 }
5838 
5839 static int
DomainInfo_sid_(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5840 DomainInfo_sid_(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
5841 {
5842     offset = lsarpc_dissect_struct_dom_sid2(tvb, offset, pinfo, tree, di, drep, DomainInfo_sid, 0);
5843 
5844     return offset;
5845 }
5846 static int
dissect_element_lsa_DnsDomainInfo_sid(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5847 dissect_element_lsa_DnsDomainInfo_sid(tvbuff_t *tvb , int offset , packet_info *pinfo , proto_tree *tree , dcerpc_info *di, guint8 *drep )
5848 {
5849     offset = dissect_ndr_embedded_pointer(tvb, offset, pinfo, tree, di, drep, DomainInfo_sid_, NDR_POINTER_UNIQUE, "Pointer to Sid (dom_sid2)",DnsDomainInfo_sid);
5850 
5851     return offset;
5852 }
5853 static int
dissect_element_lsa_DnsDomainInfo_domain_guid(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5854 dissect_element_lsa_DnsDomainInfo_domain_guid(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep )
5855 {
5856     offset = dissect_ndr_uuid_t(tvb, offset, pinfo, tree, di, drep, DnsDomainInfo_domain_guid, NULL);
5857 
5858     return offset;
5859 }
5860 
5861 
dissect_part_DnsDomainInfo(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_index _U_,guint32 param _U_)5862 static int dissect_part_DnsDomainInfo(tvbuff_t *tvb , int offset, packet_info *pinfo, proto_tree *tree , dcerpc_info *di, guint8 *drep,  int hf_index _U_, guint32 param _U_)
5863 {
5864 
5865     offset = lsarpc_dissect_struct_lsa_StringLarge(tvb, offset, pinfo, tree, di, drep, DnsDomainInfo_name, 0);
5866 
5867     offset = lsarpc_dissect_struct_lsa_StringLarge(tvb,offset, pinfo, tree, di, drep, DnsDomainInfo_dns_domain, 0);
5868 
5869     offset = lsarpc_dissect_struct_lsa_StringLarge(tvb,offset, pinfo, tree, di, drep, DnsDomainInfo_dns_forest, 0);
5870 
5871     offset = dissect_element_lsa_DnsDomainInfo_domain_guid(tvb, offset, pinfo, tree, di, drep);
5872 
5873     offset = dissect_element_lsa_DnsDomainInfo_sid(tvb, offset, pinfo, tree, di, drep);
5874 
5875 
5876     return offset;
5877 }
5878 
5879 
5880 static int
netlogon_dissect_ONE_DOMAIN_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)5881 netlogon_dissect_ONE_DOMAIN_INFO(tvbuff_t *tvb, int offset,
5882                                  packet_info *pinfo, proto_tree *parent_tree,
5883                                  dcerpc_info *di, guint8 *drep)
5884 {
5885     proto_item *item=NULL;
5886     proto_tree *tree=NULL;
5887     int old_offset=offset;
5888 
5889     if(parent_tree){
5890         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
5891                                    ett_DOMAIN_TRUST_INFO, &item, "ONE_DOMAIN_INFO");
5892     }
5893 /*hf_netlogon_dnsdomaininfo*/
5894     offset = dissect_part_DnsDomainInfo(tvb, offset, pinfo, tree, di, drep, 0, 0);
5895 
5896 
5897     /* It is structed as a string but it's not ... it's 4 ulong */
5898     offset = dissect_ndr_ulongs_as_counted_string(tvb, offset, pinfo, tree, di, drep,
5899                                                   hf_netlogon_trust_extension);
5900 
5901     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
5902                                         hf_netlogon_dummy_string2, 0);
5903 
5904     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
5905                                         hf_netlogon_dummy_string3, 0);
5906 
5907     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
5908                                         hf_netlogon_dummy_string4, 0);
5909 
5910     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5911                                 hf_netlogon_dummy1_long, NULL);
5912 
5913     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5914                                 hf_netlogon_dummy2_long, NULL);
5915 
5916     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5917                                 hf_netlogon_dummy3_long, NULL);
5918 
5919     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5920                                 hf_netlogon_dummy4_long, NULL);
5921 
5922     proto_item_set_len(item, offset-old_offset);
5923     return offset;
5924 }
5925 
5926 static int
netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5927 netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
5928                                    packet_info *pinfo, proto_tree *tree,
5929                                    dcerpc_info *di, guint8 *drep)
5930 {
5931     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
5932                                  netlogon_dissect_ONE_DOMAIN_INFO);
5933 
5934     return offset;
5935 }
5936 
5937 
5938 static int
netlogon_dissect_LSA_POLICY_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5939 netlogon_dissect_LSA_POLICY_INFO(tvbuff_t *tvb, int offset,
5940                                  packet_info *pinfo, proto_tree *tree,
5941                                  dcerpc_info *di, guint8 *drep )
5942 {
5943     proto_item *item=NULL;
5944     proto_tree *subtree=NULL;
5945     guint32 len;
5946 
5947     if(di->conformant_run){
5948         return offset;
5949     }
5950 
5951     if(tree){
5952         subtree = proto_tree_add_subtree(tree, tvb, offset, 0,
5953                                    ett_LSA_POLICY_INFO, &item, "LSA Policy");
5954     }
5955     offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
5956                                 hf_netlogon_lsapolicy_len, &len);
5957 
5958     offset = dissect_ndr_pointer(tvb, offset, pinfo, subtree, di, drep,
5959                                  netlogon_dissect_BLOB_array, NDR_POINTER_UNIQUE,
5960                                  "Pointer:", -1);
5961 
5962     return offset;
5963 }
5964 
5965 
5966 
5967 
5968 static int
netlogon_dissect_WORKSTATION_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5969 netlogon_dissect_WORKSTATION_INFO(tvbuff_t *tvb , int offset ,
5970                                   packet_info *pinfo , proto_tree *tree ,
5971                                   dcerpc_info *di, guint8 *drep )
5972 {
5973     /* This is not the good way to do it ... it stinks ...
5974      * but after half of a day fighting against wireshark and ndr ...
5975      * I decided to keep this hack ...
5976      * At least data are correctly displayed without invented ints ...
5977      */
5978     offset = netlogon_dissect_LSA_POLICY_INFO(tvb, offset,
5979                                               pinfo, tree, di, drep);
5980 
5981     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5982                                           NDR_POINTER_UNIQUE, "Workstation FQDN",
5983                                           hf_netlogon_workstation_fqdn, 0);
5984 
5985     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5986                                           NDR_POINTER_UNIQUE, "Workstation Site",
5987                                           hf_netlogon_workstation_site_name, 0);
5988 
5989     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5990                                           NDR_POINTER_UNIQUE, "Dummy 1", hf_netlogon_dummy_string, 0);
5991 
5992     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5993                                           NDR_POINTER_UNIQUE, "Dummy 2", hf_netlogon_dummy_string2, 0);
5994 
5995     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5996                                           NDR_POINTER_UNIQUE, "Dummy 3", hf_netlogon_dummy_string3, 0);
5997 
5998     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
5999                                           NDR_POINTER_UNIQUE, "Dummy 4", hf_netlogon_dummy_string4, 0);
6000 
6001     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6002                                         hf_netlogon_os_version, 0);
6003 
6004     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6005                                         hf_netlogon_workstation_os, 0);
6006 
6007     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6008                                         hf_netlogon_dummy_string3, 0);
6009 
6010     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6011                                         hf_netlogon_dummy_string4, 0);
6012 
6013     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6014                                 hf_netlogon_workstation_flags, NULL);
6015 
6016     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6017                                 hf_netlogon_dummy2_long, NULL);
6018 
6019     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6020                                 hf_netlogon_dummy3_long, NULL);
6021 
6022     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6023                                 hf_netlogon_dummy4_long, NULL);
6024     return offset;
6025 }
6026 
6027 static int
netlogon_dissect_WORKSTATION_INFORMATION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6028 netlogon_dissect_WORKSTATION_INFORMATION(tvbuff_t *tvb , int offset ,
6029                                          packet_info *pinfo , proto_tree *tree ,
6030                                          dcerpc_info *di, guint8 *drep ) {
6031 
6032     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6033                                  netlogon_dissect_WORKSTATION_INFO, NDR_POINTER_UNIQUE,
6034                                  "WORKSTATION INFO", -1);
6035     return offset;
6036 }
6037 
6038 static int
netlogon_dissect_DOMAIN_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6039 netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
6040                              packet_info *pinfo, proto_tree *tree,
6041                              dcerpc_info *di, guint8 *drep)
6042 {
6043     offset = netlogon_dissect_ONE_DOMAIN_INFO(tvb, offset, pinfo, tree, di, drep);
6044 
6045     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6046                                 hf_netlogon_num_trusts, NULL);
6047 
6048     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6049                                  netlogon_dissect_DOMAIN_TRUST_INFO, NDR_POINTER_UNIQUE,
6050                                  "DOMAIN_TRUST_ARRAY: Trusted domains", -1);
6051 
6052     offset = netlogon_dissect_LSA_POLICY_INFO(tvb,offset,pinfo, tree,di,drep);
6053 
6054 /*      offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6055         hf_netlogon_num_trusts, NULL);
6056 
6057         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6058         netlogon_dissect_DOMAIN_TRUST_INFO, NDR_POINTER_UNIQUE,
6059         "LSA Policy", -1);
6060 */
6061     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6062                                         hf_netlogon_ad_client_dns_name, 0);
6063 
6064     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6065                                         hf_netlogon_dummy_string2, 0);
6066 
6067     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6068                                         hf_netlogon_dummy_string3, 0);
6069 
6070     offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, di, drep,
6071                                         hf_netlogon_dummy_string4, 0);
6072 
6073     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6074                                 hf_netlogon_workstation_flags, NULL);
6075 
6076     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6077                                 hf_netlogon_supportedenctypes, NULL);
6078 
6079     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6080                                 hf_netlogon_dummy3_long, NULL);
6081 
6082     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6083                                 hf_netlogon_dummy4_long, NULL);
6084 
6085     return offset;
6086 }
6087 
6088 
6089 static int
netlogon_dissect_DOMAIN_INFORMATION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6090 netlogon_dissect_DOMAIN_INFORMATION(tvbuff_t *tvb, int offset,
6091                                     packet_info *pinfo, proto_tree *tree,
6092                                     dcerpc_info *di, guint8 *drep)
6093 {
6094     guint32 level = 0;
6095 
6096     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6097                                 hf_netlogon_level, &level);
6098 
6099     ALIGN_TO_4_BYTES;
6100     switch(level){
6101     case 1:
6102         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6103                                      netlogon_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
6104                                      "DOMAIN_INFO", -1);
6105         break;
6106     }
6107 
6108     return offset;
6109 }
6110 
6111 static int
netlogon_dissect_UNICODE_STRING_512(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)6112 netlogon_dissect_UNICODE_STRING_512(tvbuff_t *tvb, int offset,
6113                                     packet_info *pinfo, proto_tree *parent_tree,
6114                                     dcerpc_info *di, guint8 *drep)
6115 {
6116     proto_item *item=NULL;
6117     proto_tree *tree=NULL;
6118     int old_offset=offset;
6119     int i;
6120 
6121     if(parent_tree){
6122         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
6123                                    ett_UNICODE_STRING_512, &item, "UNICODE_STRING_512:");
6124     }
6125 
6126     for(i=0;i<512;i++){
6127         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
6128                                     hf_netlogon_unknown_short, NULL);
6129     }
6130 
6131     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6132                                 hf_netlogon_unknown_long, NULL);
6133 
6134     proto_item_set_len(item, offset-old_offset);
6135     return offset;
6136 }
6137 
6138 static int
netlogon_dissect_element_844_byte(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6139 netlogon_dissect_element_844_byte(tvbuff_t *tvb, int offset,
6140                                   packet_info *pinfo, proto_tree *tree,
6141                                   dcerpc_info *di, guint8 *drep)
6142 {
6143     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
6144                                hf_netlogon_unknown_char, NULL);
6145 
6146     return offset;
6147 }
6148 
6149 static int
netlogon_dissect_element_844_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6150 netlogon_dissect_element_844_array(tvbuff_t *tvb, int offset,
6151                                    packet_info *pinfo, proto_tree *tree,
6152                                    dcerpc_info *di, guint8 *drep)
6153 {
6154     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
6155                                  netlogon_dissect_element_844_byte);
6156 
6157     return offset;
6158 }
6159 
6160 static int
netlogon_dissect_TYPE_50(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)6161 netlogon_dissect_TYPE_50(tvbuff_t *tvb, int offset,
6162                          packet_info *pinfo, proto_tree *parent_tree,
6163                          dcerpc_info *di, guint8 *drep)
6164 {
6165     proto_item *item=NULL;
6166     proto_tree *tree=NULL;
6167     int old_offset=offset;
6168 
6169     if(parent_tree){
6170         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
6171                                    ett_TYPE_50, &item, "TYPE_50:");
6172     }
6173 
6174     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6175                                 hf_netlogon_unknown_long, NULL);
6176 
6177     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6178                                  netlogon_dissect_element_844_array, NDR_POINTER_UNIQUE,
6179                                  "unknown", hf_netlogon_unknown_string);
6180 
6181     proto_item_set_len(item, offset-old_offset);
6182     return offset;
6183 }
6184 
6185 static int
netlogon_dissect_TYPE_50_ptr(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6186 netlogon_dissect_TYPE_50_ptr(tvbuff_t *tvb, int offset,
6187                              packet_info *pinfo, proto_tree *tree,
6188                              dcerpc_info *di, guint8 *drep)
6189 {
6190     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6191                                  netlogon_dissect_TYPE_50, NDR_POINTER_UNIQUE,
6192                                  "TYPE_50 pointer: unknown_TYPE_50", -1);
6193 
6194     return offset;
6195 }
6196 
6197 static int
netlogon_dissect_DS_DOMAIN_TRUSTS(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)6198 netlogon_dissect_DS_DOMAIN_TRUSTS(tvbuff_t *tvb, int offset,
6199                                   packet_info *pinfo, proto_tree *parent_tree, dcerpc_info *di, guint8 *drep)
6200 {
6201     guint32 tmp;
6202     proto_item *item=NULL;
6203     proto_tree *tree=NULL;
6204     int old_offset=offset;
6205 
6206     if(parent_tree){
6207         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
6208                                    ett_DS_DOMAIN_TRUSTS, NULL, "DS_DOMAIN_TRUSTS");
6209     }
6210 
6211     /* name */
6212     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6213                                           NDR_POINTER_UNIQUE, "NetBIOS Name",
6214                                           hf_netlogon_downlevel_domain_name, 0);
6215 
6216     /* domain */
6217     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6218                                           NDR_POINTER_UNIQUE, "DNS Domain Name",
6219                                           hf_netlogon_dns_domain_name, 0);
6220 
6221     offset = netlogon_dissect_DOMAIN_TRUST_FLAGS(tvb, offset, pinfo, tree, di, drep);
6222 
6223     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6224                                 hf_netlogon_trust_parent_index, &tmp);
6225 
6226     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6227                                 hf_netlogon_trust_type, &tmp);
6228 
6229     offset = netlogon_dissect_DOMAIN_TRUST_ATTRIBS(tvb, offset, pinfo, tree, di, drep);
6230 
6231     /* SID pointer */
6232     offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
6233 
6234     /* GUID */
6235     offset = dissect_nt_GUID(tvb, offset, pinfo, tree, di, drep);
6236 
6237     proto_item_set_len(item, offset-old_offset);
6238     return offset;
6239 }
6240 
6241 static int
netlogon_dissect_DS_DOMAIN_TRUSTS_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6242 netlogon_dissect_DS_DOMAIN_TRUSTS_ARRAY(tvbuff_t *tvb, int offset,
6243                                         packet_info *pinfo, proto_tree *tree,
6244                                         dcerpc_info *di, guint8 *drep)
6245 {
6246     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
6247                                  netlogon_dissect_DS_DOMAIN_TRUSTS);
6248 
6249     return offset;
6250 }
6251 
6252 static int
netlogon_dissect_element_865_byte(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6253 netlogon_dissect_element_865_byte(tvbuff_t *tvb, int offset,
6254                                   packet_info *pinfo, proto_tree *tree,
6255                                   dcerpc_info *di, guint8 *drep)
6256 {
6257     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
6258                                hf_netlogon_unknown_char, NULL);
6259 
6260     return offset;
6261 }
6262 
6263 static int
netlogon_dissect_element_865_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6264 netlogon_dissect_element_865_array(tvbuff_t *tvb, int offset,
6265                                    packet_info *pinfo, proto_tree *tree,
6266                                    dcerpc_info *di, guint8 *drep)
6267 {
6268     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
6269                                  netlogon_dissect_element_865_byte);
6270 
6271     return offset;
6272 }
6273 
6274 static int
netlogon_dissect_element_866_byte(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6275 netlogon_dissect_element_866_byte(tvbuff_t *tvb, int offset,
6276                                   packet_info *pinfo, proto_tree *tree,
6277                                   dcerpc_info *di, guint8 *drep)
6278 {
6279     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
6280                                hf_netlogon_unknown_char, NULL);
6281 
6282     return offset;
6283 }
6284 
6285 static int
netlogon_dissect_element_866_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6286 netlogon_dissect_element_866_array(tvbuff_t *tvb, int offset,
6287                                    packet_info *pinfo, proto_tree *tree,
6288                                    dcerpc_info *di, guint8 *drep)
6289 {
6290     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
6291                                  netlogon_dissect_element_866_byte);
6292 
6293     return offset;
6294 }
6295 
6296 static int
netlogon_dissect_TYPE_52(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)6297 netlogon_dissect_TYPE_52(tvbuff_t *tvb, int offset,
6298                          packet_info *pinfo, proto_tree *parent_tree,
6299                          dcerpc_info *di, guint8 *drep)
6300 {
6301     proto_item *item=NULL;
6302     proto_tree *tree=NULL;
6303     int old_offset=offset;
6304 
6305     if(parent_tree){
6306         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
6307                                    ett_TYPE_52, &item, "TYPE_52:");
6308     }
6309 
6310     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6311                                 hf_netlogon_unknown_long, NULL);
6312 
6313     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6314                                  netlogon_dissect_element_865_array, NDR_POINTER_UNIQUE,
6315                                  "unknown", hf_netlogon_unknown_string);
6316 
6317     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6318                                  netlogon_dissect_element_866_array, NDR_POINTER_UNIQUE,
6319                                  "unknown", hf_netlogon_unknown_string);
6320 
6321     proto_item_set_len(item, offset-old_offset);
6322     return offset;
6323 }
6324 
6325 static int
netlogon_dissect_TYPE_52_ptr(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6326 netlogon_dissect_TYPE_52_ptr(tvbuff_t *tvb, int offset,
6327                              packet_info *pinfo, proto_tree *tree,
6328                              dcerpc_info *di, guint8 *drep)
6329 {
6330     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6331                                  netlogon_dissect_TYPE_52, NDR_POINTER_UNIQUE,
6332                                  "TYPE_52 pointer: unknown_TYPE_52", -1);
6333     return offset;
6334 }
6335 
6336 
6337 static int
netlogon_dissect_TYPE_44(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * parent_tree,dcerpc_info * di,guint8 * drep)6338 netlogon_dissect_TYPE_44(tvbuff_t *tvb, int offset,
6339                          packet_info *pinfo, proto_tree *parent_tree,
6340                          dcerpc_info *di, guint8 *drep)
6341 {
6342     proto_item *item=NULL;
6343     proto_tree *tree=NULL;
6344     int old_offset=offset;
6345     guint32 level = 0;
6346 
6347     if(parent_tree){
6348         tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
6349                                    ett_TYPE_44, &item, "TYPE_44:");
6350     }
6351 
6352     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6353                                 hf_netlogon_level, &level);
6354 
6355     ALIGN_TO_4_BYTES;
6356     switch(level){
6357     case 1:
6358         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6359                                     hf_netlogon_unknown_long, NULL);
6360         break;
6361     }
6362 
6363     proto_item_set_len(item, offset-old_offset);
6364     return offset;
6365 }
6366 
6367 static int
netlogon_dissect_WORKSTATION_BUFFER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6368 netlogon_dissect_WORKSTATION_BUFFER(tvbuff_t *tvb, int offset,
6369                                     packet_info *pinfo, proto_tree *tree,
6370                                     dcerpc_info *di, guint8 *drep)
6371 {
6372     guint32 level;
6373 
6374     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6375                                 hf_netlogon_level, &level);
6376     if (level == 2) {
6377         /* Specs are not very clear (as usual ...) it seems that the
6378          * structure in both case is a NETLOGON_WORKSTATION_INFO
6379          * but in this case only the LSA POLICY INFO will contain
6380          * something
6381          */
6382         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6383                                      netlogon_dissect_WORKSTATION_INFORMATION, NDR_POINTER_UNIQUE,
6384                                      "LSA POLICY INFO", -1);
6385     }
6386     else {
6387         if (level == 1) {
6388             offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6389                                          netlogon_dissect_WORKSTATION_INFORMATION, NDR_POINTER_UNIQUE,
6390                                          "WORKSTATION INFORMATION", -1);}
6391     }
6392     return offset;
6393 }
6394 
6395 static int
netlogon_dissect_netrenumeratetrusteddomains_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6396 netlogon_dissect_netrenumeratetrusteddomains_rqst(tvbuff_t *tvb, int offset,
6397                                                   packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6398 {
6399     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6400                                               pinfo, tree, di, drep);
6401 
6402     return offset;
6403 }
6404 
6405 
6406 static int
netlogon_dissect_netrenumeratetrusteddomains_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6407 netlogon_dissect_netrenumeratetrusteddomains_reply(tvbuff_t *tvb, int offset,
6408                                                    packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6409 {
6410     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6411                                  netlogon_dissect_UNICODE_MULTI, NDR_POINTER_REF,
6412                                  "UNICODE_MULTI pointer: trust_dom_name_list", -1);
6413 
6414     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6415                               hf_netlogon_dos_rc, NULL);
6416 
6417     return offset;
6418 }
6419 
6420 static int
netlogon_dissect_dsrgetdcname_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6421 netlogon_dissect_dsrgetdcname_rqst(tvbuff_t *tvb, int offset,
6422                                    packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6423 {
6424     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6425                                               pinfo, tree, di, drep);
6426 
6427     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6428                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_logon_dom, 0);
6429 
6430     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6431                                  dissect_nt_GUID, NDR_POINTER_UNIQUE,
6432                                  "GUID pointer: domain_guid", -1);
6433 
6434     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6435                                  dissect_nt_GUID, NDR_POINTER_UNIQUE,
6436                                  "GUID pointer: site_guid", -1);
6437 
6438     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6439                                 hf_netlogon_flags, NULL);
6440 
6441     return offset;
6442 }
6443 
6444 
6445 static int
netlogon_dissect_dsrgetdcname_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6446 netlogon_dissect_dsrgetdcname_reply(tvbuff_t *tvb, int offset,
6447                                     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6448 {
6449     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6450                                  netlogon_dissect_DOMAIN_CONTROLLER_INFO, NDR_POINTER_UNIQUE,
6451                                  "DOMAIN_CONTROLLER_INFO:", -1);
6452 
6453     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6454                               hf_netlogon_dos_rc, NULL);
6455 
6456     return offset;
6457 }
6458 
6459 static int
netlogon_dissect_netrlogondummyroutine1_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6460 netlogon_dissect_netrlogondummyroutine1_rqst(tvbuff_t *tvb, int offset,
6461                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6462 {
6463     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6464                                               pinfo, tree, di, drep);
6465 
6466     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6467                                           NDR_POINTER_UNIQUE, "unknown string",
6468                                           hf_netlogon_unknown_string, 0);
6469 
6470     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6471                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
6472                                  "AUTHENTICATOR: credential", -1);
6473 
6474     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6475                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
6476                                  "AUTHENTICATOR: return_authenticator", -1);
6477 
6478     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6479                                 hf_netlogon_unknown_long, NULL);
6480 
6481     return offset;
6482 }
6483 
6484 
6485 static int
netlogon_dissect_netrlogondummyroutine1_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6486 netlogon_dissect_netrlogondummyroutine1_reply(tvbuff_t *tvb, int offset,
6487                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6488 {
6489     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6490                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
6491                                  "AUTHENTICATOR: return_authenticator", -1);
6492 
6493     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6494                                  netlogon_dissect_TYPE_44, NDR_POINTER_UNIQUE,
6495                                  "TYPE_44 pointer: unknown_TYPE_44", -1);
6496 
6497     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6498                               hf_netlogon_rc, NULL);
6499 
6500     return offset;
6501 }
6502 
6503 static int
netlogon_dissect_netrlogonsetservicebits_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6504 netlogon_dissect_netrlogonsetservicebits_rqst(tvbuff_t *tvb, int offset,
6505                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6506 {
6507     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6508                                               pinfo, tree, di, drep);
6509 
6510     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6511                                 hf_netlogon_unknown_long, NULL);
6512 
6513     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6514                                 hf_netlogon_unknown_long, NULL);
6515 
6516     return offset;
6517 }
6518 
6519 
6520 static int
netlogon_dissect_netrlogonsetservicebits_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6521 netlogon_dissect_netrlogonsetservicebits_reply(tvbuff_t *tvb, int offset,
6522                                                packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6523 {
6524     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6525                               hf_netlogon_rc, NULL);
6526 
6527     return offset;
6528 }
6529 
6530 
6531 static int
netlogon_dissect_netrlogongettrustrid_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6532 netlogon_dissect_netrlogongettrustrid_rqst(tvbuff_t *tvb, int offset,
6533                                            packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6534 {
6535     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6536                                               pinfo, tree, di, drep);
6537 
6538     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6539                                           NDR_POINTER_UNIQUE, "unknown string",
6540                                           hf_netlogon_unknown_string, 0);
6541 
6542     return offset;
6543 }
6544 
6545 
6546 static int
netlogon_dissect_netrlogongettrustrid_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6547 netlogon_dissect_netrlogongettrustrid_reply(tvbuff_t *tvb, int offset,
6548                                             packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6549 {
6550     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6551                                  netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
6552                                  "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
6553 
6554     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6555                               hf_netlogon_rc, NULL);
6556 
6557     return offset;
6558 }
6559 
6560 
6561 static int
netlogon_dissect_netrlogoncomputeserverdigest_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6562 netlogon_dissect_netrlogoncomputeserverdigest_rqst(tvbuff_t *tvb, int offset,
6563                                                    packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6564 {
6565     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6566                                               pinfo, tree, di, drep);
6567 
6568     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6569                                 hf_netlogon_unknown_long, NULL);
6570 
6571     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6572                                  netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
6573                                  "BYTE pointer: unknown_BYTE", -1);
6574 
6575     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6576                                 hf_netlogon_unknown_long, NULL);
6577 
6578     return offset;
6579 }
6580 
6581 static int
netlogon_dissect_BYTE_16_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6582 netlogon_dissect_BYTE_16_array(tvbuff_t *tvb, int offset,
6583                                packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6584 {
6585     int i;
6586 
6587     for(i=0;i<16;i++){
6588         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
6589                                    hf_netlogon_unknown_char, NULL);
6590     }
6591 
6592     return offset;
6593 }
6594 
6595 static int
netlogon_dissect_netrlogoncomputeserverdigest_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6596 netlogon_dissect_netrlogoncomputeserverdigest_reply(tvbuff_t *tvb, int offset,
6597                                                     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6598 {
6599     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6600                                  netlogon_dissect_BYTE_16_array, NDR_POINTER_UNIQUE,
6601                                  "BYTE pointer: unknown_BYTE", -1);
6602 
6603     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6604                               hf_netlogon_rc, NULL);
6605 
6606     return offset;
6607 }
6608 
6609 static int
netlogon_dissect_netrlogoncomputeclientdigest_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6610 netlogon_dissect_netrlogoncomputeclientdigest_rqst(tvbuff_t *tvb, int offset,
6611                                                    packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6612 {
6613     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6614                                               pinfo, tree, di, drep);
6615 
6616     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6617                                           NDR_POINTER_UNIQUE, "unknown string",
6618                                           hf_netlogon_unknown_string, 0);
6619 
6620     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6621                                  netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
6622                                  "BYTE pointer: unknown_BYTE", -1);
6623 
6624     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6625                                 hf_netlogon_unknown_long, NULL);
6626 
6627     return offset;
6628 }
6629 
6630 
6631 static int
netlogon_dissect_netrlogoncomputeclientdigest_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6632 netlogon_dissect_netrlogoncomputeclientdigest_reply(tvbuff_t *tvb, int offset,
6633                                                     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6634 {
6635     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6636                                  netlogon_dissect_BYTE_16_array, NDR_POINTER_UNIQUE,
6637                                  "BYTE pointer: unknown_BYTE", -1);
6638 
6639     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6640                               hf_netlogon_rc, NULL);
6641 
6642     return offset;
6643 }
netlogon_dissect_neg_options(tvbuff_t * tvb,proto_tree * tree,guint32 flags,int offset)6644 static int netlogon_dissect_neg_options(tvbuff_t *tvb,proto_tree *tree,guint32 flags,int offset)
6645 {
6646     static int * const hf_flags[] = {
6647 #if 0
6648         &hf_netlogon_neg_flags_80000000,
6649 #endif
6650         &hf_netlogon_neg_flags_40000000,
6651         &hf_netlogon_neg_flags_20000000,
6652 #if 0
6653         &hf_netlogon_neg_flags_10000000,
6654         &hf_netlogon_neg_flags_8000000,
6655         &hf_netlogon_neg_flags_4000000,
6656         &hf_netlogon_neg_flags_2000000,
6657         &hf_netlogon_neg_flags_800000,
6658         &hf_netlogon_neg_flags_400000,
6659 #endif
6660         &hf_netlogon_neg_flags_1000000,
6661         &hf_netlogon_neg_flags_200000,
6662         &hf_netlogon_neg_flags_100000,
6663         &hf_netlogon_neg_flags_80000,
6664         &hf_netlogon_neg_flags_40000,
6665         &hf_netlogon_neg_flags_20000,
6666         &hf_netlogon_neg_flags_10000,
6667         &hf_netlogon_neg_flags_8000,
6668         &hf_netlogon_neg_flags_4000,
6669         &hf_netlogon_neg_flags_2000,
6670         &hf_netlogon_neg_flags_1000,
6671         &hf_netlogon_neg_flags_800,
6672         &hf_netlogon_neg_flags_400,
6673         &hf_netlogon_neg_flags_200,
6674         &hf_netlogon_neg_flags_100,
6675         &hf_netlogon_neg_flags_80,
6676         &hf_netlogon_neg_flags_40,
6677         &hf_netlogon_neg_flags_20,
6678         &hf_netlogon_neg_flags_10,
6679         &hf_netlogon_neg_flags_8,
6680         &hf_netlogon_neg_flags_4,
6681         &hf_netlogon_neg_flags_2,
6682         &hf_netlogon_neg_flags_1,
6683         NULL
6684     };
6685 
6686     proto_tree_add_bitmask_value_with_flags(tree, tvb, offset, hf_netlogon_neg_flags, ett_authenticate_flags, hf_flags, flags, BMT_NO_APPEND);
6687 
6688     return 0;
6689 }
6690 
6691 static int
netlogon_dissect_netrserverauthenticate3_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6692 netlogon_dissect_netrserverauthenticate3_rqst(tvbuff_t *tvb, int offset,
6693                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6694 {
6695     guint32 flags;
6696     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6697                                               pinfo, tree, di, drep);
6698     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6699                                           NDR_POINTER_REF, "Acct Name", hf_netlogon_acct_name, 0);
6700 
6701     offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
6702                                                            pinfo, tree, di, drep);
6703 
6704     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6705                                           NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
6706 
6707     offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
6708                                    hf_client_credential, NULL);
6709 #if 0
6710     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6711                                  netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
6712                                  "Client Challenge", -1);
6713 #endif
6714 
6715 #if 0
6716     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6717                                 hf_netlogon_neg_flags, NULL);
6718 #endif
6719     ALIGN_TO_4_BYTES;
6720 
6721     flags = tvb_get_letohl (tvb, offset);
6722     netlogon_dissect_neg_options(tvb,tree,flags,offset);
6723     seen.isseen = FALSE;
6724     seen.num = 0;
6725     offset +=4;
6726     return offset;
6727 }
6728 
6729 /*
6730  * IDL long NetrServerAuthenticate2(
6731  * IDL      [in][string][unique] wchar_t *logonserver,
6732  * IDL      [in][ref][string] wchar_t *username,
6733  * IDL      [in] short secure_channel_type,
6734  * IDL      [in][ref][string] wchar_t *computername,
6735  * IDL      [in][ref] CREDENTIAL *client_chal,
6736  * IDL      [out][ref] CREDENTIAL *server_chal,
6737  * IDL      [in][out][ref] long *negotiate_flags,
6738  * IDL );
6739  */
6740 static int
netlogon_dissect_netrserverauthenticate2_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6741 netlogon_dissect_netrserverauthenticate2_rqst(tvbuff_t *tvb, int offset,
6742                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6743 {
6744     return netlogon_dissect_netrserverauthenticate3_rqst(tvb,offset,pinfo,tree,di,drep);
6745 }
6746 
6747 static int
netlogon_dissect_netrserverauthenticate023_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int version)6748 netlogon_dissect_netrserverauthenticate023_reply(tvbuff_t *tvb, int offset,
6749                                                  packet_info *pinfo,
6750                                                  proto_tree *tree,
6751                                                  dcerpc_info *di,
6752                                                  guint8 *drep,
6753                                                  int version)
6754 {
6755     guint32 flags = 0;
6756     netlogon_auth_vars *vars;
6757     netlogon_auth_key key;
6758     guint64 server_cred;
6759 
6760     offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
6761                                    hf_server_credential, &server_cred);
6762 
6763     if (version >= 2) {
6764         flags = tvb_get_letohl (tvb, offset);
6765         netlogon_dissect_neg_options(tvb,tree,flags,offset);
6766         offset +=4;
6767     }
6768     ALIGN_TO_4_BYTES;
6769     if (version >= 3) {
6770         offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
6771                                        hf_server_rid, NULL);
6772     }
6773     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
6774                               hf_netlogon_rc, NULL);
6775 
6776     generate_hash_key(pinfo, 1 , &key);
6777 
6778     vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths, &key);
6779     if(vars != NULL) {
6780         debugprintf("Found some vars (ie. server/client challenges), let's see if I can get a session key\n");
6781         while(vars != NULL && vars->next_start != -1 && vars->next_start < (int) pinfo->num ) {
6782             debugprintf("looping auth reply...\n");
6783             vars = vars->next;
6784         }
6785         if(vars == NULL ) {
6786             debugprintf("Something strange happened while searching for authenticate_reply\n");
6787         }
6788         else {
6789             md4_pass *pass_list=NULL;
6790             const md4_pass *used_md4 = NULL;
6791             const char *used_method = NULL;
6792             guint32 list_size = 0;
6793             unsigned int i = 0;
6794             md4_pass password;
6795             guint8 session_key[16];
6796             int found = 0;
6797 
6798             vars->flags = flags;
6799             vars->can_decrypt = FALSE;
6800             list_size = get_md4pass_list(pinfo->pool, &pass_list);
6801             debugprintf("Found %d passwords \n",list_size);
6802             if( flags & NETLOGON_FLAG_AES )
6803             {
6804 #if GCRYPT_VERSION_NUMBER >= 0x010800 /* 1.8.0 */
6805                 guint8 salt_buf[16] = { 0 };
6806                 guint8 sha256[HASH_SHA2_256_LENGTH];
6807                 guint64 calculated_cred;
6808 
6809                 memcpy(&salt_buf[0], (guint8*)&vars->client_challenge, 8);
6810                 memcpy(&salt_buf[8], (guint8*)&vars->server_challenge, 8);
6811 
6812                 used_method = "AES";
6813                 printnbyte((guint8*)&vars->client_challenge,8,"Client challenge:","\n");
6814                 printnbyte((guint8*)&vars->server_challenge,8,"Server challenge:","\n");
6815                 printnbyte((guint8*)&server_cred,8,"Server creds:","\n");
6816                 for(i=0;i<list_size;i++)
6817                 {
6818                     used_md4 = &pass_list[i];
6819                     password = pass_list[i];
6820                     printnbyte((guint8*)&password, 16,"NTHASH:","\n");
6821                     if (!ws_hmac_buffer(GCRY_MD_SHA256, sha256, salt_buf, sizeof(salt_buf), (guint8*) &password, 16)) {
6822                         gcry_error_t err;
6823                         gcry_cipher_hd_t cipher_hd = NULL;
6824                         guint8 iv[16] = { 0 };
6825 
6826                         /* truncate the session key to 16 bytes */
6827                         memcpy(session_key, sha256, 16);
6828                         printnbyte((guint8*)session_key, 16,"Session Key","\n");
6829 
6830                         /* Open the cipher */
6831                         err = gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB8, 0);
6832                         if (err != 0) {
6833                             ws_warning("GCRY: cipher open %s/%s\n", gcry_strsource(err), gcry_strerror(err));
6834                             break;
6835                         }
6836 
6837                         /* Set the initial value */
6838                         err = gcry_cipher_setiv(cipher_hd, iv, sizeof(iv));
6839                         if (err != 0) {
6840                             ws_warning("GCRY: setiv %s/%s\n", gcry_strsource(err), gcry_strerror(err));
6841                             gcry_cipher_close(cipher_hd);
6842                             break;
6843                         }
6844 
6845                         /* Set the key */
6846                         err = gcry_cipher_setkey(cipher_hd, session_key, 16);
6847                         if (err != 0) {
6848                             ws_warning("GCRY: setkey %s/%s\n", gcry_strsource(err), gcry_strerror(err));
6849                             gcry_cipher_close(cipher_hd);
6850                             break;
6851                         }
6852 
6853                         calculated_cred = 0x1234567812345678;
6854                         err = gcry_cipher_encrypt(cipher_hd,
6855                                                   (guint8 *)&calculated_cred, 8,
6856                                                   (const guint8 *)&vars->server_challenge, 8);
6857                         if (err != 0) {
6858                             ws_warning("GCRY: encrypt %s/%s\n", gcry_strsource(err), gcry_strerror(err));
6859                             gcry_cipher_close(cipher_hd);
6860                             break;
6861                         }
6862 
6863                         /* Done with the cipher */
6864                         gcry_cipher_close(cipher_hd);
6865 
6866                         printnbyte((guint8*)&calculated_cred,8,"Calculated creds:","\n");
6867 
6868                         if(calculated_cred==server_cred) {
6869                             found = 1;
6870                             break;
6871                         }
6872                     }
6873                 }
6874 #endif
6875             } else if ( flags & NETLOGON_FLAG_STRONGKEY ) {
6876                 guint8 zeros[4] = { 0 };
6877                 guint8 md5[HASH_MD5_LENGTH];
6878                 gcry_md_hd_t md5_handle;
6879                 guint8 buf[8] = { 0 };
6880                 guint64 calculated_cred;
6881 
6882                 used_method = "MD5";
6883                 if (!gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) {
6884                     gcry_md_write(md5_handle, zeros, 4);
6885                     gcry_md_write(md5_handle, (guint8*)&vars->client_challenge, 8);
6886                     gcry_md_write(md5_handle, (guint8*)&vars->server_challenge, 8);
6887                     memcpy(md5, gcry_md_read(md5_handle, 0), 16);
6888                     gcry_md_close(md5_handle);
6889                 }
6890                 printnbyte(md5,8,"MD5:","\n");
6891                 printnbyte((guint8*)&vars->client_challenge,8,"Client challenge:","\n");
6892                 printnbyte((guint8*)&vars->server_challenge,8,"Server challenge:","\n");
6893                 printnbyte((guint8*)&server_cred,8,"Server creds:","\n");
6894                 for(i=0;i<list_size;i++)
6895                 {
6896                     used_md4 = &pass_list[i];
6897                     password = pass_list[i];
6898                     if (!ws_hmac_buffer(GCRY_MD_MD5, session_key, md5, HASH_MD5_LENGTH, (guint8*) &password, 16)) {
6899                         crypt_des_ecb(buf,(unsigned char*)&vars->server_challenge,session_key);
6900                         crypt_des_ecb((unsigned char*)&calculated_cred,buf,session_key+7);
6901                         printnbyte((guint8*)&calculated_cred,8,"Calculated creds:","\n");
6902                         if(calculated_cred==server_cred) {
6903                             found = 1;
6904                             break;
6905                         }
6906                     }
6907                 }
6908             }
6909             else
6910             {
6911                 /*Not implemented*/
6912                 debugprintf("Else case not implemented\n");
6913                 memset(session_key,0,16);
6914             }
6915             if(found) {
6916                 vars->nthash = *used_md4;
6917                 vars->auth_fd_num = pinfo->num;
6918                 memcpy(&vars->session_key,session_key,16);
6919                 debugprintf("Found the good session key !\n");
6920                 expert_add_info_format(pinfo, proto_tree_get_parent(tree),
6921                          &ei_netlogon_auth_nthash,
6922                          "%s authenticated using %s (%02x%02x%02x%02x...)",
6923                          used_method, used_md4->key_origin,
6924                          used_md4->md4[0] & 0xFF, used_md4->md4[1] & 0xFF,
6925                          used_md4->md4[2] & 0xFF, used_md4->md4[3] & 0xFF);
6926                 expert_add_info_format(pinfo, proto_tree_get_parent(tree),
6927                          &ei_netlogon_session_key,
6928                          "session key ("
6929                          "%02x%02x%02x%02x"
6930                          "%02x%02x%02x%02x"
6931                          "%02x%02x%02x%02x"
6932                          "%02x%02x%02x%02x"
6933                          ")",
6934                          session_key[0] & 0xFF,  session_key[1] & 0xFF,
6935                          session_key[2] & 0xFF,  session_key[3] & 0xFF,
6936                          session_key[4] & 0xFF,  session_key[5] & 0xFF,
6937                          session_key[6] & 0xFF,  session_key[7] & 0xFF,
6938                          session_key[8] & 0xFF,  session_key[9] & 0xFF,
6939                          session_key[10] & 0xFF, session_key[11] & 0xFF,
6940                          session_key[12] & 0xFF, session_key[13] & 0xFF,
6941                          session_key[14] & 0xFF, session_key[15] & 0xFF);
6942             }
6943             else {
6944                 debugprintf("Session key not found !\n");
6945                 memset(&vars->session_key,0,16);
6946             }
6947         }
6948     }
6949 
6950     return offset;
6951 }
6952 
6953 static int
netlogon_dissect_netrserverauthenticate3_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6954 netlogon_dissect_netrserverauthenticate3_reply(tvbuff_t *tvb, int offset,
6955                                                packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6956 {
6957     return netlogon_dissect_netrserverauthenticate023_reply(tvb,offset,pinfo,tree,di,drep,3);
6958 }
6959 
6960 static int
netlogon_dissect_netrserverauthenticate2_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6961 netlogon_dissect_netrserverauthenticate2_reply(tvbuff_t *tvb, int offset,
6962                                                packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6963 {
6964     return netlogon_dissect_netrserverauthenticate023_reply(tvb,offset,pinfo,tree,di,drep,2);
6965 }
6966 
6967 
6968 static int
netlogon_dissect_dsrgetdcnameex_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6969 netlogon_dissect_dsrgetdcnameex_rqst(tvbuff_t *tvb, int offset,
6970                                      packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6971 {
6972     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6973                                               pinfo, tree, di, drep);
6974 
6975     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6976                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_logon_dom, 0);
6977 
6978     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6979                                  dissect_nt_GUID, NDR_POINTER_UNIQUE,
6980                                  "GUID pointer: domain_guid", -1);
6981 
6982     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
6983                                           NDR_POINTER_UNIQUE, "Site Name", hf_netlogon_site_name, 0);
6984 
6985     offset = netlogon_dissect_GET_DCNAME_REQUEST_FLAGS(tvb, offset, pinfo, tree, di, drep);
6986 
6987     return offset;
6988 }
6989 
6990 
6991 static int
netlogon_dissect_dsrgetdcnameex_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6992 netlogon_dissect_dsrgetdcnameex_reply(tvbuff_t *tvb, int offset,
6993                                       packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
6994 {
6995     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
6996                                  netlogon_dissect_DOMAIN_CONTROLLER_INFO, NDR_POINTER_UNIQUE,
6997                                  "DOMAIN_CONTROLLER_INFO:", -1);
6998 
6999     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7000                               hf_netlogon_rc, NULL);
7001 
7002     return offset;
7003 }
7004 
7005 static int
netlogon_dissect_dsrgetsitename_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7006 netlogon_dissect_dsrgetsitename_rqst(tvbuff_t *tvb, int offset,
7007                                      packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7008 {
7009     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7010                                               pinfo, tree, di, drep);
7011 
7012     return offset;
7013 }
7014 
7015 
7016 static int
netlogon_dissect_dsrgetsitename_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7017 netlogon_dissect_dsrgetsitename_reply(tvbuff_t *tvb, int offset,
7018                                       packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7019 {
7020 
7021     /* XXX hmmm this does not really look like a UNIQUE pointer but
7022        will do for now.   I think it is really a 32bit integer followed by
7023        a REF pointer to a unicode string */
7024     offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, di, drep,
7025                                     dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE, "Site Name",
7026                                     hf_netlogon_site_name, cb_wstr_postprocess,
7027                                     GINT_TO_POINTER(CB_STR_COL_INFO | 1));
7028 
7029     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7030                               hf_netlogon_dos_rc, NULL);
7031 
7032     return offset;
7033 }
7034 
7035 static int
netlogon_dissect_netrlogongetdomaininfo_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7036 netlogon_dissect_netrlogongetdomaininfo_rqst(tvbuff_t *tvb, int offset,
7037                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7038 {
7039     /* Unlike the other NETLOGON RPCs, this is not a unique pointer. */
7040     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7041                                           NDR_POINTER_REF, "Server Handle", hf_netlogon_computer_name, 0);
7042     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7043                                           NDR_POINTER_UNIQUE, "Computer Name",
7044                                           hf_netlogon_computer_name, 0);
7045 
7046     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7047                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
7048                                  "AUTHENTICATOR: client", -1);
7049 
7050     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7051                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
7052                                  "AUTHENTICATOR: return_authenticator", -1);
7053     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7054                                  netlogon_dissect_WORKSTATION_BUFFER, NDR_POINTER_REF,
7055                                  "WORKSTATION_BUFFER", -1);
7056     return offset;
7057 }
7058 
7059 
7060 static int
netlogon_dissect_netrlogongetdomaininfo_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7061 netlogon_dissect_netrlogongetdomaininfo_reply(tvbuff_t *tvb, int offset,
7062                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7063 {
7064     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7065                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
7066                                  "AUTHENTICATOR: return_authenticator", -1);
7067 
7068     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7069                                  netlogon_dissect_DOMAIN_INFORMATION, NDR_POINTER_REF,
7070                                  "DOMAIN_INFORMATION", -1);
7071 
7072     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7073                               hf_netlogon_rc, NULL);
7074 
7075     return offset;
7076 }
7077 
7078 static int
netlogon_dissect_netrserverpasswordset2_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7079 netlogon_dissect_netrserverpasswordset2_rqst(tvbuff_t *tvb, int offset,
7080                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7081 {
7082     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7083                                               pinfo, tree, di, drep);
7084 
7085     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7086                                           NDR_POINTER_UNIQUE, "unknown string",
7087                                           hf_netlogon_unknown_string, 0);
7088 
7089     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
7090                                 hf_netlogon_unknown_short, NULL);
7091 
7092     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7093                                           NDR_POINTER_UNIQUE, "unknown string",
7094                                           hf_netlogon_unknown_string, 0);
7095 
7096     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7097                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
7098                                  "AUTHENTICATOR: credential", -1);
7099 
7100     offset = netlogon_dissect_UNICODE_STRING_512(tvb, offset,
7101                                                  pinfo, tree, di, drep);
7102 
7103     return offset;
7104 }
7105 
7106 
7107 static int
netlogon_dissect_netrserverpasswordset2_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7108 netlogon_dissect_netrserverpasswordset2_reply(tvbuff_t *tvb, int offset,
7109                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7110 {
7111     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7112                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
7113                                  "AUTHENTICATOR: return_authenticator", -1);
7114 
7115     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7116                               hf_netlogon_rc, NULL);
7117 
7118     return offset;
7119 }
7120 
7121 static int
netlogon_dissect_netrserverpasswordget_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7122 netlogon_dissect_netrserverpasswordget_rqst(tvbuff_t *tvb, int offset,
7123                                             packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7124 {
7125     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7126                                               pinfo, tree, di, drep);
7127 
7128     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7129                                           NDR_POINTER_UNIQUE, "Acct Name", hf_netlogon_acct_name, 0);
7130 
7131     offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
7132                                                            pinfo, tree, di, drep);
7133 
7134     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7135                                           NDR_POINTER_UNIQUE, "Computer Name",
7136                                           hf_netlogon_computer_name, 0);
7137 
7138     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7139                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
7140                                  "AUTHENTICATOR: credential", -1);
7141 
7142     return offset;
7143 }
7144 
7145 
7146 static int
netlogon_dissect_netrserverpasswordget_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7147 netlogon_dissect_netrserverpasswordget_reply(tvbuff_t *tvb, int offset,
7148                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7149 {
7150     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7151                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
7152                                  "AUTHENTICATOR: return_authenticator", -1);
7153 
7154     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7155                                  netlogon_dissect_LM_OWF_PASSWORD, NDR_POINTER_REF,
7156                                  "LM_OWF_PASSWORD pointer: server_pwd", -1);
7157 
7158     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7159                               hf_netlogon_rc, NULL);
7160 
7161     return offset;
7162 }
7163 
7164 static int
netlogon_dissect_netrlogonsendtosam_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7165 netlogon_dissect_netrlogonsendtosam_rqst(tvbuff_t *tvb, int offset,
7166                                          packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7167 {
7168     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7169                                               pinfo, tree, di, drep);
7170 
7171     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7172                                           NDR_POINTER_UNIQUE, "unknown string",
7173                                           hf_netlogon_unknown_string, 0);
7174 
7175     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7176                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
7177                                  "AUTHENTICATOR: credential", -1);
7178 
7179     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7180                                  netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
7181                                  "BYTE pointer: unknown_BYTE", -1);
7182 
7183     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7184                                 hf_netlogon_unknown_long, NULL);
7185 
7186     return offset;
7187 }
7188 
7189 
7190 static int
netlogon_dissect_netrlogonsendtosam_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7191 netlogon_dissect_netrlogonsendtosam_reply(tvbuff_t *tvb, int offset,
7192                                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7193 {
7194     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7195                                  netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
7196                                  "AUTHENTICATOR: return_authenticator", -1);
7197 
7198     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7199                               hf_netlogon_rc, NULL);
7200 
7201     return offset;
7202 }
7203 
7204 static int
netlogon_dissect_dsraddresstositenamesw_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7205 netlogon_dissect_dsraddresstositenamesw_rqst(tvbuff_t *tvb, int offset,
7206                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7207 {
7208     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7209                                               pinfo, tree, di, drep);
7210 
7211     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7212                                 hf_netlogon_unknown_long, NULL);
7213 
7214     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7215                                  netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
7216                                  "BYTE pointer: unknown_BYTE", -1);
7217 
7218     return offset;
7219 }
7220 
7221 
7222 static int
netlogon_dissect_dsraddresstositenamesw_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7223 netlogon_dissect_dsraddresstositenamesw_reply(tvbuff_t *tvb, int offset,
7224                                               packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7225 {
7226     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7227                                  netlogon_dissect_TYPE_50_ptr, NDR_POINTER_UNIQUE,
7228                                  "TYPE_50** pointer: unknown_TYPE_50", -1);
7229 
7230     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7231                               hf_netlogon_rc, NULL);
7232 
7233     return offset;
7234 }
7235 
7236 static int
netlogon_dissect_dsrgetdcnameex2_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7237 netlogon_dissect_dsrgetdcnameex2_rqst(tvbuff_t *tvb, int offset,
7238                                       packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7239 {
7240     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7241                                               pinfo, tree, di, drep);
7242 
7243     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7244                                           NDR_POINTER_UNIQUE, "Client Account",
7245                                           hf_netlogon_acct_name, 0);
7246 
7247     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7248                                 hf_netlogon_unknown_long, NULL);
7249 
7250     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7251                                           NDR_POINTER_UNIQUE, "Client Account",
7252                                           hf_netlogon_logon_dom, 0);
7253 
7254     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7255                                  dissect_nt_GUID, NDR_POINTER_UNIQUE,
7256                                  "Domain GUID:", -1);
7257 
7258     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7259                                           NDR_POINTER_UNIQUE, "Client Site",
7260                                           hf_netlogon_site_name, 0);
7261 
7262     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7263                                 hf_netlogon_unknown_long, NULL);
7264 
7265     return offset;
7266 }
7267 
7268 
7269 static int
netlogon_dissect_dsrgetdcnameex2_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7270 netlogon_dissect_dsrgetdcnameex2_reply(tvbuff_t *tvb, int offset,
7271                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7272 {
7273     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7274                                  netlogon_dissect_DOMAIN_CONTROLLER_INFO, NDR_POINTER_UNIQUE,
7275                                  "DOMAIN_CONTROLLER_INFO:", -1);
7276 
7277     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7278                               hf_netlogon_dos_rc, NULL);
7279 
7280     return offset;
7281 }
7282 
7283 static int
netlogon_dissect_netrlogongettimeserviceparentdomain_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7284 netlogon_dissect_netrlogongettimeserviceparentdomain_rqst(tvbuff_t *tvb, int offset,
7285                                                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7286 {
7287     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7288                                               pinfo, tree, di, drep);
7289 
7290     return offset;
7291 }
7292 
7293 
7294 static int
netlogon_dissect_netrlogongettimeserviceparentdomain_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7295 netlogon_dissect_netrlogongettimeserviceparentdomain_reply(tvbuff_t *tvb, int offset,
7296                                                            packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7297 {
7298     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7299                                           NDR_POINTER_UNIQUE, "unknown string",
7300                                           hf_netlogon_unknown_string, 0);
7301 
7302     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7303                                  netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
7304                                  "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
7305 
7306     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7307                               hf_netlogon_rc, NULL);
7308 
7309     return offset;
7310 }
7311 
7312 static int
netlogon_dissect_netrenumeratetrusteddomainsex_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7313 netlogon_dissect_netrenumeratetrusteddomainsex_rqst(tvbuff_t *tvb, int offset,
7314                                                     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7315 {
7316     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7317                                               pinfo, tree, di, drep);
7318 
7319     return offset;
7320 }
7321 
7322 static int
netlogon_dissect_netrenumeratetrusteddomainsex_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7323 netlogon_dissect_netrenumeratetrusteddomainsex_reply(tvbuff_t *tvb, int offset,
7324                                                      packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7325 {
7326     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7327                                 hf_netlogon_entries, NULL);
7328 
7329     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7330                                  netlogon_dissect_DS_DOMAIN_TRUSTS_ARRAY, NDR_POINTER_UNIQUE,
7331                                  "DS_DOMAIN_TRUSTS_ARRAY:", -1);
7332 
7333     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7334                               hf_netlogon_rc, NULL);
7335 
7336     return offset;
7337 }
7338 
7339 static int
netlogon_dissect_dsraddresstositenamesexw_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7340 netlogon_dissect_dsraddresstositenamesexw_rqst(tvbuff_t *tvb, int offset,
7341                                                packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7342 {
7343     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7344                                               pinfo, tree, di, drep);
7345 
7346     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7347                                 hf_netlogon_unknown_long, NULL);
7348 
7349     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7350                                  netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
7351                                  "BYTE pointer: unknown_BYTE", -1);
7352 
7353     return offset;
7354 }
7355 
7356 
7357 static int
netlogon_dissect_dsraddresstositenamesexw_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7358 netlogon_dissect_dsraddresstositenamesexw_reply(tvbuff_t *tvb, int offset,
7359                                                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7360 {
7361     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7362                                  netlogon_dissect_TYPE_52_ptr, NDR_POINTER_UNIQUE,
7363                                  "TYPE_52 pointer: unknown_TYPE_52", -1);
7364 
7365     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7366                               hf_netlogon_rc, NULL);
7367 
7368     return offset;
7369 }
7370 
7371 
7372 static int
netlogon_dissect_site_name_item(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7373 netlogon_dissect_site_name_item(tvbuff_t *tvb, int offset,
7374                                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7375 {
7376     offset = dissect_ndr_counted_string_cb(
7377         tvb, offset, pinfo, tree, di, drep, hf_netlogon_site_name,
7378         cb_wstr_postprocess,
7379         GINT_TO_POINTER(CB_STR_COL_INFO | 1));
7380 
7381     return offset;
7382 }
7383 static int
netlogon_dissect_site_name_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7384 netlogon_dissect_site_name_array(tvbuff_t *tvb, int offset,
7385                                  packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7386 {
7387     offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
7388                                  netlogon_dissect_site_name_item);
7389 
7390     return offset;
7391 }
7392 
7393 static int
netlogon_dissect_site_names(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7394 netlogon_dissect_site_names(tvbuff_t *tvb, int offset,
7395                             packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7396 {
7397     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7398                                 hf_netlogon_count, NULL);
7399 
7400     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7401                                  netlogon_dissect_site_name_array, NDR_POINTER_UNIQUE,
7402                                  "Site name array", -1);
7403 
7404     return offset;
7405 }
7406 
7407 static int
netlogon_dissect_dsrgetdcsitecoveragew_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7408 netlogon_dissect_dsrgetdcsitecoveragew_rqst(tvbuff_t *tvb, int offset,
7409                                             packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7410 {
7411     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7412                                               pinfo, tree, di, drep);
7413 
7414     return offset;
7415 }
7416 
7417 
7418 static int
netlogon_dissect_dsrgetdcsitecoveragew_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7419 netlogon_dissect_dsrgetdcsitecoveragew_reply(tvbuff_t *tvb, int offset,
7420                                              packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7421 {
7422     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7423                                  netlogon_dissect_site_names, NDR_POINTER_UNIQUE,
7424                                  "Site names", -1);
7425 
7426     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7427                               hf_netlogon_rc, NULL);
7428 
7429     return offset;
7430 }
7431 
7432 static int
netlogon_dissect_netrlogonsamlogonex_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7433 netlogon_dissect_netrlogonsamlogonex_rqst(tvbuff_t *tvb, int offset,
7434                                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7435 {
7436 
7437     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7438                                           NDR_POINTER_UNIQUE, "LogonServer",
7439                                           hf_netlogon_computer_name, 0);
7440     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7441                                           NDR_POINTER_UNIQUE, "Computer Name",
7442                                           hf_netlogon_computer_name, 0);
7443     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
7444                                 hf_netlogon_level16, NULL);
7445     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7446                                  netlogon_dissect_LEVEL, NDR_POINTER_REF,
7447                                  "LEVEL: LogonLevel", -1);
7448 
7449     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
7450                                 hf_netlogon_validation_level, NULL);
7451 
7452     offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, di, drep);
7453 
7454 #if 0
7455     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7456                                           NDR_POINTER_UNIQUE, "unknown string",
7457                                           hf_netlogon_unknown_string, 0);
7458 
7459     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7460                                           NDR_POINTER_UNIQUE, "unknown string",
7461                                           hf_netlogon_unknown_string, 0);
7462 
7463     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
7464                                 hf_netlogon_unknown_short, NULL);
7465 
7466     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7467                                  netlogon_dissect_LEVEL, NDR_POINTER_UNIQUE,
7468                                  "LEVEL pointer: unknown_NETLOGON_LEVEL", -1);
7469 
7470     offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, di, drep,
7471                                 hf_netlogon_unknown_short, NULL);
7472 
7473     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7474                                  netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
7475                                  "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
7476 #endif
7477     return offset;
7478 }
7479 
7480 
7481 static int
netlogon_dissect_netrlogonsamlogonex_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7482 netlogon_dissect_netrlogonsamlogonex_reply(tvbuff_t *tvb, int offset,
7483                                            packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7484 {
7485     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7486                                  netlogon_dissect_VALIDATION, NDR_POINTER_REF,
7487                                  "VALIDATION:", -1);
7488 
7489     offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, di, drep,
7490                                hf_netlogon_authoritative, NULL);
7491 
7492     offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, di, drep);
7493 
7494     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7495                               hf_netlogon_rc, NULL);
7496 #if 0
7497     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7498                                  netlogon_dissect_VALIDATION, NDR_POINTER_UNIQUE,
7499                                  "VALIDATION: unknown_NETLOGON_VALIDATION", -1);
7500 
7501     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7502                                  netlogon_dissect_pointer_char, NDR_POINTER_UNIQUE,
7503                                  "BOOLEAN pointer: unknown_BOOLEAN", hf_netlogon_unknown_char);
7504 
7505     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7506                                  netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
7507                                  "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
7508 
7509     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7510                               hf_netlogon_rc, NULL);
7511 #endif
7512     return offset;
7513 }
7514 
7515 
7516 static int
netlogon_dissect_dsrenumeratedomaintrusts_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7517 netlogon_dissect_dsrenumeratedomaintrusts_rqst(tvbuff_t *tvb, int offset,
7518                                                packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7519 {
7520     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7521                                               pinfo, tree, di, drep);
7522 
7523     offset = netlogon_dissect_DOMAIN_TRUST_FLAGS(tvb, offset, pinfo, tree, di, drep);
7524 
7525     return offset;
7526 }
7527 
7528 
7529 static int
netlogon_dissect_dsrenumeratedomaintrusts_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7530 netlogon_dissect_dsrenumeratedomaintrusts_reply(tvbuff_t *tvb, int offset,
7531                                                 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7532 {
7533     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
7534                                 hf_netlogon_entries, NULL);
7535 
7536     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7537                                  netlogon_dissect_DS_DOMAIN_TRUSTS_ARRAY, NDR_POINTER_UNIQUE,
7538                                  "DS_DOMAIN_TRUSTS_ARRAY:", -1);
7539 
7540     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7541                               hf_netlogon_dos_rc, NULL);
7542 
7543     return offset;
7544 }
7545 
7546 static int
netlogon_dissect_dsrderegisterdnshostrecords_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7547 netlogon_dissect_dsrderegisterdnshostrecords_rqst(tvbuff_t *tvb, int offset,
7548                                                   packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7549 {
7550     offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
7551                                               pinfo, tree, di, drep);
7552 
7553     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7554                                           NDR_POINTER_UNIQUE, "Domain", hf_netlogon_logon_dom, 0);
7555 
7556     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7557                                  dissect_nt_GUID, NDR_POINTER_UNIQUE,
7558                                  "GUID pointer: domain_guid", -1);
7559 
7560     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
7561                                  dissect_nt_GUID, NDR_POINTER_UNIQUE,
7562                                  "GUID pointer: dsa_guid", -1);
7563 
7564     offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, di, drep,
7565                                           NDR_POINTER_REF, "dns_host", hf_netlogon_dns_host, 0);
7566 
7567     return offset;
7568 }
7569 
7570 
7571 static int
netlogon_dissect_dsrderegisterdnshostrecords_reply(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)7572 netlogon_dissect_dsrderegisterdnshostrecords_reply(tvbuff_t *tvb, int offset,
7573                                                    packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
7574 {
7575     offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
7576                               hf_netlogon_rc, NULL);
7577 
7578     return offset;
7579 }
7580 
7581 /* Dissect secure channel stuff */
7582 
7583 static int hf_netlogon_secchan_nl_message_type = -1;
7584 static int hf_netlogon_secchan_nl_message_flags = -1;
7585 static int hf_netlogon_secchan_nl_message_flags_nb_domain = -1;
7586 static int hf_netlogon_secchan_nl_message_flags_nb_host = -1;
7587 static int hf_netlogon_secchan_nl_message_flags_dns_domain = -1;
7588 static int hf_netlogon_secchan_nl_message_flags_dns_host = -1;
7589 static int hf_netlogon_secchan_nl_message_flags_nb_host_utf8 = -1;
7590 static int hf_netlogon_secchan_nl_nb_domain = -1;
7591 static int hf_netlogon_secchan_nl_nb_host = -1;
7592 static int hf_netlogon_secchan_nl_dns_domain = -1;
7593 static int hf_netlogon_secchan_nl_dns_host = -1;
7594 static int hf_netlogon_secchan_nl_nb_host_utf8 = -1;
7595 
7596 static gint ett_secchan_verf = -1;
7597 static gint ett_secchan_nl_auth_message = -1;
7598 static gint ett_secchan_nl_auth_message_flags = -1;
7599 
7600 static const value_string nl_auth_types[] = {
7601     { 0x00000000,         "Request"},
7602     { 0x00000001,         "Response"},
7603     { 0, NULL }
7604 };
7605 
7606 
7607 /* MS-NRPC : 2.2.1.3.1 NL_AUTH_MESSAGE */
dissect_secchan_nl_auth_message(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di _U_,guint8 * drep)7608 static int dissect_secchan_nl_auth_message(tvbuff_t *tvb, int offset,
7609                                            packet_info *pinfo,
7610                                            proto_tree *tree, dcerpc_info *di _U_, guint8 *drep)
7611 {
7612     proto_item *item = NULL;
7613     proto_tree *subtree = NULL;
7614     guint32 messagetype;
7615     guint64 messageflags;
7616     static int * const flag_fields[] = {
7617         &hf_netlogon_secchan_nl_message_flags_nb_domain,
7618         &hf_netlogon_secchan_nl_message_flags_nb_host,
7619         &hf_netlogon_secchan_nl_message_flags_dns_domain,
7620         &hf_netlogon_secchan_nl_message_flags_dns_host,
7621         &hf_netlogon_secchan_nl_message_flags_nb_host_utf8,
7622         NULL
7623     };
7624     int len;
7625 
7626     if (tree) {
7627         subtree = proto_tree_add_subtree(
7628             tree, tvb, offset, -1, ett_secchan_nl_auth_message, &item,
7629             "Secure Channel NL_AUTH_MESSAGE");
7630     }
7631 
7632     /* We can't use the NDR routines as the DCERPC call data hasn't
7633        been initialised since we haven't made a DCERPC call yet, just
7634        a bind request. */
7635 
7636     /* Type */
7637     offset = dissect_dcerpc_uint32(
7638         tvb, offset, pinfo, subtree, drep,
7639         hf_netlogon_secchan_nl_message_type, &messagetype);
7640 
7641     /* Flags */
7642     proto_tree_add_bitmask_ret_uint64(subtree, tvb, offset,
7643                                       hf_netlogon_secchan_nl_message_flags,
7644                                       ett_secchan_nl_auth_message_flags,
7645                                       flag_fields,
7646                                       (drep[0] & DREP_LITTLE_ENDIAN) ?
7647                                           ENC_LITTLE_ENDIAN :
7648                                           ENC_BIG_ENDIAN,
7649                                       &messageflags);
7650     offset += 4;
7651 
7652 
7653     /* Buffer */
7654     /* netbios domain name */
7655     if (messageflags&0x00000001) {
7656         len = tvb_strsize(tvb, offset);
7657         proto_tree_add_item(subtree, hf_netlogon_secchan_nl_nb_domain, tvb, offset, len, ENC_ASCII|ENC_NA);
7658         offset += len;
7659     }
7660 
7661     /* netbios host name */
7662     if (messageflags&0x00000002) {
7663         len = tvb_strsize(tvb, offset);
7664         proto_tree_add_item(subtree, hf_netlogon_secchan_nl_nb_host, tvb, offset, len, ENC_ASCII|ENC_NA);
7665         offset += len;
7666     }
7667 
7668     /* DNS domain name */
7669     if (messageflags&0x00000004) {
7670         int old_offset=offset;
7671         char str[256];
7672 
7673         offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
7674         proto_tree_add_string(subtree, hf_netlogon_secchan_nl_dns_domain, tvb, old_offset, offset-old_offset, str);
7675     }
7676 
7677     /* DNS host name */
7678     if (messageflags&0x00000008) {
7679         int old_offset=offset;
7680         char str[256];
7681 
7682         offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
7683         proto_tree_add_string(subtree, hf_netlogon_secchan_nl_dns_host, tvb, old_offset, offset-old_offset, str);
7684     }
7685 
7686     /* NetBios host name (UTF8) */
7687     if (messageflags&0x00000010) {
7688         int old_offset=offset;
7689         char str[256];
7690 
7691         offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
7692         proto_tree_add_string(subtree, hf_netlogon_secchan_nl_nb_host_utf8, tvb, old_offset, offset-old_offset, str);
7693     }
7694 
7695 
7696     return offset;
7697 }
7698 
7699 /* Subdissectors */
7700 
7701 static dcerpc_sub_dissector dcerpc_netlogon_dissectors[] = {
7702     { NETLOGON_NETRLOGONUASLOGON, "NetrLogonUasLogon",
7703       netlogon_dissect_netrlogonuaslogon_rqst,
7704       netlogon_dissect_netrlogonuaslogon_reply },
7705     { NETLOGON_NETRLOGONUASLOGOFF, "NetrLogonUasLogoff",
7706       netlogon_dissect_netrlogonuaslogoff_rqst,
7707       netlogon_dissect_netrlogonuaslogoff_reply },
7708     { NETLOGON_NETRLOGONSAMLOGON, "NetrLogonSamLogon",
7709       netlogon_dissect_netrlogonsamlogon_rqst,
7710       netlogon_dissect_netrlogonsamlogon_reply },
7711     { NETLOGON_NETRLOGONSAMLOGOFF, "NetrLogonSamLogoff",
7712       netlogon_dissect_netrlogonsamlogoff_rqst,
7713       netlogon_dissect_netrlogonsamlogoff_reply },
7714     { NETLOGON_NETRSERVERREQCHALLENGE, "NetrServerReqChallenge",
7715       netlogon_dissect_netrserverreqchallenge_rqst,
7716       netlogon_dissect_netrserverreqchallenge_reply },
7717     { NETLOGON_NETRSERVERAUTHENTICATE, "NetrServerAuthenticate",
7718       netlogon_dissect_netrserverauthenticate_rqst,
7719       netlogon_dissect_netrserverauthenticate_reply },
7720     { NETLOGON_NETRSERVERPASSWORDSET, "NetrServerPasswordSet",
7721       netlogon_dissect_netrserverpasswordset_rqst,
7722       netlogon_dissect_netrserverpasswordset_reply },
7723     { NETLOGON_NETRDATABASEDELTAS, "NetrDatabaseDeltas",
7724       netlogon_dissect_netrdatabasedeltas_rqst,
7725       netlogon_dissect_netrdatabasedeltas_reply },
7726     { NETLOGON_NETRDATABASESYNC, "NetrDatabaseSync",
7727       netlogon_dissect_netrdatabasesync_rqst,
7728       netlogon_dissect_netrdatabasesync_reply },
7729     { NETLOGON_NETRACCOUNTDELTAS, "NetrAccountDeltas",
7730       netlogon_dissect_netraccountdeltas_rqst,
7731       netlogon_dissect_netraccountdeltas_reply },
7732     { NETLOGON_NETRACCOUNTSYNC, "NetrAccountSync",
7733       netlogon_dissect_netraccountsync_rqst,
7734       netlogon_dissect_netraccountsync_reply },
7735     { NETLOGON_NETRGETDCNAME, "NetrGetDCName",
7736       netlogon_dissect_netrgetdcname_rqst,
7737       netlogon_dissect_netrgetdcname_reply },
7738     { NETLOGON_NETRLOGONCONTROL, "NetrLogonControl",
7739       netlogon_dissect_netrlogoncontrol_rqst,
7740       netlogon_dissect_netrlogoncontrol_reply },
7741     { NETLOGON_NETRGETANYDCNAME, "NetrGetAnyDCName",
7742       netlogon_dissect_netrgetanydcname_rqst,
7743       netlogon_dissect_netrgetanydcname_reply },
7744     { NETLOGON_NETRLOGONCONTROL2, "NetrLogonControl2",
7745       netlogon_dissect_netrlogoncontrol2_rqst,
7746       netlogon_dissect_netrlogoncontrol2_reply },
7747     { NETLOGON_NETRSERVERAUTHENTICATE2, "NetrServerAuthenticate2",
7748       netlogon_dissect_netrserverauthenticate2_rqst,
7749       netlogon_dissect_netrserverauthenticate2_reply },
7750     { NETLOGON_NETRDATABASESYNC2, "NetrDatabaseSync2",
7751       netlogon_dissect_netrdatabasesync2_rqst,
7752       netlogon_dissect_netrdatabasesync2_reply },
7753     { NETLOGON_NETRDATABASEREDO, "NetrDatabaseRedo",
7754       netlogon_dissect_netrdatabaseredo_rqst,
7755       netlogon_dissect_netrdatabaseredo_reply },
7756     { NETLOGON_NETRLOGONCONTROL2EX, "NetrLogonControl2Ex",
7757       netlogon_dissect_netrlogoncontrol2ex_rqst,
7758       netlogon_dissect_netrlogoncontrol2ex_reply },
7759     { NETLOGON_NETRENUMERATETRUSTEDDOMAINS, "NetrEnumerateTrustedDomains",
7760       netlogon_dissect_netrenumeratetrusteddomains_rqst,
7761       netlogon_dissect_netrenumeratetrusteddomains_reply },
7762     { NETLOGON_DSRGETDCNAME, "DsrGetDcName",
7763       netlogon_dissect_dsrgetdcname_rqst,
7764       netlogon_dissect_dsrgetdcname_reply },
7765     { NETLOGON_NETRLOGONDUMMYROUTINE1, "NetrLogonDummyRoutine1",
7766       netlogon_dissect_netrlogondummyroutine1_rqst,
7767       netlogon_dissect_netrlogondummyroutine1_reply },
7768     { NETLOGON_NETRLOGONSETSERVICEBITS, "NetrLogonSetServiceBits",
7769       netlogon_dissect_netrlogonsetservicebits_rqst,
7770       netlogon_dissect_netrlogonsetservicebits_reply },
7771     { NETLOGON_NETRLOGONGETTRUSTRID, "NetrLogonGetTrustRid",
7772       netlogon_dissect_netrlogongettrustrid_rqst,
7773       netlogon_dissect_netrlogongettrustrid_reply },
7774     { NETLOGON_NETRLOGONCOMPUTESERVERDIGEST, "NetrLogonComputeServerDigest",
7775       netlogon_dissect_netrlogoncomputeserverdigest_rqst,
7776       netlogon_dissect_netrlogoncomputeserverdigest_reply },
7777     { NETLOGON_NETRLOGONCOMPUTECLIENTDIGEST, "NetrLogonComputeClientDigest",
7778       netlogon_dissect_netrlogoncomputeclientdigest_rqst,
7779       netlogon_dissect_netrlogoncomputeclientdigest_reply },
7780     { NETLOGON_NETRSERVERAUTHENTICATE3, "NetrServerAuthenticate3",
7781       netlogon_dissect_netrserverauthenticate3_rqst,
7782       netlogon_dissect_netrserverauthenticate3_reply },
7783     { NETLOGON_DSRGETDCNAMEX, "DsrGetDcNameEx",
7784       netlogon_dissect_dsrgetdcnameex_rqst,
7785       netlogon_dissect_dsrgetdcnameex_reply },
7786     { NETLOGON_DSRGETSITENAME, "DsrGetSiteName",
7787       netlogon_dissect_dsrgetsitename_rqst,
7788       netlogon_dissect_dsrgetsitename_reply },
7789     { NETLOGON_NETRLOGONGETDOMAININFO, "NetrLogonGetDomainInfo",
7790       netlogon_dissect_netrlogongetdomaininfo_rqst,
7791       netlogon_dissect_netrlogongetdomaininfo_reply },
7792     { NETLOGON_NETRSERVERPASSWORDSET2, "NetrServerPasswordSet2",
7793       netlogon_dissect_netrserverpasswordset2_rqst,
7794       netlogon_dissect_netrserverpasswordset2_reply },
7795     { NETLOGON_NETRSERVERPASSWORDGET, "NetrServerPasswordGet",
7796       netlogon_dissect_netrserverpasswordget_rqst,
7797       netlogon_dissect_netrserverpasswordget_reply },
7798     { NETLOGON_NETRLOGONSENDTOSAM, "NetrLogonSendToSam",
7799       netlogon_dissect_netrlogonsendtosam_rqst,
7800       netlogon_dissect_netrlogonsendtosam_reply },
7801     { NETLOGON_DSRADDRESSTOSITENAMESW, "DsrAddressToSiteNamesW",
7802       netlogon_dissect_dsraddresstositenamesw_rqst,
7803       netlogon_dissect_dsraddresstositenamesw_reply },
7804     { NETLOGON_DSRGETDCNAMEEX2, "DsrGetDcNameEx2",
7805       netlogon_dissect_dsrgetdcnameex2_rqst,
7806       netlogon_dissect_dsrgetdcnameex2_reply },
7807     { NETLOGON_NETRLOGONGETTIMESERVICEPARENTDOMAIN,
7808       "NetrLogonGetTimeServiceParentDomain",
7809       netlogon_dissect_netrlogongettimeserviceparentdomain_rqst,
7810       netlogon_dissect_netrlogongettimeserviceparentdomain_reply },
7811     { NETLOGON_NETRENUMERATETRUSTEDDOMAINSEX, "NetrEnumerateTrustedDomainsEx",
7812       netlogon_dissect_netrenumeratetrusteddomainsex_rqst,
7813       netlogon_dissect_netrenumeratetrusteddomainsex_reply },
7814     { NETLOGON_DSRADDRESSTOSITENAMESEXW, "DsrAddressToSiteNamesExW",
7815       netlogon_dissect_dsraddresstositenamesexw_rqst,
7816       netlogon_dissect_dsraddresstositenamesexw_reply },
7817     { NETLOGON_DSRGETDCSITECOVERAGEW, "DsrGetDcSiteCoverageW",
7818       netlogon_dissect_dsrgetdcsitecoveragew_rqst,
7819       netlogon_dissect_dsrgetdcsitecoveragew_reply },
7820     { NETLOGON_NETRLOGONSAMLOGONEX, "NetrLogonSamLogonEx",
7821       netlogon_dissect_netrlogonsamlogonex_rqst,
7822       netlogon_dissect_netrlogonsamlogonex_reply },
7823     { NETLOGON_DSRENUMERATEDOMAINTRUSTS, "DsrEnumerateDomainTrusts",
7824       netlogon_dissect_dsrenumeratedomaintrusts_rqst,
7825       netlogon_dissect_dsrenumeratedomaintrusts_reply },
7826     { NETLOGON_DSRDEREGISTERDNSHOSTRECORDS, "DsrDeregisterDnsHostRecords",
7827       netlogon_dissect_dsrderegisterdnshostrecords_rqst,
7828       netlogon_dissect_dsrderegisterdnshostrecords_reply },
7829     { NETLOGON_NETRSERVERTRUSTPASSWORDSGET, "NetrServerTrustPasswordsGet",
7830       NULL, NULL },
7831     { NETLOGON_DSRGETFORESTTRUSTINFORMATION, "DsrGetForestTrustInformation",
7832       NULL, NULL },
7833     { NETLOGON_NETRGETFORESTTRUSTINFORMATION, "NetrGetForestTrustInformation",
7834       NULL, NULL },
7835     { NETLOGON_NETRLOGONSAMLOGONWITHFLAGS, "NetrLogonSamLogonWithFlags",
7836       netlogon_dissect_netrlogonsamlogonflags_rqst,
7837       netlogon_dissect_netrlogonsamlogonflags_reply },
7838     { NETLOGON_NETRSERVERGETTRUSTINFO, "NetrServerGetTrustInfo",
7839       NULL, NULL },
7840     {0, NULL, NULL,  NULL }
7841 };
7842 
7843 static int hf_netlogon_secchan_verf = -1;
7844 static int hf_netlogon_secchan_verf_signalg = -1;
7845 static int hf_netlogon_secchan_verf_sealalg = -1;
7846 static int hf_netlogon_secchan_verf_flag = -1;
7847 static int hf_netlogon_secchan_verf_digest = -1;
7848 static int hf_netlogon_secchan_verf_seq = -1;
7849 static int hf_netlogon_secchan_verf_nonce = -1;
7850 
7851 static const value_string sign_algs[] = {
7852     { 0x0077, "HMAC-MD5"},
7853     { 0, NULL}
7854 };
7855 
7856 static const value_string seal_algs[] = {
7857     { 0xFFFF, "Not Encrypted"},
7858     { 0x007A, "RC4"},
7859     { 0, NULL}
7860 };
7861 
get_seal_key(const guint8 * session_key,int key_len,guint8 * seal_key)7862 static int get_seal_key(const guint8 *session_key,int key_len,guint8* seal_key)
7863 {
7864     guint8 zero_sk[16] = { 0 };
7865     int i = 0;
7866 
7867     memset(seal_key,0,16);
7868     if(memcmp(session_key,zero_sk,16)) {
7869         for(i=0;i<key_len;i++) {
7870             seal_key[i] = session_key[i] ^ 0xF0;
7871         }
7872         return 1;
7873     } else {
7874         return 0;
7875     }
7876 
7877 }
7878 
7879 #if GCRYPT_VERSION_NUMBER >= 0x010800 /* 1.8.0 */
uncrypt_sequence_aes(guint8 * session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)7880 static guint64 uncrypt_sequence_aes(guint8* session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)
7881 {
7882     gcry_error_t err;
7883     gcry_cipher_hd_t cipher_hd = NULL;
7884     guint8 iv[16] = { 0 };
7885 
7886     memcpy(&iv[0], (guint8*)&checksum, 8);
7887     memcpy(&iv[8], (guint8*)&checksum, 8);
7888 
7889     /* Open the cipher */
7890     err = gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB8, 0);
7891     if (err != 0) {
7892         ws_warning("GCRY: cipher open %s/%s\n", gcry_strsource(err), gcry_strerror(err));
7893         return 0;
7894     }
7895 
7896     /* Set the initial value */
7897     err = gcry_cipher_setiv(cipher_hd, iv, sizeof(iv));
7898     if (err != 0) {
7899         ws_warning("GCRY: setiv %s/%s\n", gcry_strsource(err), gcry_strerror(err));
7900         gcry_cipher_close(cipher_hd);
7901         return 0;
7902     }
7903 
7904     /* Set the key */
7905     err = gcry_cipher_setkey(cipher_hd, session_key, 16);
7906     if (err != 0) {
7907         ws_warning("GCRY: setkey %s/%s\n", gcry_strsource(err), gcry_strerror(err));
7908         gcry_cipher_close(cipher_hd);
7909         return 0;
7910     }
7911 
7912     err = gcry_cipher_decrypt(cipher_hd, (guint8*) &enc_seq, 8, NULL, 0);
7913     if (err != 0) {
7914         ws_warning("GCRY: encrypt %s/%s\n", gcry_strsource(err), gcry_strerror(err));
7915         gcry_cipher_close(cipher_hd);
7916         return 0;
7917     }
7918     /* Done with the cipher */
7919     gcry_cipher_close(cipher_hd);
7920     return enc_seq;
7921 }
7922 #endif
7923 
uncrypt_sequence_strong(guint8 * session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)7924 static guint64 uncrypt_sequence_strong(guint8* session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)
7925 {
7926     guint8 zeros[4] = { 0 };
7927     guint8 buf[HASH_MD5_LENGTH];
7928     guint8 key[HASH_MD5_LENGTH];
7929     gcry_cipher_hd_t rc4_handle;
7930     guint8 *p_seq = (guint8*) &enc_seq;
7931     /*guint32 temp;*/
7932 
7933     if (ws_hmac_buffer(GCRY_MD_MD5, buf, zeros, 4, session_key, 16)) {
7934         return 0;
7935     }
7936 
7937     if (ws_hmac_buffer(GCRY_MD_MD5, key, (guint8*)&checksum, 8, buf, HASH_MD5_LENGTH)) {
7938         return 0;
7939     }
7940 
7941     if (!gcry_cipher_open (&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) {
7942       if (!gcry_cipher_setkey(rc4_handle, key, HASH_MD5_LENGTH)) {
7943         gcry_cipher_decrypt(rc4_handle, p_seq, 8, NULL, 0);
7944       }
7945       gcry_cipher_close(rc4_handle);
7946     }
7947     /*temp = *((guint32*)p_seq);
7948      *((guint32*)p_seq) = *((guint32*)p_seq+1);
7949      *((guint32*)p_seq+1) = temp;
7950 
7951      if(!is_server) {
7952      *p_seq = *p_seq & 0x7F;
7953      }
7954     */
7955     return enc_seq;
7956 }
7957 
uncrypt_sequence(guint32 flags,guint8 * session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)7958 static guint64 uncrypt_sequence(guint32 flags, guint8* session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)
7959 {
7960 #if GCRYPT_VERSION_NUMBER >= 0x010800 /* 1.8.0 */
7961     if (flags & NETLOGON_FLAG_AES) {
7962         return uncrypt_sequence_aes(session_key, checksum, enc_seq, is_server);
7963     }
7964 #endif
7965 
7966     if (flags & NETLOGON_FLAG_STRONGKEY) {
7967         return uncrypt_sequence_strong(session_key, checksum, enc_seq, is_server);
7968     }
7969 
7970     return 0;
7971 }
7972 
7973 #if GCRYPT_VERSION_NUMBER >= 0x010800 /* 1.8.0 */
prepare_decryption_cipher_aes(netlogon_auth_vars * vars,gcry_cipher_hd_t * _cipher_hd)7974 static gcry_error_t prepare_decryption_cipher_aes(netlogon_auth_vars *vars,
7975                                                   gcry_cipher_hd_t *_cipher_hd)
7976 {
7977     gcry_error_t err;
7978     gcry_cipher_hd_t cipher_hd = NULL;
7979     guint64 sequence = vars->seq;
7980 
7981     guint8 iv[16] = { 0 };
7982 
7983     memcpy(&iv[0], (guint8*)&sequence, 8);
7984     memcpy(&iv[8], (guint8*)&sequence, 8);
7985 
7986     /* Open the cipher */
7987     err = gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB8, 0);
7988     if (err != 0) {
7989         ws_warning("GCRY: cipher open %s/%s\n", gcry_strsource(err), gcry_strerror(err));
7990         return 0;
7991     }
7992 
7993     /* Set the initial value */
7994     err = gcry_cipher_setiv(cipher_hd, iv, sizeof(iv));
7995     if (err != 0) {
7996         ws_warning("GCRY: setiv %s/%s\n", gcry_strsource(err), gcry_strerror(err));
7997         gcry_cipher_close(cipher_hd);
7998         return 0;
7999     }
8000 
8001     /* Set the key */
8002     err = gcry_cipher_setkey(cipher_hd, vars->encryption_key, 16);
8003     if (err != 0) {
8004         ws_warning("GCRY: setkey %s/%s\n", gcry_strsource(err), gcry_strerror(err));
8005         gcry_cipher_close(cipher_hd);
8006         return 0;
8007     }
8008 
8009     *_cipher_hd = cipher_hd;
8010     return 0;
8011 }
8012 #endif
8013 
prepare_decryption_cipher_strong(netlogon_auth_vars * vars,gcry_cipher_hd_t * _cipher_hd)8014 static gcry_error_t prepare_decryption_cipher_strong(netlogon_auth_vars *vars,
8015                                                      gcry_cipher_hd_t *_cipher_hd)
8016 {
8017     gcry_error_t err;
8018     gcry_cipher_hd_t cipher_hd = NULL;
8019     guint8 zeros[4] = { 0 };
8020     guint64 sequence = vars->seq;
8021     guint8 tmp[HASH_MD5_LENGTH] = { 0 };
8022     guint8 seal_key[16] = { 0 };
8023 
8024     err = ws_hmac_buffer(GCRY_MD_MD5, tmp, zeros, 4, vars->encryption_key, 16);
8025     if (err != 0) {
8026         ws_warning("GCRY: GCRY_MD_MD5 %s/%s\n", gcry_strsource(err), gcry_strerror(err));
8027         return err;
8028     }
8029     err = ws_hmac_buffer(GCRY_MD_MD5, seal_key, (guint8*)&sequence, 8, tmp, HASH_MD5_LENGTH);
8030     if (err != 0) {
8031         ws_warning("GCRY: GCRY_MD_MD5 %s/%s\n", gcry_strsource(err), gcry_strerror(err));
8032         return err;
8033     }
8034 
8035     /* Open the cipher */
8036     err = gcry_cipher_open(&cipher_hd, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
8037     if (err != 0) {
8038         ws_warning("GCRY: cipher open %s/%s\n", gcry_strsource(err), gcry_strerror(err));
8039         return err;
8040     }
8041 
8042     /* Set the key */
8043     err = gcry_cipher_setkey(cipher_hd, seal_key, 16);
8044     if (err != 0) {
8045         ws_warning("GCRY: setkey %s/%s\n", gcry_strsource(err), gcry_strerror(err));
8046         gcry_cipher_close(cipher_hd);
8047         return err;
8048     }
8049 
8050     *_cipher_hd = cipher_hd;
8051     return 0;
8052 }
8053 
prepare_decryption_cipher(netlogon_auth_vars * vars,gcry_cipher_hd_t * _cipher_hd)8054 static gcry_error_t prepare_decryption_cipher(netlogon_auth_vars *vars,
8055                                               gcry_cipher_hd_t *_cipher_hd)
8056 {
8057     *_cipher_hd = NULL;
8058 
8059 #if GCRYPT_VERSION_NUMBER >= 0x010800 /* 1.8.0 */
8060     if (vars->flags & NETLOGON_FLAG_AES) {
8061         return prepare_decryption_cipher_aes(vars, _cipher_hd);
8062     }
8063 #endif
8064 
8065     if (vars->flags & NETLOGON_FLAG_STRONGKEY) {
8066         return prepare_decryption_cipher_strong(vars, _cipher_hd);
8067     }
8068 
8069     return GPG_ERR_UNSUPPORTED_ALGORITHM;
8070 }
8071 
8072 static tvbuff_t *
dissect_packet_data(tvbuff_t * tvb,tvbuff_t * auth_tvb _U_,int offset,packet_info * pinfo,dcerpc_auth_info * auth_info _U_,unsigned char is_server)8073 dissect_packet_data(tvbuff_t *tvb ,tvbuff_t *auth_tvb _U_,
8074                     int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info _U_,unsigned char is_server)
8075 {
8076 
8077     tvbuff_t  *buf = NULL;
8078     guint8* decrypted;
8079     netlogon_auth_vars *vars;
8080     netlogon_auth_key key;
8081     /*debugprintf("Dissection of request data offset %d len=%d on packet %d\n",offset,tvb_length_remaining(tvb,offset),pinfo->num);*/
8082 
8083     generate_hash_key(pinfo,is_server,&key);
8084     vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths, &key);
8085 
8086     if(vars != NULL  ) {
8087         while(vars != NULL && vars->next_start != -1 && vars->next_start < (int) pinfo->num ) {
8088             vars = vars->next;
8089         }
8090         if(vars == NULL ) {
8091             debugprintf("Vars not found %d (packet_data)\n",wmem_map_size(netlogon_auths));
8092             return(buf);
8093         }
8094         else {
8095             if(vars->can_decrypt == TRUE) {
8096                 gcry_error_t err;
8097                 gcry_cipher_hd_t cipher_hd = NULL;
8098                 int data_len;
8099                 guint64 copyconfounder = vars->confounder;
8100 
8101                 data_len = tvb_captured_length_remaining(tvb,offset);
8102                 if (data_len < 0) {
8103                     return NULL;
8104                 }
8105                 err = prepare_decryption_cipher(vars, &cipher_hd);
8106                 if (err != 0) {
8107                     ws_warning("GCRY: prepare_decryption_cipher %s/%s\n",
8108                               gcry_strsource(err), gcry_strerror(err));
8109                     return NULL;
8110                 }
8111                 gcry_cipher_decrypt(cipher_hd, (guint8*)&copyconfounder, 8, NULL, 0);
8112                 decrypted = (guint8*)tvb_memdup(pinfo->pool, tvb, offset,data_len);
8113                 if (!(vars->flags & NETLOGON_FLAG_AES)) {
8114                     gcry_cipher_reset(cipher_hd);
8115                 }
8116                 gcry_cipher_decrypt(cipher_hd, decrypted, data_len, NULL, 0);
8117                 gcry_cipher_close(cipher_hd);
8118                 buf = tvb_new_child_real_data(tvb, decrypted, data_len, data_len);
8119                 /* Note: caller does add_new_data_source(...) */
8120             }
8121             else {
8122                 debugprintf("Session key not found can't decrypt ...\n");
8123             }
8124         }
8125     } else {
8126         debugprintf("Vars not found  %d (packet_data)\n",wmem_map_size(netlogon_auths));
8127         return(buf);
8128     }
8129 
8130     return(buf);
8131 }
8132 
dissect_request_data(tvbuff_t * header_tvb _U_,tvbuff_t * payload_tvb,tvbuff_t * trailer_tvb _U_,tvbuff_t * auth_tvb,packet_info * pinfo,dcerpc_auth_info * auth_info)8133 static tvbuff_t* dissect_request_data(tvbuff_t *header_tvb _U_,
8134                                       tvbuff_t *payload_tvb,
8135                                       tvbuff_t *trailer_tvb _U_,
8136                                       tvbuff_t *auth_tvb,
8137                                       packet_info *pinfo,
8138                                       dcerpc_auth_info *auth_info)
8139 {
8140     return dissect_packet_data(payload_tvb,auth_tvb,0,pinfo,auth_info,0);
8141 }
8142 
dissect_response_data(tvbuff_t * header_tvb _U_,tvbuff_t * payload_tvb,tvbuff_t * trailer_tvb _U_,tvbuff_t * auth_tvb,packet_info * pinfo,dcerpc_auth_info * auth_info)8143 static tvbuff_t* dissect_response_data(tvbuff_t *header_tvb _U_,
8144                                        tvbuff_t *payload_tvb,
8145                                        tvbuff_t *trailer_tvb _U_,
8146                                        tvbuff_t *auth_tvb,
8147                                        packet_info *pinfo,
8148                                        dcerpc_auth_info *auth_info)
8149 {
8150     return dissect_packet_data(payload_tvb,auth_tvb,0,pinfo,auth_info,1);
8151 }
8152 
8153 /* MS-NRPC 2.2.1.3.2 */
8154 static int
dissect_secchan_verf(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 * drep,unsigned char is_server)8155 dissect_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
8156                      proto_tree *tree, guint8 *drep, unsigned char is_server)
8157 {
8158     netlogon_auth_vars *vars;
8159     netlogon_auth_key key;
8160     proto_item *vf = NULL;
8161     proto_tree *subtree = NULL;
8162     guint64 encrypted_seq;
8163     guint64 digest = 0;
8164     guint64 confounder = 0;
8165     int update_vars = 0;
8166 
8167     generate_hash_key(pinfo,is_server,&key);
8168     vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths,(gconstpointer*) &key);
8169     if(  ! (seen.isseen && seen.num == pinfo->num) ) {
8170         /*
8171          * Create a new tree, and split into x components ...
8172          */
8173         vf = proto_tree_add_item(tree, hf_netlogon_secchan_verf, tvb,
8174                                  offset, -1, ENC_NA);
8175         subtree = proto_item_add_subtree(vf, ett_secchan_verf);
8176 
8177         proto_tree_add_item(subtree, hf_netlogon_secchan_verf_signalg, tvb,
8178                             offset, 2, ENC_LITTLE_ENDIAN);
8179         proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sealalg, tvb,
8180                             offset+2, 2, ENC_LITTLE_ENDIAN);
8181         /* 2 pad bytes */
8182         proto_tree_add_item(subtree, hf_netlogon_secchan_verf_flag, tvb,
8183                             offset+6, 2, ENC_NA);
8184         offset += 8;
8185 
8186         offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, subtree, drep,
8187                                        hf_netlogon_secchan_verf_seq, &encrypted_seq);
8188 
8189         offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, subtree, drep,
8190                                        hf_netlogon_secchan_verf_digest, &digest);
8191 
8192         /* In some cases the nonce if the data/signture are encrypted ("integrity/seal  in MS language")*/
8193 
8194         if (tvb_bytes_exist(tvb, offset, 8)) {
8195             offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, subtree, drep,
8196                                            hf_netlogon_secchan_verf_nonce, &confounder);
8197         }
8198         update_vars = 1;
8199     }
8200     if( vars != NULL ) {
8201         while(vars != NULL && vars->next_start != -1 && vars->next_start <  (int)pinfo->num ) {
8202             vars = vars->next;
8203         }
8204         if(vars == NULL ) {
8205             debugprintf("Vars not found %d (packet_data)\n",wmem_map_size(netlogon_auths));
8206             return(offset);
8207         }
8208         else {
8209             if(update_vars) {
8210                 vars->confounder = confounder;
8211                 vars->seq = uncrypt_sequence(vars->flags,vars->session_key,digest,encrypted_seq,is_server);
8212             }
8213 
8214             if(get_seal_key(vars->session_key,16,vars->encryption_key))
8215             {
8216                 vars->can_decrypt = TRUE;
8217             }
8218             else
8219             {
8220                 debugprintf("get seal key returned 0\n");
8221             }
8222 
8223             if (vars->can_decrypt) {
8224                 expert_add_info_format(pinfo, proto_tree_get_parent(subtree),
8225                          &ei_netlogon_session_key,
8226                          "Using session key learned in frame %d ("
8227                          "%02x%02x%02x%02x"
8228                          ") from %s",
8229                          vars->auth_fd_num,
8230                          vars->session_key[0] & 0xFF,  vars->session_key[1] & 0xFF,
8231                          vars->session_key[2] & 0xFF,  vars->session_key[3] & 0xFF,
8232                          vars->nthash.key_origin);
8233             }
8234         }
8235     }
8236     else
8237     {
8238         debugprintf("Vars not found (is null %d) %d (dissect_verf)\n",vars==NULL,wmem_map_size(netlogon_auths));
8239     }
8240     /*debugprintf("Setting isseen to true, old packet %d new %d\n",seen.num,pinfo->num);*/
8241     seen.isseen = TRUE;
8242     seen.num = pinfo->num;
8243 
8244     return offset;
8245 }
8246 static int
dissect_request_secchan_verf(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di _U_,guint8 * drep)8247 dissect_request_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo ,
8248                              proto_tree *tree, dcerpc_info *di _U_, guint8 *drep )
8249 {
8250     return dissect_secchan_verf(tvb,offset,pinfo,tree,drep,0);
8251 }
8252 static int
dissect_response_secchan_verf(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di _U_,guint8 * drep)8253 dissect_response_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo ,
8254                               proto_tree *tree, dcerpc_info *di _U_, guint8 *drep )
8255 {
8256     return dissect_secchan_verf(tvb,offset,pinfo,tree,drep,1);
8257 }
8258 
8259 /* Secure channel types */
8260 
8261 static const value_string sec_chan_type_vals[] = {
8262     { SEC_CHAN_WKSTA,  "Workstation" },
8263     { SEC_CHAN_DOMAIN, "Domain trust" },
8264     { SEC_CHAN_BDC,    "Backup domain controller" },
8265     { 0, NULL }
8266 };
8267 
8268 void
proto_register_dcerpc_netlogon(void)8269 proto_register_dcerpc_netlogon(void)
8270 {
8271 
8272     static hf_register_info hf[] = {
8273         { &hf_netlogon_opnum,
8274           { "Operation", "netlogon.opnum", FT_UINT16, BASE_DEC,
8275             NULL, 0x0, NULL, HFILL }},
8276 
8277         { &hf_netlogon_rc, {
8278                 "Return code", "netlogon.rc", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
8279                 &NT_errors_ext, 0x0, "Netlogon return code", HFILL }},
8280 
8281         { &hf_netlogon_dos_rc,
8282           { "DOS error code", "netlogon.dos.rc", FT_UINT32,
8283             BASE_HEX | BASE_EXT_STRING, &DOS_errors_ext, 0x0, NULL, HFILL}},
8284 
8285         { &hf_netlogon_werr_rc,
8286           { "WERR error code", "netlogon.werr.rc", FT_UINT32,
8287             BASE_HEX | BASE_EXT_STRING, &WERR_errors_ext, 0x0, NULL, HFILL}},
8288 
8289         { &hf_netlogon_param_ctrl, {
8290                 "Param Ctrl", "netlogon.param_ctrl", FT_UINT32, BASE_HEX,
8291                 NULL, 0x0, NULL, HFILL }},
8292 
8293         { &hf_netlogon_logon_id, {
8294                 "Logon ID", "netlogon.logon_id", FT_UINT64, BASE_DEC,
8295                 NULL, 0x0, NULL, HFILL }},
8296 
8297         { &hf_netlogon_modify_count, {
8298                 "Modify Count", "netlogon.modify_count", FT_UINT64, BASE_DEC,
8299                 NULL, 0x0, "How many times the object has been modified", HFILL }},
8300 
8301         { &hf_netlogon_security_information, {
8302                 "Security Information", "netlogon.security_information", FT_UINT32, BASE_DEC,
8303                 NULL, 0x0, NULL, HFILL }},
8304 
8305         { &hf_netlogon_count, {
8306                 "Count", "netlogon.count", FT_UINT32, BASE_DEC,
8307                 NULL, 0x0, NULL, HFILL }},
8308 
8309         { &hf_netlogon_entries, {
8310                 "Entries", "netlogon.entries", FT_UINT32, BASE_DEC,
8311                 NULL, 0x0, NULL, HFILL }},
8312 
8313         { &hf_netlogon_credential, {
8314                 "Credential", "netlogon.credential", FT_BYTES, BASE_NONE,
8315                 NULL, 0x0, "Netlogon Credential", HFILL }},
8316 
8317         { &hf_netlogon_challenge, {
8318                 "Challenge", "netlogon.challenge", FT_BYTES, BASE_NONE,
8319                 NULL, 0x0, "Netlogon challenge", HFILL }},
8320 
8321         { &hf_netlogon_lm_owf_password, {
8322                 "LM Pwd", "netlogon.lm_owf_pwd", FT_BYTES, BASE_NONE,
8323                 NULL, 0x0, "LanManager OWF Password", HFILL }},
8324 
8325         { &hf_netlogon_user_session_key, {
8326                 "User Session Key", "netlogon.user_session_key", FT_BYTES, BASE_NONE,
8327                 NULL, 0x0, NULL, HFILL }},
8328 
8329         { &hf_netlogon_encrypted_lm_owf_password, {
8330                 "Encrypted LM Pwd", "netlogon.lm_owf_pwd.encrypted", FT_BYTES, BASE_NONE,
8331                 NULL, 0x0, "Encrypted LanManager OWF Password", HFILL }},
8332 
8333         { &hf_netlogon_nt_owf_password, {
8334                 "NT Pwd", "netlogon.nt_owf_pwd", FT_BYTES, BASE_NONE,
8335                 NULL, 0x0, "NT OWF Password", HFILL }},
8336 
8337         { &hf_netlogon_blob, {
8338                 "BLOB", "netlogon.blob", FT_BYTES, BASE_NONE,
8339                 NULL, 0x0, NULL, HFILL }},
8340 
8341         { &hf_netlogon_len, {
8342                 "Len", "netlogon.len", FT_UINT32, BASE_DEC,
8343                 NULL, 0, "Length", HFILL }},
8344 
8345         { &hf_netlogon_priv, {
8346                 "Priv", "netlogon.priv", FT_UINT32, BASE_DEC,
8347                 NULL, 0, NULL, HFILL }},
8348 
8349         { &hf_netlogon_privilege_entries, {
8350                 "Privilege Entries", "netlogon.privilege_entries", FT_UINT32, BASE_DEC,
8351                 NULL, 0, NULL, HFILL }},
8352 
8353         { &hf_netlogon_privilege_control, {
8354                 "Privilege Control", "netlogon.privilege_control", FT_UINT32, BASE_HEX,
8355                 NULL, 0, NULL, HFILL }},
8356 
8357         { &hf_netlogon_privilege_name, {
8358                 "Privilege Name", "netlogon.privilege_name", FT_STRING, BASE_NONE,
8359                 NULL, 0, NULL, HFILL }},
8360 
8361         { &hf_netlogon_pdc_connection_status, {
8362                 "PDC Connection Status", "netlogon.pdc_connection_status", FT_UINT32, BASE_DEC,
8363                 NULL, 0, NULL, HFILL }},
8364 
8365         { &hf_netlogon_tc_connection_status, {
8366                 "TC Connection Status", "netlogon.tc_connection_status", FT_UINT32, BASE_DEC,
8367                 NULL, 0, NULL, HFILL }},
8368 
8369         { &hf_netlogon_attrs, {
8370                 "Attributes", "netlogon.attrs", FT_UINT32, BASE_HEX,
8371                 NULL, 0, NULL, HFILL }},
8372 
8373 #if 0
8374         { &hf_netlogon_lsapolicy_referentid,
8375           { "Referent ID", "netlogon.lsapolicy.referentID", FT_UINT32, BASE_HEX,
8376             NULL, 0x0, NULL, HFILL }},
8377 #endif
8378 
8379         { &hf_netlogon_lsapolicy_len,
8380           { "Length", "netlogon.lsapolicy.length", FT_UINT32, BASE_DEC,
8381             NULL, 0x0, "Length of the policy buffer", HFILL }},
8382 
8383 #if 0
8384         { &hf_netlogon_lsapolicy_pointer,
8385           { "Pointer", "netlogon.lsapolicy.pointer", FT_BYTES, BASE_NONE,
8386             NULL, 0x0, "Pointer to LSA POLICY", HFILL }},
8387 #endif
8388 
8389         { &hf_netlogon_unknown_string,
8390           { "Unknown string", "netlogon.unknown_string", FT_STRING, BASE_NONE,
8391             NULL, 0, "Unknown string. If you know what this is, contact wireshark developers.", HFILL }},
8392 
8393         { &hf_netlogon_TrustedDomainName_string,
8394           { "TrustedDomainName", "netlogon.TrustedDomainName", FT_STRING, BASE_NONE,
8395             NULL, 0, "TrustedDomainName string.", HFILL }},
8396 
8397         { &hf_netlogon_UserName_string,
8398           { "UserName", "netlogon.UserName", FT_STRING, BASE_NONE,
8399             NULL, 0, "UserName string.", HFILL }},
8400 
8401         { &hf_netlogon_dummy_string,
8402           { "Dummy String", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8403             NULL, 0, "Dummy String. Used is reserved for next evolutions.", HFILL }},
8404 
8405         { &hf_netlogon_trust_extension,
8406           { "Trust extension", "netlogon.trust.extension", FT_STRING, BASE_NONE,
8407             NULL, 0, "Trusts extension.", HFILL }},
8408 
8409         { &hf_netlogon_trust_offset,
8410           { "Offset", "netlogon.trust.extension_offset", FT_UINT32, BASE_DEC,
8411             NULL, 0, "Trusts extension.", HFILL }},
8412 
8413         { &hf_netlogon_trust_len,
8414           { "Length", "netlogon.trust.extension_length", FT_UINT32, BASE_DEC,
8415             NULL, 0, NULL, HFILL }},
8416 
8417         { &hf_netlogon_trust_max,
8418           { "Max Count", "netlogon.trust.extension.maxcount", FT_UINT32, BASE_DEC,
8419             NULL, 0, NULL, HFILL }},
8420 
8421         { &hf_netlogon_dummy_string2,
8422           { "Dummy String2", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8423             NULL, 0, "Dummy String 2. Used is reserved for next evolutions.", HFILL }},
8424 
8425         { &hf_netlogon_dummy_string3,
8426           { "Dummy String3", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8427             NULL, 0, "Dummy String 3. Used is reserved for next evolutions.", HFILL }},
8428 
8429         { &hf_netlogon_dummy_string4,
8430           { "Dummy String4", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8431             NULL, 0, "Dummy String 4. Used is reserved for next evolutions.", HFILL }},
8432 
8433         { &hf_netlogon_dummy_string5,
8434           { "Dummy String5", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8435             NULL, 0, "Dummy String 5. Used is reserved for next evolutions.", HFILL }},
8436 
8437         { &hf_netlogon_dummy_string6,
8438           { "Dummy String6", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8439             NULL, 0, "Dummy String 6. Used is reserved for next evolutions.", HFILL }},
8440 
8441         { &hf_netlogon_dummy_string7,
8442           { "Dummy String7", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8443             NULL, 0, "Dummy String 7. Used is reserved for next evolutions.", HFILL }},
8444 
8445         { &hf_netlogon_dummy_string8,
8446           { "Dummy String8", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8447             NULL, 0, "Dummy String 8. Used is reserved for next evolutions.", HFILL }},
8448 
8449         { &hf_netlogon_dummy_string9,
8450           { "Dummy String9", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8451             NULL, 0, "Dummy String 9. Used is reserved for next evolutions.", HFILL }},
8452 
8453         { &hf_netlogon_dummy_string10,
8454           { "Dummy String10", "netlogon.dummy_string", FT_STRING, BASE_NONE,
8455             NULL, 0, "Dummy String 10. Used is reserved for next evolutions.", HFILL }},
8456 
8457         { &hf_netlogon_unknown_long,
8458           { "Unknown long", "netlogon.unknown.long", FT_UINT32, BASE_HEX,
8459             NULL, 0x0, "Unknown long. If you know what this is, contact wireshark developers.", HFILL }},
8460 
8461         { &hf_netlogon_dummy1_long,
8462           { "Dummy1 Long", "netlogon.dummy.long1", FT_UINT32, BASE_HEX,
8463             NULL, 0x0, "Dummy long 1. Used is reserved for next evolutions.", HFILL }},
8464 
8465         { &hf_netlogon_dummy2_long,
8466           { "Dummy2 Long", "netlogon.dummy.long2", FT_UINT32, BASE_HEX,
8467             NULL, 0x0, "Dummy long 2. Used is reserved for next evolutions.", HFILL }},
8468 
8469         { &hf_netlogon_dummy3_long,
8470           { "Dummy3 Long", "netlogon.dummy.long3", FT_UINT32, BASE_HEX,
8471             NULL, 0x0, "Dummy long 3. Used is reserved for next evolutions.", HFILL }},
8472 
8473         { &hf_netlogon_dummy4_long,
8474           { "Dummy4 Long", "netlogon.dummy.long4", FT_UINT32, BASE_HEX,
8475             NULL, 0x0, "Dummy long 4. Used is reserved for next evolutions.", HFILL }},
8476 
8477         { &hf_netlogon_dummy5_long,
8478           { "Dummy5 Long", "netlogon.dummy.long5", FT_UINT32, BASE_HEX,
8479             NULL, 0x0, "Dummy long 5. Used is reserved for next evolutions.", HFILL }},
8480 
8481         { &hf_netlogon_dummy6_long,
8482           { "Dummy6 Long", "netlogon.dummy.long6", FT_UINT32, BASE_HEX,
8483             NULL, 0x0, "Dummy long 6. Used is reserved for next evolutions.", HFILL }},
8484 
8485         { &hf_netlogon_dummy7_long,
8486           { "Dummy7 Long", "netlogon.dummy.long7", FT_UINT32, BASE_HEX,
8487             NULL, 0x0, "Dummy long 7. Used is reserved for next evolutions.", HFILL }},
8488 
8489         { &hf_netlogon_dummy8_long,
8490           { "Dummy8 Long", "netlogon.dummy.long8", FT_UINT32, BASE_HEX,
8491             NULL, 0x0, "Dummy long 8. Used is reserved for next evolutions.", HFILL }},
8492 
8493         { &hf_netlogon_dummy9_long,
8494           { "Dummy9 Long", "netlogon.dummy.long9", FT_UINT32, BASE_HEX,
8495             NULL, 0x0, "Dummy long 9. Used is reserved for next evolutions.", HFILL }},
8496 
8497         { &hf_netlogon_dummy10_long,
8498           { "Dummy10 Long", "netlogon.dummy.long10", FT_UINT32, BASE_HEX,
8499             NULL, 0x0, "Dummy long 10. Used is reserved for next evolutions.", HFILL }},
8500 
8501 
8502         { &hf_netlogon_supportedenctypes,
8503           { "Supported Encryption Types", "netlogon.encryption.types", FT_UINT32, BASE_HEX,
8504             NULL, 0x0, "Encryption types", HFILL }},
8505 
8506         { &hf_netlogon_workstation_flags,
8507           { "Workstation Flags", "netlogon.workstation.flags", FT_UINT32, BASE_HEX,
8508             NULL, 0x0, "Flags", HFILL }},
8509 
8510         { &hf_netlogon_reserved,
8511           { "Reserved", "netlogon.reserved", FT_UINT32, BASE_HEX,
8512             NULL, 0x0, NULL, HFILL }},
8513         { &hf_netlogon_unknown_short,
8514           { "Unknown short", "netlogon.unknown.short", FT_UINT16, BASE_HEX,
8515             NULL, 0x0, "Unknown short. If you know what this is, contact wireshark developers.", HFILL }},
8516 
8517         { &hf_netlogon_unknown_char,
8518           { "Unknown char", "netlogon.unknown.char", FT_UINT8, BASE_HEX,
8519             NULL, 0x0, "Unknown char. If you know what this is, contact wireshark developers.", HFILL }},
8520 
8521         { &hf_netlogon_acct_expiry_time,
8522           { "Acct Expiry Time", "netlogon.acct.expiry_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
8523             NULL, 0x0, "When this account will expire", HFILL }},
8524 
8525         { &hf_netlogon_nt_pwd_present,
8526           { "NT PWD Present", "netlogon.nt_pwd_present", FT_UINT8, BASE_HEX,
8527             NULL, 0x0, "Is NT password present for this account?", HFILL }},
8528 
8529         { &hf_netlogon_lm_pwd_present,
8530           { "LM PWD Present", "netlogon.lm_pwd_present", FT_UINT8, BASE_HEX,
8531             NULL, 0x0, "Is LanManager password present for this account?", HFILL }},
8532 
8533         { &hf_netlogon_pwd_expired,
8534           { "PWD Expired", "netlogon.pwd_expired", FT_UINT8, BASE_HEX,
8535             NULL, 0x0, "Whether this password has expired or not", HFILL }},
8536 
8537         { &hf_netlogon_authoritative,
8538           { "Authoritative", "netlogon.authoritative", FT_UINT8, BASE_DEC,
8539             NULL, 0x0, NULL, HFILL }},
8540 
8541         { &hf_netlogon_sensitive_data_flag,
8542           { "Sensitive Data", "netlogon.sensitive_data_flag", FT_UINT8, BASE_DEC,
8543             NULL, 0x0, "Sensitive data flag", HFILL }},
8544 
8545         { &hf_netlogon_auditing_mode,
8546           { "Auditing Mode", "netlogon.auditing_mode", FT_UINT8, BASE_DEC,
8547             NULL, 0x0, NULL, HFILL }},
8548 
8549         { &hf_netlogon_max_audit_event_count,
8550           { "Max Audit Event Count", "netlogon.max_audit_event_count", FT_UINT32, BASE_DEC,
8551             NULL, 0x0, NULL, HFILL }},
8552 
8553         { &hf_netlogon_event_audit_option,
8554           { "Event Audit Option", "netlogon.event_audit_option", FT_UINT32, BASE_HEX,
8555             NULL, 0x0, NULL, HFILL }},
8556 
8557         { &hf_netlogon_sensitive_data_len,
8558           { "Length", "netlogon.sensitive_data_len", FT_UINT32, BASE_DEC,
8559             NULL, 0x0, "Length of sensitive data", HFILL }},
8560 
8561         { &hf_netlogon_nt_chal_resp,
8562           { "NT Chal resp", "netlogon.nt_chal_resp", FT_BYTES, BASE_NONE,
8563             NULL, 0, "Challenge response for NT authentication", HFILL }},
8564 
8565         { &hf_netlogon_lm_chal_resp,
8566           { "LM Chal resp", "netlogon.lm_chal_resp", FT_BYTES, BASE_NONE,
8567             NULL, 0, "Challenge response for LM authentication", HFILL }},
8568 
8569         { &hf_netlogon_cipher_len,
8570           { "Cipher Len", "netlogon.cipher_len", FT_UINT32, BASE_DEC,
8571             NULL, 0, NULL, HFILL }},
8572 
8573         { &hf_netlogon_cipher_maxlen,
8574           { "Cipher Max Len", "netlogon.cipher_maxlen", FT_UINT32, BASE_DEC,
8575             NULL, 0, NULL, HFILL }},
8576 
8577 #if 0
8578         { &hf_netlogon_pac_data,
8579           { "Pac Data", "netlogon.pac.data", FT_BYTES, BASE_NONE,
8580             NULL, 0, NULL, HFILL }},
8581 #endif
8582 
8583         { &hf_netlogon_sensitive_data,
8584           { "Data", "netlogon.sensitive_data", FT_BYTES, BASE_NONE,
8585             NULL, 0, "Sensitive Data", HFILL }},
8586 
8587 #if 0
8588         { &hf_netlogon_auth_data,
8589           { "Auth Data", "netlogon.auth.data", FT_BYTES, BASE_NONE,
8590             NULL, 0, NULL, HFILL }},
8591 #endif
8592 
8593         { &hf_netlogon_cipher_current_data,
8594           { "Cipher Current Data", "netlogon.cipher_current_data", FT_BYTES, BASE_NONE,
8595             NULL, 0, NULL, HFILL }},
8596 
8597         { &hf_netlogon_cipher_old_data,
8598           { "Cipher Old Data", "netlogon.cipher_old_data", FT_BYTES, BASE_NONE,
8599             NULL, 0, NULL, HFILL }},
8600 
8601         { &hf_netlogon_acct_name,
8602           { "Acct Name", "netlogon.acct_name", FT_STRING, BASE_NONE,
8603             NULL, 0, "Account Name", HFILL }},
8604 
8605         { &hf_netlogon_acct_desc,
8606           { "Acct Desc", "netlogon.acct_desc", FT_STRING, BASE_NONE,
8607             NULL, 0, "Account Description", HFILL }},
8608 
8609         { &hf_netlogon_group_desc,
8610           { "Group Desc", "netlogon.group_desc", FT_STRING, BASE_NONE,
8611             NULL, 0, "Group Description", HFILL }},
8612 
8613         { &hf_netlogon_full_name,
8614           { "Full Name", "netlogon.full_name", FT_STRING, BASE_NONE,
8615             NULL, 0, NULL, HFILL }},
8616 
8617         { &hf_netlogon_comment,
8618           { "Comment", "netlogon.comment", FT_STRING, BASE_NONE,
8619             NULL, 0, NULL, HFILL }},
8620 
8621         { &hf_netlogon_parameters,
8622           { "Parameters", "netlogon.parameters", FT_STRING, BASE_NONE,
8623             NULL, 0, NULL, HFILL }},
8624 
8625         { &hf_netlogon_logon_script,
8626           { "Logon Script", "netlogon.logon_script", FT_STRING, BASE_NONE,
8627             NULL, 0, NULL, HFILL }},
8628 
8629         { &hf_netlogon_profile_path,
8630           { "Profile Path", "netlogon.profile_path", FT_STRING, BASE_NONE,
8631             NULL, 0, NULL, HFILL }},
8632 
8633         { &hf_netlogon_home_dir,
8634           { "Home Dir", "netlogon.home_dir", FT_STRING, BASE_NONE,
8635             NULL, 0, "Home Directory", HFILL }},
8636 
8637         { &hf_netlogon_dir_drive,
8638           { "Dir Drive", "netlogon.dir_drive", FT_STRING, BASE_NONE,
8639             NULL, 0, "Drive letter for home directory", HFILL }},
8640 
8641         { &hf_netlogon_logon_srv,
8642           { "Server", "netlogon.server", FT_STRING, BASE_NONE,
8643             NULL, 0, NULL, HFILL }},
8644 
8645 #if 0
8646         { &hf_netlogon_principal,
8647           { "Principal", "netlogon.principal", FT_STRING, BASE_NONE,
8648             NULL, 0, NULL, HFILL }},
8649 #endif
8650 
8651         { &hf_netlogon_logon_dom,
8652           { "Domain", "netlogon.domain", FT_STRING, BASE_NONE,
8653             NULL, 0, NULL, HFILL }},
8654 
8655         { &hf_netlogon_resourcegroupcount,
8656           { "ResourceGroup count", "netlogon.resourcegroupcount", FT_UINT32, BASE_DEC,
8657             NULL, 0, "Number of Resource Groups", HFILL }},
8658 
8659         { &hf_netlogon_accountdomaingroupcount,
8660           { "AccountDomainGroup count", "netlogon.accountdomaingroupcount", FT_UINT32, BASE_DEC,
8661             NULL, 0, "Number of Account Domain Groups", HFILL }},
8662 
8663         { &hf_netlogon_domaingroupcount,
8664           { "DomainGroup count", "netlogon.domaingroupcount", FT_UINT32, BASE_DEC,
8665             NULL, 0, "Number of Domain Groups", HFILL }},
8666 
8667         { &hf_netlogon_membership_domains_count,
8668           { "Membership Domains count", "netlogon.membershipsdomainscount", FT_UINT32, BASE_DEC,
8669             NULL, 0, "Number of ExtraDomain Membership Arrays", HFILL }},
8670 
8671         { &hf_netlogon_computer_name,
8672           { "Computer Name", "netlogon.computer_name", FT_STRING, BASE_NONE,
8673             NULL, 0, NULL, HFILL }},
8674 
8675         { &hf_netlogon_site_name,
8676           { "Site Name", "netlogon.site_name", FT_STRING, BASE_NONE,
8677             NULL, 0, NULL, HFILL }},
8678 
8679         { &hf_netlogon_dc_name,
8680           { "DC Name", "netlogon.dc.name", FT_STRING, BASE_NONE,
8681             NULL, 0, NULL, HFILL }},
8682 
8683         { &hf_netlogon_dc_site_name,
8684           { "DC Site Name", "netlogon.dc.site_name", FT_STRING, BASE_NONE,
8685             NULL, 0, NULL, HFILL }},
8686 
8687         { &hf_netlogon_dns_forest_name,
8688           { "DNS Forest Name", "netlogon.dns.forest_name", FT_STRING, BASE_NONE,
8689             NULL, 0, NULL, HFILL }},
8690 
8691         { &hf_netlogon_dc_address,
8692           { "DC Address", "netlogon.dc.address", FT_STRING, BASE_NONE,
8693             NULL, 0, NULL, HFILL }},
8694 
8695         { &hf_netlogon_dc_address_type,
8696           { "DC Address Type", "netlogon.dc.address_type", FT_UINT32, BASE_DEC,
8697             VALS(dc_address_types), 0, NULL, HFILL }},
8698 
8699         { &hf_netlogon_client_site_name,
8700           { "Client Site Name", "netlogon.client.site_name", FT_STRING, BASE_NONE,
8701             NULL, 0, NULL, HFILL }},
8702 
8703         { &hf_netlogon_workstation_site_name,
8704           { "Wkst Site Name", "netlogon.wkst.site_name", FT_STRING, BASE_NONE,
8705             NULL, 0, "Workstation Site Name", HFILL }},
8706 
8707         { &hf_netlogon_workstation,
8708           { "Wkst Name", "netlogon.wkst.name", FT_STRING, BASE_NONE,
8709             NULL, 0, "Workstation Name", HFILL }},
8710 
8711         { &hf_netlogon_os_version,
8712           { "OS version", "netlogon.os.version", FT_STRING, BASE_NONE,
8713             NULL, 0, NULL, HFILL }},
8714 
8715         { &hf_netlogon_workstation_os,
8716           { "Wkst OS", "netlogon.wkst.os", FT_STRING, BASE_NONE,
8717             NULL, 0, "Workstation OS", HFILL }},
8718 
8719         { &hf_netlogon_workstations,
8720           { "Workstations", "netlogon.wksts", FT_STRING, BASE_NONE,
8721             NULL, 0, NULL, HFILL }},
8722 
8723         { &hf_netlogon_workstation_fqdn,
8724           { "Wkst FQDN", "netlogon.wkst.fqdn", FT_STRING, BASE_NONE,
8725             NULL, 0, "Workstation FQDN", HFILL }},
8726 
8727         { &hf_netlogon_group_name,
8728           { "Group Name", "netlogon.group_name", FT_STRING, BASE_NONE,
8729             NULL, 0, NULL, HFILL }},
8730 
8731         { &hf_netlogon_alias_name,
8732           { "Alias Name", "netlogon.alias_name", FT_STRING, BASE_NONE,
8733             NULL, 0, NULL, HFILL }},
8734 
8735         { &hf_netlogon_dns_host,
8736           { "DNS Host", "netlogon.dns_host", FT_STRING, BASE_NONE,
8737             NULL, 0, NULL, HFILL }},
8738 
8739         { &hf_netlogon_downlevel_domain_name,
8740           { "Downlevel Domain", "netlogon.downlevel_domain", FT_STRING, BASE_NONE,
8741             NULL, 0, "Downlevel Domain Name", HFILL }},
8742 
8743         { &hf_netlogon_dns_domain_name,
8744           { "DNS Domain", "netlogon.dns_domain", FT_STRING, BASE_NONE,
8745             NULL, 0, "DNS Domain Name", HFILL }},
8746 
8747         { &hf_netlogon_ad_client_dns_name,
8748           { "Client DNS Name", "netlogon.client_dns_name", FT_STRING, BASE_NONE,
8749             NULL, 0, NULL, HFILL }},
8750 
8751         { &hf_netlogon_domain_name,
8752           { "Domain", "netlogon.domain", FT_STRING, BASE_NONE,
8753             NULL, 0, "Domain Name", HFILL }},
8754 
8755         { &hf_netlogon_oem_info,
8756           { "OEM Info", "netlogon.oem_info", FT_STRING, BASE_NONE,
8757             NULL, 0, NULL, HFILL }},
8758 
8759         { &hf_netlogon_trusted_dc_name,
8760           { "Trusted DC", "netlogon.trusted_dc", FT_STRING, BASE_NONE,
8761             NULL, 0, NULL, HFILL }},
8762 
8763         { &hf_netlogon_logon_dnslogondomainname,
8764           { "DNS Logon Domain name", "netlogon.logon.dnslogondomainname", FT_STRING, BASE_NONE,
8765             NULL, 0, "DNS Name of the logon domain", HFILL }},
8766 
8767         { &hf_netlogon_logon_upn,
8768           { "UPN", "netlogon.logon.upn", FT_STRING, BASE_NONE,
8769             NULL, 0, "User Principal Name", HFILL }},
8770 
8771         { &hf_netlogon_logonsrv_handle,
8772           { "Handle", "netlogon.handle", FT_STRING, BASE_NONE,
8773             NULL, 0, "Logon Srv Handle", HFILL }},
8774 
8775         { &hf_netlogon_dummy,
8776           { "Dummy", "netlogon.dummy", FT_STRING, BASE_NONE,
8777             NULL, 0, "Dummy string", HFILL }},
8778 
8779         { &hf_netlogon_logon_count16,
8780           { "Logon Count", "netlogon.logon_count16", FT_UINT16, BASE_DEC,
8781             NULL, 0x0, "Number of successful logins", HFILL }},
8782 
8783         { &hf_netlogon_logon_count,
8784           { "Logon Count", "netlogon.logon_count", FT_UINT32, BASE_DEC,
8785             NULL, 0x0, "Number of successful logins", HFILL }},
8786 
8787         { &hf_netlogon_bad_pw_count16,
8788           { "Bad PW Count", "netlogon.bad_pw_count16", FT_UINT16, BASE_DEC,
8789             NULL, 0x0, "Number of failed logins", HFILL }},
8790 
8791         { &hf_netlogon_bad_pw_count,
8792           { "Bad PW Count", "netlogon.bad_pw_count", FT_UINT32, BASE_DEC,
8793             NULL, 0x0, "Number of failed logins", HFILL }},
8794 
8795         { &hf_netlogon_country,
8796           { "Country", "netlogon.country", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
8797             &ms_country_codes_ext, 0x0, "Country setting for this account", HFILL }},
8798 
8799         { &hf_netlogon_codepage,
8800           { "Codepage", "netlogon.codepage", FT_UINT16, BASE_DEC,
8801             NULL, 0x0, "Codepage setting for this account", HFILL }},
8802 
8803         { &hf_netlogon_level16,
8804           { "Level", "netlogon.level16", FT_UINT16, BASE_DEC,
8805             NULL, 0x0, "Which option of the union is represented here", HFILL }},
8806 
8807         { &hf_netlogon_validation_level,
8808           { "Validation Level", "netlogon.validation_level", FT_UINT16, BASE_DEC,
8809             NULL, 0x0, "Requested level of validation", HFILL }},
8810 
8811         { &hf_netlogon_minpasswdlen,
8812           { "Min Password Len", "netlogon.min_passwd_len", FT_UINT16, BASE_DEC,
8813             NULL, 0x0, "Minimum length of password", HFILL }},
8814 
8815         { &hf_netlogon_passwdhistorylen,
8816           { "Passwd History Len", "netlogon.passwd_history_len", FT_UINT16, BASE_DEC,
8817             NULL, 0x0, "Length of password history", HFILL }},
8818 
8819         { &hf_netlogon_secure_channel_type,
8820           { "Sec Chan Type", "netlogon.sec_chan_type", FT_UINT16, BASE_DEC,
8821             VALS(sec_chan_type_vals), 0x0, "Secure Channel Type", HFILL }},
8822 
8823         { &hf_netlogon_restart_state,
8824           { "Restart State", "netlogon.restart_state", FT_UINT16, BASE_DEC,
8825             NULL, 0x0, NULL, HFILL }},
8826 
8827         { &hf_netlogon_delta_type,
8828           { "Delta Type", "netlogon.delta_type", FT_UINT16, BASE_DEC,
8829             VALS(delta_type_vals), 0x0, NULL, HFILL }},
8830 
8831         { &hf_netlogon_blob_size,
8832           { "Size", "netlogon.blob.size", FT_UINT32, BASE_DEC,
8833             NULL, 0x0, "Size in bytes of BLOB", HFILL }},
8834 
8835         { &hf_netlogon_code,
8836           { "Code", "netlogon.code", FT_UINT32, BASE_HEX,
8837             NULL, 0x0, NULL, HFILL }},
8838 
8839         { &hf_netlogon_level,
8840           { "Level", "netlogon.level", FT_UINT32, BASE_DEC,
8841             NULL, 0x0, "Which option of the union is represented here", HFILL }},
8842 
8843         { &hf_netlogon_reference,
8844           { "Reference", "netlogon.reference", FT_UINT32, BASE_DEC,
8845             NULL, 0x0, NULL, HFILL }},
8846 
8847         { &hf_netlogon_next_reference,
8848           { "Next Reference", "netlogon.next_reference", FT_UINT32, BASE_DEC,
8849             NULL, 0x0, NULL, HFILL }},
8850 
8851         { &hf_netlogon_timestamp,
8852           { "Timestamp", "netlogon.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
8853             NULL, 0, NULL, HFILL }},
8854 
8855         { &hf_netlogon_user_rid,
8856           { "User RID", "netlogon.rid", FT_UINT32, BASE_DEC,
8857             NULL, 0x0, NULL, HFILL }},
8858 
8859         { &hf_netlogon_alias_rid,
8860           { "Alias RID", "netlogon.alias_rid", FT_UINT32, BASE_DEC,
8861             NULL, 0x0, NULL, HFILL }},
8862 
8863         { &hf_netlogon_group_rid,
8864           { "Group RID", "netlogon.group_rid", FT_UINT32, BASE_DEC,
8865             NULL, 0x0, NULL, HFILL }},
8866 
8867         { &hf_netlogon_num_rids,
8868           { "Num RIDs", "netlogon.num_rids", FT_UINT32, BASE_DEC,
8869             NULL, 0x0, "Number of RIDs", HFILL }},
8870 
8871         { &hf_netlogon_num_controllers,
8872           { "Num DCs", "netlogon.num_dc", FT_UINT32, BASE_DEC,
8873             NULL, 0x0, "Number of domain controllers", HFILL }},
8874 
8875         { &hf_netlogon_num_sid,
8876           { "Num Extra SID", "netlogon.num_sid", FT_UINT32, BASE_DEC,
8877             NULL, 0x0, NULL, HFILL }},
8878 
8879         { &hf_netlogon_flags,
8880           { "Flags", "netlogon.flags", FT_UINT32, BASE_HEX,
8881             NULL, 0x0, NULL, HFILL }},
8882 
8883         { &hf_netlogon_user_account_control,
8884           { "User Account Control", "netlogon.user_account_control", FT_UINT32, BASE_HEX,
8885             NULL, 0x0, NULL, HFILL }},
8886 
8887         { &hf_netlogon_user_flags,
8888           { "User Flags", "netlogon.user_flags", FT_UINT32, BASE_HEX,
8889             NULL, 0x0, NULL, HFILL }},
8890 
8891         { &hf_netlogon_auth_flags,
8892           { "Auth Flags", "netlogon.auth_flags", FT_UINT32, BASE_HEX,
8893             NULL, 0x0, NULL, HFILL }},
8894 
8895         { &hf_netlogon_systemflags,
8896           { "System Flags", "netlogon.system_flags", FT_UINT32, BASE_HEX,
8897             NULL, 0x0, NULL, HFILL }},
8898 
8899         { &hf_netlogon_database_id,
8900           { "Database Id", "netlogon.database_id", FT_UINT32, BASE_DEC,
8901             NULL, 0x0, NULL, HFILL }},
8902 
8903         { &hf_netlogon_sync_context,
8904           { "Sync Context", "netlogon.sync_context", FT_UINT32, BASE_DEC,
8905             NULL, 0x0, NULL, HFILL }},
8906 
8907         { &hf_netlogon_max_size,
8908           { "Max Size", "netlogon.max_size", FT_UINT32, BASE_DEC,
8909             NULL, 0x0, "Max Size of database", HFILL }},
8910 
8911         { &hf_netlogon_max_log_size,
8912           { "Max Log Size", "netlogon.max_log_size", FT_UINT32, BASE_DEC,
8913             NULL, 0x0, "Max Size of log", HFILL }},
8914 
8915 #if 0
8916         { &hf_netlogon_pac_size,
8917           { "Pac Size", "netlogon.pac.size", FT_UINT32, BASE_DEC,
8918             NULL, 0x0, "Size of PacData in bytes", HFILL }},
8919 #endif
8920 
8921 #if 0
8922         { &hf_netlogon_auth_size,
8923           { "Auth Size", "netlogon.auth.size", FT_UINT32, BASE_DEC,
8924             NULL, 0x0, "Size of AuthData in bytes", HFILL }},
8925 #endif
8926 
8927         { &hf_netlogon_num_deltas,
8928           { "Num Deltas", "netlogon.num_deltas", FT_UINT32, BASE_DEC,
8929             NULL, 0x0, "Number of SAM Deltas in array", HFILL }},
8930 
8931         { &hf_netlogon_num_trusts,
8932           { "Num Trusts", "netlogon.num_trusts", FT_UINT32, BASE_DEC,
8933             NULL, 0x0, NULL, HFILL }},
8934 
8935         { &hf_netlogon_logon_attempts,
8936           { "Logon Attempts", "netlogon.logon_attempts", FT_UINT32, BASE_DEC,
8937             NULL, 0x0, "Number of logon attempts", HFILL }},
8938 
8939         { &hf_netlogon_pagefilelimit,
8940           { "Page File Limit", "netlogon.page_file_limit", FT_UINT32, BASE_DEC,
8941             NULL, 0x0, NULL, HFILL }},
8942 
8943         { &hf_netlogon_pagedpoollimit,
8944           { "Paged Pool Limit", "netlogon.paged_pool_limit", FT_UINT32, BASE_DEC,
8945             NULL, 0x0, NULL, HFILL }},
8946 
8947         { &hf_netlogon_nonpagedpoollimit,
8948           { "Non-Paged Pool Limit", "netlogon.nonpaged_pool_limit", FT_UINT32, BASE_DEC,
8949             NULL, 0x0, NULL, HFILL }},
8950 
8951         { &hf_netlogon_minworkingsetsize,
8952           { "Min Working Set Size", "netlogon.min_working_set_size", FT_UINT32, BASE_DEC,
8953             NULL, 0x0, NULL, HFILL }},
8954 
8955         { &hf_netlogon_maxworkingsetsize,
8956           { "Max Working Set Size", "netlogon.max_working_set_size", FT_UINT32, BASE_DEC,
8957             NULL, 0x0, NULL, HFILL }},
8958 
8959         { &hf_netlogon_serial_number,
8960           { "Serial Number", "netlogon.serial_number", FT_UINT32, BASE_DEC,
8961             NULL, 0x0, NULL, HFILL }},
8962 
8963         { &hf_netlogon_neg_flags,
8964           { "Negotiation options", "netlogon.neg_flags", FT_UINT32, BASE_HEX,
8965             NULL, 0x0, "Negotiation Flags", HFILL }},
8966 
8967 #if 0
8968         { &hf_netlogon_neg_flags_80000000,
8969           { "Not used 80000000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80000000, "Not used", HFILL }},
8970 #endif
8971 
8972         { &hf_netlogon_neg_flags_40000000,
8973           { "Authenticated RPC supported", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40000000, NULL, HFILL }},
8974 
8975         { &hf_netlogon_neg_flags_20000000,
8976           { "Authenticated RPC via lsass supported", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20000000, "rpc via lsass", HFILL }},
8977 
8978 #if 0
8979         { &hf_netlogon_neg_flags_10000000,
8980           { "Not used 10000000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10000000, "Not used", HFILL }},
8981 #endif
8982 
8983 #if 0
8984         { &hf_netlogon_neg_flags_8000000,
8985           { "Not used 8000000", "ntlmssp.neg_flags.na800000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8000000, "Not used", HFILL }},
8986 #endif
8987 
8988 #if 0
8989         { &hf_netlogon_neg_flags_4000000,
8990           { "Not used 4000000", "ntlmssp.neg_flags.na400000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_4000000, "Not used", HFILL }},
8991 #endif
8992 
8993 #if 0
8994         { &hf_netlogon_neg_flags_2000000,
8995           { "Not used 2000000", "ntlmssp.neg_flags.na200000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2000000, "Not used", HFILL }},
8996 #endif
8997 
8998         { &hf_netlogon_neg_flags_1000000,
8999           { "AES supported", "ntlmssp.neg_flags.na100000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_AES, "AES", HFILL }},
9000 
9001 #if 0
9002         { &hf_netlogon_neg_flags_800000,
9003           { "Not used 800000", "ntlmssp.neg_flags.na800000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_800000, "Not used", HFILL }},
9004 #endif
9005 
9006 #if 0
9007         { &hf_netlogon_neg_flags_400000,
9008           { "Not used 400000", "ntlmssp.neg_flags.na400000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_400000, "AES&SHA2", HFILL }},
9009 #endif
9010 
9011         { &hf_netlogon_neg_flags_200000,
9012           { "RODC pass-through", "ntlmssp.neg_flags.na200000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_200000, "rodc pt", HFILL }},
9013 
9014         { &hf_netlogon_neg_flags_100000,
9015           { "NO NT4 emulation", "ntlmssp.neg_flags.na100000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_100000, "No NT4 emu", HFILL }},
9016 
9017         { &hf_netlogon_neg_flags_80000,
9018           { "Cross forest trust", "ntlmssp.neg_flags.na80000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80000, NULL, HFILL }},
9019 
9020         { &hf_netlogon_neg_flags_40000,
9021           { "GetDomainInfo supported", "ntlmssp.neg_flags.na40000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40000, "GetDomainInfo", HFILL }},
9022 
9023         { &hf_netlogon_neg_flags_20000,
9024           { "ServerPasswordSet2 supported", "ntlmssp.neg_flags.na20000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20000, "PasswordSet2", HFILL }},
9025 
9026         { &hf_netlogon_neg_flags_10000,
9027           { "DNS trusts supported", "ntlmssp.neg_flags.na10000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10000, "DNS Trusts", HFILL }},
9028 
9029         { &hf_netlogon_neg_flags_8000,
9030           { "Transitive trusts", "ntlmssp.neg_flags.na8000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8000, "Transitive trust", HFILL }},
9031 
9032         { &hf_netlogon_neg_flags_4000,
9033           { "Strong key", "ntlmssp.neg_flags.na4000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_STRONGKEY, NULL, HFILL }},
9034 
9035         { &hf_netlogon_neg_flags_2000,
9036           { "Avoid replication Auth database", "ntlmssp.neg_flags.na2000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2000, NULL, HFILL }},
9037 
9038         { &hf_netlogon_neg_flags_1000,
9039           { "Avoid replication account database", "ntlmssp.neg_flags.na1000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1000, NULL, HFILL }},
9040 
9041         { &hf_netlogon_neg_flags_800,
9042           { "Concurrent RPC", "ntlmssp.neg_flags.na800", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_800, NULL, HFILL }},
9043 
9044         { &hf_netlogon_neg_flags_400,
9045           { "Generic pass-through", "ntlmssp.neg_flags.na400", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_400, NULL, HFILL }},
9046 
9047         { &hf_netlogon_neg_flags_200,
9048           { "SendToSam", "ntlmssp.neg_flags.na200", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_200, NULL, HFILL }},
9049 
9050         { &hf_netlogon_neg_flags_100,
9051           { "Refusal of password change", "ntlmssp.neg_flags.na100", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_100, "PWD change refusal", HFILL }},
9052 
9053         { &hf_netlogon_neg_flags_80,
9054           { "DatabaseRedo call", "ntlmssp.neg_flags.na80", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80, NULL, HFILL }},
9055 
9056         { &hf_netlogon_neg_flags_40,
9057           { "Handle multiple SIDs", "ntlmssp.neg_flags.na40", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40, NULL, HFILL }},
9058 
9059         { &hf_netlogon_neg_flags_20,
9060           { "Restarting full DC sync", "ntlmssp.neg_flags.na20", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20, NULL, HFILL }},
9061 
9062         { &hf_netlogon_neg_flags_10,
9063           { "BDC handling Changelogs", "ntlmssp.neg_flags.na10", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10, "BDC Changelog", HFILL }},
9064 
9065         { &hf_netlogon_neg_flags_8,
9066           { "Promotion count(deprecated)", "ntlmssp.neg_flags.na8", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8, "Promotion count", HFILL }},
9067 
9068         { &hf_netlogon_neg_flags_4,
9069           { "RC4 encryption", "ntlmssp.neg_flags.na4", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_4, "RC4", HFILL }},
9070 
9071         { &hf_netlogon_neg_flags_2,
9072           { "NT3.5 BDC continuous update", "ntlmssp.neg_flags.na2", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2, "NT3.5", HFILL }},
9073 
9074         { &hf_netlogon_neg_flags_1,
9075           { "Account lockout", "ntlmssp.neg_flags.na1", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1, NULL, HFILL }},
9076 
9077         { &hf_netlogon_dc_flags,
9078           { "Domain Controller Flags", "netlogon.dc.flags", FT_UINT32, BASE_HEX,
9079             NULL, 0x0, NULL, HFILL }},
9080 
9081         { &hf_netlogon_dc_flags_pdc_flag,
9082           { "PDC", "netlogon.dc.flags.pdc",
9083             FT_BOOLEAN, 32, TFS(&dc_flags_pdc_flag), DS_PDC_FLAG,
9084             "If this server is a PDC", HFILL }},
9085 
9086         { &hf_netlogon_dc_flags_gc_flag,
9087           { "GC", "netlogon.dc.flags.gc",
9088             FT_BOOLEAN, 32, TFS(&dc_flags_gc_flag), DS_GC_FLAG,
9089             "If this server is a GC", HFILL }},
9090 
9091         { &hf_netlogon_dc_flags_ldap_flag,
9092           { "LDAP", "netlogon.dc.flags.ldap",
9093             FT_BOOLEAN, 32, TFS(&dc_flags_ldap_flag), DS_LDAP_FLAG,
9094             "If this is an LDAP server", HFILL }},
9095 
9096         { &hf_netlogon_dc_flags_ds_flag,
9097           { "DS", "netlogon.dc.flags.ds",
9098             FT_BOOLEAN, 32, TFS(&dc_flags_ds_flag), DS_DS_FLAG,
9099             "If this server is a DS", HFILL }},
9100 
9101         { &hf_netlogon_dc_flags_kdc_flag,
9102           { "KDC", "netlogon.dc.flags.kdc",
9103             FT_BOOLEAN, 32, TFS(&dc_flags_kdc_flag), DS_KDC_FLAG,
9104             "If this is a KDC", HFILL }},
9105 
9106         { &hf_netlogon_dc_flags_timeserv_flag,
9107           { "Timeserv", "netlogon.dc.flags.timeserv",
9108             FT_BOOLEAN, 32, TFS(&dc_flags_timeserv_flag), DS_TIMESERV_FLAG,
9109             "If this server is a TimeServer", HFILL }},
9110 
9111         { &hf_netlogon_dc_flags_closest_flag,
9112           { "Closest", "netlogon.dc.flags.closest",
9113             FT_BOOLEAN, 32, TFS(&dc_flags_closest_flag), DS_CLOSEST_FLAG,
9114             "If this is the closest server", HFILL }},
9115 
9116         { &hf_netlogon_dc_flags_writable_flag,
9117           { "Writable", "netlogon.dc.flags.writable",
9118             FT_BOOLEAN, 32, TFS(&dc_flags_writable_flag), DS_WRITABLE_FLAG,
9119             "If this server can do updates to the database", HFILL }},
9120 
9121         { &hf_netlogon_dc_flags_good_timeserv_flag,
9122           { "Good Timeserv", "netlogon.dc.flags.good_timeserv",
9123             FT_BOOLEAN, 32, TFS(&dc_flags_good_timeserv_flag), DS_GOOD_TIMESERV_FLAG,
9124             "If this is a Good TimeServer", HFILL }},
9125 
9126         { &hf_netlogon_dc_flags_ndnc_flag,
9127           { "NDNC", "netlogon.dc.flags.ndnc",
9128             FT_BOOLEAN, 32, TFS(&dc_flags_ndnc_flag), DS_NDNC_FLAG,
9129             "If this is an NDNC server", HFILL }},
9130 
9131         { &hf_netlogon_dc_flags_dns_controller_flag,
9132           { "DNS Controller", "netlogon.dc.flags.dns_controller",
9133             FT_BOOLEAN, 32, TFS(&dc_flags_dns_controller_flag), DS_DNS_CONTROLLER_FLAG,
9134             "If this server is a DNS Controller", HFILL }},
9135 
9136         { &hf_netlogon_dc_flags_dns_domain_flag,
9137           { "DNS Domain", "netlogon.dc.flags.dns_domain",
9138             FT_BOOLEAN, 32, TFS(&dc_flags_dns_domain_flag), DS_DNS_DOMAIN_FLAG,
9139             NULL, HFILL }},
9140 
9141         { &hf_netlogon_dc_flags_dns_forest_flag,
9142           { "DNS Forest", "netlogon.dc.flags.dns_forest",
9143             FT_BOOLEAN, 32, TFS(&dc_flags_dns_forest_flag), DS_DNS_FOREST_FLAG,
9144             NULL, HFILL }},
9145 
9146         { &hf_netlogon_get_dcname_request_flags,
9147           { "Flags", "netlogon.get_dcname.request.flags", FT_UINT32, BASE_HEX,
9148             NULL, 0x0, "Flags for DSGetDCName request", HFILL }},
9149 
9150         { &hf_netlogon_get_dcname_request_flags_force_rediscovery,
9151           { "Force Rediscovery", "netlogon.get_dcname.request.flags.force_rediscovery",
9152             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_force_rediscovery), DS_FORCE_REDISCOVERY,
9153             "Whether to allow the server to returned cached information or not", HFILL }},
9154 
9155         { &hf_netlogon_get_dcname_request_flags_directory_service_required,
9156           { "DS Required", "netlogon.get_dcname.request.flags.ds_required",
9157             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_directory_service_required), DS_DIRECTORY_SERVICE_REQUIRED,
9158             "Whether we require that the returned DC supports w2k or not", HFILL }},
9159 
9160         { &hf_netlogon_get_dcname_request_flags_directory_service_preferred,
9161           { "DS Preferred", "netlogon.get_dcname.request.flags.ds_preferred",
9162             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_directory_service_preferred), DS_DIRECTORY_SERVICE_PREFERRED,
9163             "Whether we prefer the call to return a w2k server (if available)", HFILL }},
9164 
9165         { &hf_netlogon_get_dcname_request_flags_gc_server_required,
9166           { "GC Required", "netlogon.get_dcname.request.flags.gc_server_required",
9167             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_gc_server_required), DS_GC_SERVER_REQUIRED,
9168             "Whether we require that the returned DC is a Global Catalog server", HFILL }},
9169 
9170         { &hf_netlogon_get_dcname_request_flags_pdc_required,
9171           { "PDC Required", "netlogon.get_dcname.request.flags.pdc_required",
9172             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_pdc_required), DS_PDC_REQUIRED,
9173             "Whether we require the returned DC to be the PDC", HFILL }},
9174 
9175         { &hf_netlogon_get_dcname_request_flags_background_only,
9176           { "Background Only", "netlogon.get_dcname.request.flags.background_only",
9177             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_background_only), DS_BACKGROUND_ONLY,
9178             "If we want cached data, even if it may have expired", HFILL }},
9179 
9180         { &hf_netlogon_get_dcname_request_flags_ip_required,
9181           { "IP Required", "netlogon.get_dcname.request.flags.ip_required",
9182             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_ip_required), DS_IP_REQUIRED,
9183             "If we require the IP of the DC in the reply", HFILL }},
9184 
9185         { &hf_netlogon_get_dcname_request_flags_kdc_required,
9186           { "KDC Required", "netlogon.get_dcname.request.flags.kdc_required",
9187             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_kdc_required), DS_KDC_REQUIRED,
9188             "If we require that the returned server is a KDC", HFILL }},
9189 
9190         { &hf_netlogon_get_dcname_request_flags_timeserv_required,
9191           { "Timeserv Required", "netlogon.get_dcname.request.flags.timeserv_required",
9192             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_timeserv_required), DS_TIMESERV_REQUIRED,
9193             "If we require the returned server to be a WindowsTimeServ server", HFILL }},
9194 
9195         { &hf_netlogon_get_dcname_request_flags_writable_required,
9196           { "Writable Required", "netlogon.get_dcname.request.flags.writable_required",
9197             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_writable_required), DS_WRITABLE_REQUIRED,
9198             "If we require that the returned server is writable", HFILL }},
9199 
9200         { &hf_netlogon_get_dcname_request_flags_good_timeserv_preferred,
9201           { "Timeserv Preferred", "netlogon.get_dcname.request.flags.good_timeserv_preferred",
9202             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_good_timeserv_preferred), DS_GOOD_TIMESERV_PREFERRED,
9203             "If we prefer Windows Time Servers", HFILL }},
9204 
9205         { &hf_netlogon_get_dcname_request_flags_avoid_self,
9206           { "Avoid Self", "netlogon.get_dcname.request.flags.avoid_self",
9207             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_avoid_self), DS_AVOID_SELF,
9208             "Return another DC than the one we ask", HFILL }},
9209 
9210         { &hf_netlogon_get_dcname_request_flags_only_ldap_needed,
9211           { "Only LDAP Needed", "netlogon.get_dcname.request.flags.only_ldap_needed",
9212             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_only_ldap_needed), DS_ONLY_LDAP_NEEDED,
9213             "We just want an LDAP server, it does not have to be a DC", HFILL }},
9214 
9215         { &hf_netlogon_get_dcname_request_flags_is_flat_name,
9216           { "Is Flat Name", "netlogon.get_dcname.request.flags.is_flat_name",
9217             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_is_flat_name), DS_IS_FLAT_NAME,
9218             "If the specified domain name is a NetBIOS name", HFILL }},
9219 
9220         { &hf_netlogon_get_dcname_request_flags_is_dns_name,
9221           { "Is DNS Name", "netlogon.get_dcname.request.flags.is_dns_name",
9222             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_is_dns_name), DS_IS_DNS_NAME,
9223             "If the specified domain name is a DNS name", HFILL }},
9224 
9225         { &hf_netlogon_get_dcname_request_flags_return_dns_name,
9226           { "Return DNS Name", "netlogon.get_dcname.request.flags.return_dns_name",
9227             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_return_dns_name), DS_RETURN_DNS_NAME,
9228             "Only return a DNS name (or an error)", HFILL }},
9229 
9230         { &hf_netlogon_get_dcname_request_flags_return_flat_name,
9231           { "Return Flat Name", "netlogon.get_dcname.request.flags.return_flat_name",
9232             FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_return_flat_name), DS_RETURN_FLAT_NAME,
9233             "Only return a NetBIOS name (or an error)", HFILL }},
9234 
9235         { &hf_netlogon_trust_attribs,
9236           { "Trust Attributes", "netlogon.trust_attribs", FT_UINT32, BASE_HEX,
9237             NULL, 0x0, NULL, HFILL }},
9238 
9239         { &hf_netlogon_trust_attribs_non_transitive,
9240           { "Non Transitive", "netlogon.trust.attribs.non_transitive", FT_BOOLEAN, 32,
9241             TFS(&trust_attribs_non_transitive), 0x00000001, NULL, HFILL }},
9242 
9243         { &hf_netlogon_trust_attribs_uplevel_only,
9244           { "Uplevel Only", "netlogon.trust.attribs.uplevel_only", FT_BOOLEAN, 32,
9245             TFS(&trust_attribs_uplevel_only), 0x00000002, NULL, HFILL }},
9246 
9247         { &hf_netlogon_trust_attribs_quarantined_domain,
9248           { "Quarantined Domain", "netlogon.trust.attribs.quarantined_domain", FT_BOOLEAN, 32,
9249             TFS(&trust_attribs_quarantined_domain), 0x00000004, NULL, HFILL }},
9250 
9251         { &hf_netlogon_trust_attribs_forest_transitive,
9252           { "Forest Transitive", "netlogon.trust.attribs.forest_transitive", FT_BOOLEAN, 32,
9253             TFS(&trust_attribs_forest_transitive), 0x00000008, NULL, HFILL }},
9254 
9255         { &hf_netlogon_trust_attribs_cross_organization,
9256           { "Cross Organization", "netlogon.trust.attribs.cross_organization", FT_BOOLEAN, 32,
9257             TFS(&trust_attribs_cross_organization), 0x00000010, NULL, HFILL }},
9258 
9259         { &hf_netlogon_trust_attribs_within_forest,
9260           { "Within Forest", "netlogon.trust.attribs.within_forest", FT_BOOLEAN, 32,
9261             TFS(&trust_attribs_within_forest), 0x00000020, NULL, HFILL }},
9262 
9263         { &hf_netlogon_trust_attribs_treat_as_external,
9264           { "Treat As External", "netlogon.trust.attribs.treat_as_external", FT_BOOLEAN, 32,
9265             TFS(&trust_attribs_treat_as_external), 0x00000040, NULL, HFILL }},
9266 
9267         { &hf_netlogon_trust_type,
9268           { "Trust Type", "netlogon.trust_type", FT_UINT32, BASE_DEC,
9269             VALS(trust_type_vals), 0x0, NULL, HFILL }},
9270 
9271         { &hf_netlogon_extraflags,
9272           { "Extra Flags", "netlogon.extra_flags", FT_UINT32, BASE_HEX,
9273             NULL, 0x0, NULL, HFILL }},
9274 
9275         { &hf_netlogon_extra_flags_root_forest,
9276           { "Request passed to DC of root forest", "netlogon.extra.flags.rootdc",
9277             FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_ROOT_FOREST,
9278             NULL, HFILL }},
9279 
9280         { &hf_netlogon_trust_flags_dc_firsthop,
9281           { "DC at the end of the first hop of cross forest", "netlogon.extra.flags.dc_firsthop",
9282             FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_DC_XFOREST,
9283             NULL, HFILL }},
9284 
9285         { &hf_netlogon_trust_flags_rodc_to_dc,
9286           { "Request from a RODC to a DC from another domain", "netlogon.extra.flags.rodc_to_dc",
9287             FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_RODC_DIF_DOMAIN,
9288             NULL, HFILL }},
9289 
9290         { &hf_netlogon_trust_flags_rodc_ntlm,
9291           { "Request is a NTLM auth passed by a RODC", "netlogon.extra.flags.rodc_ntlm",
9292             FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_NTLM_FROM_RODC,
9293             NULL, HFILL }},
9294 
9295         { &hf_netlogon_trust_flags,
9296           { "Trust Flags", "netlogon.trust_flags", FT_UINT32, BASE_HEX,
9297             NULL, 0x0, NULL, HFILL }},
9298 
9299         { &hf_netlogon_trust_flags_inbound,
9300           { "Inbound Trust", "netlogon.trust.flags.inbound",
9301             FT_BOOLEAN, 32, TFS(&trust_inbound), DS_DOMAIN_DIRECT_INBOUND,
9302             "Inbound trust. Whether the domain directly trusts the queried servers domain", HFILL }},
9303 
9304         { &hf_netlogon_trust_flags_outbound,
9305           { "Outbound Trust", "netlogon.trust.flags.outbound",
9306             FT_BOOLEAN, 32, TFS(&trust_outbound), DS_DOMAIN_DIRECT_OUTBOUND,
9307             "Outbound Trust. Whether the domain is directly trusted by the servers domain", HFILL }},
9308 
9309         { &hf_netlogon_trust_flags_in_forest,
9310           { "In Forest", "netlogon.trust.flags.in_forest",
9311             FT_BOOLEAN, 32, TFS(&trust_in_forest), DS_DOMAIN_IN_FOREST,
9312             "Whether this domain is a member of the same forest as the servers domain", HFILL }},
9313 
9314         { &hf_netlogon_trust_flags_native_mode,
9315           { "Native Mode", "netlogon.trust.flags.native_mode",
9316             FT_BOOLEAN, 32, TFS(&trust_native_mode), DS_DOMAIN_NATIVE_MODE,
9317             "Whether the domain is a w2k native mode domain or not", HFILL }},
9318 
9319         { &hf_netlogon_trust_flags_primary,
9320           { "Primary", "netlogon.trust.flags.primary",
9321             FT_BOOLEAN, 32, TFS(&trust_primary), DS_DOMAIN_PRIMARY,
9322             "Whether the domain is the primary domain for the queried server or not", HFILL }},
9323 
9324         { &hf_netlogon_trust_flags_tree_root,
9325           { "Tree Root", "netlogon.trust.flags.tree_root",
9326             FT_BOOLEAN, 32, TFS(&trust_tree_root), DS_DOMAIN_TREE_ROOT,
9327             "Whether the domain is the root of the tree for the queried server", HFILL }},
9328 
9329         { &hf_netlogon_trust_parent_index,
9330           { "Parent Index", "netlogon.parent_index", FT_UINT32, BASE_HEX,
9331             NULL, 0x0, NULL, HFILL }},
9332 
9333         { &hf_netlogon_logon_time,
9334           { "Logon Time", "netlogon.logon_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9335             NULL, 0, "Time for last time this user logged on", HFILL }},
9336 
9337         { &hf_netlogon_kickoff_time,
9338           { "Kickoff Time", "netlogon.kickoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9339             NULL, 0, "Time when this user will be kicked off", HFILL }},
9340 
9341         { &hf_netlogon_logoff_time,
9342           { "Logoff Time", "netlogon.logoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9343             NULL, 0, "Time for last time this user logged off", HFILL }},
9344 
9345         { &hf_netlogon_last_logoff_time,
9346           { "Last Logoff Time", "netlogon.last_logoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9347             NULL, 0, "Time for last time this user logged off", HFILL }},
9348 
9349         { &hf_netlogon_pwd_last_set_time,
9350           { "PWD Last Set", "netlogon.pwd_last_set_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9351             NULL, 0, "Last time this users password was changed", HFILL }},
9352 
9353         { &hf_netlogon_pwd_age,
9354           { "PWD Age", "netlogon.pwd_age", FT_RELATIVE_TIME, BASE_NONE,
9355             NULL, 0, "Time since this users password was changed", HFILL }},
9356 
9357         { &hf_netlogon_pwd_can_change_time,
9358           { "PWD Can Change", "netlogon.pwd_can_change_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9359             NULL, 0, "When this users password may be changed", HFILL }},
9360 
9361         { &hf_netlogon_pwd_must_change_time,
9362           { "PWD Must Change", "netlogon.pwd_must_change_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9363             NULL, 0, "When this users password must be changed", HFILL }},
9364 
9365         { &hf_netlogon_domain_create_time,
9366           { "Domain Create Time", "netlogon.domain_create_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9367             NULL, 0, "Time when this domain was created", HFILL }},
9368 
9369         { &hf_netlogon_domain_modify_time,
9370           { "Domain Modify Time", "netlogon.domain_modify_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9371             NULL, 0, "Time when this domain was last modified", HFILL }},
9372 
9373         { &hf_netlogon_db_modify_time,
9374           { "DB Modify Time", "netlogon.db_modify_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9375             NULL, 0, "Time when last modified", HFILL }},
9376 
9377         { &hf_netlogon_db_create_time,
9378           { "DB Create Time", "netlogon.db_create_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9379             NULL, 0, "Time when created", HFILL }},
9380 
9381         { &hf_netlogon_cipher_current_set_time,
9382           { "Cipher Current Set Time", "netlogon.cipher_current_set_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9383             NULL, 0, "Time when current cipher was initiated", HFILL }},
9384 
9385         { &hf_netlogon_cipher_old_set_time,
9386           { "Cipher Old Set Time", "netlogon.cipher_old_set_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
9387             NULL, 0, "Time when previous cipher was initiated", HFILL }},
9388 
9389         { &hf_netlogon_audit_retention_period,
9390           { "Audit Retention Period", "netlogon.audit_retention_period", FT_RELATIVE_TIME, BASE_NONE,
9391             NULL, 0, NULL, HFILL }},
9392 
9393         { &hf_netlogon_timelimit,
9394           { "Time Limit", "netlogon.time_limit", FT_RELATIVE_TIME, BASE_NONE,
9395             NULL, 0, NULL, HFILL }},
9396 
9397 
9398         { &hf_client_credential,
9399           { "Client Credential", "netlogon.clientcred", FT_BYTES, BASE_NONE,
9400             NULL, 0x0, NULL, HFILL }},
9401 
9402         { &hf_server_credential,
9403           { "Server Credential", "netlogon.servercred", FT_BYTES, BASE_NONE,
9404             NULL, 0x0, NULL, HFILL }},
9405 
9406         { &hf_server_rid,
9407           { "Account RID", "netlogon.serverrid", FT_UINT32, BASE_DEC,
9408             NULL, 0x0, NULL, HFILL }},
9409 
9410         { &hf_client_challenge,
9411           { "Client Challenge", "netlogon.clientchallenge", FT_BYTES, BASE_NONE,
9412             NULL, 0x0, NULL, HFILL }},
9413 
9414         { &hf_server_challenge,
9415           { "Server Challenge", "netlogon.serverchallenge", FT_BYTES, BASE_NONE,
9416             NULL, 0x0, NULL, HFILL }},
9417 
9418         { &hf_netlogon_secchan_nl_message_type,
9419           { "Message Type", "netlogon.secchan.nl_auth_message.message_type", FT_UINT32, BASE_HEX,
9420             VALS(nl_auth_types), 0x0, NULL, HFILL }},
9421 
9422         { &hf_netlogon_secchan_nl_message_flags,
9423           { "Message Flags", "netlogon.secchan.nl_auth_message.message_flags", FT_UINT32, BASE_HEX,
9424             NULL, 0x0, NULL, HFILL }},
9425 
9426         { &hf_netlogon_secchan_nl_message_flags_nb_domain,
9427           { "NetBios Domain", "netlogon.secchan.nl_auth_message.message_flags.nb_domain", FT_BOOLEAN, 32,
9428             NULL, 0x00000001, NULL, HFILL }},
9429 
9430         { &hf_netlogon_secchan_nl_message_flags_nb_host,
9431           { "NetBios Host", "netlogon.secchan.nl_auth_message.message_flags.nb_host", FT_BOOLEAN, 32,
9432             NULL, 0x00000002, NULL, HFILL }},
9433 
9434         { &hf_netlogon_secchan_nl_message_flags_dns_domain,
9435           { "DNS Domain", "netlogon.secchan.nl_auth_message.message_flags.dns_domain", FT_BOOLEAN, 32,
9436             NULL, 0x00000004, NULL, HFILL }},
9437 
9438         { &hf_netlogon_secchan_nl_message_flags_dns_host,
9439           { "DNS Host", "netlogon.secchan.nl_auth_message.message_flags.dns_host", FT_BOOLEAN, 32,
9440             NULL, 0x00000008, NULL, HFILL }},
9441 
9442         { &hf_netlogon_secchan_nl_message_flags_nb_host_utf8,
9443           { "NetBios Host(UTF8)", "netlogon.secchan.nl_auth_message.message_flags.nb_host_utf8", FT_BOOLEAN, 32,
9444             NULL, 0x00000010, NULL, HFILL }},
9445 
9446         { &hf_netlogon_secchan_nl_nb_domain,
9447           { "NetBios Domain", "netlogon.secchan.nl_auth_message.nb_domain", FT_STRING, BASE_NONE,
9448             NULL, 0, NULL, HFILL }},
9449 
9450         { &hf_netlogon_secchan_nl_nb_host,
9451           { "NetBios Host", "netlogon.secchan.nl_auth_message.nb_host", FT_STRING, BASE_NONE,
9452             NULL, 0, NULL, HFILL }},
9453 
9454         { &hf_netlogon_secchan_nl_nb_host_utf8,
9455           { "NetBios Host(UTF8)", "netlogon.secchan.nl_auth_message.nb_host_utf8", FT_STRING, BASE_NONE,
9456             NULL, 0, NULL, HFILL }},
9457 
9458         { &hf_netlogon_secchan_nl_dns_domain,
9459           { "DNS Domain", "netlogon.secchan.nl_auth_message.dns_domain", FT_STRING, BASE_NONE,
9460             NULL, 0, NULL, HFILL }},
9461 
9462         { &hf_netlogon_secchan_nl_dns_host,
9463           { "DNS Host", "netlogon.secchan.nl_auth_message.dns_host", FT_STRING, BASE_NONE,
9464             NULL, 0, NULL, HFILL }},
9465 
9466         { &hf_netlogon_data_length,
9467           { "Length of Data", "netlogon.data.length", FT_UINT32, BASE_DEC,
9468             NULL, 0, NULL, HFILL }},
9469 
9470         { &hf_netlogon_package_name,
9471           { "SSP Package Name", "netlogon.data.package_name", FT_STRING, BASE_NONE,
9472             NULL, 0, NULL, HFILL }},
9473 
9474         { &hf_netlogon_secchan_verf,
9475           { "Secure Channel Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE,
9476             NULL, 0x0, "Verifier", HFILL }},
9477 
9478         { &hf_netlogon_secchan_verf_signalg,
9479           { "Sign algorithm", "netlogon.secchan.signalg", FT_UINT16, BASE_HEX,
9480             VALS(sign_algs), 0, NULL, HFILL }},
9481 
9482         { &hf_netlogon_secchan_verf_sealalg,
9483           { "Seal algorithm", "netlogon.secchan.sealalg", FT_UINT16, BASE_HEX,
9484             VALS(seal_algs), 0, NULL, HFILL }},
9485 
9486         { &hf_netlogon_secchan_verf_flag,
9487           { "Flags", "netlogon.secchan.flags", FT_BYTES, BASE_NONE, NULL,
9488             0x0, NULL, HFILL }},
9489 
9490         { &hf_netlogon_secchan_verf_digest,
9491           { "Packet Digest", "netlogon.secchan.digest", FT_BYTES, BASE_NONE, NULL,
9492             0x0, NULL, HFILL }},
9493 
9494         { &hf_netlogon_secchan_verf_seq,
9495           { "Sequence No", "netlogon.secchan.seq", FT_BYTES, BASE_NONE, NULL,
9496             0x0, NULL, HFILL }},
9497 
9498         { &hf_netlogon_secchan_verf_nonce,
9499           { "Nonce", "netlogon.secchan.nonce", FT_BYTES, BASE_NONE, NULL,
9500             0x0, NULL, HFILL }},
9501 
9502         { &hf_netlogon_group_attrs_mandatory,
9503           { "Mandatory", "netlogon.groups.attrs.mandatory",
9504             FT_BOOLEAN, 32, TFS(&group_attrs_mandatory), 0x00000001,
9505             "The group attributes MANDATORY flag", HFILL }},
9506 
9507         { &hf_netlogon_group_attrs_enabled_by_default,
9508           { "Enabled By Default", "netlogon.groups.attrs.enabled_by_default",
9509             FT_BOOLEAN, 32, TFS(&group_attrs_enabled_by_default), 0x00000002,
9510             "The group attributes ENABLED_BY_DEFAULT flag", HFILL }},
9511 
9512         { &hf_netlogon_group_attrs_enabled,
9513           { "Enabled", "netlogon.groups.attrs.enabled",
9514             FT_BOOLEAN, 32, TFS(&group_attrs_enabled), 0x00000004,
9515             "The group attributes ENABLED flag", HFILL }},
9516 
9517         { &hf_netlogon_user_flags_extra_sids,
9518           { "Extra SIDs", "netlogon.user.flags.extra_sids",
9519             FT_BOOLEAN, 32, TFS(&user_flags_extra_sids), 0x00000020,
9520             "The user flags EXTRA_SIDS", HFILL }},
9521 
9522         { &hf_netlogon_user_flags_resource_groups,
9523           { "Resource Groups", "netlogon.user.flags.resource_groups",
9524             FT_BOOLEAN, 32, TFS(&user_flags_resource_groups), 0x00000200,
9525             "The user flags RESOURCE_GROUPS", HFILL }},
9526 
9527         { &hf_netlogon_user_account_control_dont_require_preauth,
9528           { "Don't Require PreAuth", "netlogon.user.account_control.dont_require_preauth",
9529             FT_BOOLEAN, 32, TFS(&user_account_control_dont_require_preauth), 0x00010000,
9530             "The user account control DONT_REQUIRE_PREAUTH flag", HFILL }},
9531 
9532         { &hf_netlogon_user_account_control_use_des_key_only,
9533           { "Use DES Key Only", "netlogon.user.account_control.use_des_key_only",
9534             FT_BOOLEAN, 32, TFS(&user_account_control_use_des_key_only), 0x00008000,
9535             "The user account control use_des_key_only flag", HFILL }},
9536 
9537         { &hf_netlogon_user_account_control_not_delegated,
9538           { "Not Delegated", "netlogon.user.account_control.not_delegated",
9539             FT_BOOLEAN, 32, TFS(&user_account_control_not_delegated), 0x00004000,
9540             "The user account control not_delegated flag", HFILL }},
9541 
9542         { &hf_netlogon_user_account_control_trusted_for_delegation,
9543           { "Trusted For Delegation", "netlogon.user.account_control.trusted_for_delegation",
9544             FT_BOOLEAN, 32, TFS(&user_account_control_trusted_for_delegation), 0x00002000,
9545             "The user account control trusted_for_delegation flag", HFILL }},
9546 
9547         { &hf_netlogon_user_account_control_smartcard_required,
9548           { "SmartCard Required", "netlogon.user.account_control.smartcard_required",
9549             FT_BOOLEAN, 32, TFS(&user_account_control_smartcard_required), 0x00001000,
9550             "The user account control smartcard_required flag", HFILL }},
9551 
9552         { &hf_netlogon_user_account_control_encrypted_text_password_allowed,
9553           { "Encrypted Text Password Allowed", "netlogon.user.account_control.encrypted_text_password_allowed",
9554             FT_BOOLEAN, 32, TFS(&user_account_control_encrypted_text_password_allowed), 0x00000800,
9555             "The user account control encrypted_text_password_allowed flag", HFILL }},
9556 
9557         { &hf_netlogon_user_account_control_account_auto_locked,
9558           { "Account Auto Locked", "netlogon.user.account_control.account_auto_locked",
9559             FT_BOOLEAN, 32, TFS(&user_account_control_account_auto_locked), 0x00000400,
9560             "The user account control account_auto_locked flag", HFILL }},
9561 
9562         { &hf_netlogon_user_account_control_dont_expire_password,
9563           { "Don't Expire Password", "netlogon.user.account_control.dont_expire_password",
9564             FT_BOOLEAN, 32, TFS(&user_account_control_dont_expire_password), 0x00000200,
9565             "The user account control dont_expire_password flag", HFILL }},
9566 
9567         { &hf_netlogon_user_account_control_server_trust_account,
9568           { "Server Trust Account", "netlogon.user.account_control.server_trust_account",
9569             FT_BOOLEAN, 32, TFS(&user_account_control_server_trust_account), 0x00000100,
9570             "The user account control server_trust_account flag", HFILL }},
9571 
9572         { &hf_netlogon_user_account_control_workstation_trust_account,
9573           { "Workstation Trust Account", "netlogon.user.account_control.workstation_trust_account",
9574             FT_BOOLEAN, 32, TFS(&user_account_control_workstation_trust_account), 0x00000080,
9575             "The user account control workstation_trust_account flag", HFILL }},
9576 
9577         { &hf_netlogon_user_account_control_interdomain_trust_account,
9578           { "Interdomain trust Account", "netlogon.user.account_control.interdomain_trust_account",
9579             FT_BOOLEAN, 32, TFS(&user_account_control_interdomain_trust_account), 0x00000040,
9580             "The user account control interdomain_trust_account flag", HFILL }},
9581 
9582         { &hf_netlogon_user_account_control_mns_logon_account,
9583           { "MNS Logon Account", "netlogon.user.account_control.mns_logon_account",
9584             FT_BOOLEAN, 32, TFS(&user_account_control_mns_logon_account), 0x00000020,
9585             "The user account control mns_logon_account flag", HFILL }},
9586 
9587         { &hf_netlogon_user_account_control_normal_account,
9588           { "Normal Account", "netlogon.user.account_control.normal_account",
9589             FT_BOOLEAN, 32, TFS(&user_account_control_normal_account), 0x00000010,
9590             "The user account control normal_account flag", HFILL }},
9591 
9592         { &hf_netlogon_user_account_control_temp_duplicate_account,
9593           { "Temp Duplicate Account", "netlogon.user.account_control.temp_duplicate_account",
9594             FT_BOOLEAN, 32, TFS(&user_account_control_temp_duplicate_account), 0x00000008,
9595             "The user account control temp_duplicate_account flag", HFILL }},
9596 
9597         { &hf_netlogon_user_account_control_password_not_required,
9598           { "Password Not Required", "netlogon.user.account_control.password_not_required",
9599             FT_BOOLEAN, 32, TFS(&user_account_control_password_not_required), 0x00000004,
9600             "The user account control password_not_required flag", HFILL }},
9601 
9602         { &hf_netlogon_user_account_control_home_directory_required,
9603           { "Home Directory Required", "netlogon.user.account_control.home_directory_required",
9604             FT_BOOLEAN, 32, TFS(&user_account_control_home_directory_required), 0x00000002,
9605             "The user account control home_directory_required flag", HFILL }},
9606 
9607         { &hf_netlogon_user_account_control_account_disabled,
9608           { "Account Disabled", "netlogon.user.account_control.account_disabled",
9609             FT_BOOLEAN, 32, TFS(&user_account_control_account_disabled), 0x00000001,
9610             "The user account control account_disabled flag", HFILL }},
9611 
9612 #if 0
9613         { &hf_netlogon_dnsdomaininfo,
9614           { "DnsDomainInfo", "netlogon.dnsdomaininfo", FT_NONE, BASE_NONE,
9615             NULL, 0x0, NULL, HFILL }},
9616 #endif
9617 
9618         { &DnsDomainInfo_sid,
9619           { "Sid", "lsarpc.lsa_DnsDomainInfo.sid", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
9620         { &DomainInfo_sid,
9621           { "Sid", "lsarpc.lsa_DomainInfo.sid", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
9622         { &DnsDomainInfo_domain_guid,
9623           { "Domain Guid", "lsarpc.lsa_DnsDomainInfo.domain_guid", FT_GUID, BASE_NONE, NULL, 0, NULL, HFILL }},
9624         { &DnsDomainInfo_dns_forest,
9625           { "Dns Forest", "lsarpc.lsa_DnsDomainInfo.dns_forest", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
9626         { &DnsDomainInfo_dns_domain,
9627           { "Dns Domain", "lsarpc.lsa_DnsDomainInfo.dns_domain", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
9628         { &DnsDomainInfo_name,
9629           { "Name", "lsarpc.lsa_DnsDomainInfo.name", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
9630         { &hf_netlogon_s4u2proxytarget,
9631           { "S4U2proxyTarget", "netlogon.s4u2proxytarget", FT_STRING, BASE_NONE,
9632             NULL, 0, "Target for constrained delegation using s4u2proxy", HFILL }},
9633         { &hf_netlogon_transitedlistsize,
9634           { "TransitedListSize", "netlogon.transited_list_size", FT_UINT32, BASE_HEX,
9635             NULL, 0x0, "Number of elements in the TransitedServices array.", HFILL }},
9636         { &hf_netlogon_transited_service,
9637           { "Transited Service", "netlogon.transited_service", FT_STRING, BASE_NONE,
9638             NULL, 0, "S4U2 Transited Service name", HFILL }},
9639         { &hf_netlogon_logon_duration,
9640           { "Duration", "netlogon.logon_duration", FT_UINT32, BASE_DEC,
9641             NULL, 0x0, NULL, HFILL }},
9642         { &hf_netlogon_time_created,
9643           { "Time Created", "netlogon.time_created", FT_UINT32, BASE_DEC,
9644             NULL, 0x0, NULL, HFILL }},
9645     };
9646 
9647     static gint *ett[] = {
9648         &ett_dcerpc_netlogon,
9649         &ett_authenticate_flags,
9650         &ett_CYPHER_VALUE,
9651         &ett_QUOTA_LIMITS,
9652         &ett_IDENTITY_INFO,
9653         &ett_DELTA_ENUM,
9654         &ett_UNICODE_MULTI,
9655         &ett_DOMAIN_CONTROLLER_INFO,
9656         &ett_UNICODE_STRING_512,
9657         &ett_TYPE_50,
9658         &ett_TYPE_52,
9659         &ett_DELTA_ID_UNION,
9660         &ett_TYPE_44,
9661         &ett_DELTA_UNION,
9662         &ett_LM_OWF_PASSWORD,
9663         &ett_NT_OWF_PASSWORD,
9664         &ett_GROUP_MEMBERSHIP,
9665         &ett_DS_DOMAIN_TRUSTS,
9666         &ett_BLOB,
9667         &ett_DOMAIN_TRUST_INFO,
9668         &ett_LSA_POLICY_INFO,
9669         &ett_trust_flags,
9670         &ett_trust_attribs,
9671         &ett_get_dcname_request_flags,
9672         &ett_dc_flags,
9673         &ett_secchan_nl_auth_message,
9674         &ett_secchan_nl_auth_message_flags,
9675         &ett_secchan_verf,
9676         &ett_group_attrs,
9677         &ett_user_flags,
9678         &ett_nt_counted_longs_as_string,
9679         &ett_user_account_control,
9680         &ett_wstr_LOGON_IDENTITY_INFO_string,
9681         &ett_domain_group_memberships,
9682         &ett_domains_group_memberships,
9683     };
9684     static ei_register_info ei[] = {
9685      { &ei_netlogon_auth_nthash, {
9686        "netlogon.authenticated", PI_SECURITY, PI_CHAT,
9687        "Authenticated NTHASH", EXPFILL
9688      }},
9689      { &ei_netlogon_session_key, {
9690        "netlogon.sessionkey", PI_SECURITY, PI_CHAT,
9691        "SessionKey", EXPFILL
9692      }},
9693     };
9694     expert_module_t* expert_netlogon;
9695 
9696     proto_dcerpc_netlogon = proto_register_protocol("Microsoft Network Logon", "RPC_NETLOGON", "rpc_netlogon");
9697 
9698     proto_register_field_array(proto_dcerpc_netlogon, hf, array_length(hf));
9699     proto_register_subtree_array(ett, array_length(ett));
9700     expert_netlogon = expert_register_protocol(proto_dcerpc_netlogon);
9701     expert_register_field_array(expert_netlogon, ei, array_length(ei));
9702 
9703     netlogon_auths = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), netlogon_auth_hash, netlogon_auth_equal);
9704 #if 0
9705     schannel_auths = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), netlogon_auth_hash, netlogon_auth_equal);
9706 #endif
9707 }
9708 
9709 static dcerpc_auth_subdissector_fns secchan_auth_fns = {
9710     dissect_secchan_nl_auth_message,    /* Bind */
9711     dissect_secchan_nl_auth_message,    /* Bind ACK */
9712     NULL,                               /* AUTH3 */
9713     dissect_request_secchan_verf,       /* Request verifier */
9714     dissect_response_secchan_verf,      /* Response verifier */
9715     dissect_request_data,               /* Request data */
9716     dissect_response_data               /* Response data */
9717 };
9718 
9719 void
proto_reg_handoff_dcerpc_netlogon(void)9720 proto_reg_handoff_dcerpc_netlogon(void)
9721 {
9722     /* Register protocol as dcerpc */
9723     seen.isseen = FALSE;
9724     seen.num = 0;
9725     dcerpc_init_uuid(proto_dcerpc_netlogon, ett_dcerpc_netlogon,
9726                      &uuid_dcerpc_netlogon, ver_dcerpc_netlogon,
9727                      dcerpc_netlogon_dissectors, hf_netlogon_opnum);
9728 
9729 
9730     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
9731                                       DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN,
9732                                       &secchan_auth_fns);
9733     register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
9734                                       DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN,
9735                                       &secchan_auth_fns);
9736 }
9737 
9738 /*
9739  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
9740  *
9741  * Local variables:
9742  * c-basic-offset: 4
9743  * tab-width: 8
9744  * indent-tabs-mode: nil
9745  * End:
9746  *
9747  * vi: set shiftwidth=4 tabstop=8 expandtab:
9748  * :indentSize=4:tabSize=8:noTabs=true:
9749  */
9750