OK, I'm impatient. In case of problems, I'm to blame, not Olivier.
[obnox/wireshark/wip.git] / packet-dcerpc-netlogon.c
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  * $Id: packet-dcerpc-netlogon.c,v 1.97 2004/03/05 23:12:09 sahlberg Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <glib.h>
32 #include <epan/packet.h>
33 #include "packet-dcerpc.h"
34 #include "packet-dcerpc-nt.h"
35 #include "packet-dcerpc-netlogon.h"
36 #include "smb.h"        /* for "NT_errors[]" */
37 #include "packet-smb-common.h"
38 #include "packet-dcerpc-lsa.h"
39
40 static int proto_dcerpc_netlogon = -1;
41 static int hf_netlogon_opnum = -1;
42 static int hf_netlogon_guid = -1;
43 static int hf_netlogon_rc = -1;
44 static int hf_netlogon_len = -1;
45 static int hf_netlogon_sensitive_data_flag = -1;
46 static int hf_netlogon_sensitive_data_len = -1;
47 static int hf_netlogon_sensitive_data = -1;
48 static int hf_netlogon_security_information = -1;
49 static int hf_netlogon_dummy = -1;
50 static int hf_netlogon_neg_flags = -1;
51 static int hf_netlogon_minworkingsetsize = -1;
52 static int hf_netlogon_maxworkingsetsize = -1;
53 static int hf_netlogon_pagedpoollimit = -1;
54 static int hf_netlogon_pagefilelimit = -1;
55 static int hf_netlogon_timelimit = -1;
56 static int hf_netlogon_nonpagedpoollimit = -1;
57 static int hf_netlogon_pac_size = -1;
58 static int hf_netlogon_pac_data = -1;
59 static int hf_netlogon_auth_size = -1;
60 static int hf_netlogon_auth_data = -1;
61 static int hf_netlogon_cipher_len = -1;
62 static int hf_netlogon_cipher_maxlen = -1;
63 static int hf_netlogon_cipher_current_data = -1;
64 static int hf_netlogon_cipher_current_set_time = -1;
65 static int hf_netlogon_cipher_old_data = -1;
66 static int hf_netlogon_cipher_old_set_time = -1;
67 static int hf_netlogon_priv = -1;
68 static int hf_netlogon_privilege_entries = -1;
69 static int hf_netlogon_privilege_control = -1;
70 static int hf_netlogon_privilege_name = -1;
71 static int hf_netlogon_systemflags = -1;
72 static int hf_netlogon_pdc_connection_status = -1;
73 static int hf_netlogon_tc_connection_status = -1;
74 static int hf_netlogon_restart_state = -1;
75 static int hf_netlogon_attrs = -1;
76 static int hf_netlogon_count = -1;
77 static int hf_netlogon_entries = -1;
78 static int hf_netlogon_minpasswdlen = -1;
79 static int hf_netlogon_passwdhistorylen = -1;
80 static int hf_netlogon_level16 = -1;
81 static int hf_netlogon_validation_level = -1;
82 static int hf_netlogon_reference = -1;
83 static int hf_netlogon_next_reference = -1;
84 static int hf_netlogon_timestamp = -1;
85 static int hf_netlogon_level = -1;
86 static int hf_netlogon_challenge = -1;
87 static int hf_netlogon_reserved = -1;
88 static int hf_netlogon_audit_retention_period = -1;
89 static int hf_netlogon_auditing_mode = -1;
90 static int hf_netlogon_max_audit_event_count = -1;
91 static int hf_netlogon_event_audit_option = -1;
92 static int hf_netlogon_unknown_string = -1;
93 static int hf_netlogon_unknown_long = -1;
94 static int hf_netlogon_unknown_short = -1;
95 static int hf_netlogon_unknown_char = -1;
96 static int hf_netlogon_logon_time = -1;
97 static int hf_netlogon_logoff_time = -1;
98 static int hf_netlogon_kickoff_time = -1;
99 static int hf_netlogon_pwd_last_set_time = -1;
100 static int hf_netlogon_pwd_can_change_time = -1;
101 static int hf_netlogon_pwd_must_change_time = -1;
102 static int hf_netlogon_nt_chal_resp = -1;
103 static int hf_netlogon_lm_chal_resp = -1;
104 static int hf_netlogon_credential = -1;
105 static int hf_netlogon_acct_name = -1;
106 static int hf_netlogon_acct_desc = -1;
107 static int hf_netlogon_group_desc = -1;
108 static int hf_netlogon_full_name = -1;
109 static int hf_netlogon_comment = -1;
110 static int hf_netlogon_parameters = -1;
111 static int hf_netlogon_logon_script = -1;
112 static int hf_netlogon_profile_path = -1;
113 static int hf_netlogon_home_dir = -1;
114 static int hf_netlogon_dir_drive = -1;
115 static int hf_netlogon_logon_count = -1;
116 static int hf_netlogon_logon_count16 = -1;
117 static int hf_netlogon_bad_pw_count = -1;
118 static int hf_netlogon_bad_pw_count16 = -1;
119 static int hf_netlogon_user_rid = -1;
120 static int hf_netlogon_alias_rid = -1;
121 static int hf_netlogon_group_rid = -1;
122 static int hf_netlogon_logon_srv = -1;
123 static int hf_netlogon_principal = -1;
124 static int hf_netlogon_logon_dom = -1;
125 static int hf_netlogon_resourcegroupdomainsid = -1;
126 static int hf_netlogon_resourcegroupcount = -1;
127 static int hf_netlogon_downlevel_domain_name = -1;
128 static int hf_netlogon_dns_domain_name = -1;
129 static int hf_netlogon_domain_name = -1;
130 static int hf_netlogon_domain_create_time = -1;
131 static int hf_netlogon_domain_modify_time = -1;
132 static int hf_netlogon_modify_count = -1;
133 static int hf_netlogon_db_modify_time = -1;
134 static int hf_netlogon_db_create_time = -1;
135 static int hf_netlogon_oem_info = -1;
136 static int hf_netlogon_serial_number = -1;
137 static int hf_netlogon_num_rids = -1;
138 static int hf_netlogon_num_trusts = -1;
139 static int hf_netlogon_num_controllers = -1;
140 static int hf_netlogon_num_other_groups = -1;
141 static int hf_netlogon_computer_name = -1;
142 static int hf_netlogon_site_name = -1;
143 static int hf_netlogon_trusted_dc_name = -1;
144 static int hf_netlogon_dc_name = -1;
145 static int hf_netlogon_dc_site_name = -1;
146 static int hf_netlogon_dns_forest_name = -1;
147 static int hf_netlogon_dc_address = -1;
148 static int hf_netlogon_dc_address_type = -1;
149 static int hf_netlogon_client_site_name = -1;
150 static int hf_netlogon_workstation = -1;
151 static int hf_netlogon_workstation_site_name = -1;
152 static int hf_netlogon_workstation_os = -1;
153 static int hf_netlogon_workstations = -1;
154 static int hf_netlogon_workstation_fqdn = -1;
155 static int hf_netlogon_group_name = -1;
156 static int hf_netlogon_alias_name = -1;
157 static int hf_netlogon_country = -1;
158 static int hf_netlogon_codepage = -1;
159 static int hf_netlogon_flags = -1;
160 static int hf_netlogon_trust_attribs = -1;
161 static int hf_netlogon_trust_type = -1;
162 static int hf_netlogon_trust_flags = -1;
163 static int hf_netlogon_trust_flags_inbound = -1;
164 static int hf_netlogon_trust_flags_outbound = -1;
165 static int hf_netlogon_trust_flags_in_forest = -1;
166 static int hf_netlogon_trust_flags_native_mode = -1;
167 static int hf_netlogon_trust_flags_primary = -1;
168 static int hf_netlogon_trust_flags_tree_root = -1;
169 static int hf_netlogon_trust_parent_index = -1;
170 static int hf_netlogon_user_flags = -1;
171 static int hf_netlogon_auth_flags = -1;
172 static int hf_netlogon_pwd_expired = -1;
173 static int hf_netlogon_nt_pwd_present = -1;
174 static int hf_netlogon_lm_pwd_present = -1;
175 static int hf_netlogon_code = -1;
176 static int hf_netlogon_database_id = -1;
177 static int hf_netlogon_sync_context = -1;
178 static int hf_netlogon_max_size = -1;
179 static int hf_netlogon_max_log_size = -1;
180 static int hf_netlogon_dns_host = -1;
181 static int hf_netlogon_acct_expiry_time = -1;
182 static int hf_netlogon_encrypted_lm_owf_password = -1;
183 static int hf_netlogon_lm_owf_password = -1;
184 static int hf_netlogon_nt_owf_password = -1;
185 static int hf_netlogon_param_ctrl = -1;
186 static int hf_netlogon_logon_id = -1;
187 static int hf_netlogon_num_deltas = -1;
188 static int hf_netlogon_user_session_key = -1;
189 static int hf_netlogon_blob_size = -1;
190 static int hf_netlogon_blob = -1;
191 static int hf_netlogon_logon_attempts = -1;
192 static int hf_netlogon_authoritative = -1;
193 static int hf_netlogon_secure_channel_type = -1;
194 static int hf_netlogon_logonsrv_handle = -1;
195 static int hf_netlogon_delta_type = -1;
196 static int hf_netlogon_get_dcname_request_flags = -1;
197 static int hf_netlogon_get_dcname_request_flags_force_rediscovery = -1;
198 static int hf_netlogon_get_dcname_request_flags_directory_service_required = -1;
199 static int hf_netlogon_get_dcname_request_flags_directory_service_preferred = -1;
200 static int hf_netlogon_get_dcname_request_flags_gc_server_required = -1;
201 static int hf_netlogon_get_dcname_request_flags_pdc_required = -1;
202 static int hf_netlogon_get_dcname_request_flags_background_only = -1;
203 static int hf_netlogon_get_dcname_request_flags_ip_required = -1;
204 static int hf_netlogon_get_dcname_request_flags_kdc_required = -1;
205 static int hf_netlogon_get_dcname_request_flags_timeserv_required = -1;
206 static int hf_netlogon_get_dcname_request_flags_writable_required = -1;
207 static int hf_netlogon_get_dcname_request_flags_good_timeserv_preferred = -1;
208 static int hf_netlogon_get_dcname_request_flags_avoid_self = -1;
209 static int hf_netlogon_get_dcname_request_flags_only_ldap_needed = -1;
210 static int hf_netlogon_get_dcname_request_flags_is_flat_name = -1;
211 static int hf_netlogon_get_dcname_request_flags_is_dns_name = -1;
212 static int hf_netlogon_get_dcname_request_flags_return_dns_name = -1;
213 static int hf_netlogon_get_dcname_request_flags_return_flat_name = -1;
214 static int hf_netlogon_dc_flags = -1;
215 static int hf_netlogon_dc_flags_pdc_flag = -1;
216 static int hf_netlogon_dc_flags_gc_flag = -1;
217 static int hf_netlogon_dc_flags_ldap_flag = -1;
218 static int hf_netlogon_dc_flags_ds_flag = -1;
219 static int hf_netlogon_dc_flags_kdc_flag = -1;
220 static int hf_netlogon_dc_flags_timeserv_flag = -1;
221 static int hf_netlogon_dc_flags_closest_flag = -1;
222 static int hf_netlogon_dc_flags_writable_flag = -1;
223 static int hf_netlogon_dc_flags_good_timeserv_flag = -1;
224 static int hf_netlogon_dc_flags_ndnc_flag = -1;
225 static int hf_netlogon_dc_flags_dns_controller_flag = -1;
226 static int hf_netlogon_dc_flags_dns_domain_flag = -1;
227 static int hf_netlogon_dc_flags_dns_forest_flag = -1;
228
229 static gint ett_dcerpc_netlogon = -1;
230 static gint ett_QUOTA_LIMITS = -1;
231 static gint ett_IDENTITY_INFO = -1;
232 static gint ett_DELTA_ENUM = -1;
233 static gint ett_CYPHER_VALUE = -1;
234 static gint ett_UNICODE_MULTI = -1;
235 static gint ett_DOMAIN_CONTROLLER_INFO = -1;
236 static gint ett_UNICODE_STRING_512 = -1;
237 static gint ett_TYPE_50 = -1;
238 static gint ett_TYPE_52 = -1;
239 static gint ett_DELTA_ID_UNION = -1;
240 static gint ett_TYPE_44 = -1;
241 static gint ett_DELTA_UNION = -1;
242 static gint ett_LM_OWF_PASSWORD = -1;
243 static gint ett_NT_OWF_PASSWORD = -1;
244 static gint ett_GROUP_MEMBERSHIP = -1;
245 static gint ett_BLOB = -1;
246 static gint ett_DS_DOMAIN_TRUSTS = -1;
247 static gint ett_DOMAIN_TRUST_INFO = -1;
248 static gint ett_trust_flags = -1;
249 static gint ett_get_dcname_request_flags = -1;
250 static gint ett_dc_flags = -1;
251
252 static e_uuid_t uuid_dcerpc_netlogon = {
253         0x12345678, 0x1234, 0xabcd,
254         { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0xcf, 0xfb }
255 };
256
257 static guint16 ver_dcerpc_netlogon = 1;
258
259
260
261 static int
262 netlogon_dissect_LOGONSRV_HANDLE(tvbuff_t *tvb, int offset,
263                         packet_info *pinfo, proto_tree *tree,
264                         guint8 *drep)
265 {
266         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
267                 NDR_POINTER_UNIQUE, "Server Handle", 
268                 hf_netlogon_logonsrv_handle, 0);
269
270         return offset;
271 }
272
273 /*
274  * IDL typedef struct {
275  * IDL    [unique][string] wchar_t *effective_name;
276  * IDL    long priv;
277  * IDL    long auth_flags;
278  * IDL    long logon_count;
279  * IDL    long bad_pw_count;
280  * IDL    long last_logon;
281  * IDL    long last_logoff;
282  * IDL    long logoff_time;
283  * IDL    long kickoff_time;
284  * IDL    long password_age;
285  * IDL    long pw_can_change;
286  * IDL    long pw_must_change;
287  * IDL    [unique][string] wchar_t *computer;
288  * IDL    [unique][string] wchar_t *domain;
289  * IDL    [unique][string] wchar_t *script_path;
290  * IDL    long reserved;
291  */
292 static int
293 netlogon_dissect_VALIDATION_UAS_INFO(tvbuff_t *tvb, int offset,
294                         packet_info *pinfo, proto_tree *tree,
295                         guint8 *drep)
296 {
297         dcerpc_info *di;
298
299         di=pinfo->private_data;
300         if(di->conformant_run){
301                 /*just a run to handle conformant arrays, nothing to dissect */
302                 return offset;
303         }
304
305         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
306                 NDR_POINTER_UNIQUE, "Effective Account", 
307                 hf_netlogon_acct_name, 0);
308
309         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
310                 hf_netlogon_priv, NULL);
311
312         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
313                 hf_netlogon_auth_flags, NULL);
314
315         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
316                 hf_netlogon_logon_count, NULL);
317
318         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
319                 hf_netlogon_bad_pw_count, NULL);
320
321         /* XXX - are these all UNIX "time_t"s, like the time stamps in
322            credentials?
323
324            Or are they, as per some RAP-based operations, UTIMEs? */
325         proto_tree_add_text(tree, tvb, offset, 4, "Last Logon: unknown time format");
326         offset+= 4;
327
328         proto_tree_add_text(tree, tvb, offset, 4, "Last Logoff: unknown time format");
329         offset+= 4;
330
331         proto_tree_add_text(tree, tvb, offset, 4, "Logoff Time: unknown time format");
332         offset+= 4;
333
334         proto_tree_add_text(tree, tvb, offset, 4, "Kickoff Time: unknown time format");
335         offset+= 4;
336
337         proto_tree_add_text(tree, tvb, offset, 4, "Password Age: unknown time format");
338         offset+= 4;
339
340         proto_tree_add_text(tree, tvb, offset, 4, "PW Can Change: unknown time format");
341         offset+= 4;
342
343         proto_tree_add_text(tree, tvb, offset, 4, "PW Must Change: unknown time format");
344         offset+= 4;
345
346         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
347                 NDR_POINTER_UNIQUE, "Computer", hf_netlogon_computer_name, 0);
348
349         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
350                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_domain_name, 0);
351
352         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
353                 NDR_POINTER_UNIQUE, "Script", hf_netlogon_logon_script, 0);
354
355         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
356                 hf_netlogon_reserved, NULL);
357
358         return offset;
359 }
360
361 /*
362  * IDL long NetrLogonUasLogon(
363  * IDL      [in][unique][string] wchar_t *ServerName,
364  * IDL      [in][ref][string] wchar_t *UserName,
365  * IDL      [in][ref][string] wchar_t *Workstation,
366  * IDL      [out][unique] VALIDATION_UAS_INFO *info
367  * IDL );
368  */
369 static int
370 netlogon_dissect_netrlogonuaslogon_rqst(tvbuff_t *tvb, int offset,
371         packet_info *pinfo, proto_tree *tree, guint8 *drep)
372 {
373         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
374                 pinfo, tree, drep);
375
376         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
377                 NDR_POINTER_REF, "Account", hf_netlogon_acct_name, 0);
378
379         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
380                 NDR_POINTER_REF, "Workstation", hf_netlogon_workstation, 0);
381
382         return offset;
383 }
384
385
386 static int
387 netlogon_dissect_netrlogonuaslogon_reply(tvbuff_t *tvb, int offset,
388         packet_info *pinfo, proto_tree *tree, guint8 *drep)
389 {
390         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
391                 netlogon_dissect_VALIDATION_UAS_INFO, NDR_POINTER_UNIQUE,
392                 "VALIDATION_UAS_INFO", -1);
393
394         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
395                                   hf_netlogon_rc, NULL);
396
397         return offset;
398 }
399
400 /*
401  * IDL typedef struct {
402  * IDL   long duration;
403  * IDL   short logon_count;
404  * IDL } LOGOFF_UAS_INFO;
405  */
406 static int
407 netlogon_dissect_LOGOFF_UAS_INFO(tvbuff_t *tvb, int offset,
408                         packet_info *pinfo, proto_tree *tree,
409                         guint8 *drep)
410 {
411         dcerpc_info *di;
412
413         di=pinfo->private_data;
414         if(di->conformant_run){
415                 /*just a run to handle conformant arrays, nothing to dissect */
416                 return offset;
417         }
418
419         proto_tree_add_text(tree, tvb, offset, 4, "Duration: unknown time format");
420         offset+= 4;
421
422         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
423                 hf_netlogon_logon_count16, NULL);
424
425         return offset;
426 }
427
428 /*
429  * IDL long NetrLogonUasLogoff(
430  * IDL      [in][unique][string] wchar_t *ServerName,
431  * IDL      [in][ref][string] wchar_t *UserName,
432  * IDL      [in][ref][string] wchar_t *Workstation,
433  * IDL      [out][ref] LOGOFF_UAS_INFO *info
434  * IDL );
435  */
436 static int
437 netlogon_dissect_netrlogonuaslogoff_rqst(tvbuff_t *tvb, int offset,
438         packet_info *pinfo, proto_tree *tree, guint8 *drep)
439 {
440         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
441                 pinfo, tree, drep);
442
443         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
444                 NDR_POINTER_REF, "Account", hf_netlogon_acct_name, 0);
445
446         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
447                 NDR_POINTER_REF, "Workstation", hf_netlogon_workstation, 0);
448
449         return offset;
450 }
451
452
453 static int
454 netlogon_dissect_netrlogonuaslogoff_reply(tvbuff_t *tvb, int offset,
455         packet_info *pinfo, proto_tree *tree, guint8 *drep)
456 {
457         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
458                 netlogon_dissect_LOGOFF_UAS_INFO, NDR_POINTER_REF,
459                 "LOGOFF_UAS_INFO", -1);
460
461         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
462                                   hf_netlogon_rc, NULL);
463
464         return offset;
465 }
466
467
468
469
470 /*
471  * IDL typedef struct {
472  * IDL   UNICODESTRING LogonDomainName;
473  * IDL   long ParameterControl;
474  * IDL   uint64 LogonID;
475  * IDL   UNICODESTRING UserName;
476  * IDL   UNICODESTRING Workstation;
477  * IDL } LOGON_IDENTITY_INFO;
478  */
479 static int
480 netlogon_dissect_LOGON_IDENTITY_INFO(tvbuff_t *tvb, int offset,
481                         packet_info *pinfo, proto_tree *parent_tree,
482                         guint8 *drep)
483 {
484         proto_item *item=NULL;
485         proto_tree *tree=NULL;
486         int old_offset=offset;
487
488         if(parent_tree){
489                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
490                         "IDENTITY_INFO:");
491                 tree = proto_item_add_subtree(item, ett_IDENTITY_INFO);
492         }
493
494         /* XXX: It would be nice to get the domain and account name 
495            displayed in COL_INFO. */
496
497         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
498                 hf_netlogon_logon_dom, 0);
499
500         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
501                 hf_netlogon_param_ctrl, NULL);
502
503         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
504                 hf_netlogon_logon_id, NULL);
505
506         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
507                 hf_netlogon_acct_name, 0);
508
509         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
510                 hf_netlogon_workstation, 0);
511
512 #ifdef REMOVED
513         /* NetMon does not recognize these bytes. Ill comment them out until someone complains */
514         /* XXX 8 extra bytes here */
515         /* there were 8 extra bytes, either here or in NETWORK_INFO that does not match
516            the idl file. Could be a bug in either the NETLOGON implementation or in the
517            idl file.
518         */
519         offset = netlogon_dissect_8_unknown_bytes(tvb, offset, pinfo, tree, drep);
520 #endif
521
522         proto_item_set_len(item, offset-old_offset);
523         return offset;
524 }
525
526
527 /*
528  * IDL typedef struct {
529  * IDL   char password[16];
530  * IDL } LM_OWF_PASSWORD;
531  */
532 static int
533 netlogon_dissect_LM_OWF_PASSWORD(tvbuff_t *tvb, int offset,
534                         packet_info *pinfo, proto_tree *parent_tree,
535                         guint8 *drep _U_)
536 {
537         proto_item *item=NULL;
538         proto_tree *tree=NULL;
539         dcerpc_info *di;
540
541         di=pinfo->private_data;
542         if(di->conformant_run){
543                 /*just a run to handle conformant arrays, nothing to dissect.*/
544                 return offset;
545         }
546
547         if(parent_tree){
548                 item = proto_tree_add_text(parent_tree, tvb, offset, 16,
549                         "LM_OWF_PASSWORD:");
550                 tree = proto_item_add_subtree(item, ett_LM_OWF_PASSWORD);
551         }
552
553         proto_tree_add_item(tree, hf_netlogon_lm_owf_password, tvb, offset, 16,
554                 FALSE);
555         offset += 16;
556
557         return offset;
558 }
559
560 /*
561  * IDL typedef struct {
562  * IDL   char password[16];
563  * IDL } NT_OWF_PASSWORD;
564  */
565 static int
566 netlogon_dissect_NT_OWF_PASSWORD(tvbuff_t *tvb, int offset,
567                         packet_info *pinfo, proto_tree *parent_tree,
568                         guint8 *drep _U_)
569 {
570         proto_item *item=NULL;
571         proto_tree *tree=NULL;
572         dcerpc_info *di;
573
574         di=pinfo->private_data;
575         if(di->conformant_run){
576                 /*just a run to handle conformant arrays, nothing to dissect.*/
577                 return offset;
578         }
579
580         if(parent_tree){
581                 item = proto_tree_add_text(parent_tree, tvb, offset, 16,
582                         "NT_OWF_PASSWORD:");
583                 tree = proto_item_add_subtree(item, ett_NT_OWF_PASSWORD);
584         }
585
586         proto_tree_add_item(tree, hf_netlogon_nt_owf_password, tvb, offset, 16,
587                 FALSE);
588         offset += 16;
589
590         return offset;
591 }
592
593
594 /*
595  * IDL typedef struct {
596  * IDL   LOGON_IDENTITY_INFO identity_info;
597  * IDL   LM_OWF_PASSWORD lmpassword;
598  * IDL   NT_OWF_PASSWORD ntpassword;
599  * IDL } INTERACTIVE_INFO;
600  */
601 static int
602 netlogon_dissect_INTERACTIVE_INFO(tvbuff_t *tvb, int offset,
603                         packet_info *pinfo, proto_tree *tree,
604                         guint8 *drep)
605 {
606         offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
607                 pinfo, tree, drep);
608
609         offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
610                 pinfo, tree, drep);
611
612         offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
613                 pinfo, tree, drep);
614
615         return offset;
616 }
617
618 /*
619  * IDL typedef struct {
620  * IDL   char chl[8];
621  * IDL } CHALLENGE;
622  */
623 static int
624 netlogon_dissect_CHALLENGE(tvbuff_t *tvb, int offset,
625                         packet_info *pinfo, proto_tree *tree,
626                         guint8 *drep _U_)
627 {
628         dcerpc_info *di;
629
630         di=pinfo->private_data;
631         if(di->conformant_run){
632                 /*just a run to handle conformant arrays, nothing to dissect.*/
633                 return offset;
634         }
635
636         proto_tree_add_item(tree, hf_netlogon_challenge, tvb, offset, 8,
637                 FALSE);
638         offset += 8;
639
640         return offset;
641 }
642
643 /*
644  * IDL typedef struct {
645  * IDL   LOGON_IDENTITY_INFO logon_info;
646  * IDL   CHALLENGE chal;
647  * IDL   STRING ntchallengeresponse;
648  * IDL   STRING lmchallengeresponse;
649  * IDL } NETWORK_INFO;
650  */
651
652 static void dissect_nt_chal_resp_cb(packet_info *pinfo _U_, proto_tree *tree, 
653                                     proto_item *item _U_, tvbuff_t *tvb, 
654                                     int start_offset, int end_offset, 
655                                     void *callback_args _U_)
656 {
657         int len;
658
659         /* Skip over 3 guint32's in NDR format */
660
661         if (start_offset % 4)
662                 start_offset += 4 - (start_offset % 4);
663
664         start_offset += 12;
665         len = end_offset - start_offset;
666
667         /* Call ntlmv2 response dissector */
668
669         if (len > 24)
670                 dissect_ntlmv2_response(tvb, tree, start_offset, len);
671 }
672
673 static int
674 netlogon_dissect_NETWORK_INFO(tvbuff_t *tvb, int offset,
675                 packet_info *pinfo, proto_tree *tree,
676                 guint8 *drep)
677 {
678         offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
679                 pinfo, tree, drep);
680
681         offset = netlogon_dissect_CHALLENGE(tvb, offset,
682                 pinfo, tree, drep);
683
684         offset = dissect_ndr_counted_byte_array_cb(
685                 tvb, offset, pinfo, tree, drep, hf_netlogon_nt_chal_resp,
686                 dissect_nt_chal_resp_cb, NULL);
687
688         offset = dissect_ndr_counted_byte_array(tvb, offset, pinfo, tree, drep,
689                 hf_netlogon_lm_chal_resp);
690
691         return offset;
692 }
693
694 /*
695  * IDL typedef struct {
696  * IDL   LOGON_IDENTITY_INFO logon_info;
697  * IDL   LM_OWF_PASSWORD lmpassword;
698  * IDL   NT_OWF_PASSWORD ntpassword;
699  * IDL } SERVICE_INFO;
700  */
701 static int
702 netlogon_dissect_SERVICE_INFO(tvbuff_t *tvb, int offset,
703                 packet_info *pinfo, proto_tree *tree,
704                 guint8 *drep)
705 {
706         offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
707                 pinfo, tree, drep);
708
709         offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
710                 pinfo, tree, drep);
711
712         offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
713                 pinfo, tree, drep);
714
715         return offset;
716 }
717
718 /*
719  * IDL typedef [switch_type(short)] union {
720  * IDL    [case(1)][unique] INTERACTIVE_INFO *iinfo;
721  * IDL    [case(2)][unique] NETWORK_INFO *ninfo;
722  * IDL    [case(3)][unique] SERVICE_INFO *sinfo;
723  * IDL } LEVEL;
724  */
725 static int
726 netlogon_dissect_LEVEL(tvbuff_t *tvb, int offset,
727                         packet_info *pinfo, proto_tree *tree,
728                         guint8 *drep)
729 {
730         guint16 level;
731
732         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
733                 hf_netlogon_level16, &level);
734
735         ALIGN_TO_4_BYTES;
736         switch(level){
737         case 1:
738                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
739                         netlogon_dissect_INTERACTIVE_INFO, NDR_POINTER_UNIQUE,
740                         "INTERACTIVE_INFO:", -1);
741                 break;
742         case 2:
743                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
744                         netlogon_dissect_NETWORK_INFO, NDR_POINTER_UNIQUE,
745                         "NETWORK_INFO:", -1);
746                 break;
747         case 3:
748                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
749                         netlogon_dissect_SERVICE_INFO, NDR_POINTER_UNIQUE,
750                         "SERVICE_INFO:", -1);
751                 break;
752         }
753
754         return offset;
755 }
756
757 /*
758  * IDL typedef struct {
759  * IDL   char cred[8];
760  * IDL } CREDENTIAL;
761  */
762 static int
763 netlogon_dissect_CREDENTIAL(tvbuff_t *tvb, int offset,
764                         packet_info *pinfo, proto_tree *tree,
765                         guint8 *drep _U_)
766 {
767         dcerpc_info *di;
768
769         di=pinfo->private_data;
770         if(di->conformant_run){
771                 /*just a run to handle conformant arrays, nothing to dissect.*/
772                 return offset;
773         }
774
775         proto_tree_add_item(tree, hf_netlogon_credential, tvb, offset, 8,
776                 FALSE);
777         offset += 8;
778
779         return offset;
780 }
781
782
783 /*
784  * IDL typedef struct {
785  * IDL   CREDENTIAL cred;
786  * IDL   long timestamp;
787  * IDL } AUTHENTICATOR;
788  */
789 static int
790 netlogon_dissect_AUTHENTICATOR(tvbuff_t *tvb, int offset,
791                         packet_info *pinfo, proto_tree *tree,
792                         guint8 *drep)
793 {
794         dcerpc_info *di;
795         nstime_t ts;
796
797         di=pinfo->private_data;
798         if(di->conformant_run){
799                 /*just a run to handle conformant arrays, nothing to dissect */
800                 return offset;
801         }
802
803         offset = netlogon_dissect_CREDENTIAL(tvb, offset,
804                 pinfo, tree, drep);
805
806         /*
807          * XXX - this appears to be a UNIX time_t in some credentials, but
808          * appears to be random junk in other credentials.
809          * For example, it looks like a UNIX time_t in "credential"
810          * AUTHENTICATORs, but like random junk in "return_authenticator"
811          * AUTHENTICATORs.
812          */
813         ALIGN_TO_4_BYTES;
814         ts.secs = tvb_get_letohl(tvb, offset);
815         ts.nsecs = 0;
816         proto_tree_add_time(tree, hf_netlogon_timestamp, tvb, offset, 4, &ts);
817         offset+= 4;
818
819         return offset;
820 }
821
822
823 /*
824  * IDL typedef struct {
825  * IDL   long user_id;
826  * IDL   long attributes;
827  * IDL } GROUP_MEMBERSHIP;
828  */
829 static int
830 netlogon_dissect_GROUP_MEMBERSHIP(tvbuff_t *tvb, int offset,
831                         packet_info *pinfo, proto_tree *parent_tree,
832                         guint8 *drep)
833 {
834         proto_item *item=NULL;
835         proto_tree *tree=NULL;
836
837         if(parent_tree){
838                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
839                         "GROUP_MEMBERSHIP:");
840                 tree = proto_item_add_subtree(item, ett_GROUP_MEMBERSHIP);
841         }
842
843         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
844                 hf_netlogon_group_rid, NULL);
845
846         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
847                 hf_netlogon_attrs, NULL);
848
849         return offset;
850 }
851
852 static int
853 netlogon_dissect_GROUP_MEMBERSHIP_ARRAY(tvbuff_t *tvb, int offset,
854                         packet_info *pinfo, proto_tree *tree,
855                         guint8 *drep)
856 {
857         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
858                 netlogon_dissect_GROUP_MEMBERSHIP);
859
860         return offset;
861 }
862
863 /*
864  * IDL typedef struct {
865  * IDL   char user_session_key[16];
866  * IDL } USER_SESSION_KEY;
867  */
868 static int
869 netlogon_dissect_USER_SESSION_KEY(tvbuff_t *tvb, int offset,
870                         packet_info *pinfo, proto_tree *tree,
871                         guint8 *drep _U_)
872 {
873         dcerpc_info *di;
874
875         di=pinfo->private_data;
876         if(di->conformant_run){
877                 /*just a run to handle conformant arrays, nothing to dissect.*/
878                 return offset;
879         }
880
881         proto_tree_add_item(tree, hf_netlogon_user_session_key, tvb, offset, 16,
882                 FALSE);
883         offset += 16;
884
885         return offset;
886 }
887
888 /*
889  * IDL typedef struct {
890  * IDL   uint64 LogonTime;
891  * IDL   uint64 LogoffTime;
892  * IDL   uint64 KickOffTime;
893  * IDL   uint64 PasswdLastSet;
894  * IDL   uint64 PasswdCanChange;
895  * IDL   uint64 PasswdMustChange;
896  * IDL   unicodestring effectivename;
897  * IDL   unicodestring fullname;
898  * IDL   unicodestring logonscript;
899  * IDL   unicodestring profilepath;
900  * IDL   unicodestring homedirectory;
901  * IDL   unicodestring homedirectorydrive;
902  * IDL   short LogonCount;
903  * IDL   short BadPasswdCount;
904  * IDL   long userid;
905  * IDL   long primarygroup;
906  * IDL   long groupcount;
907  * IDL   [unique][size_is(groupcount)] GROUP_MEMBERSHIP *groupids;
908  * IDL   long userflags;
909  * IDL   USER_SESSION_KEY key;
910  * IDL   unicodestring logonserver;
911  * IDL   unicodestring domainname;
912  * IDL   [unique] SID logondomainid;
913  * IDL   long expansionroom[10];
914  * IDL } VALIDATION_SAM_INFO;
915  */
916 static int
917 netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
918                 packet_info *pinfo, proto_tree *tree,
919                 guint8 *drep)
920 {
921         int i;
922
923         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
924                 hf_netlogon_logon_time);
925
926         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
927                 hf_netlogon_logoff_time);
928
929         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
930                 hf_netlogon_kickoff_time);
931
932         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
933                 hf_netlogon_pwd_last_set_time);
934
935         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
936                 hf_netlogon_pwd_can_change_time);
937
938         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
939                 hf_netlogon_pwd_must_change_time);
940
941         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
942                 hf_netlogon_acct_name, 0);
943
944         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
945                 hf_netlogon_full_name, 0);
946
947         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
948                 hf_netlogon_logon_script, 0);
949
950         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
951                 hf_netlogon_profile_path, 0);
952
953         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
954                 hf_netlogon_home_dir, 0);
955
956         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
957                 hf_netlogon_dir_drive, 0);
958
959         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
960                 hf_netlogon_logon_count16, NULL);
961
962         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
963                 hf_netlogon_bad_pw_count16, NULL);
964
965         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
966                 hf_netlogon_user_rid, NULL);
967
968         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
969                 hf_netlogon_group_rid, NULL);
970
971         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
972                 hf_netlogon_num_rids, NULL);
973
974         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
975                 netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
976                 "GROUP_MEMBERSHIP_ARRAY", -1);
977
978         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
979                 hf_netlogon_user_flags, NULL);
980
981         offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
982                 pinfo, tree, drep);
983
984         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
985                 hf_netlogon_logon_srv, 0);
986
987         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
988                 hf_netlogon_logon_dom, 0);
989
990         offset = dissect_ndr_nt_PSID(tvb, offset,
991                 pinfo, tree, drep, -1);
992
993         for(i=0;i<10;i++){
994                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
995                         hf_netlogon_reserved, NULL);
996         }
997
998         return offset;
999 }
1000
1001
1002
1003 /*
1004  * IDL typedef struct {
1005  * IDL   uint64 LogonTime;
1006  * IDL   uint64 LogoffTime;
1007  * IDL   uint64 KickOffTime;
1008  * IDL   uint64 PasswdLastSet;
1009  * IDL   uint64 PasswdCanChange;
1010  * IDL   uint64 PasswdMustChange;
1011  * IDL   unicodestring effectivename;
1012  * IDL   unicodestring fullname;
1013  * IDL   unicodestring logonscript;
1014  * IDL   unicodestring profilepath;
1015  * IDL   unicodestring homedirectory;
1016  * IDL   unicodestring homedirectorydrive;
1017  * IDL   short LogonCount;
1018  * IDL   short BadPasswdCount;
1019  * IDL   long userid;
1020  * IDL   long primarygroup;
1021  * IDL   long groupcount;
1022  * IDL   [unique] GROUP_MEMBERSHIP *groupids;
1023  * IDL   long userflags;
1024  * IDL   USER_SESSION_KEY key;
1025  * IDL   unicodestring logonserver;
1026  * IDL   unicodestring domainname;
1027  * IDL   [unique] SID logondomainid;
1028  * IDL   long expansionroom[10];
1029  * IDL   long sidcount;
1030  * IDL   [unique] SID_AND_ATTRIBS;
1031  * IDL } VALIDATION_SAM_INFO2;
1032  */
1033 static int
1034 netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
1035                         packet_info *pinfo, proto_tree *tree,
1036                         guint8 *drep)
1037 {
1038         int i;
1039
1040         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1041                 hf_netlogon_logon_time);
1042
1043         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1044                 hf_netlogon_logoff_time);
1045
1046         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1047                 hf_netlogon_kickoff_time);
1048
1049         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1050                 hf_netlogon_pwd_last_set_time);
1051
1052         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1053                 hf_netlogon_pwd_can_change_time);
1054
1055         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1056                 hf_netlogon_pwd_must_change_time);
1057
1058         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1059                 hf_netlogon_acct_name, 0);
1060
1061         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1062                 hf_netlogon_full_name, 0);
1063
1064         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1065                 hf_netlogon_logon_script, 0);
1066
1067         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1068                 hf_netlogon_profile_path, 0);
1069
1070         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1071                 hf_netlogon_home_dir, 0);
1072
1073         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1074                 hf_netlogon_dir_drive, 0);
1075
1076         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1077                 hf_netlogon_logon_count16, NULL);
1078
1079         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1080                 hf_netlogon_bad_pw_count16, NULL);
1081
1082         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1083                 hf_netlogon_user_rid, NULL);
1084
1085         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1086                 hf_netlogon_group_rid, NULL);
1087
1088         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1089                 hf_netlogon_num_rids, NULL);
1090
1091         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1092                 netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
1093                 "GROUP_MEMBERSHIP_ARRAY", -1);
1094
1095         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1096                 hf_netlogon_user_flags, NULL);
1097
1098         offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
1099                 pinfo, tree, drep);
1100
1101         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1102                 hf_netlogon_logon_srv, 0);
1103
1104         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1105                 hf_netlogon_logon_dom, 0);
1106
1107         offset = dissect_ndr_nt_PSID(tvb, offset,
1108                 pinfo, tree, drep, -1);
1109
1110         for(i=0;i<10;i++){
1111                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1112                         hf_netlogon_unknown_long, NULL);
1113         }
1114
1115         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1116                 hf_netlogon_num_other_groups, NULL);
1117
1118         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1119                 dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
1120                 "SID_AND_ATTRIBUTES_ARRAY:", -1);
1121
1122         return offset;
1123 }
1124
1125
1126
1127
1128
1129 /*
1130  * IDL typedef struct {
1131  * IDL   uint64 LogonTime;
1132  * IDL   uint64 LogoffTime;
1133  * IDL   uint64 KickOffTime;
1134  * IDL   uint64 PasswdLastSet;
1135  * IDL   uint64 PasswdCanChange;
1136  * IDL   uint64 PasswdMustChange;
1137  * IDL   unicodestring effectivename;
1138  * IDL   unicodestring fullname;
1139  * IDL   unicodestring logonscript;
1140  * IDL   unicodestring profilepath;
1141  * IDL   unicodestring homedirectory;
1142  * IDL   unicodestring homedirectorydrive;
1143  * IDL   short LogonCount;
1144  * IDL   short BadPasswdCount;
1145  * IDL   long userid;
1146  * IDL   long primarygroup;
1147  * IDL   long groupcount;
1148  * IDL   [unique] GROUP_MEMBERSHIP *groupids;
1149  * IDL   long userflags;
1150  * IDL   USER_SESSION_KEY key;
1151  * IDL   unicodestring logonserver;
1152  * IDL   unicodestring domainname;
1153  * IDL   [unique] SID logondomainid;
1154  * IDL   long expansionroom[10];
1155  * IDL   long sidcount;
1156  * IDL   [unique] SID_AND_ATTRIBS;
1157  * IDL   [unique] SID resourcegroupdomainsid;
1158  * IDL   long resourcegroupcount;
1159 qqq
1160  * IDL } PAC_LOGON_INFO;
1161  */
1162 int
1163 netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
1164                         packet_info *pinfo, proto_tree *tree,
1165                         guint8 *drep)
1166 {
1167         int i;
1168         guint32 rgc;
1169
1170         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1171                 hf_netlogon_logon_time);
1172
1173         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1174                 hf_netlogon_logoff_time);
1175
1176         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1177                 hf_netlogon_kickoff_time);
1178
1179         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1180                 hf_netlogon_pwd_last_set_time);
1181
1182         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1183                 hf_netlogon_pwd_can_change_time);
1184
1185         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1186                 hf_netlogon_pwd_must_change_time);
1187
1188         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1189                 hf_netlogon_acct_name, 0);
1190
1191         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1192                 hf_netlogon_full_name, 0);
1193
1194         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1195                 hf_netlogon_logon_script, 0);
1196
1197         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1198                 hf_netlogon_profile_path, 0);
1199
1200         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1201                 hf_netlogon_home_dir, 0);
1202
1203         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1204                 hf_netlogon_dir_drive, 0);
1205
1206         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1207                 hf_netlogon_logon_count16, NULL);
1208
1209         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1210                 hf_netlogon_bad_pw_count16, NULL);
1211
1212         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1213                 hf_netlogon_user_rid, NULL);
1214
1215         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1216                 hf_netlogon_group_rid, NULL);
1217
1218         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1219                 hf_netlogon_num_rids, NULL);
1220
1221         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1222                 netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
1223                 "GROUP_MEMBERSHIP_ARRAY", -1);
1224
1225         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1226                 hf_netlogon_user_flags, NULL);
1227
1228         offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
1229                 pinfo, tree, drep);
1230
1231         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1232                 hf_netlogon_logon_srv, 0);
1233
1234         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1235                 hf_netlogon_logon_dom, 0);
1236
1237         offset = dissect_ndr_nt_PSID(tvb, offset,
1238                 pinfo, tree, drep, -1);
1239
1240         for(i=0;i<10;i++){
1241                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1242                         hf_netlogon_unknown_long, NULL);
1243         }
1244
1245         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1246                 hf_netlogon_num_other_groups, NULL);
1247
1248         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1249                 dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
1250                 "SID_AND_ATTRIBUTES_ARRAY:", -1);
1251
1252         offset = dissect_ndr_nt_PSID(tvb, offset,
1253                 pinfo, tree, drep, hf_netlogon_resourcegroupdomainsid);
1254
1255         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1256                 hf_netlogon_resourcegroupcount, &rgc);
1257
1258         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1259                 netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
1260                 "ResourceGroupIDs", -1);
1261
1262         return offset;
1263 }
1264
1265
1266
1267 static int
1268 netlogon_dissect_PAC(tvbuff_t *tvb, int offset,
1269                         packet_info *pinfo, proto_tree *tree,
1270                         guint8 *drep _U_)
1271 {
1272         dcerpc_info *di;
1273         guint32 pac_size;
1274
1275         di=pinfo->private_data;
1276         if(di->conformant_run){
1277                 /*just a run to handle conformant arrays, nothing to dissect */
1278                 return offset;
1279         }
1280
1281         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1282                 hf_netlogon_pac_size, &pac_size);
1283
1284         proto_tree_add_item(tree, hf_netlogon_pac_data, tvb, offset, pac_size,
1285                 FALSE);
1286         offset += pac_size;
1287
1288         return offset;
1289 }
1290
1291 static int
1292 netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
1293                         packet_info *pinfo, proto_tree *tree,
1294                         guint8 *drep _U_)
1295 {
1296         dcerpc_info *di;
1297         guint32 auth_size;
1298
1299         di=pinfo->private_data;
1300         if(di->conformant_run){
1301                 /*just a run to handle conformant arrays, nothing to dissect */
1302                 return offset;
1303         }
1304
1305         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1306                 hf_netlogon_auth_size, &auth_size);
1307
1308         proto_tree_add_item(tree, hf_netlogon_auth_data, tvb, offset, auth_size,
1309                 FALSE);
1310         offset += auth_size;
1311
1312         return offset;
1313 }
1314
1315
1316 /*
1317  * IDL typedef struct {
1318  * IDL   long pac_size
1319  * IDL   [unique][size_is(pac_size)] char *pac;
1320  * IDL   UNICODESTRING logondomain;
1321  * IDL   UNICODESTRING logonserver;
1322  * IDL   UNICODESTRING principalname;
1323  * IDL   long auth_size;
1324  * IDL   [unique][size_is(auth_size)] char *auth;
1325  * IDL   USER_SESSION_KEY user_session_key;
1326  * IDL   long expansionroom[10];
1327  * IDL   UNICODESTRING dummy1;
1328  * IDL   UNICODESTRING dummy2;
1329  * IDL   UNICODESTRING dummy3;
1330  * IDL   UNICODESTRING dummy4;
1331  * IDL } VALIDATION_PAC_INFO;
1332  */
1333 static int
1334 netlogon_dissect_VALIDATION_PAC_INFO(tvbuff_t *tvb, int offset,
1335                         packet_info *pinfo, proto_tree *tree,
1336                         guint8 *drep)
1337 {
1338         int i;
1339
1340         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1341                 hf_netlogon_pac_size, NULL);
1342
1343         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1344                 netlogon_dissect_PAC, NDR_POINTER_UNIQUE, "PAC:", -1);
1345
1346         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1347                 hf_netlogon_logon_dom, 0);
1348
1349         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1350                 hf_netlogon_logon_srv, 0);
1351
1352         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1353                 hf_netlogon_principal, 0);
1354
1355         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1356                 hf_netlogon_auth_size, NULL);
1357
1358         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1359                 netlogon_dissect_AUTH, NDR_POINTER_UNIQUE, "AUTH:", -1);
1360
1361         offset = netlogon_dissect_USER_SESSION_KEY(tvb, offset,
1362                 pinfo, tree, drep);
1363
1364         for(i=0;i<10;i++){
1365                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1366                         hf_netlogon_unknown_long, NULL);
1367         }
1368
1369         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1370                 hf_netlogon_dummy, 0);
1371
1372         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1373                 hf_netlogon_dummy, 0);
1374
1375         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1376                 hf_netlogon_dummy, 0);
1377
1378         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1379                 hf_netlogon_dummy, 0);
1380
1381         return offset;
1382 }
1383
1384
1385 /*
1386  * IDL typedef [switch_type(short)] union {
1387  * IDL    [case(2)][unique] VALIDATION_SAM_INFO *sam;
1388  * IDL    [case(3)][unique] VALIDATION_SAM_INFO2 *sam2;
1389  * IDL    [case(4)][unique] VALIDATION_PAC_INFO *pac;
1390  * IDL    [case(5)][unique] VALIDATION_PAC_INFO *pac2;
1391  * IDL } VALIDATION;
1392  */
1393 static int
1394 netlogon_dissect_VALIDATION(tvbuff_t *tvb, int offset,
1395                         packet_info *pinfo, proto_tree *tree,
1396                         guint8 *drep)
1397 {
1398         guint16 level;
1399
1400         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1401                 hf_netlogon_validation_level, &level);
1402
1403         ALIGN_TO_4_BYTES;
1404         switch(level){
1405         case 2:
1406                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1407                         netlogon_dissect_VALIDATION_SAM_INFO, NDR_POINTER_UNIQUE,
1408                         "VALIDATION_SAM_INFO:", -1);
1409                 break;
1410         case 3:
1411                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1412                         netlogon_dissect_VALIDATION_SAM_INFO2, NDR_POINTER_UNIQUE,
1413                         "VALIDATION_SAM_INFO2:", -1);
1414                 break;
1415         case 4:
1416                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1417                         netlogon_dissect_VALIDATION_PAC_INFO, NDR_POINTER_UNIQUE,
1418                         "VALIDATION_PAC_INFO:", -1);
1419                 break;
1420         case 5:
1421                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1422                         netlogon_dissect_VALIDATION_PAC_INFO, NDR_POINTER_UNIQUE,
1423                         "VALIDATION_PAC_INFO:", -1);
1424                 break;
1425         }
1426
1427         return offset;
1428 }
1429
1430
1431 /*
1432  * IDL long NetrLogonSamLogon(
1433  * IDL      [in][unique][string] wchar_t *ServerName,
1434  * IDL      [in][unique][string] wchar_t *Workstation,
1435  * IDL      [in][unique] AUTHENTICATOR *credential,
1436  * IDL      [in][out][unique] AUTHENTICATOR *returnauthenticator,
1437  * IDL      [in] short LogonLevel,
1438  * IDL      [in][ref] LOGON_LEVEL *logonlevel,
1439  * IDL      [in] short ValidationLevel,
1440  * IDL      [out][ref] VALIDATION *validation,
1441  * IDL      [out][ref] boolean Authorative
1442  * IDL );
1443  */
1444 static int
1445 netlogon_dissect_netrlogonsamlogon_rqst(tvbuff_t *tvb, int offset,
1446         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1447 {
1448         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
1449                 pinfo, tree, drep);
1450
1451         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1452                 NDR_POINTER_UNIQUE, "Computer Name", 
1453                 hf_netlogon_computer_name, 0);
1454
1455         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1456                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
1457                 "AUTHENTICATOR: credential", -1);
1458
1459         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1460                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
1461                 "AUTHENTICATOR: return_authenticator", -1);
1462
1463         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1464                 hf_netlogon_level16, NULL);
1465
1466         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1467                 netlogon_dissect_LEVEL, NDR_POINTER_REF,
1468                 "LEVEL: LogonLevel", -1);
1469
1470         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1471                 hf_netlogon_validation_level, NULL);
1472
1473         return offset;
1474 }
1475
1476 static int
1477 netlogon_dissect_netrlogonsamlogon_reply(tvbuff_t *tvb, int offset,
1478         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1479 {
1480         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1481                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
1482                 "AUTHENTICATOR: return_authenticator", -1);
1483
1484         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1485                 netlogon_dissect_VALIDATION, NDR_POINTER_REF,
1486                 "VALIDATION:", -1);
1487
1488         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
1489                 hf_netlogon_authoritative, NULL);
1490
1491         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1492                                   hf_netlogon_rc, NULL);
1493
1494         return offset;
1495 }
1496
1497
1498 /*
1499  * IDL long NetrLogonSamLogoff(
1500  * IDL      [in][unique][string] wchar_t *ServerName,
1501  * IDL      [in][unique][string] wchar_t *ComputerName,
1502  * IDL      [in][unique] AUTHENTICATOR credential,
1503  * IDL      [in][unique] AUTHENTICATOR return_authenticator,
1504  * IDL      [in] short logon_level,
1505  * IDL      [in][ref] LEVEL logoninformation
1506  * IDL );
1507  */
1508 static int
1509 netlogon_dissect_netrlogonsamlogoff_rqst(tvbuff_t *tvb, int offset,
1510         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1511 {
1512         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
1513                 pinfo, tree, drep);
1514
1515         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1516                 NDR_POINTER_UNIQUE, "Computer Name", 
1517                 hf_netlogon_computer_name, 0);
1518
1519         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1520                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
1521                 "AUTHENTICATOR: credential", -1);
1522
1523         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1524                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
1525                 "AUTHENTICATOR: return_authenticator", -1);
1526
1527         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1528                 hf_netlogon_level16, NULL);
1529
1530         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1531                 netlogon_dissect_LEVEL, NDR_POINTER_REF,
1532                 "LEVEL: logoninformation", -1);
1533
1534         return offset;
1535 }
1536 static int
1537 netlogon_dissect_netrlogonsamlogoff_reply(tvbuff_t *tvb, int offset,
1538         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1539 {
1540
1541         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1542                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
1543                 "AUTHENTICATOR: return_authenticator", -1);
1544
1545         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1546                                   hf_netlogon_rc, NULL);
1547
1548         return offset;
1549 }
1550
1551
1552 /*
1553  * IDL long NetrServerReqChallenge(
1554  * IDL      [in][unique][string] wchar_t *ServerName,
1555  * IDL      [in][ref][string] wchar_t *ComputerName,
1556  * IDL      [in][ref] CREDENTIAL client_credential,
1557  * IDL      [out][ref] CREDENTIAL server_credential
1558  * IDL );
1559  */
1560 static int
1561 netlogon_dissect_netrserverreqchallenge_rqst(tvbuff_t *tvb, int offset,
1562         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1563 {
1564         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
1565                 pinfo, tree, drep);
1566
1567         offset = dissect_ndr_pointer_cb(
1568                 tvb, offset, pinfo, tree, drep, 
1569                 dissect_ndr_wchar_cvstring, NDR_POINTER_REF, 
1570                 "Computer Name", hf_netlogon_computer_name, 
1571                 cb_wstr_postprocess, 
1572                 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
1573
1574         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1575                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
1576                 "CREDENTIAL: client challenge", -1);
1577
1578         return offset;
1579 }
1580 static int
1581 netlogon_dissect_netrserverreqchallenge_reply(tvbuff_t *tvb, int offset,
1582         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1583 {
1584         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1585                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
1586                 "CREDENTIAL: server credential", -1);
1587
1588         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1589                                   hf_netlogon_rc, NULL);
1590
1591         return offset;
1592 }
1593
1594
1595 static int
1596 netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvbuff_t *tvb, int offset,
1597                         packet_info *pinfo, proto_tree *tree,
1598                         guint8 *drep)
1599 {
1600         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1601                         hf_netlogon_secure_channel_type, NULL);
1602
1603         return offset;
1604 }
1605
1606
1607 /*
1608  * IDL long NetrServerAuthenticate(
1609  * IDL      [in][unique][string] wchar_t *ServerName,
1610  * IDL      [in][ref][string] wchar_t *UserName,
1611  * IDL      [in] short secure_challenge_type,
1612  * IDL      [in][ref][string] wchar_t *ComputerName,
1613  * IDL      [in][ref] CREDENTIAL client_challenge,
1614  * IDL      [out][ref] CREDENTIAL server_challenge
1615  * IDL );
1616  */
1617 static int
1618 netlogon_dissect_netrserverauthenticate_rqst(tvbuff_t *tvb, int offset,
1619         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1620 {
1621         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
1622                 pinfo, tree, drep);
1623
1624         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1625                 NDR_POINTER_REF, "User Name", hf_netlogon_acct_name, 0);
1626
1627         offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
1628                 pinfo, tree, drep);
1629
1630         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1631                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
1632
1633         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1634                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
1635                 "CREDENTIAL: client challenge", -1);
1636
1637         return offset;
1638 }
1639 static int
1640 netlogon_dissect_netrserverauthenticate_reply(tvbuff_t *tvb, int offset,
1641         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1642 {
1643         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1644                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
1645                 "CREDENTIAL: server challenge", -1);
1646
1647         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1648                                   hf_netlogon_rc, NULL);
1649
1650         return offset;
1651 }
1652
1653
1654
1655 /*
1656  * IDL typedef struct {
1657  * IDL   char encrypted_password[16];
1658  * IDL } ENCRYPTED_LM_OWF_PASSWORD;
1659  */
1660 static int
1661 netlogon_dissect_ENCRYPTED_LM_OWF_PASSWORD(tvbuff_t *tvb, int offset,
1662                         packet_info *pinfo, proto_tree *tree,
1663                         guint8 *drep _U_)
1664 {
1665         dcerpc_info *di;
1666
1667         di=pinfo->private_data;
1668         if(di->conformant_run){
1669                 /*just a run to handle conformant arrays, nothing to dissect.*/
1670                 return offset;
1671         }
1672
1673         proto_tree_add_item(tree, hf_netlogon_encrypted_lm_owf_password, tvb, offset, 16,
1674                 FALSE);
1675         offset += 16;
1676
1677         return offset;
1678 }
1679
1680 /*
1681  * IDL long NetrServerPasswordSet(
1682  * IDL      [in][unique][string] wchar_t *ServerName,
1683  * IDL      [in][ref][string] wchar_t *UserName,
1684  * IDL      [in] short secure_challenge_type,
1685  * IDL      [in][ref][string] wchar_t *ComputerName,
1686  * IDL      [in][ref] AUTHENTICATOR credential,
1687  * IDL      [in][ref] LM_OWF_PASSWORD UasNewPassword,
1688  * IDL      [out][ref] AUTHENTICATOR return_authenticator
1689  * IDL );
1690  */
1691 static int
1692 netlogon_dissect_netrserverpasswordset_rqst(tvbuff_t *tvb, int offset,
1693         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1694 {
1695         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
1696                 pinfo, tree, drep);
1697
1698         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1699                 NDR_POINTER_REF, "User Name", hf_netlogon_acct_name, 0);
1700
1701         offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
1702                 pinfo, tree, drep);
1703
1704         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1705                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
1706
1707         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1708                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
1709                 "AUTHENTICATOR: credential", -1);
1710
1711         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1712                 netlogon_dissect_ENCRYPTED_LM_OWF_PASSWORD, NDR_POINTER_REF,
1713                 "ENCRYPTED_LM_OWF_PASSWORD: hashed_pwd", -1);
1714
1715         return offset;
1716 }
1717 static int
1718 netlogon_dissect_netrserverpasswordset_reply(tvbuff_t *tvb, int offset,
1719         packet_info *pinfo, proto_tree *tree, guint8 *drep)
1720 {
1721         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1722                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
1723                 "AUTHENTICATOR: return_authenticator", -1);
1724
1725         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1726                                   hf_netlogon_rc, NULL);
1727
1728         return offset;
1729 }
1730
1731
1732 /*
1733  * IDL typedef struct {
1734  * IDL   [unique][string] wchar_t *UserName;
1735  * IDL   UNICODESTRING dummy1;
1736  * IDL   UNICODESTRING dummy2;
1737  * IDL   UNICODESTRING dummy3;
1738  * IDL   UNICODESTRING dummy4;
1739  * IDL   long dummy5;
1740  * IDL   long dummy6;
1741  * IDL   long dummy7;
1742  * IDL   long dummy8;
1743  * IDL } DELTA_DELETE_USER;
1744  */
1745 static int
1746 netlogon_dissect_DELTA_DELETE_USER(tvbuff_t *tvb, int offset,
1747                         packet_info *pinfo, proto_tree *tree,
1748                         guint8 *drep)
1749 {
1750         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1751                 NDR_POINTER_UNIQUE, "Account Name", hf_netlogon_acct_name, 0);
1752
1753         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1754                 hf_netlogon_dummy, 0);
1755
1756         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1757                 hf_netlogon_dummy, 0);
1758
1759         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1760                 hf_netlogon_dummy, 0);
1761
1762         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1763                 hf_netlogon_dummy, 0);
1764
1765         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1766                 hf_netlogon_reserved, NULL);
1767
1768         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1769                 hf_netlogon_reserved, NULL);
1770
1771         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1772                 hf_netlogon_reserved, NULL);
1773
1774         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1775                 hf_netlogon_reserved, NULL);
1776
1777         return offset;
1778 }
1779
1780
1781 /*
1782  * IDL typedef struct {
1783  * IDL   bool SensitiveDataFlag;
1784  * IDL   long DataLength;
1785  * IDL   [unique][size_is(DataLength)] char *SensitiveData;
1786  * IDL } USER_PRIVATE_INFO;
1787  */
1788 static int
1789 netlogon_dissect_SENSITIVE_DATA(tvbuff_t *tvb, int offset,
1790                         packet_info *pinfo, proto_tree *tree,
1791                         guint8 *drep)
1792 {
1793         dcerpc_info *di;
1794         guint32 data_len;
1795
1796         di=pinfo->private_data;
1797         if(di->conformant_run){
1798                 /*just a run to handle conformant arrays, nothing to dissect */
1799                 return offset;
1800         }
1801
1802         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1803                 hf_netlogon_sensitive_data_len, &data_len);
1804
1805         proto_tree_add_item(tree, hf_netlogon_sensitive_data, tvb, offset,
1806                 data_len, FALSE);
1807         offset += data_len;
1808
1809         return offset;
1810 }
1811 static int
1812 netlogon_dissect_USER_PRIVATE_INFO(tvbuff_t *tvb, int offset,
1813                         packet_info *pinfo, proto_tree *tree,
1814                         guint8 *drep)
1815 {
1816         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
1817                 hf_netlogon_sensitive_data_flag, NULL);
1818
1819         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1820                 hf_netlogon_sensitive_data_len, NULL);
1821
1822         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1823                 netlogon_dissect_SENSITIVE_DATA, NDR_POINTER_UNIQUE,
1824                 "SENSITIVE_DATA", -1);
1825
1826         return offset;
1827 }
1828
1829 /*
1830  * IDL typedef struct {
1831  * IDL   UNICODESTRING UserName;
1832  * IDL   UNICODESTRING FullName;
1833  * IDL   long UserID;
1834  * IDL   long PrimaryGroupID;
1835  * IDL   UNICODESTRING HomeDir;
1836  * IDL   UNICODESTRING HomeDirDrive;
1837  * IDL   UNICODESTRING LogonScript;
1838  * IDL   UNICODESTRING Comment;
1839  * IDL   UNICODESTRING Workstations;
1840  * IDL   NTTIME LastLogon;
1841  * IDL   NTTIME LastLogoff;
1842  * IDL   LOGON_HOURS logonhours;
1843  * IDL   short BadPwCount;
1844  * IDL   short LogonCount;
1845  * IDL   NTTIME PwLastSet;
1846  * IDL   NTTIME AccountExpires;
1847  * IDL   long AccountControl;
1848  * IDL   LM_OWF_PASSWORD lmpw;
1849  * IDL   NT_OWF_PASSWORD ntpw;
1850  * IDL   bool NTPwPresent;
1851  * IDL   bool LMPwPresent;
1852  * IDL   bool PwExpired;
1853  * IDL   UNICODESTRING UserComment;
1854  * IDL   UNICODESTRING Parameters;
1855  * IDL   short CountryCode;
1856  * IDL   short CodePage;
1857  * IDL   USER_PRIVATE_INFO user_private_info;
1858  * IDL   long SecurityInformation;
1859  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
1860  * IDL   UNICODESTRING dummy1;
1861  * IDL   UNICODESTRING dummy2;
1862  * IDL   UNICODESTRING dummy3;
1863  * IDL   UNICODESTRING dummy4;
1864  * IDL   long dummy5;
1865  * IDL   long dummy6;
1866  * IDL   long dummy7;
1867  * IDL   long dummy8;
1868  * IDL } DELTA_USER;
1869  */
1870 static int
1871 netlogon_dissect_DELTA_USER(tvbuff_t *tvb, int offset,
1872                         packet_info *pinfo, proto_tree *tree,
1873                         guint8 *drep)
1874 {
1875         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1876                 hf_netlogon_acct_name, 3);
1877
1878         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1879                 hf_netlogon_full_name, 0);
1880
1881         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1882                 hf_netlogon_user_rid, NULL);
1883
1884         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1885                 hf_netlogon_group_rid, NULL);
1886
1887         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1888                 hf_netlogon_home_dir, 0);
1889
1890         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1891                 hf_netlogon_dir_drive, 0);
1892
1893         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1894                 hf_netlogon_logon_script, 0);
1895
1896         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1897                 hf_netlogon_acct_desc, 0);
1898
1899         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1900                 hf_netlogon_workstations, 0);
1901
1902         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1903                 hf_netlogon_logon_time);
1904
1905         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1906                 hf_netlogon_logoff_time);
1907
1908         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
1909
1910         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1911                 hf_netlogon_bad_pw_count16, NULL);
1912
1913         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1914                 hf_netlogon_logon_count16, NULL);
1915
1916         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1917                 hf_netlogon_pwd_last_set_time);
1918
1919         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1920                 hf_netlogon_acct_expiry_time);
1921
1922         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
1923
1924         offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
1925                 pinfo, tree, drep);
1926
1927         offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
1928                 pinfo, tree, drep);
1929
1930         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
1931                 hf_netlogon_nt_pwd_present, NULL);
1932
1933         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
1934                 hf_netlogon_lm_pwd_present, NULL);
1935
1936         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
1937                 hf_netlogon_pwd_expired, NULL);
1938
1939         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1940                 hf_netlogon_comment, 0);
1941
1942         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1943                 hf_netlogon_parameters, 0);
1944
1945         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1946                 hf_netlogon_country, NULL);
1947
1948         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1949                 hf_netlogon_codepage, NULL);
1950
1951         offset = netlogon_dissect_USER_PRIVATE_INFO(tvb, offset, pinfo, tree,
1952                 drep);
1953
1954         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1955                 hf_netlogon_security_information, NULL);
1956
1957         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
1958                 pinfo, tree, drep);
1959
1960         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1961                 hf_netlogon_dummy, 0);
1962
1963         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1964                 hf_netlogon_dummy, 0);
1965
1966         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1967                 hf_netlogon_dummy, 0);
1968
1969         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1970                 hf_netlogon_dummy, 0);
1971
1972         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1973                 hf_netlogon_reserved, NULL);
1974
1975         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1976                 hf_netlogon_reserved, NULL);
1977
1978         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1979                 hf_netlogon_reserved, NULL);
1980
1981         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1982                 hf_netlogon_reserved, NULL);
1983
1984         return offset;
1985 }
1986
1987
1988 /*
1989  * IDL typedef struct {
1990  * IDL   UNICODESTRING DomainName;
1991  * IDL   UNICODESTRING OEMInfo;
1992  * IDL   NTTIME forcedlogoff;
1993  * IDL   short minpasswdlen;
1994  * IDL   short passwdhistorylen;
1995  * IDL   NTTIME pwd_must_change_time;
1996  * IDL   NTTIME pwd_can_change_time;
1997  * IDL   NTTIME domain_modify_time;
1998  * IDL   NTTIME domain_create_time;
1999  * IDL   long SecurityInformation;
2000  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
2001  * IDL   UNICODESTRING dummy1;
2002  * IDL   UNICODESTRING dummy2;
2003  * IDL   UNICODESTRING dummy3;
2004  * IDL   UNICODESTRING dummy4;
2005  * IDL   long dummy5;
2006  * IDL   long dummy6;
2007  * IDL   long dummy7;
2008  * IDL   long dummy8;
2009  * IDL } DELTA_DOMAIN;
2010  */
2011 static int
2012 netlogon_dissect_DELTA_DOMAIN(tvbuff_t *tvb, int offset,
2013                         packet_info *pinfo, proto_tree *tree,
2014                         guint8 *drep)
2015 {
2016         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2017                 hf_netlogon_domain_name, 3);
2018
2019         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2020                 hf_netlogon_oem_info, 0);
2021
2022         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2023                 hf_netlogon_kickoff_time);
2024
2025         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2026                 hf_netlogon_minpasswdlen, NULL);
2027
2028         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2029                 hf_netlogon_passwdhistorylen, NULL);
2030
2031         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2032                 hf_netlogon_pwd_must_change_time);
2033
2034         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2035                 hf_netlogon_pwd_can_change_time);
2036
2037         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2038                 hf_netlogon_domain_modify_time);
2039
2040         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2041                 hf_netlogon_domain_create_time);
2042
2043         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2044                 hf_netlogon_security_information, NULL);
2045
2046         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
2047                 pinfo, tree, drep);
2048
2049         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2050                 hf_netlogon_dummy, 0);
2051
2052         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2053                 hf_netlogon_dummy, 0);
2054
2055         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2056                 hf_netlogon_dummy, 0);
2057
2058         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2059                 hf_netlogon_dummy, 0);
2060
2061         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2062                 hf_netlogon_reserved, NULL);
2063
2064         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2065                 hf_netlogon_reserved, NULL);
2066
2067         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2068                 hf_netlogon_reserved, NULL);
2069
2070         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2071                 hf_netlogon_reserved, NULL);
2072
2073         return offset;
2074 }
2075
2076
2077 /*
2078  * IDL typedef struct {
2079  * IDL   UNICODESTRING groupname;
2080  * IDL   GROUP_MEMBERSHIP group_membership;
2081  * IDL   UNICODESTRING comment;
2082  * IDL   long SecurityInformation;
2083  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
2084  * IDL   UNICODESTRING dummy1;
2085  * IDL   UNICODESTRING dummy2;
2086  * IDL   UNICODESTRING dummy3;
2087  * IDL   UNICODESTRING dummy4;
2088  * IDL   long dummy5;
2089  * IDL   long dummy6;
2090  * IDL   long dummy7;
2091  * IDL   long dummy8;
2092  * IDL } DELTA_GROUP;
2093  */
2094 static int
2095 netlogon_dissect_DELTA_GROUP(tvbuff_t *tvb, int offset,
2096                         packet_info *pinfo, proto_tree *tree,
2097                         guint8 *drep)
2098 {
2099         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2100                 hf_netlogon_group_name, 3);
2101
2102         offset = netlogon_dissect_GROUP_MEMBERSHIP(tvb, offset,
2103                 pinfo, tree, drep);
2104
2105         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2106                 hf_netlogon_group_desc, 0);
2107
2108         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2109                 hf_netlogon_security_information, NULL);
2110
2111         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
2112                 pinfo, tree, drep);
2113
2114         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2115                 hf_netlogon_dummy, 0);
2116
2117         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2118                 hf_netlogon_dummy, 0);
2119
2120         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2121                 hf_netlogon_dummy, 0);
2122
2123         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2124                 hf_netlogon_dummy, 0);
2125
2126         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2127                 hf_netlogon_reserved, NULL);
2128
2129         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2130                 hf_netlogon_reserved, NULL);
2131
2132         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2133                 hf_netlogon_reserved, NULL);
2134
2135         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2136                 hf_netlogon_reserved, NULL);
2137
2138         return offset;
2139 }
2140
2141
2142 /*
2143  * IDL typedef struct {
2144  * IDL   UNICODESTRING OldName;
2145  * IDL   UNICODESTRING NewName;
2146  * IDL   UNICODESTRING dummy1;
2147  * IDL   UNICODESTRING dummy2;
2148  * IDL   UNICODESTRING dummy3;
2149  * IDL   UNICODESTRING dummy4;
2150  * IDL   long dummy5;
2151  * IDL   long dummy6;
2152  * IDL   long dummy7;
2153  * IDL   long dummy8;
2154  * IDL } DELTA_RENAME;
2155  */
2156 static int
2157 netlogon_dissect_DELTA_RENAME(tvbuff_t *tvb, int offset,
2158                         packet_info *pinfo, proto_tree *tree,
2159                         guint8 *drep)
2160 {
2161         dcerpc_info *di;
2162
2163         di=pinfo->private_data;
2164
2165         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2166                 di->hf_index, 0);
2167
2168         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2169                 di->hf_index, 0);
2170
2171         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2172                 hf_netlogon_dummy, 0);
2173
2174         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2175                 hf_netlogon_dummy, 0);
2176
2177         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2178                 hf_netlogon_dummy, 0);
2179
2180         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2181                 hf_netlogon_dummy, 0);
2182
2183         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2184                 hf_netlogon_reserved, NULL);
2185
2186         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2187                 hf_netlogon_reserved, NULL);
2188
2189         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2190                 hf_netlogon_reserved, NULL);
2191
2192         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2193                 hf_netlogon_reserved, NULL);
2194
2195         return offset;
2196 }
2197
2198
2199 static int
2200 netlogon_dissect_RID(tvbuff_t *tvb, int offset,
2201                         packet_info *pinfo, proto_tree *tree,
2202                         guint8 *drep)
2203 {
2204         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2205                                 hf_netlogon_user_rid, NULL);
2206
2207         return offset;
2208 }
2209
2210 static int
2211 netlogon_dissect_RID_array(tvbuff_t *tvb, int offset,
2212                         packet_info *pinfo, proto_tree *tree,
2213                         guint8 *drep)
2214 {
2215         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2216                         netlogon_dissect_RID);
2217
2218         return offset;
2219 }
2220
2221 static int
2222 netlogon_dissect_ATTRIB(tvbuff_t *tvb, int offset,
2223                         packet_info *pinfo, proto_tree *tree,
2224                         guint8 *drep)
2225 {
2226         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2227                 hf_netlogon_attrs, NULL);
2228
2229         return offset;
2230 }
2231
2232 static int
2233 netlogon_dissect_ATTRIB_array(tvbuff_t *tvb, int offset,
2234                         packet_info *pinfo, proto_tree *tree,
2235                         guint8 *drep)
2236 {
2237         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2238                         netlogon_dissect_ATTRIB);
2239
2240         return offset;
2241 }
2242
2243 /*
2244  * IDL typedef struct {
2245  * IDL   [unique][size_is(num_rids)] long *rids;
2246  * IDL   [unique][size_is(num_rids)] long *attribs;
2247  * IDL   long num_rids;
2248  * IDL   long dummy1;
2249  * IDL   long dummy2;
2250  * IDL   long dummy3;
2251  * IDL   long dummy4;
2252  * IDL } DELTA_GROUP_MEMBER;
2253  */
2254 static int
2255 netlogon_dissect_DELTA_GROUP_MEMBER(tvbuff_t *tvb, int offset,
2256                         packet_info *pinfo, proto_tree *tree,
2257                         guint8 *drep)
2258 {
2259         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2260                 netlogon_dissect_RID_array, NDR_POINTER_UNIQUE,
2261                 "RIDs:", -1);
2262
2263         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2264                 netlogon_dissect_ATTRIB_array, NDR_POINTER_UNIQUE,
2265                 "Attribs:", -1);
2266
2267         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2268                 hf_netlogon_num_rids, NULL);
2269
2270         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2271                 hf_netlogon_reserved, NULL);
2272
2273         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2274                 hf_netlogon_reserved, NULL);
2275
2276         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2277                 hf_netlogon_reserved, NULL);
2278
2279         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2280                 hf_netlogon_reserved, NULL);
2281
2282         return offset;
2283 }
2284
2285
2286 /*
2287  * IDL typedef struct {
2288  * IDL   UNICODESTRING alias_name;
2289  * IDL   long rid;
2290  * IDL   long SecurityInformation;
2291  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
2292  * IDL   UNICODESTRING dummy1;
2293  * IDL   UNICODESTRING dummy2;
2294  * IDL   UNICODESTRING dummy3;
2295  * IDL   UNICODESTRING dummy4;
2296  * IDL   long dummy5;
2297  * IDL   long dummy6;
2298  * IDL   long dummy7;
2299  * IDL   long dummy8;
2300  * IDL } DELTA_ALIAS;
2301  */
2302 static int
2303 netlogon_dissect_DELTA_ALIAS(tvbuff_t *tvb, int offset,
2304                         packet_info *pinfo, proto_tree *tree,
2305                         guint8 *drep)
2306 {
2307         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2308                 hf_netlogon_alias_name, 0);
2309
2310         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2311                 hf_netlogon_alias_rid, NULL);
2312
2313         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2314                 hf_netlogon_security_information, NULL);
2315
2316         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
2317                 pinfo, tree, drep);
2318
2319         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2320                 hf_netlogon_dummy, 0);
2321
2322         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2323                 hf_netlogon_dummy, 0);
2324
2325         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2326                 hf_netlogon_dummy, 0);
2327
2328         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2329                 hf_netlogon_dummy, 0);
2330
2331         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2332                 hf_netlogon_reserved, NULL);
2333
2334         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2335                 hf_netlogon_reserved, NULL);
2336
2337         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2338                 hf_netlogon_reserved, NULL);
2339
2340         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2341                 hf_netlogon_reserved, NULL);
2342
2343         return offset;
2344 }
2345
2346
2347 /*
2348  * IDL typedef struct {
2349  * IDL   [unique] SID_ARRAY sids;
2350  * IDL   long dummy1;
2351  * IDL   long dummy2;
2352  * IDL   long dummy3;
2353  * IDL   long dummy4;
2354  * IDL } DELTA_ALIAS_MEMBER;
2355  */
2356 static int
2357 netlogon_dissect_DELTA_ALIAS_MEMBER(tvbuff_t *tvb, int offset,
2358                         packet_info *pinfo, proto_tree *tree,
2359                         guint8 *drep)
2360 {
2361         offset = dissect_ndr_nt_PSID_ARRAY(tvb, offset, pinfo, tree, drep);
2362
2363         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2364                 hf_netlogon_reserved, NULL);
2365
2366         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2367                 hf_netlogon_reserved, NULL);
2368
2369         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2370                 hf_netlogon_reserved, NULL);
2371
2372         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2373                 hf_netlogon_reserved, NULL);
2374
2375         return offset;
2376 }
2377
2378
2379 static int
2380 netlogon_dissect_EVENT_AUDIT_OPTION(tvbuff_t *tvb, int offset,
2381                         packet_info *pinfo, proto_tree *tree,
2382                         guint8 *drep)
2383 {
2384         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2385                 hf_netlogon_event_audit_option, NULL);
2386
2387         return offset;
2388 }
2389
2390 static int
2391 netlogon_dissect_EVENT_AUDIT_OPTIONS_ARRAY(tvbuff_t *tvb, int offset,
2392                         packet_info *pinfo, proto_tree *tree,
2393                         guint8 *drep)
2394 {
2395         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2396                 netlogon_dissect_EVENT_AUDIT_OPTION);
2397
2398         return offset;
2399 }
2400
2401
2402 /*
2403  * IDL typedef struct {
2404  * IDL   long pagedpoollimit;
2405  * IDL   long nonpagedpoollimit;
2406  * IDL   long minimumworkingsetsize;
2407  * IDL   long maximumworkingsetsize;
2408  * IDL   long pagefilelimit;
2409  * IDL   NTTIME timelimit;
2410  * IDL } QUOTA_LIMITS;
2411  */
2412 static int
2413 netlogon_dissect_QUOTA_LIMITS(tvbuff_t *tvb, int offset,
2414                         packet_info *pinfo, proto_tree *parent_tree,
2415                         guint8 *drep)
2416 {
2417         proto_item *item=NULL;
2418         proto_tree *tree=NULL;
2419         int old_offset=offset;
2420
2421         if(parent_tree){
2422                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2423                         "QUOTA_LIMTS:");
2424                 tree = proto_item_add_subtree(item, ett_QUOTA_LIMITS);
2425         }
2426
2427         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2428                 hf_netlogon_pagedpoollimit, NULL);
2429
2430         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2431                 hf_netlogon_nonpagedpoollimit, NULL);
2432
2433         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2434                 hf_netlogon_minworkingsetsize, NULL);
2435
2436         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2437                 hf_netlogon_maxworkingsetsize, NULL);
2438
2439         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2440                 hf_netlogon_pagefilelimit, NULL);
2441
2442         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2443                 hf_netlogon_timelimit);
2444
2445         proto_item_set_len(item, offset-old_offset);
2446         return offset;
2447 }
2448
2449
2450 /*
2451  * IDL typedef struct {
2452  * IDL   long maxlogsize;
2453  * IDL   NTTIME auditretentionperiod;
2454  * IDL   bool auditingmode;
2455  * IDL   long maxauditeventcount;
2456  * IDL   [unique][size_is(maxauditeventcount)] long *eventauditoptions;
2457  * IDL   UNICODESTRING primarydomainname;
2458  * IDL   [unique] SID *sid;
2459  * IDL   QUOTA_LIMITS quota_limits;
2460  * IDL   NTTIME db_modify_time;
2461  * IDL   NTTIME db_create_time;
2462  * IDL   long SecurityInformation;
2463  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
2464  * IDL   UNICODESTRING dummy1;
2465  * IDL   UNICODESTRING dummy2;
2466  * IDL   UNICODESTRING dummy3;
2467  * IDL   UNICODESTRING dummy4;
2468  * IDL   long dummy5;
2469  * IDL   long dummy6;
2470  * IDL   long dummy7;
2471  * IDL   long dummy8;
2472  * IDL } DELTA_POLICY;
2473  */
2474 static int
2475 netlogon_dissect_DELTA_POLICY(tvbuff_t *tvb, int offset,
2476                         packet_info *pinfo, proto_tree *tree,
2477                         guint8 *drep)
2478 {
2479         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2480                 hf_netlogon_max_log_size, NULL);
2481
2482         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2483                 hf_netlogon_audit_retention_period);
2484
2485         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
2486                 hf_netlogon_auditing_mode, NULL);
2487
2488         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2489                 hf_netlogon_max_audit_event_count, NULL);
2490
2491         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2492                 netlogon_dissect_EVENT_AUDIT_OPTIONS_ARRAY, NDR_POINTER_UNIQUE,
2493                 "Event Audit Options:", -1);
2494
2495         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2496                 hf_netlogon_domain_name, 0);
2497
2498         offset = dissect_ndr_nt_PSID(tvb, offset,
2499                 pinfo, tree, drep, -1);
2500
2501         offset = netlogon_dissect_QUOTA_LIMITS(tvb, offset,
2502                 pinfo, tree, drep);
2503
2504         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2505                 hf_netlogon_db_modify_time);
2506
2507         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2508                 hf_netlogon_db_create_time);
2509
2510         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2511                 hf_netlogon_security_information, NULL);
2512
2513         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
2514                 pinfo, tree, drep);
2515
2516         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2517                 hf_netlogon_dummy, 0);
2518
2519         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2520                 hf_netlogon_dummy, 0);
2521
2522         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2523                 hf_netlogon_dummy, 0);
2524
2525         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2526                 hf_netlogon_dummy, 0);
2527
2528         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2529                 hf_netlogon_reserved, NULL);
2530
2531         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2532                 hf_netlogon_reserved, NULL);
2533
2534         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2535                 hf_netlogon_reserved, NULL);
2536
2537         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2538                 hf_netlogon_reserved, NULL);
2539
2540         return offset;
2541 }
2542
2543
2544 static int
2545 netlogon_dissect_CONTROLLER(tvbuff_t *tvb, int offset,
2546                         packet_info *pinfo, proto_tree *tree,
2547                         guint8 *drep)
2548 {
2549         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2550                 hf_netlogon_dc_name, 0);
2551
2552         return offset;
2553 }
2554
2555 static int
2556 netlogon_dissect_CONTROLLER_ARRAY(tvbuff_t *tvb, int offset,
2557                         packet_info *pinfo, proto_tree *tree,
2558                         guint8 *drep)
2559 {
2560         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2561                 netlogon_dissect_CONTROLLER);
2562
2563         return offset;
2564 }
2565
2566
2567 /*
2568  * IDL typedef struct {
2569  * IDL   UNICODESTRING DomainName;
2570  * IDL   long num_controllers;
2571  * IDL   [unique][size_is(num_controllers)] UNICODESTRING *controller_names;
2572  * IDL   long SecurityInformation;
2573  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
2574  * IDL   UNICODESTRING dummy1;
2575  * IDL   UNICODESTRING dummy2;
2576  * IDL   UNICODESTRING dummy3;
2577  * IDL   UNICODESTRING dummy4;
2578  * IDL   long dummy5;
2579  * IDL   long dummy6;
2580  * IDL   long dummy7;
2581  * IDL   long dummy8;
2582  * IDL } DELTA_TRUSTED_DOMAINS;
2583  */
2584 static int
2585 netlogon_dissect_DELTA_TRUSTED_DOMAINS(tvbuff_t *tvb, int offset,
2586                         packet_info *pinfo, proto_tree *tree,
2587                         guint8 *drep)
2588 {
2589         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2590                 hf_netlogon_domain_name, 0);
2591
2592         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2593                 hf_netlogon_num_controllers, NULL);
2594
2595         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2596                 netlogon_dissect_CONTROLLER_ARRAY, NDR_POINTER_UNIQUE,
2597                 "Domain Controllers:", -1);
2598
2599         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2600                 hf_netlogon_security_information, NULL);
2601
2602         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
2603                 pinfo, tree, drep);
2604
2605         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2606                 hf_netlogon_dummy, 0);
2607
2608         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2609                 hf_netlogon_dummy, 0);
2610
2611         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2612                 hf_netlogon_dummy, 0);
2613
2614         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2615                 hf_netlogon_dummy, 0);
2616
2617         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2618                 hf_netlogon_reserved, NULL);
2619
2620         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2621                 hf_netlogon_reserved, NULL);
2622
2623         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2624                 hf_netlogon_reserved, NULL);
2625
2626         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2627                 hf_netlogon_reserved, NULL);
2628
2629         return offset;
2630 }
2631
2632
2633 static int
2634 netlogon_dissect_PRIV_ATTR(tvbuff_t *tvb, int offset,
2635                         packet_info *pinfo, proto_tree *tree,
2636                         guint8 *drep)
2637 {
2638         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2639                 hf_netlogon_attrs, NULL);
2640
2641         return offset;
2642 }
2643
2644 static int
2645 netlogon_dissect_PRIV_ATTR_ARRAY(tvbuff_t *tvb, int offset,
2646                         packet_info *pinfo, proto_tree *tree,
2647                         guint8 *drep)
2648 {
2649         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2650                 netlogon_dissect_PRIV_ATTR);
2651
2652         return offset;
2653 }
2654
2655 static int
2656 netlogon_dissect_PRIV_NAME(tvbuff_t *tvb, int offset,
2657                         packet_info *pinfo, proto_tree *tree,
2658                         guint8 *drep)
2659 {
2660         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2661                 hf_netlogon_privilege_name, 1);
2662
2663         return offset;
2664 }
2665
2666 static int
2667 netlogon_dissect_PRIV_NAME_ARRAY(tvbuff_t *tvb, int offset,
2668                         packet_info *pinfo, proto_tree *tree,
2669                         guint8 *drep)
2670 {
2671         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2672                 netlogon_dissect_PRIV_NAME);
2673
2674         return offset;
2675 }
2676
2677
2678
2679 /*
2680  * IDL typedef struct {
2681  * IDL   long privilegeentries;
2682  * IDL   long provolegecontrol;
2683  * IDL   [unique][size_is(privilege_entries)] long *privilege_attrib;
2684  * IDL   [unique][size_is(privilege_entries)] UNICODESTRING *privilege_name;
2685  * IDL   QUOTALIMITS quotalimits;
2686  * IDL   long SecurityInformation;
2687  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
2688  * IDL   UNICODESTRING dummy1;
2689  * IDL   UNICODESTRING dummy2;
2690  * IDL   UNICODESTRING dummy3;
2691  * IDL   UNICODESTRING dummy4;
2692  * IDL   long dummy5;
2693  * IDL   long dummy6;
2694  * IDL   long dummy7;
2695  * IDL   long dummy8;
2696  * IDL } DELTA_ACCOUNTS;
2697  */
2698 static int
2699 netlogon_dissect_DELTA_ACCOUNTS(tvbuff_t *tvb, int offset,
2700                         packet_info *pinfo, proto_tree *tree,
2701                         guint8 *drep)
2702 {
2703         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2704                 hf_netlogon_privilege_entries, NULL);
2705
2706         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2707                 hf_netlogon_privilege_control, NULL);
2708
2709         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2710                 netlogon_dissect_PRIV_ATTR_ARRAY, NDR_POINTER_UNIQUE,
2711                 "PRIV_ATTR_ARRAY:", -1);
2712
2713         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2714                 netlogon_dissect_PRIV_NAME_ARRAY, NDR_POINTER_UNIQUE,
2715                 "PRIV_NAME_ARRAY:", -1);
2716
2717         offset = netlogon_dissect_QUOTA_LIMITS(tvb, offset,
2718                 pinfo, tree, drep);
2719
2720         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2721                 hf_netlogon_systemflags, NULL);
2722
2723         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2724                 hf_netlogon_security_information, NULL);
2725
2726         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
2727                 pinfo, tree, drep);
2728
2729         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2730                 hf_netlogon_dummy, 0);
2731
2732         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2733                 hf_netlogon_dummy, 0);
2734
2735         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2736                 hf_netlogon_dummy, 0);
2737
2738         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2739                 hf_netlogon_dummy, 0);
2740
2741         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2742                 hf_netlogon_reserved, NULL);
2743
2744         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2745                 hf_netlogon_reserved, NULL);
2746
2747         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2748                 hf_netlogon_reserved, NULL);
2749
2750         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2751                 hf_netlogon_reserved, NULL);
2752
2753         return offset;
2754 }
2755
2756 /*
2757  * IDL typedef struct {
2758  * IDL   long len;
2759  * IDL   long maxlen;
2760  * IDL   [unique][size_is(maxlen)][length_is(len)] char *cipher_data;
2761  * IDL } CIPHER_VALUE;
2762  */
2763 static int
2764 netlogon_dissect_CIPHER_VALUE_DATA(tvbuff_t *tvb, int offset,
2765                         packet_info *pinfo, proto_tree *tree,
2766                         guint8 *drep)
2767 {
2768         dcerpc_info *di;
2769         guint32 data_len;
2770
2771         di=pinfo->private_data;
2772         if(di->conformant_run){
2773                 /*just a run to handle conformant arrays, nothing to dissect */
2774                 return offset;
2775         }
2776
2777         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2778                 hf_netlogon_cipher_maxlen, NULL);
2779
2780         /* skip offset */
2781         offset += 4;
2782
2783         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2784                 hf_netlogon_cipher_len, &data_len);
2785
2786         proto_tree_add_item(tree, di->hf_index, tvb, offset,
2787                 data_len, FALSE);
2788         offset += data_len;
2789
2790         return offset;
2791 }
2792 static int
2793 netlogon_dissect_CIPHER_VALUE(tvbuff_t *tvb, int offset,
2794                         packet_info *pinfo, proto_tree *parent_tree,
2795                         guint8 *drep, char *name, int hf_index)
2796 {
2797         proto_item *item=NULL;
2798         proto_tree *tree=NULL;
2799         int old_offset=offset;
2800
2801         if(parent_tree){
2802                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2803                         name);
2804                 tree = proto_item_add_subtree(item, ett_CYPHER_VALUE);
2805         }
2806
2807         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2808                 hf_netlogon_cipher_len, NULL);
2809
2810         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2811                 hf_netlogon_cipher_maxlen, NULL);
2812
2813         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2814                 netlogon_dissect_CIPHER_VALUE_DATA, NDR_POINTER_UNIQUE,
2815                 name, hf_index);
2816
2817         proto_item_set_len(item, offset-old_offset);
2818         return offset;
2819 }
2820
2821 /*
2822  * IDL typedef struct {
2823  * IDL   CIPHER_VALUE current_cipher;
2824  * IDL   NTTIME current_cipher_set_time;
2825  * IDL   CIPHER_VALUE old_cipher;
2826  * IDL   NTTIME old_cipher_set_time;
2827  * IDL   long SecurityInformation;
2828  * IDL   LSA_SECURITY_DESCRIPTOR sec_desc;
2829  * IDL   UNICODESTRING dummy1;
2830  * IDL   UNICODESTRING dummy2;
2831  * IDL   UNICODESTRING dummy3;
2832  * IDL   UNICODESTRING dummy4;
2833  * IDL   long dummy5;
2834  * IDL   long dummy6;
2835  * IDL   long dummy7;
2836  * IDL   long dummy8;
2837  * IDL } DELTA_SECRET;
2838  */
2839 static int
2840 netlogon_dissect_DELTA_SECRET(tvbuff_t *tvb, int offset,
2841                         packet_info *pinfo, proto_tree *tree,
2842                         guint8 *drep)
2843 {
2844         offset = netlogon_dissect_CIPHER_VALUE(tvb, offset,
2845                 pinfo, tree, drep,
2846                 "CIPHER_VALUE: current cipher value",
2847                 hf_netlogon_cipher_current_data);
2848
2849         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2850                 hf_netlogon_cipher_current_set_time);
2851
2852         offset = netlogon_dissect_CIPHER_VALUE(tvb, offset,
2853                 pinfo, tree, drep,
2854                 "CIPHER_VALUE: old cipher value",
2855                 hf_netlogon_cipher_old_data);
2856
2857         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2858                 hf_netlogon_cipher_old_set_time);
2859
2860         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2861                 hf_netlogon_security_information, NULL);
2862
2863         offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset,
2864                 pinfo, tree, drep);
2865
2866         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2867                 hf_netlogon_dummy, 0);
2868
2869         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2870                 hf_netlogon_dummy, 0);
2871
2872         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2873                 hf_netlogon_dummy, 0);
2874
2875         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2876                 hf_netlogon_dummy, 0);
2877
2878         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2879                 hf_netlogon_reserved, NULL);
2880
2881         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2882                 hf_netlogon_reserved, NULL);
2883
2884         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2885                 hf_netlogon_reserved, NULL);
2886
2887         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2888                 hf_netlogon_reserved, NULL);
2889
2890         return offset;
2891 }
2892
2893 /*
2894  * IDL typedef struct {
2895  * IDL   long low_value;
2896  * IDL   long high_value;
2897  * } MODIFIED_COUNT;
2898  */
2899 static int
2900 netlogon_dissect_MODIFIED_COUNT(tvbuff_t *tvb, int offset,
2901                         packet_info *pinfo, proto_tree *tree,
2902                         guint8 *drep)
2903 {
2904         offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep,
2905                 hf_netlogon_modify_count, NULL);
2906
2907         return offset;
2908 }
2909
2910
2911 #define DT_DELTA_DOMAIN                 1
2912 #define DT_DELTA_GROUP                  2
2913 #define DT_DELTA_RENAME_GROUP           4
2914 #define DT_DELTA_USER                   5
2915 #define DT_DELTA_RENAME_USER            7
2916 #define DT_DELTA_GROUP_MEMBER           8
2917 #define DT_DELTA_ALIAS                  9
2918 #define DT_DELTA_RENAME_ALIAS           11
2919 #define DT_DELTA_ALIAS_MEMBER           12
2920 #define DT_DELTA_POLICY                 13
2921 #define DT_DELTA_TRUSTED_DOMAINS        14
2922 #define DT_DELTA_ACCOUNTS               16
2923 #define DT_DELTA_SECRET                 18
2924 #define DT_DELTA_DELETE_GROUP           20
2925 #define DT_DELTA_DELETE_USER            21
2926 #define DT_MODIFIED_COUNT               22
2927 static const value_string delta_type_vals[] = {
2928         { DT_DELTA_DOMAIN,              "Domain" },
2929         { DT_DELTA_GROUP,               "Group" },
2930         { DT_DELTA_RENAME_GROUP,        "Rename Group" },
2931         { DT_DELTA_USER,                "User" },
2932         { DT_DELTA_RENAME_USER,         "Rename User" },
2933         { DT_DELTA_GROUP_MEMBER,        "Group Member" },
2934         { DT_DELTA_ALIAS,               "Alias" },
2935         { DT_DELTA_RENAME_ALIAS,        "Rename Alias" },
2936         { DT_DELTA_ALIAS_MEMBER,        "Alias Member" },
2937         { DT_DELTA_POLICY,              "Policy" },
2938         { DT_DELTA_TRUSTED_DOMAINS,     "Trusted Domains" },
2939         { DT_DELTA_ACCOUNTS,            "Accounts" },
2940         { DT_DELTA_SECRET,              "Secret" },
2941         { DT_DELTA_DELETE_GROUP,        "Delete Group" },
2942         { DT_DELTA_DELETE_USER,         "Delete User" },
2943         { DT_MODIFIED_COUNT,            "Modified Count" },
2944         { 0, NULL }
2945 };
2946 /*
2947  * IDL typedef [switch_type(short)] union {
2948  * IDL   [case(1)][unique] DELTA_DOMAIN *domain;
2949  * IDL   [case(2)][unique] DELTA_GROUP *group;
2950  * IDL   [case(4)][unique] DELTA_RENAME_GROUP *rename_group;
2951  * IDL   [case(5)][unique] DELTA_USER *user;
2952  * IDL   [case(7)][unique] DELTA_RENAME_USER *rename_user;
2953  * IDL   [case(8)][unique] DELTA_GROUP_MEMBER *group_member;
2954  * IDL   [case(9)][unique] DELTA_ALIAS *alias;
2955  * IDL   [case(11)][unique] DELTA_RENAME_ALIAS *rename_alias;
2956  * IDL   [case(12)][unique] DELTA_ALIAS_MEMBER *alias_member;
2957  * IDL   [case(13)][unique] DELTA_POLICY *policy;
2958  * IDL   [case(14)][unique] DELTA_TRUSTED_DOMAINS *trusted_domains;
2959  * IDL   [case(16)][unique] DELTA_ACCOUNTS *accounts;
2960  * IDL   [case(18)][unique] DELTA_SECRET *secret;
2961  * IDL   [case(20)][unique] DELTA_DELETE_USER *delete_group;
2962  * IDL   [case(21)][unique] DELTA_DELETE_USER *delete_user;
2963  * IDL   [case(22)][unique] MODIFIED_COUNT *modified_count;
2964  * IDL } DELTA_UNION;
2965  */
2966 static int
2967 netlogon_dissect_DELTA_UNION(tvbuff_t *tvb, int offset,
2968                         packet_info *pinfo, proto_tree *parent_tree,
2969                         guint8 *drep)
2970 {
2971         proto_item *item=NULL;
2972         proto_tree *tree=NULL;
2973         int old_offset=offset;
2974         guint16 level;
2975
2976         if(parent_tree){
2977                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2978                         "DELTA_UNION:");
2979                 tree = proto_item_add_subtree(item, ett_DELTA_UNION);
2980         }
2981
2982         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2983                 hf_netlogon_delta_type, &level);
2984
2985         ALIGN_TO_4_BYTES;
2986         switch(level){
2987         case 1:
2988                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2989                         netlogon_dissect_DELTA_DOMAIN, NDR_POINTER_UNIQUE,
2990                         "DELTA_DOMAIN:", -1);
2991                 break;
2992         case 2:
2993                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2994                         netlogon_dissect_DELTA_GROUP, NDR_POINTER_UNIQUE,
2995                         "DELTA_GROUP:", -1);
2996                 break;
2997         case 4:
2998                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2999                         netlogon_dissect_DELTA_RENAME, NDR_POINTER_UNIQUE,
3000                         "DELTA_RENAME_GROUP:", hf_netlogon_group_name);
3001                 break;
3002         case 5:
3003                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3004                         netlogon_dissect_DELTA_USER, NDR_POINTER_UNIQUE,
3005                         "DELTA_USER:", -1);
3006                 break;
3007         case 7:
3008                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3009                         netlogon_dissect_DELTA_RENAME, NDR_POINTER_UNIQUE,
3010                         "DELTA_RENAME_USER:", hf_netlogon_acct_name);
3011                 break;
3012         case 8:
3013                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3014                         netlogon_dissect_DELTA_GROUP_MEMBER, NDR_POINTER_UNIQUE,
3015                         "DELTA_GROUP_MEMBER:", -1);
3016                 break;
3017         case 9:
3018                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3019                         netlogon_dissect_DELTA_ALIAS, NDR_POINTER_UNIQUE,
3020                         "DELTA_ALIAS:", -1);
3021                 break;
3022         case 11:
3023                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3024                         netlogon_dissect_DELTA_RENAME, NDR_POINTER_UNIQUE,
3025                         "DELTA_RENAME_ALIAS:", hf_netlogon_alias_name);
3026                 break;
3027         case 12:
3028                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3029                         netlogon_dissect_DELTA_ALIAS_MEMBER, NDR_POINTER_UNIQUE,
3030                         "DELTA_ALIAS_MEMBER:", -1);
3031                 break;
3032         case 13:
3033                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3034                         netlogon_dissect_DELTA_POLICY, NDR_POINTER_UNIQUE,
3035                         "DELTA_POLICY:", -1);
3036                 break;
3037         case 14:
3038                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3039                         netlogon_dissect_DELTA_TRUSTED_DOMAINS, NDR_POINTER_UNIQUE,
3040                         "DELTA_TRUSTED_DOMAINS:", -1);
3041                 break;
3042         case 16:
3043                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3044                         netlogon_dissect_DELTA_ACCOUNTS, NDR_POINTER_UNIQUE,
3045                         "DELTA_ACCOUNTS:", -1);
3046                 break;
3047         case 18:
3048                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3049                         netlogon_dissect_DELTA_SECRET, NDR_POINTER_UNIQUE,
3050                         "DELTA_SECRET:", -1);
3051                 break;
3052         case 20:
3053                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3054                         netlogon_dissect_DELTA_DELETE_USER, NDR_POINTER_UNIQUE,
3055                         "DELTA_DELETE_GROUP:", -1);
3056                 break;
3057         case 21:
3058                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3059                         netlogon_dissect_DELTA_DELETE_USER, NDR_POINTER_UNIQUE,
3060                         "DELTA_DELETE_USER:", -1);
3061                 break;
3062         case 22:
3063                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3064                         netlogon_dissect_MODIFIED_COUNT, NDR_POINTER_UNIQUE,
3065                         "MODIFIED_COUNT:", -1);
3066                 break;
3067         }
3068
3069         proto_item_set_len(item, offset-old_offset);
3070         return offset;
3071 }
3072
3073
3074
3075 /* IDL XXX must verify this one, especially 13-19
3076  * IDL typedef [switch_type(short)] union {
3077  * IDL   [case(1)] long rid;
3078  * IDL   [case(2)] long rid;
3079  * IDL   [case(3)] long rid;
3080  * IDL   [case(4)] long rid;
3081  * IDL   [case(5)] long rid;
3082  * IDL   [case(6)] long rid;
3083  * IDL   [case(7)] long rid;
3084  * IDL   [case(8)] long rid;
3085  * IDL   [case(9)] long rid;
3086  * IDL   [case(10)] long rid;
3087  * IDL   [case(11)] long rid;
3088  * IDL   [case(12)] long rid;
3089  * IDL   [case(13)] [unique] SID *sid;
3090  * IDL   [case(14)] [unique] SID *sid;
3091  * IDL   [case(15)] [unique] SID *sid;
3092  * IDL   [case(16)] [unique] SID *sid;
3093  * IDL   [case(17)] [unique] SID *sid;
3094  * IDL   [case(18)] [unique][string] wchar_t *Name ;
3095  * IDL   [case(19)] [unique][string] wchar_t *Name ;
3096  * IDL   [case(20)] long rid;
3097  * IDL   [case(21)] long rid;
3098  * IDL } DELTA_ID_UNION;
3099  */
3100 static int
3101 netlogon_dissect_DELTA_ID_UNION(tvbuff_t *tvb, int offset,
3102                         packet_info *pinfo, proto_tree *parent_tree,
3103                         guint8 *drep)
3104 {
3105         proto_item *item=NULL;
3106         proto_tree *tree=NULL;
3107         int old_offset=offset;
3108         guint16 level;
3109
3110         if(parent_tree){
3111                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
3112                         "DELTA_ID_UNION:");
3113                 tree = proto_item_add_subtree(item, ett_DELTA_ID_UNION);
3114         }
3115
3116         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3117                 hf_netlogon_delta_type, &level);
3118
3119         ALIGN_TO_4_BYTES;
3120         switch(level){
3121         case 1:
3122                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3123                         hf_netlogon_group_rid, NULL);
3124                 break;
3125         case 2:
3126                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3127                         hf_netlogon_user_rid, NULL);
3128                 break;
3129         case 3:
3130                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3131                         hf_netlogon_user_rid, NULL);
3132                 break;
3133         case 4:
3134                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3135                         hf_netlogon_user_rid, NULL);
3136                 break;
3137         case 5:
3138                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3139                         hf_netlogon_user_rid, NULL);
3140                 break;
3141         case 6:
3142                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3143                         hf_netlogon_user_rid, NULL);
3144                 break;
3145         case 7:
3146                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3147                         hf_netlogon_user_rid, NULL);
3148                 break;
3149         case 8:
3150                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3151                         hf_netlogon_user_rid, NULL);
3152                 break;
3153         case 9:
3154                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3155                         hf_netlogon_user_rid, NULL);
3156                 break;
3157         case 10:
3158                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3159                         hf_netlogon_user_rid, NULL);
3160                 break;
3161         case 11:
3162                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3163                         hf_netlogon_user_rid, NULL);
3164                 break;
3165         case 12:
3166                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3167                         hf_netlogon_user_rid, NULL);
3168                 break;
3169         case 13:
3170                 offset = dissect_ndr_nt_PSID(tvb, offset,
3171                         pinfo, tree, drep, -1);
3172                 break;
3173         case 14:
3174                 offset = dissect_ndr_nt_PSID(tvb, offset,
3175                         pinfo, tree, drep, -1);
3176                 break;
3177         case 15:
3178                 offset = dissect_ndr_nt_PSID(tvb, offset,
3179                         pinfo, tree, drep, -1);
3180                 break;
3181         case 16:
3182                 offset = dissect_ndr_nt_PSID(tvb, offset,
3183                         pinfo, tree, drep, -1);
3184                 break;
3185         case 17:
3186                 offset = dissect_ndr_nt_PSID(tvb, offset,
3187                         pinfo, tree, drep, -1);
3188                 break;
3189         case 18:
3190                 offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, 
3191                         tree, drep, NDR_POINTER_UNIQUE, "unknown", 
3192                         hf_netlogon_unknown_string, 0);
3193                 break;
3194         case 19:
3195                 offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, 
3196                         tree, drep, NDR_POINTER_UNIQUE, "unknown", 
3197                         hf_netlogon_unknown_string, 0);
3198                 break;
3199         case 20:
3200                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3201                         hf_netlogon_user_rid, NULL);
3202                 break;
3203         case 21:
3204                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3205                         hf_netlogon_user_rid, NULL);
3206                 break;
3207         }
3208
3209         proto_item_set_len(item, offset-old_offset);
3210         return offset;
3211 }
3212
3213 /*
3214  * IDL typedef struct {
3215  * IDL   short delta_type;
3216  * IDL   DELTA_ID_UNION delta_id_union;
3217  * IDL   DELTA_UNION delta_union;
3218  * IDL } DELTA_ENUM;
3219  */
3220 static int
3221 netlogon_dissect_DELTA_ENUM(tvbuff_t *tvb, int offset,
3222                         packet_info *pinfo, proto_tree *parent_tree,
3223                         guint8 *drep)
3224 {
3225         proto_item *item=NULL;
3226         proto_tree *tree=NULL;
3227         int old_offset=offset;
3228         guint16 type;
3229
3230         if(parent_tree){
3231                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
3232                         "DELTA_ENUM:");
3233                 tree = proto_item_add_subtree(item, ett_DELTA_ENUM);
3234         }
3235
3236         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3237                 hf_netlogon_delta_type, &type);
3238
3239         proto_item_append_text(item, val_to_str(
3240                                        type, delta_type_vals, "Unknown"));
3241
3242         offset = netlogon_dissect_DELTA_ID_UNION(tvb, offset,
3243                 pinfo, tree, drep);
3244
3245         offset = netlogon_dissect_DELTA_UNION(tvb, offset,
3246                 pinfo, tree, drep);
3247
3248         proto_item_set_len(item, offset-old_offset);
3249         return offset;
3250 }
3251
3252 static int
3253 netlogon_dissect_DELTA_ENUM_array(tvbuff_t *tvb, int offset,
3254                         packet_info *pinfo, proto_tree *tree,
3255                         guint8 *drep)
3256 {
3257         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3258                 netlogon_dissect_DELTA_ENUM);
3259
3260         return offset;
3261 }
3262
3263 /*
3264  * IDL typedef struct {
3265  * IDL   long num_deltas;
3266  * IDL   [unique][size_is(num_deltas)] DELTA_ENUM *delta_enum;
3267  * IDL } DELTA_ENUM_ARRAY;
3268  */
3269 static int
3270 netlogon_dissect_DELTA_ENUM_ARRAY(tvbuff_t *tvb, int offset,
3271                         packet_info *pinfo, proto_tree *tree,
3272                         guint8 *drep)
3273 {
3274         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3275                 hf_netlogon_num_deltas, NULL);
3276
3277         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3278                 netlogon_dissect_DELTA_ENUM_array, NDR_POINTER_UNIQUE,
3279                 "DELTA_ENUM: deltas", -1);
3280
3281         return offset;
3282 }
3283
3284
3285 /*
3286  * IDL long NetrDatabaseDeltas(
3287  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
3288  * IDL      [in][string][ref] wchar_t *computername,
3289  * IDL      [in][ref] AUTHENTICATOR credential,
3290  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
3291  * IDL      [in] long database_id,
3292  * IDL      [in][out][ref] MODIFIED_COUNT domain_modify_count,
3293  * IDL      [in] long preferredmaximumlength,
3294  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
3295  * IDL );
3296  */
3297 static int
3298 netlogon_dissect_netrdatabasedeltas_rqst(tvbuff_t *tvb, int offset,
3299         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3300 {
3301         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3302                 NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
3303
3304         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3305                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
3306
3307         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3308                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3309                 "AUTHENTICATOR: credential", -1);
3310
3311         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3312                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3313                 "AUTHENTICATOR: return_authenticator", -1);
3314
3315         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3316                 hf_netlogon_database_id, NULL);
3317
3318         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3319                 netlogon_dissect_MODIFIED_COUNT, NDR_POINTER_REF,
3320                 "MODIFIED_COUNT: domain modified count", -1);
3321
3322         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3323                 hf_netlogon_max_size, NULL);
3324
3325         return offset;
3326 }
3327 static int
3328 netlogon_dissect_netrdatabasedeltas_reply(tvbuff_t *tvb, int offset,
3329         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3330 {
3331         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3332                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3333                 "AUTHENTICATOR: return_authenticator", -1);
3334
3335         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3336                 netlogon_dissect_MODIFIED_COUNT, NDR_POINTER_REF,
3337                 "MODIFIED_COUNT: domain modified count", -1);
3338
3339         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3340                 netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
3341                 "DELTA_ENUM_ARRAY: deltas", -1);
3342
3343         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3344                                   hf_netlogon_rc, NULL);
3345
3346         return offset;
3347 }
3348
3349
3350 /*
3351  * IDL long NetrDatabaseSync(
3352  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
3353  * IDL      [in][string][ref] wchar_t *computername,
3354  * IDL      [in][ref] AUTHENTICATOR credential,
3355  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
3356  * IDL      [in] long database_id,
3357  * IDL      [in][out][ref] long sync_context,
3358  * IDL      [in] long preferredmaximumlength,
3359  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
3360  * IDL );
3361  */
3362 static int
3363 netlogon_dissect_netrdatabasesync_rqst(tvbuff_t *tvb, int offset,
3364         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3365 {
3366         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3367                 NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
3368
3369         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3370                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
3371
3372         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3373                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3374                 "AUTHENTICATOR: credential", -1);
3375
3376         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3377                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3378                 "AUTHENTICATOR: return_authenticator", -1);
3379
3380         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3381                 hf_netlogon_database_id, NULL);
3382
3383         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3384                 hf_netlogon_sync_context, NULL);
3385
3386         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3387                 hf_netlogon_max_size, NULL);
3388
3389         return offset;
3390 }
3391
3392
3393 static int
3394 netlogon_dissect_netrdatabasesync_reply(tvbuff_t *tvb, int offset,
3395         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3396 {
3397         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3398                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3399                 "AUTHENTICATOR: return_authenticator", -1);
3400
3401         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3402                 hf_netlogon_sync_context, NULL);
3403
3404         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3405                 netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
3406                 "DELTA_ENUM_ARRAY: deltas", -1);
3407
3408         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3409                                   hf_netlogon_rc, NULL);
3410
3411         return offset;
3412 }
3413
3414 /*
3415  * IDL typedef struct {
3416  * IDL   char computer_name[16];
3417  * IDL   long timecreated;
3418  * IDL   long serial_number;
3419  * IDL } UAS_INFO_0;
3420  */
3421 static int
3422 netlogon_dissect_UAS_INFO_0(tvbuff_t *tvb, int offset,
3423                         packet_info *pinfo, proto_tree *tree,
3424                         guint8 *drep)
3425 {
3426         dcerpc_info *di;
3427
3428         di=pinfo->private_data;
3429         if(di->conformant_run){
3430                 /*just a run to handle conformant arrays, nothing to dissect */
3431                 return offset;
3432         }
3433
3434         proto_tree_add_item(tree, hf_netlogon_computer_name, tvb, offset, 16, FALSE);
3435         offset += 16;
3436
3437         proto_tree_add_text(tree, tvb, offset, 4, "Time Created: unknown time format");
3438         offset+= 4;
3439
3440         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3441                 hf_netlogon_serial_number, NULL);
3442
3443         return offset;
3444 }
3445
3446
3447 static int
3448 netlogon_dissect_BYTE_byte(tvbuff_t *tvb, int offset,
3449                         packet_info *pinfo, proto_tree *tree,
3450                         guint8 *drep)
3451 {
3452                 offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
3453                         hf_netlogon_unknown_char, NULL);
3454
3455         return offset;
3456 }
3457
3458 static int
3459 netlogon_dissect_BYTE_array(tvbuff_t *tvb, int offset,
3460                         packet_info *pinfo, proto_tree *tree,
3461                         guint8 *drep)
3462 {
3463         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3464                 netlogon_dissect_BYTE_byte);
3465
3466         return offset;
3467 }
3468
3469 /*
3470  * IDL long NetrAccountDeltas(
3471  * IDL      [in][string][unique] wchar_t *logonserver,
3472  * IDL      [in][string][ref] wchar_t *computername,
3473  * IDL      [in][ref] AUTHENTICATOR credential,
3474  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
3475  * IDL      [out][ref][size_is(count_returned)] char *Buffer,
3476  * IDL      [out][ref] long count_returned,
3477  * IDL      [out][ref] long total_entries,
3478  * IDL      [in][out][ref] UAS_INFO_0 recordid,
3479  * IDL      [in][long] count,
3480  * IDL      [in][long] level,
3481  * IDL      [in][long] buffersize,
3482  * IDL );
3483  */
3484 static int
3485 netlogon_dissect_netraccountdeltas_rqst(tvbuff_t *tvb, int offset,
3486         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3487 {
3488         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
3489                 pinfo, tree, drep);
3490
3491         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3492                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
3493
3494         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3495                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3496                 "AUTHENTICATOR: credential", -1);
3497
3498         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3499                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3500                 "AUTHENTICATOR: return_authenticator", -1);
3501
3502         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3503                 netlogon_dissect_UAS_INFO_0, NDR_POINTER_REF,
3504                 "UAS_INFO_0: RecordID", -1);
3505
3506         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3507                 hf_netlogon_count, NULL);
3508
3509         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3510                 hf_netlogon_level, NULL);
3511
3512         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3513                 hf_netlogon_max_size, NULL);
3514
3515         return offset;
3516 }
3517 static int
3518 netlogon_dissect_netraccountdeltas_reply(tvbuff_t *tvb, int offset,
3519         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3520 {
3521         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3522                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3523                 "AUTHENTICATOR: return_authenticator", -1);
3524
3525         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3526                 netlogon_dissect_BYTE_array, NDR_POINTER_REF,
3527                 "BYTE_array: Buffer", -1);
3528
3529         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3530                 hf_netlogon_count, NULL);
3531
3532         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3533                 hf_netlogon_entries, NULL);
3534
3535         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3536                 netlogon_dissect_UAS_INFO_0, NDR_POINTER_REF,
3537                 "UAS_INFO_0: RecordID", -1);
3538
3539         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3540                                   hf_netlogon_rc, NULL);
3541
3542         return offset;
3543 }
3544
3545
3546 /*
3547  * IDL long NetrAccountSync(
3548  * IDL      [in][string][unique] wchar_t *logonserver,
3549  * IDL      [in][string][ref] wchar_t *computername,
3550  * IDL      [in][ref] AUTHENTICATOR credential,
3551  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
3552  * IDL      [out][ref][size_is(count_returned)] char *Buffer,
3553  * IDL      [out][ref] long count_returned,
3554  * IDL      [out][ref] long total_entries,
3555  * IDL      [out][ref] long next_reference,
3556  * IDL      [in][long] reference,
3557  * IDL      [in][long] level,
3558  * IDL      [in][long] buffersize,
3559  * IDL      [in][out][ref] UAS_INFO_0 recordid,
3560  * IDL );
3561  */
3562 static int
3563 netlogon_dissect_netraccountsync_rqst(tvbuff_t *tvb, int offset,
3564         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3565 {
3566         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
3567                 pinfo, tree, drep);
3568
3569         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3570                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
3571
3572         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3573                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3574                 "AUTHENTICATOR: credential", -1);
3575
3576         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3577                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3578                 "AUTHENTICATOR: return_authenticator", -1);
3579
3580         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3581                 hf_netlogon_reference, NULL);
3582
3583         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3584                 hf_netlogon_level, NULL);
3585
3586         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3587                 hf_netlogon_max_size, NULL);
3588
3589         return offset;
3590 }
3591 static int
3592 netlogon_dissect_netraccountsync_reply(tvbuff_t *tvb, int offset,
3593         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3594 {
3595         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3596                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
3597                 "AUTHENTICATOR: return_authenticator", -1);
3598
3599         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3600                 netlogon_dissect_BYTE_array, NDR_POINTER_REF,
3601                 "BYTE_array: Buffer", -1);
3602
3603         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3604                 hf_netlogon_count, NULL);
3605
3606         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3607                 hf_netlogon_entries, NULL);
3608
3609         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3610                 hf_netlogon_next_reference, NULL);
3611
3612         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3613                 netlogon_dissect_UAS_INFO_0, NDR_POINTER_REF,
3614                 "UAS_INFO_0: RecordID", -1);
3615
3616         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3617                                   hf_netlogon_rc, NULL);
3618
3619         return offset;
3620 }
3621
3622
3623 /*
3624  * IDL long NetrGetDcName(
3625  * IDL    [in][ref][string] wchar_t *logon_server,
3626  * IDL    [in][unique][string] wchar_t *domainname,
3627  * IDL    [out][unique][string] wchar_t *dcname,
3628  * IDL };
3629  */
3630 static int
3631 netlogon_dissect_netrgetdcname_rqst(tvbuff_t *tvb, int offset,
3632         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3633 {
3634         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3635                 NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
3636
3637         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3638                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_domain_name, 0);
3639
3640         return offset;
3641 }
3642 static int
3643 netlogon_dissect_netrgetdcname_reply(tvbuff_t *tvb, int offset,
3644         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3645 {
3646         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3647                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_dc_name, 0);
3648
3649         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3650                                   hf_netlogon_rc, NULL);
3651
3652         return offset;
3653 }
3654
3655
3656
3657 /*
3658  * IDL typedef struct {
3659  * IDL   long flags;
3660  * IDL   long pdc_connection_status;
3661  * IDL } NETLOGON_INFO_1;
3662  */
3663 static int
3664 netlogon_dissect_NETLOGON_INFO_1(tvbuff_t *tvb, int offset,
3665                         packet_info *pinfo, proto_tree *tree,
3666                         guint8 *drep)
3667 {
3668         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3669                 hf_netlogon_flags, NULL);
3670
3671         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3672                 hf_netlogon_pdc_connection_status, NULL);
3673
3674         return offset;
3675 }
3676
3677
3678 /*
3679  * IDL typedef struct {
3680  * IDL   long flags;
3681  * IDL   long pdc_connection_status;
3682  * IDL   [unique][string] wchar_t trusted_dc_name;
3683  * IDL   long tc_connection_status;
3684  * IDL } NETLOGON_INFO_2;
3685  */
3686 static int
3687 netlogon_dissect_NETLOGON_INFO_2(tvbuff_t *tvb, int offset,
3688                         packet_info *pinfo, proto_tree *tree,
3689                         guint8 *drep)
3690 {
3691         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3692                 hf_netlogon_flags, NULL);
3693
3694         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3695                 hf_netlogon_pdc_connection_status, NULL);
3696
3697         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3698                 NDR_POINTER_UNIQUE, "Trusted DC Name", 
3699                 hf_netlogon_trusted_dc_name, 0);
3700
3701         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3702                 hf_netlogon_tc_connection_status, NULL);
3703
3704         return offset;
3705 }
3706
3707
3708 /*
3709  * IDL typedef struct {
3710  * IDL   long flags;
3711  * IDL   long logon_attempts;
3712  * IDL   long reserved;
3713  * IDL   long reserved;
3714  * IDL   long reserved;
3715  * IDL   long reserved;
3716  * IDL   long reserved;
3717  * IDL } NETLOGON_INFO_3;
3718  */
3719 static int
3720 netlogon_dissect_NETLOGON_INFO_3(tvbuff_t *tvb, int offset,
3721                         packet_info *pinfo, proto_tree *tree,
3722                         guint8 *drep)
3723 {
3724         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3725                 hf_netlogon_flags, NULL);
3726
3727         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3728                 hf_netlogon_logon_attempts, NULL);
3729
3730         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3731                 hf_netlogon_reserved, NULL);
3732
3733         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3734                 hf_netlogon_reserved, NULL);
3735
3736         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3737                 hf_netlogon_reserved, NULL);
3738
3739         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3740                 hf_netlogon_reserved, NULL);
3741
3742         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3743                 hf_netlogon_reserved, NULL);
3744
3745         return offset;
3746 }
3747
3748
3749 /*
3750  * IDL typedef [switch_type(long)] union {
3751  * IDL   [case(1)] [unique] NETLOGON_INFO_1 *i1;
3752  * IDL   [case(2)] [unique] NETLOGON_INFO_2 *i2;
3753  * IDL   [case(3)] [unique] NETLOGON_INFO_3 *i3;
3754  * IDL } CONTROL_QUERY_INFORMATION;
3755  */
3756 static int
3757 netlogon_dissect_CONTROL_QUERY_INFORMATION(tvbuff_t *tvb, int offset,
3758                         packet_info *pinfo, proto_tree *tree,
3759                         guint8 *drep)
3760 {
3761         guint32 level;
3762
3763         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3764                 hf_netlogon_level, &level);
3765
3766         ALIGN_TO_4_BYTES;
3767         switch(level){
3768         case 1:
3769                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3770                         netlogon_dissect_NETLOGON_INFO_1, NDR_POINTER_UNIQUE,
3771                         "NETLOGON_INFO_1:", -1);
3772                 break;
3773         case 2:
3774                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3775                         netlogon_dissect_NETLOGON_INFO_2, NDR_POINTER_UNIQUE,
3776                         "NETLOGON_INFO_2:", -1);
3777                 break;
3778         case 3:
3779                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3780                         netlogon_dissect_NETLOGON_INFO_3, NDR_POINTER_UNIQUE,
3781                         "NETLOGON_INFO_3:", -1);
3782                 break;
3783         }
3784
3785         return offset;
3786 }
3787
3788
3789 /*
3790  * IDL long NetrLogonControl(
3791  * IDL      [in][string][unique] wchar_t *logonserver,
3792  * IDL      [in] long function_code,
3793  * IDL      [in] long level,
3794  * IDL      [out][ref] CONTROL_QUERY_INFORMATION
3795  * IDL );
3796  */
3797 static int
3798 netlogon_dissect_netrlogoncontrol_rqst(tvbuff_t *tvb, int offset,
3799         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3800 {
3801         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
3802                 pinfo, tree, drep);
3803
3804         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3805                 hf_netlogon_code, NULL);
3806
3807         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3808                 hf_netlogon_level, NULL);
3809
3810         return offset;
3811 }
3812 static int
3813 netlogon_dissect_netrlogoncontrol_reply(tvbuff_t *tvb, int offset,
3814         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3815 {
3816         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3817                 netlogon_dissect_CONTROL_QUERY_INFORMATION, NDR_POINTER_REF,
3818                 "CONTROL_QUERY_INFORMATION:", -1);
3819
3820         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3821                                   hf_netlogon_rc, NULL);
3822
3823         return offset;
3824 }
3825
3826
3827 /*
3828  * IDL long NetrGetAnyDCName(
3829  * IDL    [in][unique][string] wchar_t *logon_server,
3830  * IDL    [in][unique][string] wchar_t *domainname,
3831  * IDL    [out][unique][string] wchar_t *dcname,
3832  * IDL };
3833  */
3834 static int
3835 netlogon_dissect_netrgetanydcname_rqst(tvbuff_t *tvb, int offset,
3836         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3837 {
3838         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3839                 NDR_POINTER_UNIQUE, "Server Handle", 
3840                 hf_netlogon_logonsrv_handle, 0);
3841
3842         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3843                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_domain_name, 0);
3844
3845         return offset;
3846 }
3847 static int
3848 netlogon_dissect_netrgetanydcname_reply(tvbuff_t *tvb, int offset,
3849         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3850 {
3851         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3852                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_dc_name, 0);
3853
3854         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3855                                   hf_netlogon_rc, NULL);
3856
3857         return offset;
3858 }
3859
3860
3861 /*
3862  * IDL typedef [switch_type(long)] union {
3863  * IDL   [case(5)] [unique][string] wchar_t *unknown;
3864  * IDL   [case(6)] [unique][string] wchar_t *unknown;
3865  * IDL   [case(0xfffe)] long unknown;
3866  * IDL   [case(7)] [unique][string] wchar_t *unknown;
3867  * IDL } CONTROL_DATA_INFORMATION;
3868  */
3869 /* XXX
3870  * According to muddle this is what CONTROL_DATA_INFORMATION is supposed
3871  * to look like. However NetMon does not recognize any such informationlevels.
3872  *
3873  * Ill leave it as CONTROL_DATA_INFORMATION with no informationlevels
3874  * until someone has any source of better authority to call upon.
3875  */
3876 static int
3877 netlogon_dissect_CONTROL_DATA_INFORMATION(tvbuff_t *tvb, int offset,
3878                         packet_info *pinfo, proto_tree *tree,
3879                         guint8 *drep)
3880 {
3881         guint32 level;
3882
3883         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3884                 hf_netlogon_level, &level);
3885
3886         ALIGN_TO_4_BYTES;
3887         switch(level){
3888         case 5:
3889                 offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, 
3890                         tree, drep, NDR_POINTER_UNIQUE, "unknown", 
3891                         hf_netlogon_unknown_string, 0);
3892                 break;
3893         case 6:
3894                 offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, 
3895                         tree, drep, NDR_POINTER_UNIQUE, "unknown", 
3896                         hf_netlogon_unknown_string, 0);
3897                 break;
3898         case 0xfffe:
3899                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3900                         hf_netlogon_unknown_long, NULL);
3901                 break;
3902         case 8:
3903                 offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, 
3904                         tree, drep, NDR_POINTER_UNIQUE, "unknown", 
3905                         hf_netlogon_unknown_string, 0);
3906                 break;
3907         }
3908
3909         return offset;
3910 }
3911
3912
3913 /*
3914  * IDL long NetrLogonControl2(
3915  * IDL      [in][string][unique] wchar_t *logonserver,
3916  * IDL      [in] long function_code,
3917  * IDL      [in] long level,
3918  * IDL      [in][ref] CONTROL_DATA_INFORMATION *data,
3919  * IDL      [out][ref] CONTROL_QUERY_INFORMATION *query
3920  * IDL );
3921  */
3922 static int
3923 netlogon_dissect_netrlogoncontrol2_rqst(tvbuff_t *tvb, int offset,
3924         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3925 {
3926         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
3927                 pinfo, tree, drep);
3928
3929         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3930                 hf_netlogon_code, NULL);
3931
3932         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3933                 hf_netlogon_level, NULL);
3934
3935         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3936                 netlogon_dissect_CONTROL_DATA_INFORMATION, NDR_POINTER_REF,
3937                 "CONTROL_DATA_INFORMATION: ", -1);
3938
3939         return offset;
3940 }
3941
3942 static int
3943 netlogon_dissect_netrlogoncontrol2_reply(tvbuff_t *tvb, int offset,
3944         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3945 {
3946         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3947                 netlogon_dissect_CONTROL_QUERY_INFORMATION, NDR_POINTER_REF,
3948                 "CONTROL_QUERY_INFORMATION:", -1);
3949
3950         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3951                                   hf_netlogon_rc, NULL);
3952
3953         return offset;
3954 }
3955
3956
3957 /*
3958  * IDL long NetrServerAuthenticate2(
3959  * IDL      [in][string][unique] wchar_t *logonserver,
3960  * IDL      [in][ref][string] wchar_t *username,
3961  * IDL      [in] short secure_channel_type,
3962  * IDL      [in][ref][string] wchar_t *computername,
3963  * IDL      [in][ref] CREDENTIAL *client_chal,
3964  * IDL      [out][ref] CREDENTIAL *server_chal,
3965  * IDL      [in][out][ref] long *negotiate_flags,
3966  * IDL );
3967  */
3968 static int
3969 netlogon_dissect_netrserverauthenticate2_rqst(tvbuff_t *tvb, int offset,
3970         packet_info *pinfo, proto_tree *tree, guint8 *drep)
3971 {
3972         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
3973                 pinfo, tree, drep);
3974
3975         offset = dissect_ndr_pointer_cb(
3976                 tvb, offset, pinfo, tree, drep, 
3977                 dissect_ndr_wchar_cvstring, NDR_POINTER_REF, 
3978                 "User Name", hf_netlogon_acct_name, 
3979                 cb_wstr_postprocess, GINT_TO_POINTER(CB_STR_COL_INFO | 1));
3980
3981         offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
3982                 pinfo, tree, drep);
3983
3984         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
3985                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
3986
3987         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3988                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
3989                 "CREDENTIAL: client_chal", -1);
3990
3991         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3992                 hf_netlogon_neg_flags, NULL);
3993
3994         return offset;
3995 }
3996
3997 static int
3998 netlogon_dissect_netrserverauthenticate2_reply(tvbuff_t *tvb, int offset,
3999         packet_info *pinfo, proto_tree *tree, guint8 *drep)
4000 {
4001         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4002                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
4003                 "CREDENTIAL: server_chal", -1);
4004
4005         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4006                 hf_netlogon_neg_flags, NULL);
4007
4008         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4009                                   hf_netlogon_rc, NULL);
4010
4011         return offset;
4012 }
4013
4014
4015 /*
4016  * IDL long NetrDatabaseSync2(
4017  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
4018  * IDL      [in][string][ref] wchar_t *computername,
4019  * IDL      [in][ref] AUTHENTICATOR credential,
4020  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
4021  * IDL      [in] long database_id,
4022  * IDL      [in] short restart_state,
4023  * IDL      [in][out][ref] long *sync_context,
4024  * IDL      [in] long preferredmaximumlength,
4025  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
4026  * IDL );
4027  */
4028 static int
4029 netlogon_dissect_netrdatabasesync2_rqst(tvbuff_t *tvb, int offset,
4030         packet_info *pinfo, proto_tree *tree, guint8 *drep)
4031 {
4032         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4033                 NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
4034
4035         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4036                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
4037
4038         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4039                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4040                 "AUTHENTICATOR: credential", -1);
4041
4042         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4043                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4044                 "AUTHENTICATOR: return_authenticator", -1);
4045
4046         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4047                 hf_netlogon_database_id, NULL);
4048
4049         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
4050                 hf_netlogon_restart_state, NULL);
4051
4052         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4053                 hf_netlogon_sync_context, NULL);
4054
4055         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4056                 hf_netlogon_max_size, NULL);
4057
4058         return offset;
4059 }
4060
4061 static int
4062 netlogon_dissect_netrdatabasesync2_reply(tvbuff_t *tvb, int offset,
4063         packet_info *pinfo, proto_tree *tree, guint8 *drep)
4064 {
4065         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4066                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4067                 "AUTHENTICATOR: return_authenticator", -1);
4068
4069         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4070                 hf_netlogon_sync_context, NULL);
4071
4072         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4073                 netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
4074                 "DELTA_ENUM_ARRAY: deltas", -1);
4075
4076         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4077                                   hf_netlogon_rc, NULL);
4078
4079         return offset;
4080 }
4081
4082
4083 /*
4084  * IDL long NetrDatabaseRedo(
4085  * IDL      [in][string][ref] wchar_t *logonserver, # REF!!!
4086  * IDL      [in][string][ref] wchar_t *computername,
4087  * IDL      [in][ref] AUTHENTICATOR credential,
4088  * IDL      [in][out][ref] AUTHENTICATOR return_authenticator,
4089  * IDL      [in][ref][size_is(change_log_entry_size)] char *change_log_entry,
4090  * IDL      [in] long change_log_entry_size,
4091  * IDL      [out][unique] DELTA_ENUM_ARRAY *delta_enum_array
4092  * IDL );
4093  */
4094 static int
4095 netlogon_dissect_netrdatabaseredo_rqst(tvbuff_t *tvb, int offset,
4096         packet_info *pinfo, proto_tree *tree, guint8 *drep)
4097 {
4098         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4099                 NDR_POINTER_REF, "Server Handle", hf_netlogon_logonsrv_handle, 0);
4100
4101         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4102                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
4103
4104         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4105                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4106                 "AUTHENTICATOR: credential", -1);
4107
4108         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4109                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4110                 "AUTHENTICATOR: return_authenticator", -1);
4111
4112         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4113                 netlogon_dissect_BYTE_array, NDR_POINTER_REF,
4114                 "Change log entry: ", -1);
4115
4116         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4117                 hf_netlogon_max_log_size, NULL);
4118
4119         return offset;
4120 }
4121
4122 static int
4123 netlogon_dissect_netrdatabaseredo_reply(tvbuff_t *tvb, int offset,
4124         packet_info *pinfo, proto_tree *tree, guint8 *drep)
4125 {
4126         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4127                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
4128                 "AUTHENTICATOR: return_authenticator", -1);
4129
4130         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4131                 netlogon_dissect_DELTA_ENUM_ARRAY, NDR_POINTER_UNIQUE,
4132                 "DELTA_ENUM_ARRAY: deltas", -1);
4133
4134         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4135                                   hf_netlogon_rc, NULL);
4136
4137         return offset;
4138 }
4139
4140
4141 /*
4142  * IDL long NetrLogonControl2Ex(
4143  * IDL      [in][string][unique] wchar_t *logonserver,
4144  * IDL      [in] long function_code,
4145  * IDL      [in] long level,
4146  * IDL      [in][ref] CONTROL_DATA_INFORMATION *data,
4147  * IDL      [out][ref] CONTROL_QUERY_INFORMATION *query
4148  * IDL );
4149  */
4150 static int
4151 netlogon_dissect_netrlogoncontrol2ex_rqst(tvbuff_t *tvb, int offset,
4152         packet_info *pinfo, proto_tree *tree, guint8 *drep)
4153 {
4154         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
4155                 pinfo, tree, drep);
4156
4157         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4158                 hf_netlogon_code, NULL);
4159
4160         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4161                 hf_netlogon_level, NULL);
4162
4163         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4164                 netlogon_dissect_CONTROL_DATA_INFORMATION, NDR_POINTER_REF,
4165                 "CONTROL_DATA_INFORMATION: ", -1);
4166
4167         return offset;
4168 }
4169 static int
4170 netlogon_dissect_netrlogoncontrol2ex_reply(tvbuff_t *tvb, int offset,
4171         packet_info *pinfo, proto_tree *tree, guint8 *drep)
4172 {
4173         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4174                 netlogon_dissect_CONTROL_QUERY_INFORMATION, NDR_POINTER_REF,
4175                 "CONTROL_QUERY_INFORMATION:", -1);
4176
4177         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4178                                   hf_netlogon_rc, NULL);
4179
4180         return offset;
4181 }
4182
4183
4184
4185
4186 static const value_string trust_type_vals[] = {
4187         { 1,                            "DOWNLEVEL" },
4188         { 2,                            "UPLEVEL" },
4189         { 3,                            "MIT" },
4190         { 4,                            "DCE" },
4191         { 0, NULL }
4192 };
4193
4194 #define DS_INET_ADDRESS         1
4195 #define DS_NETBIOS_ADDRESS      2
4196 static const value_string dc_address_types[] = {
4197         { DS_INET_ADDRESS,              "IP/DNS name" },
4198         { DS_NETBIOS_ADDRESS,           "NetBIOS name" },
4199         { 0, NULL}
4200 };
4201
4202
4203 #define DS_DOMAIN_IN_FOREST             0x0001
4204 #define DS_DOMAIN_DIRECT_OUTBOUND       0x0002
4205 #define DS_DOMAIN_TREE_ROOT             0x0004
4206 #define DS_DOMAIN_PRIMARY               0x0008
4207 #define DS_DOMAIN_NATIVE_MODE           0x0010
4208 #define DS_DOMAIN_DIRECT_INBOUND        0x0020
4209 static const true_false_string trust_inbound = {
4210         "There is a DIRECT INBOUND trust for the servers domain",
4211         "There is NO direct inbound trust for the servers domain"
4212 };
4213 static const true_false_string trust_outbound = {
4214         "There is a DIRECT OUTBOUND trust for this domain",
4215         "There is NO direct outbound trust for this domain"
4216 };
4217 static const true_false_string trust_in_forest = {
4218         "The domain is a member IN the same FOREST as the queried server",
4219         "The domain is NOT a member of the queried servers domain"
4220 };
4221 static const true_false_string trust_native_mode = {
4222         "The primary domain is a NATIVE MODE w2k domain",
4223         "The primary is NOT a native mode w2k domain"
4224 };
4225 static const true_false_string trust_primary = {
4226         "The domain is the PRIMARY domain of the queried server",
4227         "The domain is NOT the primary domain of the queried server"
4228 };
4229 static const true_false_string trust_tree_root = {
4230         "The domain is the ROOT of a domain TREE",
4231         "The domain is NOT a root of a domain tree"
4232 };
4233 static int
4234 netlogon_dissect_DOMAIN_TRUST_FLAGS(tvbuff_t *tvb, int offset,
4235         packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
4236 {
4237         guint32 mask;
4238         proto_item *item = NULL;
4239         proto_tree *tree = NULL;
4240         dcerpc_info *di;
4241
4242         di=pinfo->private_data;
4243         if(di->conformant_run){
4244                 /*just a run to handle conformant arrays, nothing to dissect */
4245                 return offset;
4246         }
4247
4248         offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
4249                         hf_netlogon_trust_flags, &mask);
4250
4251         if(parent_tree){
4252                 item = proto_tree_add_uint(parent_tree, hf_netlogon_trust_flags,
4253                         tvb, offset-4, 4, mask);
4254                 tree = proto_item_add_subtree(item, ett_trust_flags);
4255         }
4256
4257         proto_tree_add_boolean(tree, hf_netlogon_trust_flags_inbound,
4258                 tvb, offset-4, 4, mask);
4259         proto_tree_add_boolean(tree, hf_netlogon_trust_flags_native_mode,
4260                 tvb, offset-4, 4, mask);
4261         proto_tree_add_boolean(tree, hf_netlogon_trust_flags_primary,
4262                 tvb, offset-4, 4, mask);
4263         proto_tree_add_boolean(tree, hf_netlogon_trust_flags_tree_root,
4264                 tvb, offset-4, 4, mask);
4265         proto_tree_add_boolean(tree, hf_netlogon_trust_flags_outbound,
4266                 tvb, offset-4, 4, mask);
4267         proto_tree_add_boolean(tree, hf_netlogon_trust_flags_in_forest,
4268                 tvb, offset-4, 4, mask);
4269
4270         return offset;
4271 }
4272
4273
4274 #define DS_FORCE_REDISCOVERY            0x00000001
4275 #define DS_DIRECTORY_SERVICE_REQUIRED   0x00000010
4276 #define DS_DIRECTORY_SERVICE_PREFERRED  0x00000020
4277 #define DS_GC_SERVER_REQUIRED           0x00000040
4278 #define DS_PDC_REQUIRED                 0x00000080
4279 #define DS_BACKGROUND_ONLY              0x00000100
4280 #define DS_IP_REQUIRED                  0x00000200
4281 #define DS_KDC_REQUIRED                 0x00000400
4282 #define DS_TIMESERV_REQUIRED            0x00000800
4283 #define DS_WRITABLE_REQUIRED            0x00001000
4284 #define DS_GOOD_TIMESERV_PREFERRED      0x00002000
4285 #define DS_AVOID_SELF                   0x00004000
4286 #define DS_ONLY_LDAP_NEEDED             0x00008000
4287 #define DS_IS_FLAT_NAME                 0x00010000
4288 #define DS_IS_DNS_NAME                  0x00020000
4289 #define DS_RETURN_DNS_NAME              0x40000000
4290 #define DS_RETURN_FLAT_NAME             0x80000000
4291 static const true_false_string get_dcname_request_flags_force_rediscovery = {
4292         "FORCE REDISCOVERY of any cached data",
4293         "You may return cached data"
4294 };
4295 static const true_false_string get_dcname_request_flags_directory_service_required = {
4296         "DIRECRTORY SERVICE is REQUIRED on the server",
4297         "We do NOT require directory service servers"
4298 };
4299 static const true_false_string get_dcname_request_flags_directory_service_preferred = {
4300         "DIRECTORY SERVICE servers are PREFERRED",
4301         "We do NOT have a preference for directory service servers"
4302 };
4303 static const true_false_string get_dcname_request_flags_gc_server_required = {
4304         "GC SERVER is REQUIRED",
4305         "gc server is NOT required"
4306 };
4307 static const true_false_string get_dcname_request_flags_pdc_required = {
4308         "PDC SERVER is REQUIRED",
4309         "pdc server is NOT required"
4310 };
4311 static const true_false_string get_dcname_request_flags_background_only = {
4312         "Only returned cahced data, even if it has expired",
4313         "Return cached data unless it has expired"
4314 };
4315 static const true_false_string get_dcname_request_flags_ip_required = {
4316         "IP address is REQUIRED",
4317         "ip address is NOT required"
4318 };
4319 static const true_false_string get_dcname_request_flags_kdc_required = {
4320         "KDC server is REQUIRED",
4321         "kdc server is NOT required"
4322 };
4323 static const true_false_string get_dcname_request_flags_timeserv_required = {
4324         "TIMESERV service is REQUIRED",
4325         "timeserv service is NOT required"
4326 };
4327 static const true_false_string get_dcname_request_flags_writable_required = {
4328         "the requrned dc MUST be WRITEABLE",
4329         "a read-only dc may be returned"
4330 };
4331 static const true_false_string get_dcname_request_flags_good_timeserv_preferred = {
4332         "GOOD TIMESERV servers are PREFERRED",
4333         "we do NOT have a preference for good timeserv servers"
4334 };
4335 static const true_false_string get_dcname_request_flags_avoid_self = {
4336         "do NOT return self as dc, return someone else",
4337         "you may return yourSELF as the dc"
4338 };
4339 static const true_false_string get_dcname_request_flags_only_ldap_needed = {
4340         "we ONLY NEED LDAP, you dont have to return a dc",
4341         "we need a normal dc, an ldap only server will not do"
4342 };
4343 static const true_false_string get_dcname_request_flags_is_flat_name = {
4344         "the name we specify is a NetBIOS name",
4345         "the name we specify is NOT a NetBIOS name"
4346 };
4347 static const true_false_string get_dcname_request_flags_is_dns_name = {
4348         "the name we specify is a DNS name",
4349         "ther name we specify is NOT a dns name"
4350 };
4351 static const true_false_string get_dcname_request_flags_return_dns_name = {
4352         "return a DNS name",
4353         "you may return a NON-dns name"
4354 };
4355 static const true_false_string get_dcname_request_flags_return_flat_name = {
4356         "return a NetBIOS name",
4357         "you may return a NON-NetBIOS name"
4358 };
4359 static int
4360 netlogon_dissect_GET_DCNAME_REQUEST_FLAGS(tvbuff_t *tvb, int offset,
4361         packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
4362 {
4363         guint32 mask;
4364         proto_item *item = NULL;
4365         proto_tree *tree = NULL;
4366         dcerpc_info *di;
4367
4368         di=pinfo->private_data;
4369         if(di->conformant_run){
4370                 /*just a run to handle conformant arrays, nothing to dissect */
4371                 return offset;
4372         }
4373
4374         offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
4375                         hf_netlogon_get_dcname_request_flags, &mask);
4376
4377         if(parent_tree){
4378                 item = proto_tree_add_uint(parent_tree, hf_netlogon_get_dcname_request_flags,
4379                         tvb, offset-4, 4, mask);
4380                 tree = proto_item_add_subtree(item, ett_get_dcname_request_flags);
4381         }
4382
4383         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_return_flat_name,
4384                 tvb, offset-4, 4, mask);
4385         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_return_dns_name,
4386                 tvb, offset-4, 4, mask);
4387         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_is_flat_name,
4388                 tvb, offset-4, 4, mask);
4389         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_is_dns_name,
4390                 tvb, offset-4, 4, mask);
4391         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_only_ldap_needed,
4392                 tvb, offset-4, 4, mask);
4393         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_avoid_self,
4394                 tvb, offset-4, 4, mask);
4395         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_good_timeserv_preferred,
4396                 tvb, offset-4, 4, mask);
4397         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_writable_required,
4398                 tvb, offset-4, 4, mask);
4399         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_timeserv_required,
4400                 tvb, offset-4, 4, mask);
4401         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_kdc_required,
4402                 tvb, offset-4, 4, mask);
4403         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_ip_required,
4404                 tvb, offset-4, 4, mask);
4405         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_background_only,
4406                 tvb, offset-4, 4, mask);
4407         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_pdc_required,
4408                 tvb, offset-4, 4, mask);
4409         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_gc_server_required,
4410                 tvb, offset-4, 4, mask);
4411         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_directory_service_preferred,
4412                 tvb, offset-4, 4, mask);
4413         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_directory_service_required,
4414                 tvb, offset-4, 4, mask);
4415         proto_tree_add_boolean(tree, hf_netlogon_get_dcname_request_flags_force_rediscovery,
4416                 tvb, offset-4, 4, mask);
4417         
4418         return offset;
4419 }
4420
4421
4422
4423 #define DS_PDC_FLAG             0x00000001
4424 #define DS_GC_FLAG              0x00000004
4425 #define DS_LDAP_FLAG            0x00000008
4426 #define DS_DS_FLAG              0x00000010
4427 #define DS_KDC_FLAG             0x00000020
4428 #define DS_TIMESERV_FLAG        0x00000040
4429 #define DS_CLOSEST_FLAG         0x00000080
4430 #define DS_WRITABLE_FLAG        0x00000100
4431 #define DS_GOOD_TIMESERV_FLAG   0x00000200
4432 #define DS_NDNC_FLAG            0x00000400
4433 #define DS_DNS_CONTROLLER_FLAG  0x20000000
4434 #define DS_DNS_DOMAIN_FLAG      0x40000000
4435 #define DS_DNS_FOREST_FLAG      0x80000000
4436 static const true_false_string dc_flags_pdc_flag = {
4437         "this is the PDC of the domain",
4438         "this is NOT the pdc of the domain"
4439 };
4440 static const true_false_string dc_flags_gc_flag = {
4441         "this is the GC of the forest",
4442         "this is NOT the gc of the forest"
4443 };
4444 static const true_false_string dc_flags_ldap_flag = {
4445         "this is an LDAP server",
4446         "this is NOT an ldap server"
4447 };
4448 static const true_false_string dc_flags_ds_flag = {
4449         "this is a DS server",
4450         "this is NOT a ds server"
4451 };
4452 static const true_false_string dc_flags_kdc_flag = {
4453         "this is a KDC server",
4454         "this is NOT a kdc server"
4455 };
4456 static const true_false_string dc_flags_timeserv_flag = {
4457         "this is a TIMESERV server",
4458         "this is NOT a timeserv server"
4459 };
4460 static const true_false_string dc_flags_closest_flag = {
4461         "this is the CLOSEST server",
4462         "this is NOT the closest server"
4463 };
4464 static const true_false_string dc_flags_writable_flag = {
4465         "this server has a WRITABLE ds database",
4466         "this server has a READ-ONLY ds database"
4467 };
4468 static const true_false_string dc_flags_good_timeserv_flag = {
4469         "this server is a GOOD TIMESERV server",
4470         "this is NOT a good timeserv server"
4471 };
4472 static const true_false_string dc_flags_ndnc_flag = {
4473         "NDNC is set",
4474         "ndnc is NOT set"
4475 };
4476 static const true_false_string dc_flags_dns_controller_flag = {
4477         "DomainControllerName is a DNS name",
4478         "DomainControllerName is NOT a dns name"
4479 };
4480 static const true_false_string dc_flags_dns_domain_flag = {
4481         "DomainName is a DNS name",
4482         "DomainName is NOT a dns name"
4483 };
4484 static const true_false_string dc_flags_dns_forest_flag = {
4485         "DnsForestName is a DNS name",
4486         "DnsForestName is NOT a dns name"
4487 };
4488 static int
4489 netlogon_dissect_DC_FLAGS(tvbuff_t *tvb, int offset,
4490         packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
4491 {
4492         guint32 mask;
4493         proto_item *item = NULL;
4494         proto_tree *tree = NULL;
4495         dcerpc_info *di;
4496
4497         di=pinfo->private_data;
4498         if(di->conformant_run){
4499                 /*just a run to handle conformant arrays, nothing to dissect */
4500                 return offset;
4501         }
4502
4503         offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
4504                         hf_netlogon_dc_flags, &mask);
4505
4506         if(parent_tree){
4507                 item = proto_tree_add_uint_format(parent_tree, hf_netlogon_dc_flags,
4508                                 tvb, offset-4, 4, mask, "Domain Controller Flags: 0x%08x%s", mask, (mask==0x0000ffff)?"  PING (mask==0x0000ffff)":"");
4509                 tree = proto_item_add_subtree(item, ett_dc_flags);
4510         }
4511
4512         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_dns_forest_flag,
4513                 tvb, offset-4, 4, mask);
4514         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_dns_domain_flag,
4515                 tvb, offset-4, 4, mask);
4516         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_dns_controller_flag,
4517                 tvb, offset-4, 4, mask);
4518         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_ndnc_flag,
4519                 tvb, offset-4, 4, mask);
4520         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_good_timeserv_flag,
4521                 tvb, offset-4, 4, mask);
4522         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_writable_flag,
4523                 tvb, offset-4, 4, mask);
4524         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_closest_flag,
4525                 tvb, offset-4, 4, mask);
4526         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_timeserv_flag,
4527                 tvb, offset-4, 4, mask);
4528         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_kdc_flag,
4529                 tvb, offset-4, 4, mask);
4530         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_ds_flag,
4531                 tvb, offset-4, 4, mask);
4532         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_ldap_flag,
4533                 tvb, offset-4, 4, mask);
4534         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_gc_flag,
4535                 tvb, offset-4, 4, mask);
4536         proto_tree_add_boolean(tree, hf_netlogon_dc_flags_pdc_flag,
4537                 tvb, offset-4, 4, mask);
4538
4539         return offset;
4540 }
4541
4542
4543
4544 static int
4545 netlogon_dissect_pointer_long(tvbuff_t *tvb, int offset,
4546                              packet_info *pinfo, proto_tree *tree,
4547                              guint8 *drep)
4548 {
4549         dcerpc_info *di;
4550
4551         di=pinfo->private_data;
4552         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4553                                      di->hf_index, NULL);
4554         return offset;
4555 }
4556
4557 static int
4558 netlogon_dissect_pointer_char(tvbuff_t *tvb, int offset,
4559                              packet_info *pinfo, proto_tree *tree,
4560                              guint8 *drep)
4561 {
4562         dcerpc_info *di;
4563
4564         di=pinfo->private_data;
4565         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
4566                                      di->hf_index, NULL);
4567         return offset;
4568 }
4569
4570 static int
4571 netlogon_dissect_UNICODE_MULTI_byte(tvbuff_t *tvb, int offset,
4572                         packet_info *pinfo, proto_tree *tree,
4573                         guint8 *drep)
4574 {
4575                 offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
4576                         hf_netlogon_unknown_char, NULL);
4577
4578         return offset;
4579 }
4580
4581 static int
4582 netlogon_dissect_UNICODE_MULTI_array(tvbuff_t *tvb, int offset,
4583                         packet_info *pinfo, proto_tree *tree,
4584                         guint8 *drep)
4585 {
4586         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
4587                 netlogon_dissect_UNICODE_MULTI_byte);
4588
4589         return offset;
4590 }
4591
4592 static int
4593 netlogon_dissect_UNICODE_MULTI(tvbuff_t *tvb, int offset,
4594                         packet_info *pinfo, proto_tree *parent_tree,
4595                         guint8 *drep)
4596 {
4597         proto_item *item=NULL;
4598         proto_tree *tree=NULL;
4599         int old_offset=offset;
4600
4601         if(parent_tree){
4602                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
4603                         "UNICODE_MULTI:");
4604                 tree = proto_item_add_subtree(item, ett_UNICODE_MULTI);
4605         }
4606
4607         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4608                 hf_netlogon_len, NULL);
4609
4610         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4611                 netlogon_dissect_UNICODE_MULTI_array, NDR_POINTER_UNIQUE,
4612                 "unknown", hf_netlogon_unknown_string);
4613
4614         proto_item_set_len(item, offset-old_offset);
4615         return offset;
4616 }
4617
4618 int
4619 dissect_nt_GUID(tvbuff_t *tvb, int offset,
4620                         packet_info *pinfo, proto_tree *tree,
4621                         guint8 *drep)
4622 {
4623         offset=dissect_ndr_uuid_t(tvb, offset, pinfo, tree, drep, hf_netlogon_guid, NULL);
4624
4625         return offset;
4626 }
4627
4628 static int
4629 netlogon_dissect_DOMAIN_CONTROLLER_INFO(tvbuff_t *tvb, int offset,
4630                         packet_info *pinfo, proto_tree *parent_tree,
4631                         guint8 *drep)
4632 {
4633         proto_item *item=NULL;
4634         proto_tree *tree=NULL;
4635         int old_offset=offset;
4636
4637         if(parent_tree){
4638                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
4639                         "DOMAIN_CONTROLLER_INFO:");
4640                 tree = proto_item_add_subtree(item, ett_DOMAIN_CONTROLLER_INFO);
4641         }
4642
4643         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4644                 NDR_POINTER_UNIQUE, "DC Name", hf_netlogon_dc_name, 0);
4645
4646         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4647                 NDR_POINTER_UNIQUE, "DC Address", hf_netlogon_dc_address, 0);
4648
4649         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4650                 hf_netlogon_dc_address_type, NULL);
4651
4652         offset = dissect_nt_GUID(tvb, offset,
4653                 pinfo, tree, drep);
4654
4655         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4656                 NDR_POINTER_UNIQUE, "Logon Domain", hf_netlogon_logon_dom, 0);
4657
4658         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4659                 NDR_POINTER_UNIQUE, "DNS Forest", hf_netlogon_dns_forest_name, 0);
4660
4661         offset = netlogon_dissect_DC_FLAGS(tvb, offset, pinfo, tree, drep);
4662
4663         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4664                 NDR_POINTER_UNIQUE, "DC Site", hf_netlogon_dc_site_name, 0);
4665
4666         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4667                 NDR_POINTER_UNIQUE, "Client Site", 
4668                 hf_netlogon_client_site_name, 0);
4669
4670         proto_item_set_len(item, offset-old_offset);
4671         return offset;
4672 }
4673
4674 static int
4675 netlogon_dissect_BLOB_array(tvbuff_t *tvb, int offset,
4676                         packet_info *pinfo, proto_tree *tree,
4677                         guint8 *drep)
4678 {
4679         guint32 len;
4680         dcerpc_info *di;
4681
4682         di=pinfo->private_data;
4683         if(di->conformant_run){
4684                 /*just a run to handle conformant arrays, nothing to dissect.*/
4685                 return offset;
4686         }
4687
4688         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4689                 hf_netlogon_blob_size, &len);
4690
4691         proto_tree_add_item(tree, hf_netlogon_blob, tvb, offset, len,
4692                 FALSE);
4693         offset += len;
4694
4695         return offset;
4696 }
4697
4698 static int
4699 netlogon_dissect_BLOB(tvbuff_t *tvb, int offset,
4700                         packet_info *pinfo, proto_tree *parent_tree,
4701                         guint8 *drep)
4702 {
4703         proto_item *item=NULL;
4704         proto_tree *tree=NULL;
4705
4706         if(parent_tree){
4707                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
4708                         "BLOB:");
4709                 tree = proto_item_add_subtree(item, ett_BLOB);
4710         }
4711
4712         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4713                 hf_netlogon_blob_size, NULL);
4714
4715         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4716                 netlogon_dissect_BLOB_array, NDR_POINTER_UNIQUE,
4717                 "BLOB:", -1);
4718
4719         return offset;
4720 }
4721
4722 static int
4723 netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
4724                         packet_info *pinfo, proto_tree *parent_tree,
4725                         guint8 *drep)
4726 {
4727         proto_item *item=NULL;
4728         proto_tree *tree=NULL;
4729         int old_offset=offset;
4730
4731         if(parent_tree){
4732                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
4733                         "DOMAIN_TRUST_INFO:");
4734                 tree = proto_item_add_subtree(item, ett_DOMAIN_TRUST_INFO);
4735         }
4736
4737
4738         offset = lsa_dissect_POLICY_DNS_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
4739
4740         /* Guesses at best. */
4741         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4742                 hf_netlogon_unknown_string, 0);
4743
4744         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4745                 hf_netlogon_unknown_string, 0);
4746
4747         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4748                 hf_netlogon_unknown_string, 0);
4749
4750         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4751                 hf_netlogon_unknown_string, 0);
4752
4753         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4754                 hf_netlogon_unknown_long, NULL);
4755
4756         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4757                 hf_netlogon_unknown_long, NULL);
4758
4759         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4760                 hf_netlogon_unknown_long, NULL);
4761
4762         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4763                 hf_netlogon_unknown_long, NULL);
4764
4765         proto_item_set_len(item, offset-old_offset);
4766         return offset;
4767 }
4768
4769 static int
4770 netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY(tvbuff_t *tvb, int offset,
4771                         packet_info *pinfo, proto_tree *tree,
4772                         guint8 *drep)
4773 {
4774         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
4775                 netlogon_dissect_DOMAIN_TRUST_INFO);
4776
4777         return offset;
4778 }
4779
4780 static int
4781 netlogon_dissect_DOMAIN_QUERY_1(tvbuff_t *tvb, int offset,
4782                         packet_info *pinfo, proto_tree *tree,
4783                         guint8 *drep)
4784 {
4785         offset = netlogon_dissect_BLOB(tvb, offset,
4786                 pinfo, tree, drep);
4787
4788         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4789                 NDR_POINTER_UNIQUE, "Workstation FQDN", 
4790                 hf_netlogon_workstation_fqdn, 0);
4791
4792         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4793                 NDR_POINTER_UNIQUE, "Workstation Site", 
4794                 hf_netlogon_workstation_site_name, 0);
4795
4796         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4797                 NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
4798
4799         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4800                 NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
4801
4802         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4803                 NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
4804
4805         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
4806                 NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
4807
4808         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4809                 hf_netlogon_unknown_string, 0);
4810
4811         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4812                 hf_netlogon_workstation_os, 0);
4813
4814         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4815                 hf_netlogon_unknown_string, 0);
4816
4817         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4818                 hf_netlogon_unknown_string, 0);
4819
4820         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4821                 hf_netlogon_unknown_long, NULL);
4822
4823         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4824                 hf_netlogon_unknown_long, NULL);
4825
4826         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4827                 hf_netlogon_unknown_long, NULL);
4828
4829         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4830                 hf_netlogon_unknown_long, NULL);
4831
4832         return offset;
4833 }
4834
4835 static int
4836 netlogon_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset,
4837                         packet_info *pinfo, proto_tree *tree,
4838                         guint8 *drep)
4839 {
4840         offset = netlogon_dissect_DOMAIN_TRUST_INFO(tvb, offset, pinfo, tree, drep);
4841
4842         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4843                 hf_netlogon_num_trusts, NULL);
4844
4845         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4846                 netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY, NDR_POINTER_UNIQUE,
4847                 "DOMAIN_TRUST_ARRAY: Trusts", -1);
4848
4849         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4850                 hf_netlogon_num_trusts, NULL);
4851
4852         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4853                 netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY, NDR_POINTER_UNIQUE,
4854                 "DOMAIN_TRUST_ARRAY:", -1);
4855  
4856         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4857                 hf_netlogon_dns_domain_name, 0);
4858
4859         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4860                 hf_netlogon_unknown_string, 0);
4861
4862         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4863                 hf_netlogon_unknown_string, 0);
4864
4865         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4866                 hf_netlogon_unknown_string, 0);
4867
4868         /* These four integers appear to mirror the last four in the query. */
4869         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4870                 hf_netlogon_unknown_long, NULL);
4871
4872         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4873                 hf_netlogon_unknown_long, NULL);
4874
4875         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4876                 hf_netlogon_unknown_long, NULL);
4877
4878         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4879                 hf_netlogon_unknown_long, NULL);
4880
4881         return offset;
4882 }
4883
4884
4885 static int
4886 netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
4887                         packet_info *pinfo, proto_tree *tree,
4888                         guint8 *drep)
4889 {
4890         guint32 level;
4891
4892         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4893                 hf_netlogon_level, &level);
4894
4895         ALIGN_TO_4_BYTES;
4896         switch(level){
4897         case 1:
4898                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4899                         netlogon_dissect_DOMAIN_INFO_1, NDR_POINTER_UNIQUE,
4900                         "DOMAIN_INFO_1:", -1);
4901                 break;
4902         }
4903
4904         return offset;
4905 }
4906
4907 static int
4908 netlogon_dissect_UNICODE_STRING_512(tvbuff_t *tvb, int offset,
4909                         packet_info *pinfo, proto_tree *parent_tree,
4910                         guint8 *drep)
4911 {
4912         proto_item *item=NULL;
4913         proto_tree *tree=NULL;
4914         int old_offset=offset;
4915         int i;
4916
4917         if(parent_tree){
4918                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
4919                         "UNICODE_STRING_512:");
4920                 tree = proto_item_add_subtree(item, ett_UNICODE_STRING_512);
4921         }
4922
4923         for(i=0;i<512;i++){
4924                 offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
4925                         hf_netlogon_unknown_short, NULL);
4926         }
4927
4928         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4929                 hf_netlogon_unknown_long, NULL);
4930
4931         proto_item_set_len(item, offset-old_offset);
4932         return offset;
4933 }
4934
4935 static int
4936 netlogon_dissect_element_844_byte(tvbuff_t *tvb, int offset,
4937                         packet_info *pinfo, proto_tree *tree,
4938                         guint8 *drep)
4939 {
4940                 offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
4941                         hf_netlogon_unknown_char, NULL);
4942
4943         return offset;
4944 }
4945
4946 static int
4947 netlogon_dissect_element_844_array(tvbuff_t *tvb, int offset,
4948                         packet_info *pinfo, proto_tree *tree,
4949                         guint8 *drep)
4950 {
4951         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
4952                 netlogon_dissect_element_844_byte);
4953
4954         return offset;
4955 }
4956
4957 static int
4958 netlogon_dissect_TYPE_50(tvbuff_t *tvb, int offset,
4959                         packet_info *pinfo, proto_tree *parent_tree,
4960                         guint8 *drep)
4961 {
4962         proto_item *item=NULL;
4963         proto_tree *tree=NULL;
4964         int old_offset=offset;
4965
4966         if(parent_tree){
4967                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
4968                         "TYPE_50:");
4969                 tree = proto_item_add_subtree(item, ett_TYPE_50);
4970         }
4971
4972         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4973                 hf_netlogon_unknown_long, NULL);
4974
4975         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4976                 netlogon_dissect_element_844_array, NDR_POINTER_UNIQUE,
4977                 "unknown", hf_netlogon_unknown_string);
4978
4979         proto_item_set_len(item, offset-old_offset);
4980         return offset;
4981 }
4982
4983 static int
4984 netlogon_dissect_TYPE_50_ptr(tvbuff_t *tvb, int offset,
4985                         packet_info *pinfo, proto_tree *tree,
4986                         guint8 *drep)
4987 {
4988         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4989                 netlogon_dissect_TYPE_50, NDR_POINTER_UNIQUE,
4990                 "TYPE_50 pointer: unknown_TYPE_50", -1);
4991
4992         return offset;
4993 }
4994
4995 static int
4996 netlogon_dissect_DS_DOMAIN_TRUSTS(tvbuff_t *tvb, int offset,
4997         packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
4998 {
4999         guint32 tmp;
5000         proto_item *item=NULL;
5001         proto_tree *tree=NULL;
5002         int old_offset=offset;
5003
5004         if(parent_tree){
5005                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
5006                         "DS_DOMAIN_TRUSTS");
5007                 tree = proto_item_add_subtree(item, ett_DS_DOMAIN_TRUSTS);
5008         }
5009
5010         /* name */
5011         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5012                 NDR_POINTER_UNIQUE, "NetBIOS Name", 
5013                 hf_netlogon_downlevel_domain_name, 0);
5014
5015         /* domain */
5016         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5017                 NDR_POINTER_UNIQUE, "DNS Domain Name", 
5018                 hf_netlogon_dns_domain_name, 0);
5019
5020         offset = netlogon_dissect_DOMAIN_TRUST_FLAGS(tvb, offset, pinfo, tree, drep);
5021
5022         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5023                 hf_netlogon_trust_parent_index, &tmp);
5024
5025         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5026                 hf_netlogon_trust_type, &tmp);
5027
5028         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5029                 hf_netlogon_trust_attribs, &tmp);
5030
5031         /* SID pointer */
5032         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, drep, -1);
5033
5034         /* GUID */
5035         offset = dissect_nt_GUID(tvb, offset, pinfo, tree, drep);
5036
5037         proto_item_set_len(item, offset-old_offset);
5038         return offset;
5039 }
5040
5041 static int
5042 netlogon_dissect_DS_DOMAIN_TRUSTS_ARRAY(tvbuff_t *tvb, int offset,
5043                         packet_info *pinfo, proto_tree *tree,
5044                         guint8 *drep)
5045 {
5046         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
5047                 netlogon_dissect_DS_DOMAIN_TRUSTS);
5048
5049         return offset;
5050 }
5051
5052 static int
5053 netlogon_dissect_element_865_byte(tvbuff_t *tvb, int offset,
5054                         packet_info *pinfo, proto_tree *tree,
5055                         guint8 *drep)
5056 {
5057                 offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
5058                         hf_netlogon_unknown_char, NULL);
5059
5060         return offset;
5061 }
5062
5063 static int
5064 netlogon_dissect_element_865_array(tvbuff_t *tvb, int offset,
5065                         packet_info *pinfo, proto_tree *tree,
5066                         guint8 *drep)
5067 {
5068         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
5069                 netlogon_dissect_element_865_byte);
5070
5071         return offset;
5072 }
5073
5074 static int
5075 netlogon_dissect_element_866_byte(tvbuff_t *tvb, int offset,
5076                         packet_info *pinfo, proto_tree *tree,
5077                         guint8 *drep)
5078 {
5079                 offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
5080                         hf_netlogon_unknown_char, NULL);
5081
5082         return offset;
5083 }
5084
5085 static int
5086 netlogon_dissect_element_866_array(tvbuff_t *tvb, int offset,
5087                         packet_info *pinfo, proto_tree *tree,
5088                         guint8 *drep)
5089 {
5090         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
5091                 netlogon_dissect_element_866_byte);
5092
5093         return offset;
5094 }
5095
5096 static int
5097 netlogon_dissect_TYPE_52(tvbuff_t *tvb, int offset,
5098                         packet_info *pinfo, proto_tree *parent_tree,
5099                         guint8 *drep)
5100 {
5101         proto_item *item=NULL;
5102         proto_tree *tree=NULL;
5103         int old_offset=offset;
5104
5105         if(parent_tree){
5106                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
5107                         "TYPE_52:");
5108                 tree = proto_item_add_subtree(item, ett_TYPE_52);
5109         }
5110
5111         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5112                 hf_netlogon_unknown_long, NULL);
5113
5114         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5115                 netlogon_dissect_element_865_array, NDR_POINTER_UNIQUE,
5116                 "unknown", hf_netlogon_unknown_string);
5117
5118         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5119                 netlogon_dissect_element_866_array, NDR_POINTER_UNIQUE,
5120                 "unknown", hf_netlogon_unknown_string);
5121
5122         proto_item_set_len(item, offset-old_offset);
5123         return offset;
5124 }
5125
5126 static int
5127 netlogon_dissect_TYPE_52_ptr(tvbuff_t *tvb, int offset,
5128                         packet_info *pinfo, proto_tree *tree,
5129                         guint8 *drep)
5130 {
5131         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5132                 netlogon_dissect_TYPE_52, NDR_POINTER_UNIQUE,
5133                 "TYPE_52 pointer: unknown_TYPE_52", -1);
5134         return offset;
5135 }
5136
5137
5138 static int
5139 netlogon_dissect_TYPE_44(tvbuff_t *tvb, int offset,
5140                         packet_info *pinfo, proto_tree *parent_tree,
5141                         guint8 *drep)
5142 {
5143         proto_item *item=NULL;
5144         proto_tree *tree=NULL;
5145         int old_offset=offset;
5146         guint32 level;
5147
5148         if(parent_tree){
5149                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
5150                         "TYPE_44:");
5151                 tree = proto_item_add_subtree(item, ett_TYPE_44);
5152         }
5153
5154         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5155                 hf_netlogon_level, &level);
5156
5157         ALIGN_TO_4_BYTES;
5158         switch(level){
5159         case 1:
5160                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5161                         hf_netlogon_unknown_long, NULL);
5162                 break;
5163         }
5164
5165         proto_item_set_len(item, offset-old_offset);
5166         return offset;
5167 }
5168
5169 static int
5170 netlogon_dissect_DOMAIN_QUERY(tvbuff_t *tvb, int offset,
5171                         packet_info *pinfo, proto_tree *tree,
5172                         guint8 *drep)
5173 {
5174         guint32 level;
5175
5176         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5177                 hf_netlogon_level, &level);
5178
5179         ALIGN_TO_4_BYTES;
5180         switch(level){
5181         case 1:
5182                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5183                         netlogon_dissect_DOMAIN_QUERY_1, NDR_POINTER_UNIQUE,
5184                         "DOMAIN_QUERY_1:", -1);
5185                 break;
5186         case 2:
5187                 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5188                         netlogon_dissect_DOMAIN_QUERY_1, NDR_POINTER_UNIQUE,
5189                         "DOMAIN_QUERY_1:", -1);
5190                 break;
5191         }
5192
5193         return offset;
5194 }
5195
5196 static int
5197 netlogon_dissect_netrenumeratetrusteddomains_rqst(tvbuff_t *tvb, int offset,
5198         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5199 {
5200         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5201                 pinfo, tree, drep);
5202
5203         return offset;
5204 }
5205
5206
5207 static int
5208 netlogon_dissect_netrenumeratetrusteddomains_reply(tvbuff_t *tvb, int offset,
5209         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5210 {
5211         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5212                 netlogon_dissect_UNICODE_MULTI, NDR_POINTER_REF,
5213                 "UNICODE_MULTI pointer: trust_dom_name_list", -1);
5214
5215         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5216                                   hf_netlogon_rc, NULL);
5217
5218         return offset;
5219 }
5220
5221 static int
5222 netlogon_dissect_dsrgetdcname_rqst(tvbuff_t *tvb, int offset,
5223         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5224 {
5225         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5226                 pinfo, tree, drep);
5227
5228         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5229                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_logon_dom, 0);
5230
5231         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5232                 dissect_nt_GUID, NDR_POINTER_UNIQUE,
5233                 "GUID pointer: domain_guid", -1);
5234
5235         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5236                 dissect_nt_GUID, NDR_POINTER_UNIQUE,
5237                 "GUID pointer: site_guid", -1);
5238
5239         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5240                 hf_netlogon_flags, NULL);
5241
5242         return offset;
5243 }
5244
5245
5246 static int
5247 netlogon_dissect_dsrgetdcname_reply(tvbuff_t *tvb, int offset,
5248         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5249 {
5250         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5251                 netlogon_dissect_DOMAIN_CONTROLLER_INFO, NDR_POINTER_UNIQUE,
5252                 "DOMAIN_CONTROLLER_INFO:", -1);
5253
5254         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5255                                   hf_netlogon_rc, NULL);
5256
5257         return offset;
5258 }
5259
5260 static int
5261 netlogon_dissect_netrlogondummyroutine1_rqst(tvbuff_t *tvb, int offset,
5262         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5263 {
5264         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5265                 pinfo, tree, drep);
5266
5267         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5268                 NDR_POINTER_UNIQUE, "unknown string", 
5269                 hf_netlogon_unknown_string, 0);
5270
5271         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5272                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5273                 "AUTHENTICATOR: credential", -1);
5274
5275         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5276                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
5277                 "AUTHENTICATOR: return_authenticator", -1);
5278
5279         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5280                 hf_netlogon_unknown_long, NULL);
5281
5282         return offset;
5283 }
5284
5285
5286 static int
5287 netlogon_dissect_netrlogondummyroutine1_reply(tvbuff_t *tvb, int offset,
5288         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5289 {
5290         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5291                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
5292                 "AUTHENTICATOR: return_authenticator", -1);
5293
5294         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5295                 netlogon_dissect_TYPE_44, NDR_POINTER_UNIQUE,
5296                 "TYPE_44 pointer: unknown_TYPE_44", -1);
5297
5298         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5299                                   hf_netlogon_rc, NULL);
5300
5301         return offset;
5302 }
5303
5304 static int
5305 netlogon_dissect_netrlogonsetservicebits_rqst(tvbuff_t *tvb, int offset,
5306         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5307 {
5308         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5309                 pinfo, tree, drep);
5310
5311         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5312                 hf_netlogon_unknown_long, NULL);
5313
5314         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5315                 hf_netlogon_unknown_long, NULL);
5316
5317         return offset;
5318 }
5319
5320
5321 static int
5322 netlogon_dissect_netrlogonsetservicebits_reply(tvbuff_t *tvb, int offset,
5323         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5324 {
5325         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5326                                   hf_netlogon_rc, NULL);
5327
5328         return offset;
5329 }
5330
5331
5332 static int
5333 netlogon_dissect_netrlogongettrustrid_rqst(tvbuff_t *tvb, int offset,
5334         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5335 {
5336         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5337                 pinfo, tree, drep);
5338
5339         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5340                 NDR_POINTER_UNIQUE, "unknown string", 
5341                 hf_netlogon_unknown_string, 0);
5342
5343         return offset;
5344 }
5345
5346
5347 static int
5348 netlogon_dissect_netrlogongettrustrid_reply(tvbuff_t *tvb, int offset,
5349         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5350 {
5351         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5352                 netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
5353                 "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
5354
5355         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5356                                   hf_netlogon_rc, NULL);
5357
5358         return offset;
5359 }
5360
5361
5362 static int
5363 netlogon_dissect_netrlogoncomputeserverdigest_rqst(tvbuff_t *tvb, int offset,
5364         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5365 {
5366         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5367                 pinfo, tree, drep);
5368
5369         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5370                 hf_netlogon_unknown_long, NULL);
5371
5372         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5373                 netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
5374                 "BYTE pointer: unknown_BYTE", -1);
5375
5376         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5377                 hf_netlogon_unknown_long, NULL);
5378
5379         return offset;
5380 }
5381
5382 static int
5383 netlogon_dissect_BYTE_16_array(tvbuff_t *tvb, int offset,
5384         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5385 {
5386         int i;
5387
5388         for(i=0;i<16;i++){
5389                 offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
5390                         hf_netlogon_unknown_char, NULL);
5391         }
5392
5393         return offset;
5394 }
5395
5396 static int
5397 netlogon_dissect_netrlogoncomputeserverdigest_reply(tvbuff_t *tvb, int offset,
5398         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5399 {
5400         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5401                 netlogon_dissect_BYTE_16_array, NDR_POINTER_UNIQUE,
5402                 "BYTE pointer: unknown_BYTE", -1);
5403
5404         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5405                                   hf_netlogon_rc, NULL);
5406
5407         return offset;
5408 }
5409
5410 static int
5411 netlogon_dissect_netrlogoncomputeclientdigest_rqst(tvbuff_t *tvb, int offset,
5412         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5413 {
5414         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5415                 pinfo, tree, drep);
5416
5417         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5418                 NDR_POINTER_UNIQUE, "unknown string", 
5419                 hf_netlogon_unknown_string, 0);
5420
5421         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5422                 netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
5423                 "BYTE pointer: unknown_BYTE", -1);
5424
5425         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5426                 hf_netlogon_unknown_long, NULL);
5427
5428         return offset;
5429 }
5430
5431
5432 static int
5433 netlogon_dissect_netrlogoncomputeclientdigest_reply(tvbuff_t *tvb, int offset,
5434         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5435 {
5436         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5437                 netlogon_dissect_BYTE_16_array, NDR_POINTER_UNIQUE,
5438                 "BYTE pointer: unknown_BYTE", -1);
5439
5440         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5441                                   hf_netlogon_rc, NULL);
5442
5443         return offset;
5444 }
5445
5446 static int
5447 netlogon_dissect_netrserverauthenticate3_rqst(tvbuff_t *tvb, int offset,
5448         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5449 {
5450         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5451                 pinfo, tree, drep);
5452
5453         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5454                 NDR_POINTER_REF, "Acct Name", hf_netlogon_acct_name, 0);
5455
5456         offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
5457                 pinfo, tree, drep);
5458
5459         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5460                 NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
5461
5462         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5463                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
5464                 "CREDENTIAL: authenticator", -1);
5465
5466         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5467                 hf_netlogon_neg_flags, NULL);
5468
5469         return offset;
5470 }
5471
5472
5473 static int
5474 netlogon_dissect_netrserverauthenticate3_reply(tvbuff_t *tvb, int offset,
5475         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5476 {
5477         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5478                 netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
5479                 "CREDENTIAL pointer: unknown_NETLOGON_CREDENTIAL", -1);
5480
5481         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5482                 hf_netlogon_neg_flags, NULL);
5483
5484         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5485                 netlogon_dissect_pointer_long, NDR_POINTER_REF,
5486                 "ULONG: unknown_ULONG", hf_netlogon_unknown_long);
5487
5488         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5489                                   hf_netlogon_rc, NULL);
5490
5491         return offset;
5492 }
5493
5494 static int
5495 netlogon_dissect_dsrgetdcnameex_rqst(tvbuff_t *tvb, int offset,
5496         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5497 {
5498         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5499                 pinfo, tree, drep);
5500
5501         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5502                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_logon_dom, 0);
5503
5504         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5505                 dissect_nt_GUID, NDR_POINTER_UNIQUE,
5506                 "GUID pointer: domain_guid", -1);
5507
5508         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5509                 NDR_POINTER_UNIQUE, "Site Name", hf_netlogon_site_name, 0);
5510
5511         offset = netlogon_dissect_GET_DCNAME_REQUEST_FLAGS(tvb, offset, pinfo, tree, drep);
5512
5513         return offset;
5514 }
5515
5516
5517 static int
5518 netlogon_dissect_dsrgetdcnameex_reply(tvbuff_t *tvb, int offset,
5519         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5520 {
5521         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5522                 netlogon_dissect_DOMAIN_CONTROLLER_INFO, NDR_POINTER_UNIQUE,
5523                 "DOMAIN_CONTROLLER_INFO:", -1);
5524
5525         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5526                                   hf_netlogon_rc, NULL);
5527
5528         return offset;
5529 }
5530
5531 static int
5532 netlogon_dissect_dsrgetsitename_rqst(tvbuff_t *tvb, int offset,
5533         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5534 {
5535         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5536                 pinfo, tree, drep);
5537
5538         return offset;
5539 }
5540
5541
5542 static int
5543 netlogon_dissect_dsrgetsitename_reply(tvbuff_t *tvb, int offset,
5544         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5545 {
5546
5547         /* XXX hmmm this does not really look like a UNIQUE pointer but
5548            will do for now.   I think it is really a 32bit integer followed by
5549            a REF pointer to a unicode string */
5550         offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, drep,
5551                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE, "Site Name", 
5552                 hf_netlogon_site_name, cb_wstr_postprocess, 
5553                 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
5554
5555         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5556                                   hf_netlogon_rc, NULL);
5557
5558         return offset;
5559 }
5560
5561 static int
5562 netlogon_dissect_netrlogongetdomaininfo_rqst(tvbuff_t *tvb, int offset,
5563         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5564 {
5565        /* Unlike the other NETLOGON RPCs, this is not a unique pointer. */
5566        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5567                NDR_POINTER_REF, "Server Handle", hf_netlogon_computer_name, 0);
5568
5569         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5570                 NDR_POINTER_UNIQUE, "Computer Name", 
5571                 hf_netlogon_computer_name, 0);
5572
5573         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5574                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5575                 "AUTHENTICATOR: credential", -1);
5576
5577         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5578                 hf_netlogon_unknown_long, NULL);
5579
5580         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5581                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5582                 "AUTHENTICATOR: return_authenticator", -1);
5583
5584         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5585                 netlogon_dissect_DOMAIN_QUERY, NDR_POINTER_REF,
5586                 "DOMAIN_QUERY: ", -1);
5587
5588         return offset;
5589 }
5590
5591
5592 static int
5593 netlogon_dissect_netrlogongetdomaininfo_reply(tvbuff_t *tvb, int offset,
5594         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5595 {
5596         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5597                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5598                 "AUTHENTICATOR: return_authenticator", -1);
5599
5600         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5601                 netlogon_dissect_DOMAIN_INFO, NDR_POINTER_REF,
5602                 "DOMAIN_INFO: ", -1);
5603
5604         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5605                                   hf_netlogon_rc, NULL);
5606
5607         return offset;
5608 }
5609
5610 static int
5611 netlogon_dissect_netrserverpasswordset2_rqst(tvbuff_t *tvb, int offset,
5612         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5613 {
5614         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5615                 pinfo, tree, drep);
5616
5617         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5618                 NDR_POINTER_UNIQUE, "unknown string", 
5619                 hf_netlogon_unknown_string, 0);
5620
5621         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
5622                 hf_netlogon_unknown_short, NULL);
5623
5624         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5625                 NDR_POINTER_UNIQUE, "unknown string", 
5626                 hf_netlogon_unknown_string, 0);
5627
5628         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5629                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5630                 "AUTHENTICATOR: credential", -1);
5631
5632         offset = netlogon_dissect_UNICODE_STRING_512(tvb, offset,
5633                 pinfo, tree, drep);
5634
5635         return offset;
5636 }
5637
5638
5639 static int
5640 netlogon_dissect_netrserverpasswordset2_reply(tvbuff_t *tvb, int offset,
5641         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5642 {
5643         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5644                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
5645                 "AUTHENTICATOR: return_authenticator", -1);
5646
5647         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5648                                   hf_netlogon_rc, NULL);
5649
5650         return offset;
5651 }
5652
5653 static int
5654 netlogon_dissect_netrserverpasswordget_rqst(tvbuff_t *tvb, int offset,
5655         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5656 {
5657         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5658                 pinfo, tree, drep);
5659
5660         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5661                 NDR_POINTER_UNIQUE, "Acct Name", hf_netlogon_acct_name, 0);
5662
5663         offset = netlogon_dissect_NETLOGON_SECURE_CHANNEL_TYPE(tvb, offset,
5664                 pinfo, tree, drep);
5665
5666         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5667                 NDR_POINTER_UNIQUE, "Computer Name", 
5668                 hf_netlogon_computer_name, 0);
5669
5670         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5671                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5672                 "AUTHENTICATOR: credential", -1);
5673
5674         return offset;
5675 }
5676
5677
5678 static int
5679 netlogon_dissect_netrserverpasswordget_reply(tvbuff_t *tvb, int offset,
5680         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5681 {
5682         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5683                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5684                 "AUTHENTICATOR: return_authenticator", -1);
5685
5686         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5687                 netlogon_dissect_LM_OWF_PASSWORD, NDR_POINTER_REF,
5688                 "LM_OWF_PASSWORD pointer: server_pwd", -1);
5689
5690         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5691                                   hf_netlogon_rc, NULL);
5692
5693         return offset;
5694 }
5695
5696 static int
5697 netlogon_dissect_netrlogonsendtosam_rqst(tvbuff_t *tvb, int offset,
5698         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5699 {
5700         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5701                 pinfo, tree, drep);
5702
5703         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5704                 NDR_POINTER_UNIQUE, "unknown string", 
5705                 hf_netlogon_unknown_string, 0);
5706
5707         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5708                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
5709                 "AUTHENTICATOR: credential", -1);
5710
5711         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5712                 netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
5713                 "BYTE pointer: unknown_BYTE", -1);
5714
5715         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5716                 hf_netlogon_unknown_long, NULL);
5717
5718         return offset;
5719 }
5720
5721
5722 static int
5723 netlogon_dissect_netrlogonsendtosam_reply(tvbuff_t *tvb, int offset,
5724         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5725 {
5726         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5727                 netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
5728                 "AUTHENTICATOR: return_authenticator", -1);
5729
5730         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5731                                   hf_netlogon_rc, NULL);
5732
5733         return offset;
5734 }
5735
5736 static int
5737 netlogon_dissect_dsraddresstositenamesw_rqst(tvbuff_t *tvb, int offset,
5738         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5739 {
5740         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5741                 pinfo, tree, drep);
5742
5743         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5744                 hf_netlogon_unknown_long, NULL);
5745
5746         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5747                 netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
5748                 "BYTE pointer: unknown_BYTE", -1);
5749
5750         return offset;
5751 }
5752
5753
5754 static int
5755 netlogon_dissect_dsraddresstositenamesw_reply(tvbuff_t *tvb, int offset,
5756         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5757 {
5758         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5759                 netlogon_dissect_TYPE_50_ptr, NDR_POINTER_UNIQUE,
5760                 "TYPE_50** pointer: unknown_TYPE_50", -1);
5761
5762         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5763                                   hf_netlogon_rc, NULL);
5764
5765         return offset;
5766 }
5767
5768 static int
5769 netlogon_dissect_dsrgetdcnameex2_rqst(tvbuff_t *tvb, int offset,
5770         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5771 {
5772         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5773                 pinfo, tree, drep);
5774
5775         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5776                 NDR_POINTER_UNIQUE, "unknown string", 
5777                 hf_netlogon_unknown_string, 0);
5778
5779         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5780                 hf_netlogon_unknown_long, NULL);
5781
5782         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5783                 NDR_POINTER_UNIQUE, "unknown string", 
5784                 hf_netlogon_unknown_string, 0);
5785
5786         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5787                 dissect_nt_GUID, NDR_POINTER_UNIQUE,
5788                 "GUID pointer: unknown_GUID", -1);
5789
5790         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5791                 NDR_POINTER_UNIQUE, "unknown string", 
5792                 hf_netlogon_unknown_string, 0);
5793
5794         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5795                 hf_netlogon_unknown_long, NULL);
5796
5797         return offset;
5798 }
5799
5800
5801 static int
5802 netlogon_dissect_dsrgetdcnameex2_reply(tvbuff_t *tvb, int offset,
5803         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5804 {
5805         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5806                 netlogon_dissect_DOMAIN_CONTROLLER_INFO, NDR_POINTER_UNIQUE,
5807                 "DOMAIN_CONTROLLER_INFO:", -1);
5808
5809         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5810                                   hf_netlogon_rc, NULL);
5811
5812         return offset;
5813 }
5814
5815 static int
5816 netlogon_dissect_netrlogongettimeserviceparentdomain_rqst(tvbuff_t *tvb, int offset,
5817         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5818 {
5819         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5820                 pinfo, tree, drep);
5821
5822         return offset;
5823 }
5824
5825
5826 static int
5827 netlogon_dissect_netrlogongettimeserviceparentdomain_reply(tvbuff_t *tvb, int offset,
5828         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5829 {
5830         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5831                 NDR_POINTER_UNIQUE, "unknown string", 
5832                 hf_netlogon_unknown_string, 0);
5833
5834         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5835                 netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
5836                 "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
5837
5838         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5839                                   hf_netlogon_rc, NULL);
5840
5841         return offset;
5842 }
5843
5844 static int
5845 netlogon_dissect_netrenumeratetrusteddomainsex_rqst(tvbuff_t *tvb, int offset,
5846         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5847 {
5848         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5849                 pinfo, tree, drep);
5850
5851         return offset;
5852 }
5853
5854 static int
5855 netlogon_dissect_netrenumeratetrusteddomainsex_reply(tvbuff_t *tvb, int offset,
5856         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5857 {
5858         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5859                 hf_netlogon_entries, NULL);
5860
5861         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5862                 netlogon_dissect_DS_DOMAIN_TRUSTS_ARRAY, NDR_POINTER_UNIQUE,
5863                 "DS_DOMAIN_TRUSTS_ARRAY:", -1);
5864
5865         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5866                                   hf_netlogon_rc, NULL);
5867
5868         return offset;
5869 }
5870
5871 static int
5872 netlogon_dissect_dsraddresstositenamesexw_rqst(tvbuff_t *tvb, int offset,
5873         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5874 {
5875         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5876                 pinfo, tree, drep);
5877
5878         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5879                 hf_netlogon_unknown_long, NULL);
5880
5881         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5882                 netlogon_dissect_BYTE_array, NDR_POINTER_UNIQUE,
5883                 "BYTE pointer: unknown_BYTE", -1);
5884
5885         return offset;
5886 }
5887
5888
5889 static int
5890 netlogon_dissect_dsraddresstositenamesexw_reply(tvbuff_t *tvb, int offset,
5891         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5892 {
5893         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5894                 netlogon_dissect_TYPE_52_ptr, NDR_POINTER_UNIQUE,
5895                 "TYPE_52 pointer: unknown_TYPE_52", -1);
5896
5897         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5898                                   hf_netlogon_rc, NULL);
5899
5900         return offset;
5901 }
5902
5903
5904 static int
5905 netlogon_dissect_site_name_item(tvbuff_t *tvb, int offset,
5906         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5907 {
5908         offset = dissect_ndr_counted_string_cb(
5909                 tvb, offset, pinfo, tree, drep, hf_netlogon_site_name,
5910                 cb_wstr_postprocess, 
5911                 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
5912
5913         return offset;
5914 }
5915 static int
5916 netlogon_dissect_site_name_array(tvbuff_t *tvb, int offset,
5917         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5918 {
5919         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
5920                 netlogon_dissect_site_name_item);
5921
5922         return offset;
5923 }
5924
5925 static int
5926 netlogon_dissect_site_names(tvbuff_t *tvb, int offset,
5927         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5928 {
5929         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
5930                 hf_netlogon_count, NULL);
5931
5932         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5933                 netlogon_dissect_site_name_array, NDR_POINTER_UNIQUE,
5934                 "Site name array", -1);
5935
5936         return offset;
5937 }
5938
5939 static int
5940 netlogon_dissect_dsrgetdcsitecoveragew_rqst(tvbuff_t *tvb, int offset,
5941         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5942 {
5943         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
5944                 pinfo, tree, drep);
5945
5946         return offset;
5947 }
5948
5949
5950 static int
5951 netlogon_dissect_dsrgetdcsitecoveragew_reply(tvbuff_t *tvb, int offset,
5952         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5953 {
5954         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5955                 netlogon_dissect_site_names, NDR_POINTER_UNIQUE,
5956                 "Site names", -1);
5957
5958         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
5959                                   hf_netlogon_rc, NULL);
5960
5961         return offset;
5962 }
5963
5964 static int
5965 netlogon_dissect_netrlogonsamlogonex_rqst(tvbuff_t *tvb, int offset,
5966         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5967 {
5968         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5969                 NDR_POINTER_UNIQUE, "unknown string", 
5970                 hf_netlogon_unknown_string, 0);
5971
5972         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
5973                 NDR_POINTER_UNIQUE, "unknown string", 
5974                 hf_netlogon_unknown_string, 0);
5975
5976         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
5977                 hf_netlogon_unknown_short, NULL);
5978
5979         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5980                 netlogon_dissect_LEVEL, NDR_POINTER_UNIQUE,
5981                 "LEVEL pointer: unknown_NETLOGON_LEVEL", -1);
5982
5983         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
5984                 hf_netlogon_unknown_short, NULL);
5985
5986         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5987                 netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
5988                 "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
5989         return offset;
5990 }
5991
5992
5993 static int
5994 netlogon_dissect_netrlogonsamlogonex_reply(tvbuff_t *tvb, int offset,
5995         packet_info *pinfo, proto_tree *tree, guint8 *drep)
5996 {
5997         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
5998                 netlogon_dissect_VALIDATION, NDR_POINTER_UNIQUE,
5999                 "VALIDATION: unknown_NETLOGON_VALIDATION", -1);
6000
6001         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
6002                 netlogon_dissect_pointer_char, NDR_POINTER_UNIQUE,
6003                 "BOOLEAN pointer: unknown_BOOLEAN", hf_netlogon_unknown_char);
6004
6005         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
6006                 netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
6007                 "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
6008
6009         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
6010                                   hf_netlogon_rc, NULL);
6011
6012         return offset;
6013 }
6014
6015
6016 static int
6017 netlogon_dissect_dsrenumeratedomaintrusts_rqst(tvbuff_t *tvb, int offset,
6018         packet_info *pinfo, proto_tree *tree, guint8 *drep)
6019 {
6020         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6021                 pinfo, tree, drep);
6022
6023         offset = netlogon_dissect_DOMAIN_TRUST_FLAGS(tvb, offset, pinfo, tree, drep);
6024
6025         return offset;
6026 }
6027
6028
6029 static int
6030 netlogon_dissect_dsrenumeratedomaintrusts_reply(tvbuff_t *tvb, int offset,
6031         packet_info *pinfo, proto_tree *tree, guint8 *drep)
6032 {
6033         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
6034                 hf_netlogon_entries, NULL);
6035
6036         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
6037                 netlogon_dissect_DS_DOMAIN_TRUSTS_ARRAY, NDR_POINTER_UNIQUE,
6038                 "DS_DOMAIN_TRUSTS_ARRAY:", -1);
6039
6040         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
6041                                   hf_netlogon_rc, NULL);
6042
6043         return offset;
6044 }
6045
6046 static int
6047 netlogon_dissect_dsrderegisterdnshostrecords_rqst(tvbuff_t *tvb, int offset,
6048         packet_info *pinfo, proto_tree *tree, guint8 *drep)
6049 {
6050         offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
6051                 pinfo, tree, drep);
6052
6053         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
6054                 NDR_POINTER_UNIQUE, "Domain", hf_netlogon_logon_dom, 0);
6055
6056         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
6057                 dissect_nt_GUID, NDR_POINTER_UNIQUE,
6058                 "GUID pointer: domain_guid", -1);
6059
6060         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
6061                 dissect_nt_GUID, NDR_POINTER_UNIQUE,
6062                 "GUID pointer: dsa_guid", -1);
6063
6064         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
6065                 NDR_POINTER_REF, "dns_host", hf_netlogon_dns_host, 0);
6066
6067         return offset;
6068 }
6069
6070
6071 static int
6072 netlogon_dissect_dsrderegisterdnshostrecords_reply(tvbuff_t *tvb, int offset,
6073         packet_info *pinfo, proto_tree *tree, guint8 *drep)
6074 {
6075         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
6076                                   hf_netlogon_rc, NULL);
6077
6078         return offset;
6079 }
6080
6081 /* Dissect secure channel stuff */
6082
6083 static int hf_netlogon_secchan_bind_unknown1 = -1;
6084 static int hf_netlogon_secchan_bind_unknown2 = -1;
6085 static int hf_netlogon_secchan_domain = -1;
6086 static int hf_netlogon_secchan_host = -1;
6087 static int hf_netlogon_secchan_bind_ack_unknown1 = -1;
6088 static int hf_netlogon_secchan_bind_ack_unknown2 = -1;
6089 static int hf_netlogon_secchan_bind_ack_unknown3 = -1;
6090
6091 static gint ett_secchan_verf = -1;
6092 static gint ett_secchan_bind_creds = -1;
6093 static gint ett_secchan_bind_ack_creds = -1;
6094
6095 static int dissect_secchan_bind_creds(tvbuff_t *tvb, int offset,
6096                                       packet_info *pinfo, 
6097                                       proto_tree *tree, guint8 *drep)
6098 {
6099         proto_item *item = NULL;
6100         proto_tree *subtree = NULL;
6101         int len;
6102
6103         if (tree) {
6104                 item = proto_tree_add_text(
6105                         tree, tvb, offset, -1,
6106                         "Secure Channel Bind Credentials");
6107                 subtree = proto_item_add_subtree(
6108                         item, ett_secchan_bind_creds);
6109         }
6110
6111         /* We can't use the NDR routines as the DCERPC call data hasn't
6112            been initialised since we haven't made a DCERPC call yet, just
6113            a bind request. */
6114
6115         offset = dissect_dcerpc_uint32(
6116                 tvb, offset, pinfo, subtree, drep, 
6117                 hf_netlogon_secchan_bind_unknown1, NULL);
6118
6119         offset = dissect_dcerpc_uint32(
6120                 tvb, offset, pinfo, subtree, drep, 
6121                 hf_netlogon_secchan_bind_unknown2, NULL);
6122
6123         len = tvb_strsize(tvb, offset);
6124
6125         proto_tree_add_item(
6126                 subtree, hf_netlogon_secchan_domain, tvb, offset, len, FALSE);
6127
6128         offset += len;
6129
6130         len = tvb_strsize(tvb, offset);
6131
6132         proto_tree_add_item(
6133                 subtree, hf_netlogon_secchan_host, tvb, offset, len, FALSE);
6134
6135         offset += len;
6136
6137         return offset;
6138 }
6139
6140 static int dissect_secchan_bind_ack_creds(tvbuff_t *tvb, int offset,
6141                                           packet_info *pinfo, 
6142                                           proto_tree *tree, guint8 *drep)
6143 {
6144         proto_item *item = NULL;
6145         proto_tree *subtree = NULL;
6146
6147         if (tree) {
6148                 item = proto_tree_add_text(
6149                         tree, tvb, offset, -1,
6150                         "Secure Channel Bind ACK Credentials");
6151                 subtree = proto_item_add_subtree(
6152                         item, ett_secchan_bind_ack_creds);
6153         }
6154
6155         /* Don't use NDR routines here */
6156
6157         offset = dissect_dcerpc_uint32(
6158                 tvb, offset, pinfo, subtree, drep, 
6159                 hf_netlogon_secchan_bind_ack_unknown1, NULL);
6160
6161         offset = dissect_dcerpc_uint32(
6162                 tvb, offset, pinfo, subtree, drep, 
6163                 hf_netlogon_secchan_bind_ack_unknown2, NULL);
6164
6165         offset = dissect_dcerpc_uint32(
6166                 tvb, offset, pinfo, subtree, drep, 
6167                 hf_netlogon_secchan_bind_ack_unknown3, NULL);
6168
6169         return offset;
6170 }
6171
6172 /* Subdissectors */
6173
6174 static dcerpc_sub_dissector dcerpc_netlogon_dissectors[] = {
6175         { NETLOGON_NETRLOGONUASLOGON, "NetrLogonUasLogon",
6176                 netlogon_dissect_netrlogonuaslogon_rqst,
6177                 netlogon_dissect_netrlogonuaslogon_reply },
6178         { NETLOGON_NETRLOGONUASLOGOFF, "NetrLogonUasLogoff",
6179                 netlogon_dissect_netrlogonuaslogoff_rqst,
6180                 netlogon_dissect_netrlogonuaslogoff_reply },
6181         { NETLOGON_NETRLOGONSAMLOGON, "NetrLogonSamLogon",
6182                 netlogon_dissect_netrlogonsamlogon_rqst,
6183                 netlogon_dissect_netrlogonsamlogon_reply },
6184         { NETLOGON_NETRLOGONSAMLOGOFF, "NetrLogonSamLogoff",
6185                 netlogon_dissect_netrlogonsamlogoff_rqst,
6186                 netlogon_dissect_netrlogonsamlogoff_reply },
6187         { NETLOGON_NETRSERVERREQCHALLENGE, "NetrServerReqChallenge",
6188                 netlogon_dissect_netrserverreqchallenge_rqst,
6189                 netlogon_dissect_netrserverreqchallenge_reply },
6190         { NETLOGON_NETRSERVERAUTHENTICATE, "NetrServerAuthenticate",
6191                 netlogon_dissect_netrserverauthenticate_rqst,
6192                 netlogon_dissect_netrserverauthenticate_reply },
6193         { NETLOGON_NETRSERVERPASSWORDSET, "NetrServerPasswordSet",
6194                 netlogon_dissect_netrserverpasswordset_rqst,
6195                 netlogon_dissect_netrserverpasswordset_reply },
6196         { NETLOGON_NETRDATABASEDELTAS, "NetrDatabaseDeltas",
6197                 netlogon_dissect_netrdatabasedeltas_rqst,
6198                 netlogon_dissect_netrdatabasedeltas_reply },
6199         { NETLOGON_NETRDATABASESYNC, "NetrDatabaseSync",
6200                 netlogon_dissect_netrdatabasesync_rqst,
6201                 netlogon_dissect_netrdatabasesync_reply },
6202         { NETLOGON_NETRACCOUNTDELTAS, "NetrAccountDeltas",
6203                 netlogon_dissect_netraccountdeltas_rqst,
6204                 netlogon_dissect_netraccountdeltas_reply },
6205         { NETLOGON_NETRACCOUNTSYNC, "NetrAccountSync",
6206                 netlogon_dissect_netraccountsync_rqst,
6207                 netlogon_dissect_netraccountsync_reply },
6208         { NETLOGON_NETRGETDCNAME, "NetrGetDCName",
6209                 netlogon_dissect_netrgetdcname_rqst,
6210                 netlogon_dissect_netrgetdcname_reply },
6211         { NETLOGON_NETRLOGONCONTROL, "NetrLogonControl",
6212                 netlogon_dissect_netrlogoncontrol_rqst,
6213                 netlogon_dissect_netrlogoncontrol_reply },
6214         { NETLOGON_NETRGETANYDCNAME, "NetrGetAnyDCName",
6215                 netlogon_dissect_netrgetanydcname_rqst,
6216                 netlogon_dissect_netrgetanydcname_reply },
6217         { NETLOGON_NETRLOGONCONTROL2, "NetrLogonControl2",
6218                 netlogon_dissect_netrlogoncontrol2_rqst,
6219                 netlogon_dissect_netrlogoncontrol2_reply },
6220         { NETLOGON_NETRSERVERAUTHENTICATE2, "NetrServerAuthenticate2",
6221                 netlogon_dissect_netrserverauthenticate2_rqst,
6222                 netlogon_dissect_netrserverauthenticate2_reply },
6223         { NETLOGON_NETRDATABASESYNC2, "NetrDatabaseSync2",
6224                 netlogon_dissect_netrdatabasesync2_rqst,
6225                 netlogon_dissect_netrdatabasesync2_reply },
6226         { NETLOGON_NETRDATABASEREDO, "NetrDatabaseRedo",
6227                 netlogon_dissect_netrdatabaseredo_rqst,
6228                 netlogon_dissect_netrdatabaseredo_reply },
6229         { NETLOGON_NETRLOGONCONTROL2EX, "NetrLogonControl2Ex",
6230                 netlogon_dissect_netrlogoncontrol2ex_rqst,
6231                 netlogon_dissect_netrlogoncontrol2ex_reply },
6232         { NETLOGON_NETRENUMERATETRUSTEDDOMAINS, "NetrEnumerateTrustedDomains",
6233                 netlogon_dissect_netrenumeratetrusteddomains_rqst,
6234                 netlogon_dissect_netrenumeratetrusteddomains_reply },
6235         { NETLOGON_DSRGETDCNAME, "DsrGetDcName",
6236                 netlogon_dissect_dsrgetdcname_rqst,
6237                 netlogon_dissect_dsrgetdcname_reply },
6238         { NETLOGON_NETRLOGONDUMMYROUTINE1, "NetrLogonDummyRoutine1",
6239                 netlogon_dissect_netrlogondummyroutine1_rqst,
6240                 netlogon_dissect_netrlogondummyroutine1_reply },
6241         { NETLOGON_NETRLOGONSETSERVICEBITS, "NetrLogonSetServiceBits",
6242                 netlogon_dissect_netrlogonsetservicebits_rqst,
6243                 netlogon_dissect_netrlogonsetservicebits_reply },
6244         { NETLOGON_NETRLOGONGETTRUSTRID, "NetrLogonGetTrustRid",
6245                 netlogon_dissect_netrlogongettrustrid_rqst,
6246                 netlogon_dissect_netrlogongettrustrid_reply },
6247         { NETLOGON_NETRLOGONCOMPUTESERVERDIGEST, "NetrLogonComputeServerDigest",
6248                 netlogon_dissect_netrlogoncomputeserverdigest_rqst,
6249                 netlogon_dissect_netrlogoncomputeserverdigest_reply },
6250         { NETLOGON_NETRLOGONCOMPUTECLIENTDIGEST, "NetrLogonComputeClientDigest",
6251                 netlogon_dissect_netrlogoncomputeclientdigest_rqst,
6252                 netlogon_dissect_netrlogoncomputeclientdigest_reply },
6253         { NETLOGON_NETRSERVERAUTHENTICATE3, "NetrServerAuthenticate3",
6254                 netlogon_dissect_netrserverauthenticate3_rqst,
6255                 netlogon_dissect_netrserverauthenticate3_reply },
6256         { NETLOGON_DSRGETDCNAMEX, "DsrGetDcNameEx",
6257                 netlogon_dissect_dsrgetdcnameex_rqst,
6258                 netlogon_dissect_dsrgetdcnameex_reply },
6259         { NETLOGON_DSRGETSITENAME, "DsrGetSiteName",
6260                 netlogon_dissect_dsrgetsitename_rqst,
6261                 netlogon_dissect_dsrgetsitename_reply },
6262         { NETLOGON_NETRLOGONGETDOMAININFO, "NetrLogonGetDomainInfo",
6263                 netlogon_dissect_netrlogongetdomaininfo_rqst,
6264                 netlogon_dissect_netrlogongetdomaininfo_reply },
6265         { NETLOGON_NETRSERVERPASSWORDSET2, "NetrServerPasswordSet2",
6266                 netlogon_dissect_netrserverpasswordset2_rqst,
6267                 netlogon_dissect_netrserverpasswordset2_reply },
6268         { NETLOGON_NETRSERVERPASSWORDGET, "NetrServerPasswordGet",
6269                 netlogon_dissect_netrserverpasswordget_rqst,
6270                 netlogon_dissect_netrserverpasswordget_reply },
6271         { NETLOGON_NETRLOGONSENDTOSAM, "NetrLogonSendToSam",
6272                 netlogon_dissect_netrlogonsendtosam_rqst,
6273                 netlogon_dissect_netrlogonsendtosam_reply },
6274         { NETLOGON_DSRADDRESSTOSITENAMESW, "DsrAddressToSiteNamesW",
6275                 netlogon_dissect_dsraddresstositenamesw_rqst,
6276                 netlogon_dissect_dsraddresstositenamesw_reply },
6277         { NETLOGON_DSRGETDCNAMEEX2, "DsrGetDcNameEx2",
6278                 netlogon_dissect_dsrgetdcnameex2_rqst,
6279                 netlogon_dissect_dsrgetdcnameex2_reply },
6280         { NETLOGON_NETRLOGONGETTIMESERVICEPARENTDOMAIN, 
6281                 "NetrLogonGetTimeServiceParentDomain",
6282                 netlogon_dissect_netrlogongettimeserviceparentdomain_rqst,
6283                 netlogon_dissect_netrlogongettimeserviceparentdomain_reply },
6284         { NETLOGON_NETRENUMERATETRUSTEDDOMAINSEX, "NetrEnumerateTrustedDomainsEx",
6285                 netlogon_dissect_netrenumeratetrusteddomainsex_rqst,
6286                 netlogon_dissect_netrenumeratetrusteddomainsex_reply },
6287         { NETLOGON_DSRADDRESSTOSITENAMESEXW, "DsrAddressToSiteNamesExW",
6288                 netlogon_dissect_dsraddresstositenamesexw_rqst,
6289                 netlogon_dissect_dsraddresstositenamesexw_reply },
6290         { NETLOGON_DSRGETDCSITECOVERAGEW, "DsrGetDcSiteCoverageW",
6291                 netlogon_dissect_dsrgetdcsitecoveragew_rqst,
6292                 netlogon_dissect_dsrgetdcsitecoveragew_reply },
6293         { NETLOGON_NETRLOGONSAMLOGONEX, "NetrLogonSamLogonEx",
6294                 netlogon_dissect_netrlogonsamlogonex_rqst,
6295                 netlogon_dissect_netrlogonsamlogonex_reply },
6296         { NETLOGON_DSRENUMERATEDOMAINTRUSTS, "DsrEnumerateDomainTrusts",
6297                 netlogon_dissect_dsrenumeratedomaintrusts_rqst,
6298                 netlogon_dissect_dsrenumeratedomaintrusts_reply },
6299         { NETLOGON_DSRDEREGISTERDNSHOSTRECORDS, "DsrDeregisterDnsHostRecords",
6300                 netlogon_dissect_dsrderegisterdnshostrecords_rqst,
6301                 netlogon_dissect_dsrderegisterdnshostrecords_reply },
6302         { NETLOGON_NETRSERVERTRUSTPASSWORDSGET, "NetrServerTrustPasswordsGet",
6303                 NULL, NULL },
6304         { NETLOGON_DSRGETFORESTTRUSTINFORMATION, "DsrGetForestTrustInformation",
6305                 NULL, NULL },
6306         { NETLOGON_NETRGETFORESTTRUSTINFORMATION, "NetrGetForestTrustInformation",
6307                 NULL, NULL },
6308         { NETLOGON_NETRLOGONSAMLOGONWITHFLAGS, "NetrLogonSamLogonWithFlags", 
6309                 NULL, NULL },
6310         { NETLOGON_NETRSERVERGETTRUSTINFO, "NetrServerGetTrustInfo",
6311                 NULL, NULL },
6312         {0, NULL, NULL,  NULL }
6313 };
6314
6315 static int hf_netlogon_secchan_verf = -1;
6316 static int hf_netlogon_secchan_verf_sig = -1;
6317 static int hf_netlogon_secchan_verf_unk = -1;
6318 static int hf_netlogon_secchan_verf_seq = -1;
6319 static int hf_netlogon_secchan_verf_nonce = -1;
6320
6321 static int
6322 dissect_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
6323                      proto_tree *tree, guint8 *drep _U_)
6324 {
6325           proto_item *vf = NULL;
6326           proto_tree *subtree = NULL;
6327           
6328           /*
6329            * Create a new tree, and split into 4 components ...
6330            */
6331           vf = proto_tree_add_item(tree, hf_netlogon_secchan_verf, tvb,
6332               offset, -1, FALSE);
6333           subtree = proto_item_add_subtree(vf, ett_secchan_verf);
6334
6335           proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sig, tvb,
6336               offset, 8, FALSE);
6337           offset += 8;
6338
6339           proto_tree_add_item(subtree, hf_netlogon_secchan_verf_unk, tvb,
6340               offset, 8, FALSE);
6341           offset += 8;
6342
6343           proto_tree_add_item(subtree, hf_netlogon_secchan_verf_seq, tvb,
6344               offset, 8, FALSE);
6345           offset += 8;
6346
6347           /* In some cases the nonce isn't present although it isn't clear
6348              why this is so. */
6349
6350           if (tvb_bytes_exist(tvb, offset, 8)) {
6351                   proto_tree_add_item(subtree, hf_netlogon_secchan_verf_nonce,
6352                                       tvb, offset, 8, FALSE);
6353                   offset += 8;
6354           }
6355
6356           return offset;
6357 }
6358
6359 /* Secure channel types */
6360
6361 static const value_string sec_chan_type_vals[] = {
6362         { SEC_CHAN_WKSTA,  "Workstation" },
6363         { SEC_CHAN_DOMAIN, "Domain trust" },
6364         { SEC_CHAN_BDC,    "Backup domain controller" },
6365         { 0, NULL }
6366 };
6367
6368 void
6369 proto_register_dcerpc_netlogon(void)
6370 {
6371
6372 static hf_register_info hf[] = {
6373         { &hf_netlogon_opnum,
6374           { "Operation", "netlogon.opnum", FT_UINT16, BASE_DEC,
6375             NULL, 0x0, "Operation", HFILL }},
6376
6377         { &hf_netlogon_rc, {
6378                 "Return code", "netlogon.rc", FT_UINT32, BASE_HEX,
6379                 VALS(NT_errors), 0x0, "Netlogon return code", HFILL }},
6380
6381         { &hf_netlogon_param_ctrl, {
6382                 "Param Ctrl", "netlogon.param_ctrl", FT_UINT32, BASE_HEX,
6383                 NULL, 0x0, "Param ctrl", HFILL }},
6384
6385         { &hf_netlogon_logon_id, {
6386                 "Logon ID", "netlogon.logon_id", FT_UINT64, BASE_DEC,
6387                 NULL, 0x0, "Logon ID", HFILL }},
6388
6389         { &hf_netlogon_modify_count, {
6390                 "Modify Count", "netlogon.modify_count", FT_UINT64, BASE_DEC,
6391                 NULL, 0x0, "How many times the object has been modified", HFILL }},
6392
6393         { &hf_netlogon_security_information, {
6394                 "Security Information", "netlogon.security_information", FT_UINT32, BASE_DEC,
6395                 NULL, 0x0, "Security Information", HFILL }},
6396
6397         { &hf_netlogon_count, {
6398                 "Count", "netlogon.count", FT_UINT32, BASE_DEC,
6399                 NULL, 0x0, "", HFILL }},
6400
6401         { &hf_netlogon_entries, {
6402                 "Entries", "netlogon.entries", FT_UINT32, BASE_DEC,
6403                 NULL, 0x0, "", HFILL }},
6404
6405         { &hf_netlogon_credential, {
6406                 "Credential", "netlogon.credential", FT_BYTES, BASE_HEX,
6407                 NULL, 0x0, "Netlogon Credential", HFILL }},
6408
6409         { &hf_netlogon_challenge, {
6410                 "Challenge", "netlogon.challenge", FT_BYTES, BASE_HEX,
6411                 NULL, 0x0, "Netlogon challenge", HFILL }},
6412
6413         { &hf_netlogon_lm_owf_password, {
6414                 "LM Pwd", "netlogon.lm_owf_pwd", FT_BYTES, BASE_HEX,
6415                 NULL, 0x0, "LanManager OWF Password", HFILL }},
6416
6417         { &hf_netlogon_user_session_key, {
6418                 "User Session Key", "netlogon.user_session_key", FT_BYTES, BASE_HEX,
6419                 NULL, 0x0, "User Session Key", HFILL }},
6420
6421         { &hf_netlogon_encrypted_lm_owf_password, {
6422                 "Encrypted LM Pwd", "netlogon.lm_owf_pwd.encrypted", FT_BYTES, BASE_HEX,
6423                 NULL, 0x0, "Encrypted LanManager OWF Password", HFILL }},
6424
6425         { &hf_netlogon_nt_owf_password, {
6426                 "NT Pwd", "netlogon.nt_owf_pwd", FT_BYTES, BASE_HEX,
6427                 NULL, 0x0, "NT OWF Password", HFILL }},
6428
6429         { &hf_netlogon_blob, {
6430                 "BLOB", "netlogon.blob", FT_BYTES, BASE_HEX,
6431                 NULL, 0x0, "BLOB", HFILL }},
6432
6433         { &hf_netlogon_len, {
6434                 "Len", "netlogon.len", FT_UINT32, BASE_DEC,
6435                 NULL, 0, "Length", HFILL }},
6436
6437         { &hf_netlogon_priv, {
6438                 "Priv", "netlogon.priv", FT_UINT32, BASE_DEC,
6439                 NULL, 0, "", HFILL }},
6440
6441         { &hf_netlogon_privilege_entries, {
6442                 "Privilege Entries", "netlogon.privilege_entries", FT_UINT32, BASE_DEC,
6443                 NULL, 0, "", HFILL }},
6444
6445         { &hf_netlogon_privilege_control, {
6446                 "Privilege Control", "netlogon.privilege_control", FT_UINT32, BASE_HEX,
6447                 NULL, 0, "", HFILL }},
6448
6449         { &hf_netlogon_privilege_name, {
6450                 "Privilege Name", "netlogon.privilege_name", FT_STRING, BASE_HEX,
6451                 NULL, 0, "", HFILL }},
6452
6453         { &hf_netlogon_pdc_connection_status, {
6454                 "PDC Connection Status", "netlogon.pdc_connection_status", FT_UINT32, BASE_DEC,
6455                 NULL, 0, "PDC Connection Status", HFILL }},
6456
6457         { &hf_netlogon_tc_connection_status, {
6458                 "TC Connection Status", "netlogon.tc_connection_status", FT_UINT32, BASE_DEC,
6459                 NULL, 0, "TC Connection Status", HFILL }},
6460
6461         { &hf_netlogon_attrs, {
6462                 "Attributes", "netlogon.attrs", FT_UINT32, BASE_HEX,
6463                 NULL, 0, "Attributes", HFILL }},
6464
6465         { &hf_netlogon_unknown_string,
6466                 { "Unknown string", "netlogon.unknown_string", FT_STRING, BASE_NONE,
6467                 NULL, 0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }},
6468         { &hf_netlogon_unknown_long,
6469                 { "Unknown long", "netlogon.unknown.long", FT_UINT32, BASE_HEX,
6470                 NULL, 0x0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
6471         { &hf_netlogon_reserved,
6472                 { "Reserved", "netlogon.reserved", FT_UINT32, BASE_HEX,
6473                 NULL, 0x0, "Reserved", HFILL }},
6474         { &hf_netlogon_unknown_short,
6475                 { "Unknown short", "netlogon.unknown.short", FT_UINT16, BASE_HEX,
6476                 NULL, 0x0, "Unknown short. If you know what this is, contact ethereal developers.", HFILL }},
6477
6478         { &hf_netlogon_unknown_char,
6479                 { "Unknown char", "netlogon.unknown.char", FT_UINT8, BASE_HEX,
6480                 NULL, 0x0, "Unknown char. If you know what this is, contact ethereal developers.", HFILL }},
6481
6482         { &hf_netlogon_acct_expiry_time,
6483                 { "Acct Expiry Time", "netlogon.acct.expiry_time", FT_ABSOLUTE_TIME, BASE_NONE,
6484                 NULL, 0x0, "When this account will expire", HFILL }},
6485
6486         { &hf_netlogon_nt_pwd_present,
6487                 { "NT PWD Present", "netlogon.nt_pwd_present", FT_UINT8, BASE_HEX,
6488                 NULL, 0x0, "Is NT password present for this account?", HFILL }},
6489
6490         { &hf_netlogon_lm_pwd_present,
6491                 { "LM PWD Present", "netlogon.lm_pwd_present", FT_UINT8, BASE_HEX,
6492                 NULL, 0x0, "Is LanManager password present for this account?", HFILL }},
6493
6494         { &hf_netlogon_pwd_expired,
6495                 { "PWD Expired", "netlogon.pwd_expired", FT_UINT8, BASE_HEX,
6496                 NULL, 0x0, "Whether this password has expired or not", HFILL }},
6497
6498         { &hf_netlogon_authoritative,
6499                 { "Authoritative", "netlogon.authoritative", FT_UINT8, BASE_DEC,
6500                 NULL, 0x0, "", HFILL }},
6501
6502         { &hf_netlogon_sensitive_data_flag,
6503                 { "Sensitive Data", "netlogon.sensitive_data_flag", FT_UINT8, BASE_DEC,
6504                 NULL, 0x0, "Sensitive data flag", HFILL }},
6505
6506         { &hf_netlogon_auditing_mode,
6507                 { "Auditing Mode", "netlogon.auditing_mode", FT_UINT8, BASE_DEC,
6508                 NULL, 0x0, "Auditing Mode", HFILL }},
6509
6510         { &hf_netlogon_max_audit_event_count,
6511                 { "Max Audit Event Count", "netlogon.max_audit_event_count", FT_UINT32, BASE_DEC,
6512                 NULL, 0x0, "Max audit event count", HFILL }},
6513
6514         { &hf_netlogon_event_audit_option,
6515                 { "Event Audit Option", "netlogon.event_audit_option", FT_UINT32, BASE_HEX,
6516                 NULL, 0x0, "Event audit option", HFILL }},
6517
6518         { &hf_netlogon_sensitive_data_len,
6519                 { "Length", "netlogon.sensitive_data_len", FT_UINT32, BASE_DEC,
6520                 NULL, 0x0, "Length of sensitive data", HFILL }},
6521
6522         { &hf_netlogon_nt_chal_resp,
6523                 { "NT Chal resp", "netlogon.nt_chal_resp", FT_BYTES, BASE_HEX,
6524                 NULL, 0, "Challenge response for NT authentication", HFILL }},
6525
6526         { &hf_netlogon_lm_chal_resp,
6527                 { "LM Chal resp", "netlogon.lm_chal_resp", FT_BYTES, BASE_HEX,
6528                 NULL, 0, "Challenge response for LM authentication", HFILL }},
6529
6530         { &hf_netlogon_cipher_len,
6531                 { "Cipher Len", "netlogon.cipher_len", FT_UINT32, BASE_DEC,
6532                 NULL, 0, "", HFILL }},
6533
6534         { &hf_netlogon_cipher_maxlen,
6535                 { "Cipher Max Len", "netlogon.cipher_maxlen", FT_UINT32, BASE_DEC,
6536                 NULL, 0, "", HFILL }},
6537
6538         { &hf_netlogon_pac_data,
6539                 { "Pac Data", "netlogon.pac.data", FT_BYTES, BASE_HEX,
6540                 NULL, 0, "Pac Data", HFILL }},
6541
6542         { &hf_netlogon_sensitive_data,
6543                 { "Data", "netlogon.sensitive_data", FT_BYTES, BASE_HEX,
6544                 NULL, 0, "Sensitive Data", HFILL }},
6545
6546         { &hf_netlogon_auth_data,
6547                 { "Auth Data", "netlogon.auth.data", FT_BYTES, BASE_HEX,
6548                 NULL, 0, "Auth Data", HFILL }},
6549
6550         { &hf_netlogon_cipher_current_data,
6551                 { "Cipher Current Data", "netlogon.cipher_current_data", FT_BYTES, BASE_HEX,
6552                 NULL, 0, "", HFILL }},
6553
6554         { &hf_netlogon_cipher_old_data,
6555                 { "Cipher Old Data", "netlogon.cipher_old_data", FT_BYTES, BASE_HEX,
6556                 NULL, 0, "", HFILL }},
6557
6558         { &hf_netlogon_acct_name,
6559                 { "Acct Name", "netlogon.acct_name", FT_STRING, BASE_NONE,
6560                 NULL, 0, "Account Name", HFILL }},
6561
6562         { &hf_netlogon_acct_desc,
6563                 { "Acct Desc", "netlogon.acct_desc", FT_STRING, BASE_NONE,
6564                 NULL, 0, "Account Description", HFILL }},
6565
6566         { &hf_netlogon_group_desc,
6567                 { "Group Desc", "netlogon.group_desc", FT_STRING, BASE_NONE,
6568                 NULL, 0, "Group Description", HFILL }},
6569
6570         { &hf_netlogon_full_name,
6571                 { "Full Name", "netlogon.full_name", FT_STRING, BASE_NONE,
6572                 NULL, 0, "Full Name", HFILL }},
6573
6574         { &hf_netlogon_comment,
6575                 { "Comment", "netlogon.comment", FT_STRING, BASE_NONE,
6576                 NULL, 0, "Comment", HFILL }},
6577
6578         { &hf_netlogon_parameters,
6579                 { "Parameters", "netlogon.parameters", FT_STRING, BASE_NONE,
6580                 NULL, 0, "Parameters", HFILL }},
6581
6582         { &hf_netlogon_logon_script,
6583                 { "Logon Script", "netlogon.logon_script", FT_STRING, BASE_NONE,
6584                 NULL, 0, "Logon Script", HFILL }},
6585
6586         { &hf_netlogon_profile_path,
6587                 { "Profile Path", "netlogon.profile_path", FT_STRING, BASE_NONE,
6588                 NULL, 0, "Profile Path", HFILL }},
6589
6590         { &hf_netlogon_home_dir,
6591                 { "Home Dir", "netlogon.home_dir", FT_STRING, BASE_NONE,
6592                 NULL, 0, "Home Directory", HFILL }},
6593
6594         { &hf_netlogon_dir_drive,
6595                 { "Dir Drive", "netlogon.dir_drive", FT_STRING, BASE_NONE,
6596                 NULL, 0, "Drive letter for home directory", HFILL }},
6597
6598         { &hf_netlogon_logon_srv,
6599                 { "Server", "netlogon.server", FT_STRING, BASE_NONE,
6600                 NULL, 0, "Server", HFILL }},
6601
6602         { &hf_netlogon_principal,
6603                 { "Principal", "netlogon.principal", FT_STRING, BASE_NONE,
6604                 NULL, 0, "Principal", HFILL }},
6605
6606         { &hf_netlogon_logon_dom,
6607                 { "Domain", "netlogon.domain", FT_STRING, BASE_NONE,
6608                 NULL, 0, "Domain", HFILL }},
6609
6610         { &hf_netlogon_resourcegroupdomainsid,
6611                 { "ResourceGroupDomainSID", "netlogon.resourcegroupdomainsid", FT_STRING, BASE_NONE,
6612                 NULL, 0, "Resource Group Domain SID", HFILL }},
6613
6614         { &hf_netlogon_resourcegroupcount,
6615                 { "ResourceGroup count", "netlogon.resourcegroupcount", FT_UINT32, BASE_DEC,
6616                 NULL, 0, "Number of Resource Groups", HFILL }},
6617
6618         { &hf_netlogon_computer_name,
6619                 { "Computer Name", "netlogon.computer_name", FT_STRING, BASE_NONE,
6620                 NULL, 0, "Computer Name", HFILL }},
6621
6622         { &hf_netlogon_site_name,
6623                 { "Site Name", "netlogon.site_name", FT_STRING, BASE_NONE,
6624                 NULL, 0, "Site Name", HFILL }},
6625
6626         { &hf_netlogon_dc_name,
6627                 { "DC Name", "netlogon.dc.name", FT_STRING, BASE_NONE,
6628                 NULL, 0, "DC Name", HFILL }},
6629
6630         { &hf_netlogon_dc_site_name,
6631                 { "DC Site Name", "netlogon.dc.site_name", FT_STRING, BASE_NONE,
6632                 NULL, 0, "DC Site Name", HFILL }},
6633
6634         { &hf_netlogon_dns_forest_name,
6635                 { "DNS Forest Name", "netlogon.dns.forest_name", FT_STRING, BASE_NONE,
6636                 NULL, 0, "DNS Forest Name", HFILL }},
6637
6638         { &hf_netlogon_dc_address,
6639                 { "DC Address", "netlogon.dc.address", FT_STRING, BASE_NONE,
6640                 NULL, 0, "DC Address", HFILL }},
6641
6642         { &hf_netlogon_dc_address_type,
6643                 { "DC Address Type", "netlogon.dc.address_type", FT_UINT32, BASE_DEC,
6644                 VALS(dc_address_types), 0, "DC Address Type", HFILL }},
6645
6646         { &hf_netlogon_client_site_name,
6647                 { "Client Site Name", "netlogon.client.site_name", FT_STRING, BASE_NONE,
6648                 NULL, 0, "Client Site Name", HFILL }},
6649
6650         { &hf_netlogon_workstation_site_name,
6651                 { "Wkst Site Name", "netlogon.wkst.site_name", FT_STRING, BASE_NONE,
6652                 NULL, 0, "Workstation Site Name", HFILL }},
6653
6654         { &hf_netlogon_workstation,
6655                 { "Wkst Name", "netlogon.wkst.name", FT_STRING, BASE_NONE,
6656                 NULL, 0, "Workstation Name", HFILL }},
6657
6658         { &hf_netlogon_workstation_os,
6659                 { "Wkst OS", "netlogon.wkst.os", FT_STRING, BASE_NONE,
6660                 NULL, 0, "Workstation OS", HFILL }},
6661
6662         { &hf_netlogon_workstations,
6663                 { "Workstations", "netlogon.wksts", FT_STRING, BASE_NONE,
6664                 NULL, 0, "Workstations", HFILL }},
6665
6666         { &hf_netlogon_workstation_fqdn,
6667                 { "Wkst FQDN", "netlogon.wkst.fqdn", FT_STRING, BASE_NONE,
6668                 NULL, 0, "Workstation FQDN", HFILL }},
6669
6670         { &hf_netlogon_group_name,
6671                 { "Group Name", "netlogon.group_name", FT_STRING, BASE_NONE,
6672                 NULL, 0, "Group Name", HFILL }},
6673
6674         { &hf_netlogon_alias_name,
6675                 { "Alias Name", "netlogon.alias_name", FT_STRING, BASE_NONE,
6676                 NULL, 0, "Alias Name", HFILL }},
6677
6678         { &hf_netlogon_dns_host,
6679                 { "DNS Host", "netlogon.dns_host", FT_STRING, BASE_NONE,
6680                 NULL, 0, "DNS Host", HFILL }},
6681
6682         { &hf_netlogon_downlevel_domain_name,
6683                 { "Downlevel Domain", "netlogon.downlevel_domain", FT_STRING, BASE_NONE,
6684                 NULL, 0, "Downlevel Domain Name", HFILL }},
6685
6686         { &hf_netlogon_dns_domain_name,
6687                 { "DNS Domain", "netlogon.dns_domain", FT_STRING, BASE_NONE,
6688                 NULL, 0, "DNS Domain Name", HFILL }},
6689
6690         { &hf_netlogon_domain_name,
6691                 { "Domain", "netlogon.domain", FT_STRING, BASE_NONE,
6692                 NULL, 0, "Domain Name", HFILL }},
6693
6694         { &hf_netlogon_oem_info,
6695                 { "OEM Info", "netlogon.oem_info", FT_STRING, BASE_NONE,
6696                 NULL, 0, "OEM Info", HFILL }},
6697
6698         { &hf_netlogon_trusted_dc_name,
6699                 { "Trusted DC", "netlogon.trusted_dc", FT_STRING, BASE_NONE,
6700                 NULL, 0, "Trusted DC", HFILL }},
6701
6702         { &hf_netlogon_logonsrv_handle,
6703                 { "Handle", "netlogon.handle", FT_STRING, BASE_NONE,
6704                 NULL, 0, "Logon Srv Handle", HFILL }},
6705
6706         { &hf_netlogon_dummy,
6707                 { "Dummy", "netlogon.dummy", FT_STRING, BASE_NONE,
6708                 NULL, 0, "Dummy string", HFILL }},
6709
6710         { &hf_netlogon_logon_count16,
6711                 { "Logon Count", "netlogon.logon_count16", FT_UINT16, BASE_DEC,
6712                 NULL, 0x0, "Number of successful logins", HFILL }},
6713
6714         { &hf_netlogon_logon_count,
6715                 { "Logon Count", "netlogon.logon_count", FT_UINT32, BASE_DEC,
6716                 NULL, 0x0, "Number of successful logins", HFILL }},
6717
6718         { &hf_netlogon_bad_pw_count16,
6719                 { "Bad PW Count", "netlogon.bad_pw_count16", FT_UINT16, BASE_DEC,
6720                 NULL, 0x0, "Number of failed logins", HFILL }},
6721
6722         { &hf_netlogon_bad_pw_count,
6723                 { "Bad PW Count", "netlogon.bad_pw_count", FT_UINT32, BASE_DEC,
6724                 NULL, 0x0, "Number of failed logins", HFILL }},
6725
6726         { &hf_netlogon_country,
6727                 { "Country", "netlogon.country", FT_UINT16, BASE_DEC,
6728                 VALS(ms_country_codes), 0x0, "Country setting for this account", HFILL }},
6729
6730         { &hf_netlogon_codepage,
6731                 { "Codepage", "netlogon.codepage", FT_UINT16, BASE_DEC,
6732                 NULL, 0x0, "Codepage setting for this account", HFILL }},
6733
6734         { &hf_netlogon_level16,
6735                 { "Level", "netlogon.level16", FT_UINT16, BASE_DEC,
6736                 NULL, 0x0, "Which option of the union is represented here", HFILL }},
6737
6738         { &hf_netlogon_validation_level,
6739                 { "Validation Level", "netlogon.validation_level", FT_UINT16, BASE_DEC,
6740                 NULL, 0x0, "Requested level of validation", HFILL }},
6741
6742         { &hf_netlogon_minpasswdlen,
6743                 { "Min Password Len", "netlogon.min_passwd_len", FT_UINT16, BASE_DEC,
6744                 NULL, 0x0, "Minimum length of password", HFILL }},
6745
6746         { &hf_netlogon_passwdhistorylen,
6747                 { "Passwd History Len", "netlogon.passwd_history_len", FT_UINT16, BASE_DEC,
6748                 NULL, 0x0, "Length of password history", HFILL }},
6749
6750         { &hf_netlogon_secure_channel_type,
6751                 { "Sec Chan Type", "netlogon.sec_chan_type", FT_UINT16, BASE_DEC,
6752                 VALS(sec_chan_type_vals), 0x0, "Secure Channel Type", HFILL }},
6753
6754         { &hf_netlogon_restart_state,
6755                 { "Restart State", "netlogon.restart_state", FT_UINT16, BASE_DEC,
6756                 NULL, 0x0, "Restart State", HFILL }},
6757
6758         { &hf_netlogon_delta_type,
6759                 { "Delta Type", "netlogon.delta_type", FT_UINT16, BASE_DEC,
6760                 VALS(delta_type_vals), 0x0, "Delta Type", HFILL }},
6761
6762         { &hf_netlogon_blob_size,
6763                 { "Size", "netlogon.blob.size", FT_UINT32, BASE_DEC,
6764                 NULL, 0x0, "Size in bytes of BLOB", HFILL }},
6765
6766         { &hf_netlogon_code,
6767                 { "Code", "netlogon.code", FT_UINT32, BASE_HEX,
6768                 NULL, 0x0, "Code", HFILL }},
6769
6770         { &hf_netlogon_level,
6771                 { "Level", "netlogon.level", FT_UINT32, BASE_DEC,
6772                 NULL, 0x0, "Which option of the union is represented here", HFILL }},
6773
6774         { &hf_netlogon_reference,
6775                 { "Reference", "netlogon.reference", FT_UINT32, BASE_DEC,
6776                 NULL, 0x0, "", HFILL }},
6777
6778         { &hf_netlogon_next_reference,
6779                 { "Next Reference", "netlogon.next_reference", FT_UINT32, BASE_DEC,
6780                 NULL, 0x0, "", HFILL }},
6781
6782         { &hf_netlogon_timestamp,
6783                 { "Timestamp", "netlogon.timestamp", FT_ABSOLUTE_TIME, BASE_NONE,
6784                 NULL, 0, "", HFILL }},
6785
6786         { &hf_netlogon_user_rid,
6787                 { "User RID", "netlogon.rid", FT_UINT32, BASE_DEC,
6788                 NULL, 0x0, "", HFILL }},
6789
6790         { &hf_netlogon_alias_rid,
6791                 { "Alias RID", "netlogon.alias_rid", FT_UINT32, BASE_DEC,
6792                 NULL, 0x0, "", HFILL }},
6793
6794         { &hf_netlogon_group_rid,
6795                 { "Group RID", "netlogon.group_rid", FT_UINT32, BASE_DEC,
6796                 NULL, 0x0, "", HFILL }},
6797
6798         { &hf_netlogon_num_rids,
6799                 { "Num RIDs", "netlogon.num_rids", FT_UINT32, BASE_DEC,
6800                 NULL, 0x0, "Number of RIDs", HFILL }},
6801
6802         { &hf_netlogon_num_controllers,
6803                 { "Num DCs", "netlogon.num_dc", FT_UINT32, BASE_DEC,
6804                 NULL, 0x0, "Number of domain controllers", HFILL }},
6805
6806         { &hf_netlogon_num_other_groups,
6807                 { "Num Other Groups", "netlogon.num_other_groups", FT_UINT32, BASE_DEC,
6808                 NULL, 0x0, "", HFILL }},
6809
6810         { &hf_netlogon_flags,
6811                 { "Flags", "netlogon.flags", FT_UINT32, BASE_HEX,
6812                 NULL, 0x0, "", HFILL }},
6813
6814         { &hf_netlogon_user_flags,
6815                 { "User Flags", "netlogon.user_flags", FT_UINT32, BASE_HEX,
6816                 NULL, 0x0, "", HFILL }},
6817
6818         { &hf_netlogon_auth_flags,
6819                 { "Auth Flags", "netlogon.auth_flags", FT_UINT32, BASE_HEX,
6820                 NULL, 0x0, "", HFILL }},
6821
6822         { &hf_netlogon_systemflags,
6823                 { "System Flags", "netlogon.system_flags", FT_UINT32, BASE_HEX,
6824                 NULL, 0x0, "", HFILL }},
6825
6826         { &hf_netlogon_database_id,
6827                 { "Database Id", "netlogon.database_id", FT_UINT32, BASE_DEC,
6828                 NULL, 0x0, "Database Id", HFILL }},
6829
6830         { &hf_netlogon_sync_context,
6831                 { "Sync Context", "netlogon.sync_context", FT_UINT32, BASE_DEC,
6832                 NULL, 0x0, "Sync Context", HFILL }},
6833
6834         { &hf_netlogon_max_size,
6835                 { "Max Size", "netlogon.max_size", FT_UINT32, BASE_DEC,
6836                 NULL, 0x0, "Max Size of database", HFILL }},
6837
6838         { &hf_netlogon_max_log_size,
6839                 { "Max Log Size", "netlogon.max_log_size", FT_UINT32, BASE_DEC,
6840                 NULL, 0x0, "Max Size of log", HFILL }},
6841
6842         { &hf_netlogon_pac_size,
6843                 { "Pac Size", "netlogon.pac.size", FT_UINT32, BASE_DEC,
6844                 NULL, 0x0, "Size of PacData in bytes", HFILL }},
6845
6846         { &hf_netlogon_auth_size,
6847                 { "Auth Size", "netlogon.auth.size", FT_UINT32, BASE_DEC,
6848                 NULL, 0x0, "Size of AuthData in bytes", HFILL }},
6849
6850         { &hf_netlogon_num_deltas,
6851                 { "Num Deltas", "netlogon.num_deltas", FT_UINT32, BASE_DEC,
6852                 NULL, 0x0, "Number of SAM Deltas in array", HFILL }},
6853
6854         { &hf_netlogon_num_trusts,
6855                 { "Num Trusts", "netlogon.num_trusts", FT_UINT32, BASE_DEC,
6856                 NULL, 0x0, "", HFILL }},
6857
6858         { &hf_netlogon_logon_attempts,
6859                 { "Logon Attempts", "netlogon.logon_attempts", FT_UINT32, BASE_DEC,
6860                 NULL, 0x0, "Number of logon attempts", HFILL }},
6861
6862         { &hf_netlogon_pagefilelimit,
6863                 { "Page File Limit", "netlogon.page_file_limit", FT_UINT32, BASE_DEC,
6864                 NULL, 0x0, "", HFILL }},
6865
6866         { &hf_netlogon_pagedpoollimit,
6867                 { "Paged Pool Limit", "netlogon.paged_pool_limit", FT_UINT32, BASE_DEC,
6868                 NULL, 0x0, "", HFILL }},
6869
6870         { &hf_netlogon_nonpagedpoollimit,
6871                 { "Non-Paged Pool Limit", "netlogon.nonpaged_pool_limit", FT_UINT32, BASE_DEC,
6872                 NULL, 0x0, "", HFILL }},
6873
6874         { &hf_netlogon_minworkingsetsize,
6875                 { "Min Working Set Size", "netlogon.min_working_set_size", FT_UINT32, BASE_DEC,
6876                 NULL, 0x0, "", HFILL }},
6877
6878         { &hf_netlogon_maxworkingsetsize,
6879                 { "Max Working Set Size", "netlogon.max_working_set_size", FT_UINT32, BASE_DEC,
6880                 NULL, 0x0, "", HFILL }},
6881
6882         { &hf_netlogon_serial_number,
6883                 { "Serial Number", "netlogon.serial_number", FT_UINT32, BASE_DEC,
6884                 NULL, 0x0, "", HFILL }},
6885
6886         { &hf_netlogon_neg_flags,
6887                 { "Neg Flags", "netlogon.neg_flags", FT_UINT32, BASE_HEX,
6888                 NULL, 0x0, "Negotiation Flags", HFILL }},
6889
6890         { &hf_netlogon_dc_flags,
6891                 { "Flags", "netlogon.dc.flags", FT_UINT32, BASE_HEX,
6892                 NULL, 0x0, "Domain Controller Flags", HFILL }},
6893
6894         { &hf_netlogon_dc_flags_pdc_flag,
6895                 { "PDC", "netlogon.dc.flags.pdc",
6896                   FT_BOOLEAN, 32, TFS(&dc_flags_pdc_flag), DS_PDC_FLAG,
6897                   "If this server is a PDC", HFILL }},
6898
6899         { &hf_netlogon_dc_flags_gc_flag,
6900                 { "GC", "netlogon.dc.flags.gc",
6901                   FT_BOOLEAN, 32, TFS(&dc_flags_gc_flag), DS_GC_FLAG,
6902                   "If this server is a GC", HFILL }},
6903
6904         { &hf_netlogon_dc_flags_ldap_flag,
6905                 { "LDAP", "netlogon.dc.flags.ldap",
6906                   FT_BOOLEAN, 32, TFS(&dc_flags_ldap_flag), DS_LDAP_FLAG,
6907                   "If this is an LDAP server", HFILL }},
6908
6909         { &hf_netlogon_dc_flags_ds_flag,
6910                 { "DS", "netlogon.dc.flags.ds",
6911                   FT_BOOLEAN, 32, TFS(&dc_flags_ds_flag), DS_DS_FLAG,
6912                   "If this server is a DS", HFILL }},
6913
6914         { &hf_netlogon_dc_flags_kdc_flag,
6915                 { "KDC", "netlogon.dc.flags.kdc",
6916                   FT_BOOLEAN, 32, TFS(&dc_flags_kdc_flag), DS_KDC_FLAG,
6917                   "If this is a KDC", HFILL }},
6918
6919         { &hf_netlogon_dc_flags_timeserv_flag,
6920                 { "Timeserv", "netlogon.dc.flags.timeserv",
6921                   FT_BOOLEAN, 32, TFS(&dc_flags_timeserv_flag), DS_TIMESERV_FLAG,
6922                   "If this server is a TimeServer", HFILL }},
6923
6924         { &hf_netlogon_dc_flags_closest_flag,
6925                 { "Closest", "netlogon.dc.flags.closest",
6926                   FT_BOOLEAN, 32, TFS(&dc_flags_closest_flag), DS_CLOSEST_FLAG,
6927                   "If this is the closest server", HFILL }},
6928
6929         { &hf_netlogon_dc_flags_writable_flag,
6930                 { "Writable", "netlogon.dc.flags.writable",
6931                   FT_BOOLEAN, 32, TFS(&dc_flags_writable_flag), DS_WRITABLE_FLAG,
6932                   "If this server can do updates to the database", HFILL }},
6933
6934         { &hf_netlogon_dc_flags_good_timeserv_flag,
6935                 { "Good Timeserv", "netlogon.dc.flags.good_timeserv",
6936                   FT_BOOLEAN, 32, TFS(&dc_flags_good_timeserv_flag), DS_GOOD_TIMESERV_FLAG,
6937                   "If this is a Good TimeServer", HFILL }},
6938
6939         { &hf_netlogon_dc_flags_ndnc_flag,
6940                 { "NDNC", "netlogon.dc.flags.ndnc",
6941                   FT_BOOLEAN, 32, TFS(&dc_flags_ndnc_flag), DS_NDNC_FLAG,
6942                   "If this is an NDNC server", HFILL }},
6943
6944         { &hf_netlogon_dc_flags_dns_controller_flag,
6945                 { "DNS Controller", "netlogon.dc.flags.dns_controller",
6946                   FT_BOOLEAN, 32, TFS(&dc_flags_dns_controller_flag), DS_DNS_CONTROLLER_FLAG,
6947                   "If this server is a DNS Controller", HFILL }},
6948
6949         { &hf_netlogon_dc_flags_dns_domain_flag,
6950                 { "DNS Domain", "netlogon.dc.flags.dns_domain",
6951                   FT_BOOLEAN, 32, TFS(&dc_flags_dns_domain_flag), DS_DNS_DOMAIN_FLAG,
6952                   "", HFILL }},
6953
6954         { &hf_netlogon_dc_flags_dns_forest_flag,
6955                 { "DNS Forest", "netlogon.dc.flags.dns_forest",
6956                   FT_BOOLEAN, 32, TFS(&dc_flags_dns_forest_flag), DS_DNS_FOREST_FLAG,
6957                   "", HFILL }},
6958
6959         { &hf_netlogon_get_dcname_request_flags,
6960                 { "Flags", "netlogon.get_dcname.request.flags", FT_UINT32, BASE_HEX,
6961                 NULL, 0x0, "Flags for DSGetDCName request", HFILL }},
6962
6963         { &hf_netlogon_get_dcname_request_flags_force_rediscovery,
6964                 { "Force Rediscovery", "netlogon.get_dcname.request.flags.force_rediscovery",
6965                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_force_rediscovery), DS_FORCE_REDISCOVERY,
6966                   "Whether to allow the server to returned cached information or not", HFILL }},
6967
6968         { &hf_netlogon_get_dcname_request_flags_directory_service_required,
6969                 { "DS Required", "netlogon.get_dcname.request.flags.ds_required",
6970                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_directory_service_required), DS_DIRECTORY_SERVICE_REQUIRED,
6971                   "Whether we require that the returned DC supports w2k or not", HFILL }},
6972
6973         { &hf_netlogon_get_dcname_request_flags_directory_service_preferred,
6974                 { "DS Preferred", "netlogon.get_dcname.request.flags.ds_preferred",
6975                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_directory_service_preferred), DS_DIRECTORY_SERVICE_PREFERRED,
6976                   "Whether we prefer the call to return a w2k server (if available)", HFILL }},
6977
6978         { &hf_netlogon_get_dcname_request_flags_gc_server_required,
6979                 { "GC Required", "netlogon.get_dcname.request.flags.gc_server_required",
6980                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_gc_server_required), DS_GC_SERVER_REQUIRED,
6981                   "Whether we require that the returned DC is a Global Catalog server", HFILL }},
6982
6983         { &hf_netlogon_get_dcname_request_flags_pdc_required,
6984                 { "PDC Required", "netlogon.get_dcname.request.flags.pdc_required",
6985                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_pdc_required), DS_PDC_REQUIRED,
6986                   "Whether we require the returned DC to be the PDC", HFILL }},
6987
6988         { &hf_netlogon_get_dcname_request_flags_background_only,
6989                 { "Background Only", "netlogon.get_dcname.request.flags.background_only",
6990                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_background_only), DS_BACKGROUND_ONLY,
6991                   "If we want cached data, even if it may have expired", HFILL }},
6992
6993         { &hf_netlogon_get_dcname_request_flags_ip_required,
6994                 { "IP Required", "netlogon.get_dcname.request.flags.ip_required",
6995                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_ip_required), DS_IP_REQUIRED,
6996                   "If we requre the IP of the DC in the reply", HFILL }},
6997
6998         { &hf_netlogon_get_dcname_request_flags_kdc_required,
6999                 { "KDC Required", "netlogon.get_dcname.request.flags.kdc_required",
7000                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_kdc_required), DS_KDC_REQUIRED,
7001                   "If we require that the returned server is a KDC", HFILL }},
7002
7003         { &hf_netlogon_get_dcname_request_flags_timeserv_required,
7004                 { "Timeserv Required", "netlogon.get_dcname.request.flags.timeserv_required",
7005                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_timeserv_required), DS_TIMESERV_REQUIRED,
7006                   "If we require the retruned server to be a NTP serveruns WindowsTimeServicer", HFILL }},
7007
7008         { &hf_netlogon_get_dcname_request_flags_writable_required,
7009                 { "Writable Required", "netlogon.get_dcname.request.flags.writable_required",
7010                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_writable_required), DS_WRITABLE_REQUIRED,
7011                   "If we require that the return server is writable", HFILL }},
7012
7013         { &hf_netlogon_get_dcname_request_flags_good_timeserv_preferred,
7014                 { "Timeserv Preferred", "netlogon.get_dcname.request.flags.good_timeserv_preferred",
7015                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_good_timeserv_preferred), DS_GOOD_TIMESERV_PREFERRED,
7016                   "If we prefer Windows Time Servers", HFILL }},
7017
7018         { &hf_netlogon_get_dcname_request_flags_avoid_self,
7019                 { "Avoid Self", "netlogon.get_dcname.request.flags.avoid_self",
7020                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_avoid_self), DS_AVOID_SELF,
7021                   "Return another DC than the one we ask", HFILL }},
7022
7023         { &hf_netlogon_get_dcname_request_flags_only_ldap_needed,
7024                 { "Only LDAP Needed", "netlogon.get_dcname.request.flags.only_ldap_needed",
7025                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_only_ldap_needed), DS_ONLY_LDAP_NEEDED,
7026                   "We just want an LDAP server, it does not have to be a DC", HFILL }},
7027
7028         { &hf_netlogon_get_dcname_request_flags_is_flat_name,
7029                 { "Is Flat Name", "netlogon.get_dcname.request.flags.is_flat_name",
7030                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_is_flat_name), DS_IS_FLAT_NAME,
7031                   "If the specified domain name is a NetBIOS name", HFILL }},
7032
7033         { &hf_netlogon_get_dcname_request_flags_is_dns_name,
7034                 { "Is DNS Name", "netlogon.get_dcname.request.flags.is_dns_name",
7035                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_is_dns_name), DS_IS_DNS_NAME,
7036                   "If the specified domain name is a DNS name", HFILL }},
7037
7038         { &hf_netlogon_get_dcname_request_flags_return_dns_name,
7039                 { "Return DNS Name", "netlogon.get_dcname.request.flags.return_dns_name",
7040                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_return_dns_name), DS_RETURN_DNS_NAME,
7041                   "Only return a DNS name (or an error)", HFILL }},
7042
7043         { &hf_netlogon_get_dcname_request_flags_return_flat_name,
7044                 { "Return Flat Name", "netlogon.get_dcname.request.flags.return_flat_name",
7045                   FT_BOOLEAN, 32, TFS(&get_dcname_request_flags_return_flat_name), DS_RETURN_FLAT_NAME,
7046                   "Only return a NetBIOS name (or an error)", HFILL }},
7047
7048         { &hf_netlogon_trust_attribs,
7049                 { "Trust Attributes", "netlogon.trust_attribs", FT_UINT32, BASE_HEX,
7050                 NULL, 0x0, "Trust Attributes", HFILL }},
7051
7052         { &hf_netlogon_trust_type,
7053                 { "Trust Type", "netlogon.trust_type", FT_UINT32, BASE_DEC,
7054                 VALS(trust_type_vals), 0x0, "Trust Type", HFILL }},
7055
7056         { &hf_netlogon_trust_flags,
7057                 { "Trust Flags", "netlogon.trust_flags", FT_UINT32, BASE_HEX,
7058                 NULL, 0x0, "Trust Flags", HFILL }},
7059
7060         { &hf_netlogon_trust_flags_inbound,
7061                 { "Inbound Trust", "netlogon.trust.flags.inbound",
7062                   FT_BOOLEAN, 32, TFS(&trust_inbound), DS_DOMAIN_DIRECT_INBOUND,
7063                   "Inbound trust. Whether the domain directly trusts the queried servers domain", HFILL }},
7064
7065         { &hf_netlogon_trust_flags_outbound,
7066                 { "Outbound Trust", "netlogon.trust.flags.outbound",
7067                   FT_BOOLEAN, 32, TFS(&trust_outbound), DS_DOMAIN_DIRECT_OUTBOUND,
7068                   "Outbound Trust. Whether the domain is directly trusted by the servers domain", HFILL }},
7069
7070         { &hf_netlogon_trust_flags_in_forest,
7071                 { "In Forest", "netlogon.trust.flags.in_forest",
7072                   FT_BOOLEAN, 32, TFS(&trust_in_forest), DS_DOMAIN_IN_FOREST,
7073                   "Whether this domain is a member of the same forest as the servers domain", HFILL }},
7074
7075         { &hf_netlogon_trust_flags_native_mode,
7076                 { "Native Mode", "netlogon.trust.flags.native_mode",
7077                   FT_BOOLEAN, 32, TFS(&trust_native_mode), DS_DOMAIN_NATIVE_MODE,
7078                   "Whether the domain is a w2k native mode domain or not", HFILL }},
7079
7080         { &hf_netlogon_trust_flags_primary,
7081                 { "Primary", "netlogon.trust.flags.primary",
7082                   FT_BOOLEAN, 32, TFS(&trust_primary), DS_DOMAIN_PRIMARY,
7083                   "Whether the domain is the primary domain for the queried server or not", HFILL }},
7084
7085         { &hf_netlogon_trust_flags_tree_root,
7086                 { "Tree Root", "netlogon.trust.flags.tree_root",
7087                   FT_BOOLEAN, 32, TFS(&trust_tree_root), DS_DOMAIN_TREE_ROOT,
7088                   "Whether the domain is the root of the tree for the queried server", HFILL }},
7089
7090         { &hf_netlogon_trust_parent_index,
7091                 { "Parent Index", "netlogon.parent_index", FT_UINT32, BASE_HEX,
7092                 NULL, 0x0, "Parent Index", HFILL }},
7093
7094         { &hf_netlogon_logon_time,
7095                 { "Logon Time", "netlogon.logon_time", FT_ABSOLUTE_TIME, BASE_NONE,
7096                 NULL, 0, "Time for last time this user logged on", HFILL }},
7097
7098         { &hf_netlogon_kickoff_time,
7099                 { "Kickoff Time", "netlogon.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
7100                 NULL, 0, "Time when this user will be kicked off", HFILL }},
7101
7102         { &hf_netlogon_logoff_time,
7103                 { "Logoff Time", "netlogon.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
7104                 NULL, 0, "Time for last time this user logged off", HFILL }},
7105
7106         { &hf_netlogon_pwd_last_set_time,
7107                 { "PWD Last Set", "netlogon.pwd_last_set_time", FT_ABSOLUTE_TIME, BASE_NONE,
7108                 NULL, 0, "Last time this users password was changed", HFILL }},
7109
7110         { &hf_netlogon_pwd_can_change_time,
7111                 { "PWD Can Change", "netlogon.pwd_can_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
7112                 NULL, 0, "When this users password may be changed", HFILL }},
7113
7114         { &hf_netlogon_pwd_must_change_time,
7115                 { "PWD Must Change", "netlogon.pwd_must_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
7116                 NULL, 0, "When this users password must be changed", HFILL }},
7117
7118         { &hf_netlogon_domain_create_time,
7119                 { "Domain Create Time", "netlogon.domain_create_time", FT_ABSOLUTE_TIME, BASE_NONE,
7120                 NULL, 0, "Time when this domain was created", HFILL }},
7121
7122         { &hf_netlogon_domain_modify_time,
7123                 { "Domain Modify Time", "netlogon.domain_modify_time", FT_ABSOLUTE_TIME, BASE_NONE,
7124                 NULL, 0, "Time when this domain was last modified", HFILL }},
7125
7126         { &hf_netlogon_db_modify_time,
7127                 { "DB Modify Time", "netlogon.db_modify_time", FT_ABSOLUTE_TIME, BASE_NONE,
7128                 NULL, 0, "Time when last modified", HFILL }},
7129
7130         { &hf_netlogon_db_create_time,
7131                 { "DB Create Time", "netlogon.db_create_time", FT_ABSOLUTE_TIME, BASE_NONE,
7132                 NULL, 0, "Time when created", HFILL }},
7133
7134         { &hf_netlogon_cipher_current_set_time,
7135                 { "Cipher Current Set Time", "netlogon.cipher_current_set_time", FT_ABSOLUTE_TIME, BASE_NONE,
7136                 NULL, 0, "Time when current cipher was initiated", HFILL }},
7137
7138         { &hf_netlogon_cipher_old_set_time,
7139                 { "Cipher Old Set Time", "netlogon.cipher_old_set_time", FT_ABSOLUTE_TIME, BASE_NONE,
7140                 NULL, 0, "Time when previous cipher was initiated", HFILL }},
7141
7142         { &hf_netlogon_audit_retention_period,
7143                 { "Audit Retention Period", "netlogon.audit_retention_period", FT_RELATIVE_TIME, BASE_NONE,
7144                 NULL, 0, "Audit retention period", HFILL }},
7145
7146         { &hf_netlogon_guid,
7147                 { "GUID", "netlogon.guid", FT_STRING, BASE_NONE, 
7148                 NULL, 0x0, "GUID (uuid for groups?)", HFILL }},
7149
7150         { &hf_netlogon_timelimit,
7151                 { "Time Limit", "netlogon.time_limit", FT_RELATIVE_TIME, BASE_NONE,
7152                 NULL, 0, "", HFILL }},
7153
7154         /* Secure channel dissection */
7155
7156         { &hf_netlogon_secchan_bind_unknown1,
7157           { "Unknown1", "netlogon.secchan.bind.unknown1", FT_UINT32, BASE_HEX,
7158             NULL, 0x0, "", HFILL }},
7159
7160         { &hf_netlogon_secchan_bind_unknown2,
7161           { "Unknown2", "netlogon.secchan.bind.unknown2", FT_UINT32, BASE_HEX,
7162             NULL, 0x0, "", HFILL }},
7163
7164         { &hf_netlogon_secchan_domain,
7165           { "Domain", "netlogon.secchan.domain", FT_STRING, BASE_NONE,
7166             NULL, 0, "", HFILL }},
7167
7168         { &hf_netlogon_secchan_host,
7169           { "Host", "netlogon.secchan.host", FT_STRING, BASE_NONE,
7170             NULL, 0, "", HFILL }},
7171
7172         { &hf_netlogon_secchan_bind_ack_unknown1,
7173           { "Unknown1", "netlogon.secchan.bind_ack.unknown1", FT_UINT32, 
7174             BASE_HEX, NULL, 0x0, "", HFILL }},
7175
7176         { &hf_netlogon_secchan_bind_ack_unknown2,
7177           { "Unknown2", "netlogon.secchan.bind_ack.unknown2", FT_UINT32, 
7178             BASE_HEX, NULL, 0x0, "", HFILL }},
7179
7180         { &hf_netlogon_secchan_bind_ack_unknown3,
7181           { "Unknown3", "netlogon.secchan.bind_ack.unknown3", FT_UINT32, 
7182             BASE_HEX, NULL, 0x0, "", HFILL }},
7183
7184         { &hf_netlogon_secchan_verf,
7185           { "Secure Channel Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE, 
7186             NULL, 0x0, "Verifier", HFILL }},
7187
7188         { &hf_netlogon_secchan_verf_sig,
7189           { "Signature", "netlogon.secchan.sig", FT_BYTES, BASE_HEX, NULL, 
7190             0x0, "Signature", HFILL }}, 
7191
7192         { &hf_netlogon_secchan_verf_unk,
7193           { "Unknown", "netlogon.secchan.unk", FT_BYTES, BASE_HEX, NULL, 
7194           0x0, "Unknown", HFILL }}, 
7195
7196         { &hf_netlogon_secchan_verf_seq,
7197           { "Sequence No", "netlogon.secchan.seq", FT_BYTES, BASE_HEX, NULL, 
7198           0x0, "Sequence No", HFILL }}, 
7199
7200         { &hf_netlogon_secchan_verf_nonce,
7201           { "Nonce", "netlogon.secchan.nonce", FT_BYTES, BASE_HEX, NULL, 
7202           0x0, "Nonce", HFILL }}, 
7203         };
7204
7205         static gint *ett[] = {
7206                 &ett_dcerpc_netlogon,
7207                 &ett_CYPHER_VALUE,
7208                 &ett_QUOTA_LIMITS,
7209                 &ett_IDENTITY_INFO,
7210                 &ett_DELTA_ENUM,
7211                 &ett_UNICODE_MULTI,
7212                 &ett_DOMAIN_CONTROLLER_INFO,
7213                 &ett_UNICODE_STRING_512,
7214                 &ett_TYPE_50,
7215                 &ett_TYPE_52,
7216                 &ett_DELTA_ID_UNION,
7217                 &ett_TYPE_44,
7218                 &ett_DELTA_UNION,
7219                 &ett_LM_OWF_PASSWORD,
7220                 &ett_NT_OWF_PASSWORD,
7221                 &ett_GROUP_MEMBERSHIP,
7222                 &ett_DS_DOMAIN_TRUSTS,
7223                 &ett_BLOB,
7224                 &ett_DOMAIN_TRUST_INFO,
7225                 &ett_trust_flags,
7226                 &ett_get_dcname_request_flags,
7227                 &ett_dc_flags,
7228                 &ett_secchan_bind_creds,
7229                 &ett_secchan_bind_ack_creds,
7230                 &ett_secchan_verf
7231         };
7232
7233         proto_dcerpc_netlogon = proto_register_protocol(
7234                 "Microsoft Network Logon", "RPC_NETLOGON", "rpc_netlogon");
7235
7236         proto_register_field_array(proto_dcerpc_netlogon, hf,
7237                                    array_length(hf));
7238         proto_register_subtree_array(ett, array_length(ett));
7239 }
7240
7241 static dcerpc_auth_subdissector_fns secchan_auth_fns = {
7242         dissect_secchan_bind_creds,             /* Bind */
7243         dissect_secchan_bind_ack_creds,         /* Bind ACK */
7244         NULL,                                   /* AUTH3 */
7245         dissect_secchan_verf,                   /* Request verifier */
7246         dissect_secchan_verf,                   /* Response verifier */
7247         NULL,                                   /* Request data */
7248         NULL                                    /* Response data */
7249 };
7250
7251 void
7252 proto_reg_handoff_dcerpc_netlogon(void)
7253 {
7254         /* Register protocol as dcerpc */
7255
7256         dcerpc_init_uuid(proto_dcerpc_netlogon, ett_dcerpc_netlogon,
7257                          &uuid_dcerpc_netlogon, ver_dcerpc_netlogon,
7258                          dcerpc_netlogon_dissectors, hf_netlogon_opnum);
7259
7260         register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
7261                                           DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN,
7262                                           &secchan_auth_fns);   
7263         register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
7264                                           DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN,
7265                                           &secchan_auth_fns);   
7266 }