Change the interface to dissect_ndr_nt_PSID to take one extra parameter which if...
[metze/wireshark/wip.git] / packet-dcerpc-samr.c
1 /* packet-dcerpc-samr.c
2  * Routines for SMB \PIPE\samr packet disassembly
3  * Copyright 2001,2003 Tim Potter <tpot@samba.org>
4  *   2002 Added all command dissectors  Ronnie Sahlberg
5  *
6  * $Id: packet-dcerpc-samr.c,v 1.87 2003/05/21 09:34:54 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 <string.h>
34 #include "prefs.h"
35 #include "packet-dcerpc.h"
36 #include "packet-dcerpc-nt.h"
37 #include "packet-dcerpc-samr.h"
38 #include "packet-dcerpc-lsa.h"
39 #include "smb.h"        /* for "NT_errors[]" */
40 #include "packet-smb-common.h"
41 #include "crypt-md4.h"
42 #include "crypt-rc4.h"
43
44 #ifdef NEED_SNPRINTF_H
45 # include "snprintf.h"
46 #endif
47
48 static int proto_dcerpc_samr = -1;
49
50 static int hf_samr_opnum = -1;
51 static int hf_samr_hnd = -1;
52 static int hf_samr_group = -1;
53 static int hf_samr_rid = -1;
54 static int hf_samr_type = -1;
55 static int hf_samr_alias = -1;
56 static int hf_samr_rid_attrib = -1;
57 static int hf_samr_rc = -1;
58 static int hf_samr_index = -1;
59 static int hf_samr_count = -1;
60
61 static int hf_samr_level = -1;
62 static int hf_samr_start_idx = -1;
63 static int hf_samr_max_entries = -1;
64 static int hf_samr_entries = -1;
65 static int hf_samr_pref_maxsize = -1;
66 static int hf_samr_total_size = -1;
67 static int hf_samr_ret_size = -1;
68 static int hf_samr_alias_name = -1;
69 static int hf_samr_group_name = -1;
70 static int hf_samr_acct_name = -1;
71 static int hf_samr_full_name = -1;
72 static int hf_samr_acct_desc = -1;
73 static int hf_samr_home = -1;
74 static int hf_samr_home_drive = -1;
75 static int hf_samr_script = -1;
76 static int hf_samr_workstations = -1;
77 static int hf_samr_profile = -1;
78 static int hf_samr_server = -1;
79 static int hf_samr_domain = -1;
80 static int hf_samr_controller = -1;
81 static int hf_samr_access = -1;
82 static int hf_samr_access_granted = -1;
83 static int hf_samr_crypt_password = -1;
84 static int hf_samr_crypt_hash = -1;
85 static int hf_samr_lm_change = -1;
86 static int hf_samr_lm_passchange_block = -1;
87 static int hf_samr_nt_passchange_block = -1;
88 static int hf_samr_nt_passchange_block_decrypted = -1;
89 static int hf_samr_nt_passchange_block_newpass = -1;
90 static int hf_samr_nt_passchange_block_newpass_len = -1;
91 static int hf_samr_nt_passchange_block_pseudorandom = -1;
92 static int hf_samr_lm_verifier = -1;
93 static int hf_samr_nt_verifier = -1;
94 static int hf_samr_attrib = -1;
95 static int hf_samr_max_pwd_age = -1;
96 static int hf_samr_min_pwd_age = -1;
97 static int hf_samr_min_pwd_len = -1;
98 static int hf_samr_pwd_history_len = -1;
99 static int hf_samr_num_users = -1;
100 static int hf_samr_num_groups = -1;
101 static int hf_samr_num_aliases = -1;
102 static int hf_samr_resume_hnd = -1;
103 static int hf_samr_bad_pwd_count = -1;
104 static int hf_samr_logon_count = -1;
105 static int hf_samr_logon_time = -1;
106 static int hf_samr_logoff_time = -1;
107 static int hf_samr_kickoff_time = -1;
108 static int hf_samr_pwd_last_set_time = -1;
109 static int hf_samr_pwd_can_change_time = -1;
110 static int hf_samr_pwd_must_change_time = -1;
111 static int hf_samr_acct_expiry_time = -1;
112 static int hf_samr_country = -1;
113 static int hf_samr_codepage = -1;
114 static int hf_samr_comment = -1;
115 static int hf_samr_parameters = -1;
116 static int hf_samr_nt_pwd_set = -1;
117 static int hf_samr_lm_pwd_set = -1;
118 static int hf_samr_pwd_expired = -1;
119 static int hf_samr_revision = -1;
120 static int hf_samr_divisions = -1;
121 static int hf_samr_info_type = -1;
122
123 static int hf_samr_unknown_hyper = -1;
124 static int hf_samr_unknown_long = -1;
125 static int hf_samr_unknown_short = -1;
126 static int hf_samr_unknown_char = -1;
127 static int hf_samr_unknown_string = -1;
128 static int hf_samr_unknown_time = -1;
129
130 static int hf_nt_acct_ctrl = -1;
131 static int hf_nt_acb_disabled = -1;
132 static int hf_nt_acb_homedirreq = -1;
133 static int hf_nt_acb_pwnotreq = -1;
134 static int hf_nt_acb_tempdup = -1;
135 static int hf_nt_acb_normal = -1;
136 static int hf_nt_acb_mns = -1;
137 static int hf_nt_acb_domtrust = -1;
138 static int hf_nt_acb_wstrust = -1;
139 static int hf_nt_acb_svrtrust = -1;
140 static int hf_nt_acb_pwnoexp = -1;
141 static int hf_nt_acb_autolock = -1;
142
143 static gint ett_dcerpc_samr = -1;
144 static gint ett_samr_user_dispinfo_1 = -1;
145 static gint ett_samr_user_dispinfo_1_array = -1;
146 static gint ett_samr_user_dispinfo_2 = -1;
147 static gint ett_samr_user_dispinfo_2_array = -1;
148 static gint ett_samr_group_dispinfo = -1;
149 static gint ett_samr_group_dispinfo_array = -1;
150 static gint ett_samr_ascii_dispinfo = -1;
151 static gint ett_samr_ascii_dispinfo_array = -1;
152 static gint ett_samr_display_info = -1;
153 static gint ett_samr_password_info = -1;
154 static gint ett_samr_server = -1;
155 static gint ett_samr_user_group = -1;
156 static gint ett_samr_user_group_array = -1;
157 static gint ett_samr_alias_info = -1;
158 static gint ett_samr_group_info = -1;
159 static gint ett_samr_domain_info_1 = -1;
160 static gint ett_samr_domain_info_2 = -1;
161 static gint ett_samr_domain_info_8 = -1;
162 static gint ett_samr_replication_status = -1;
163 static gint ett_samr_domain_info_11 = -1;
164 static gint ett_samr_domain_info_13 = -1;
165 static gint ett_samr_domain_info = -1;
166 static gint ett_samr_sid_pointer = -1;
167 static gint ett_samr_sid_array = -1;
168 static gint ett_samr_index_array = -1;
169 static gint ett_samr_idx_and_name = -1;
170 static gint ett_samr_idx_and_name_array = -1;
171 static gint ett_samr_logon_hours = -1;
172 static gint ett_samr_logon_hours_hours = -1;
173 static gint ett_samr_user_info_1 = -1;
174 static gint ett_samr_user_info_2 = -1;
175 static gint ett_samr_user_info_3 = -1;
176 static gint ett_samr_user_info_5 = -1;
177 static gint ett_samr_user_info_6 = -1;
178 static gint ett_samr_user_info_18 = -1;
179 static gint ett_samr_user_info_19 = -1;
180 static gint ett_samr_buffer_buffer = -1;
181 static gint ett_samr_buffer = -1;
182 static gint ett_samr_user_info_21 = -1;
183 static gint ett_samr_user_info_22 = -1;
184 static gint ett_samr_user_info_23 = -1;
185 static gint ett_samr_user_info_24 = -1;
186 static gint ett_samr_user_info = -1;
187 static gint ett_samr_member_array_types = -1;
188 static gint ett_samr_member_array_rids = -1;
189 static gint ett_samr_member_array = -1;
190 static gint ett_samr_names = -1;
191 static gint ett_samr_rids = -1;
192 static gint ett_nt_acct_ctrl = -1;
193 static gint ett_samr_sid_and_attributes_array = -1;
194 static gint ett_samr_sid_and_attributes = -1;
195 #ifdef SAMR_UNUSED_HANDLES
196 static gint ett_samr_hnd = -1;
197 #endif
198
199 static e_uuid_t uuid_dcerpc_samr = {
200         0x12345778, 0x1234, 0xabcd,
201         { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xac}
202 };
203
204 static guint16 ver_dcerpc_samr = 1;
205
206 /* Configuration variables */
207 static char *nt_password = NULL;
208
209 /* Dissect connect specific access rights */
210
211 static gint hf_access_connect_unknown_01 = -1;
212 static gint hf_access_connect_shutdown_server = -1;
213 static gint hf_access_connect_unknown_04 = -1;
214 static gint hf_access_connect_unknown_08 = -1;
215 static gint hf_access_connect_enum_domains = -1;
216 static gint hf_access_connect_open_domain = -1;
217
218 static void
219 specific_rights_connect(tvbuff_t *tvb, gint offset, proto_tree *tree,
220                         guint32 access)
221 {
222         proto_tree_add_boolean(
223                 tree, hf_access_connect_open_domain,
224                 tvb, offset, 4, access);
225
226         proto_tree_add_boolean(
227                 tree, hf_access_connect_enum_domains,
228                 tvb, offset, 4, access);
229
230         proto_tree_add_boolean(
231                 tree, hf_access_connect_unknown_08,
232                 tvb, offset, 4, access);
233
234         proto_tree_add_boolean(
235                 tree, hf_access_connect_unknown_04,
236                 tvb, offset, 4, access);
237
238         proto_tree_add_boolean(
239                 tree, hf_access_connect_shutdown_server,
240                 tvb, offset, 4, access);
241
242         proto_tree_add_boolean(
243                 tree, hf_access_connect_unknown_01,
244                 tvb, offset, 4, access);
245 }
246
247 struct access_mask_info samr_connect_access_mask_info = {
248         "SAMR connect",
249         specific_rights_connect,
250         NULL,                       /* Generic rights mapping */
251         NULL                        /* Standard rights mapping */
252 };
253
254 /* Dissect domain specific access rights */
255
256 static gint hf_access_domain_lookup_info1 = -1;
257 static gint hf_access_domain_set_info1 = -1;
258 static gint hf_access_domain_lookup_info2 = -1;
259 static gint hf_access_domain_set_info2 = -1;
260 static gint hf_access_domain_create_user = -1;
261 static gint hf_access_domain_create_group = -1;
262 static gint hf_access_domain_create_alias = -1;
263 static gint hf_access_domain_lookup_alias_by_mem = -1;
264 static gint hf_access_domain_enum_accounts = -1;
265 static gint hf_access_domain_open_account = -1;
266 static gint hf_access_domain_set_info3 = -1;
267
268 static void
269 specific_rights_domain(tvbuff_t *tvb, gint offset, proto_tree *tree,
270                        guint32 access)
271 {
272         proto_tree_add_boolean(
273                 tree, hf_access_domain_set_info3,
274                 tvb, offset, 4, access);
275
276         proto_tree_add_boolean(
277                 tree, hf_access_domain_open_account,
278                 tvb, offset, 4, access);
279
280         proto_tree_add_boolean(
281                 tree, hf_access_domain_enum_accounts,
282                 tvb, offset, 4, access);
283
284         proto_tree_add_boolean(
285                 tree, hf_access_domain_lookup_alias_by_mem,
286                 tvb, offset, 4, access);
287
288         proto_tree_add_boolean(
289                 tree, hf_access_domain_create_alias,
290                 tvb, offset, 4, access);
291
292         proto_tree_add_boolean(
293                 tree, hf_access_domain_create_group,
294                 tvb, offset, 4, access);
295
296         proto_tree_add_boolean(
297                 tree, hf_access_domain_create_user,
298                 tvb, offset, 4, access);
299
300         proto_tree_add_boolean(
301                 tree, hf_access_domain_set_info2,
302                 tvb, offset, 4, access);
303
304         proto_tree_add_boolean(
305                 tree, hf_access_domain_lookup_info2,
306                 tvb, offset, 4, access);
307
308         proto_tree_add_boolean(
309                 tree, hf_access_domain_set_info1,
310                 tvb, offset, 4, access);
311
312         proto_tree_add_boolean(
313                 tree, hf_access_domain_lookup_info1,
314                 tvb, offset, 4, access);
315         }
316
317 struct access_mask_info samr_domain_access_mask_info = {
318         "SAMR domain",
319         specific_rights_domain,
320         NULL,                   /* Generic mapping table */
321         NULL                    /* Standard mapping table */
322 };
323
324 /* Dissect user specific access rights */
325
326 static gint hf_access_user_get_name_etc = -1;
327 static gint hf_access_user_get_locale = -1;
328 static gint hf_access_user_get_loc_com = -1;
329 static gint hf_access_user_get_logoninfo = -1;
330 static gint hf_access_user_unknown_10 = -1;
331 static gint hf_access_user_set_attributes = -1;
332 static gint hf_access_user_change_password = -1;
333 static gint hf_access_user_set_password = -1;
334 static gint hf_access_user_get_groups = -1;
335 static gint hf_access_user_unknown_200 = -1;
336 static gint hf_access_user_unknown_400 = -1;
337
338 static void
339 specific_rights_user(tvbuff_t *tvb, gint offset, proto_tree *tree,
340                      guint32 access)
341 {
342         proto_tree_add_boolean(
343                 tree, hf_access_user_unknown_400,
344                 tvb, offset, 4, access);
345
346         proto_tree_add_boolean(
347                 tree, hf_access_user_unknown_200,
348                 tvb, offset, 4, access);
349
350         proto_tree_add_boolean(
351                 tree, hf_access_user_get_groups,
352                 tvb, offset, 4, access);
353
354         proto_tree_add_boolean(
355                 tree, hf_access_user_set_password,
356                 tvb, offset, 4, access);
357
358         proto_tree_add_boolean(
359                 tree, hf_access_user_change_password,
360                 tvb, offset, 4, access);
361
362         proto_tree_add_boolean(
363                 tree, hf_access_user_set_attributes,
364                 tvb, offset, 4, access);
365
366         proto_tree_add_boolean(
367                 tree, hf_access_user_unknown_10,
368                 tvb, offset, 4, access);
369
370         proto_tree_add_boolean(
371                 tree, hf_access_user_get_logoninfo,
372                 tvb, offset, 4, access);
373
374         proto_tree_add_boolean(
375                 tree, hf_access_user_get_loc_com,
376                 tvb, offset, 4, access);
377
378         proto_tree_add_boolean(
379                 tree, hf_access_user_get_locale,
380                 tvb, offset, 4, access);
381
382         proto_tree_add_boolean(
383                 tree, hf_access_user_get_name_etc,
384                 tvb, offset, 4, access);
385 }
386
387 struct access_mask_info samr_user_access_mask_info = {
388         "SAMR user",
389         specific_rights_user,
390         NULL,                   /* Generic mapping table */
391         NULL                    /* Standard mapping table */
392 };
393
394 /* Dissect alias specific access rights */
395
396 static gint hf_access_alias_add_member = -1;
397 static gint hf_access_alias_remove_member = -1;
398 static gint hf_access_alias_get_members = -1;
399 static gint hf_access_alias_lookup_info = -1;
400 static gint hf_access_alias_set_info = -1;
401
402 static void
403 specific_rights_alias(tvbuff_t *tvb, gint offset, proto_tree *tree,
404                       guint32 access)
405 {
406         proto_tree_add_boolean(
407                 tree, hf_access_alias_set_info,
408                 tvb, offset, 4, access);
409
410         proto_tree_add_boolean(
411                 tree, hf_access_alias_lookup_info,
412                 tvb, offset, 4, access);
413
414         proto_tree_add_boolean(
415                 tree, hf_access_alias_get_members,
416                 tvb, offset, 4, access);
417
418         proto_tree_add_boolean(
419                 tree, hf_access_alias_remove_member,
420                 tvb, offset, 4, access);
421
422         proto_tree_add_boolean(
423                 tree, hf_access_alias_add_member,
424                 tvb, offset, 4, access);
425 }
426
427 struct access_mask_info samr_alias_access_mask_info = {
428         "SAMR alias",
429         specific_rights_alias,
430         NULL,                   /* Generic mapping table */
431         NULL                    /* Standard mapping table */
432 };
433
434 /* Dissect group specific access rights */
435
436 static gint hf_access_group_lookup_info = -1;
437 static gint hf_access_group_set_info = -1;
438 static gint hf_access_group_add_member = -1;
439 static gint hf_access_group_remove_member = -1;
440 static gint hf_access_group_get_members = -1;
441
442 static void
443 specific_rights_group(tvbuff_t *tvb, gint offset, proto_tree *tree,
444                       guint32 access)
445 {
446         proto_tree_add_boolean(
447                 tree, hf_access_group_get_members,
448                 tvb, offset, 4, access);
449
450         proto_tree_add_boolean(
451                 tree, hf_access_group_remove_member,
452                 tvb, offset, 4, access);
453
454         proto_tree_add_boolean(
455                 tree, hf_access_group_add_member,
456                 tvb, offset, 4, access);
457
458         proto_tree_add_boolean(
459                 tree, hf_access_group_set_info,
460                 tvb, offset, 4, access);
461
462         proto_tree_add_boolean(
463                 tree, hf_access_group_lookup_info,
464                 tvb, offset, 4, access);
465 }
466
467 struct access_mask_info samr_group_access_mask_info = {
468         "SAMR group",
469         specific_rights_group,
470         NULL,                   /* Generic mapping table */
471         NULL                    /* Standard mapping table */
472 };
473
474 int
475 dissect_ndr_nt_SID(tvbuff_t *tvb, int offset, packet_info *pinfo, 
476                    proto_tree *tree, char *drep)
477 {
478         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
479         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
480         char *sid_str;
481
482         if(di->conformant_run){
483                 /* just a run to handle conformant arrays, no scalars to dissect */
484                 return offset;
485         }
486
487         /* the SID contains a conformant array, first we must eat
488            the 4-byte max_count before we can hand it off */
489
490         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
491                         hf_samr_count, NULL);
492
493         offset = dissect_nt_sid(tvb, offset, tree, "Domain", &sid_str);
494
495         dcv->private_data = sid_str;
496
497         return offset;
498 }
499
500 static int
501 dissect_ndr_nt_SID_ptr(tvbuff_t *tvb, int offset,
502                         packet_info *pinfo, proto_tree *tree,
503                         char *drep)
504 {
505         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
506                         dissect_ndr_nt_SID, NDR_POINTER_UNIQUE,
507                         "SID pointer", -1);
508         return offset;
509 }
510
511
512
513 static const true_false_string tfs_nt_acb_disabled = {
514         "Account is DISABLED",
515         "Account is NOT disabled"
516 };
517 static const true_false_string tfs_nt_acb_homedirreq = {
518         "Homedir is REQUIRED",
519         "Homedir is NOT required"
520 };
521 static const true_false_string tfs_nt_acb_pwnotreq = {
522         "Password is NOT required",
523         "Password is REQUIRED"
524 };
525 static const true_false_string tfs_nt_acb_tempdup = {
526         "This is a TEMPORARY DUPLICATE account",
527         "This is NOT a temporary duplicate account"
528 };
529 static const true_false_string tfs_nt_acb_normal = {
530         "This is a NORMAL USER account",
531         "This is NOT a normal user account"
532 };
533 static const true_false_string tfs_nt_acb_mns = {
534         "This is a MNS account",
535         "This is NOT a mns account"
536 };
537 static const true_false_string tfs_nt_acb_domtrust = {
538         "This is a DOMAIN TRUST account",
539         "This is NOT a domain trust account"
540 };
541 static const true_false_string tfs_nt_acb_wstrust = {
542         "This is a WORKSTATION TRUST account",
543         "This is NOT a workstation trust account"
544 };
545 static const true_false_string tfs_nt_acb_svrtrust = {
546         "This is a SERVER TRUST account",
547         "This is NOT a server trust account"
548 };
549 static const true_false_string tfs_nt_acb_pwnoexp = {
550         "Passwords does NOT expire",
551         "Password will EXPIRE"
552 };
553 static const true_false_string tfs_nt_acb_autolock = {
554         "This account has been AUTO LOCKED",
555         "This account has NOT been auto locked"
556 };
557 int
558 dissect_ndr_nt_acct_ctrl(tvbuff_t *tvb, int offset, packet_info *pinfo,
559                         proto_tree *parent_tree, char *drep)
560 {
561         guint32 mask;
562         proto_item *item = NULL;
563         proto_tree *tree = NULL;
564
565         offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
566                         hf_nt_acct_ctrl, &mask);
567
568         if(parent_tree){
569                 item = proto_tree_add_uint(parent_tree, hf_nt_acct_ctrl,
570                         tvb, offset-4, 4, mask);
571                 tree = proto_item_add_subtree(item, ett_nt_acct_ctrl);
572         }
573
574         proto_tree_add_boolean(tree, hf_nt_acb_autolock,
575                 tvb, offset-4, 4, mask);
576         proto_tree_add_boolean(tree, hf_nt_acb_pwnoexp,
577                 tvb, offset-4, 4, mask);
578         proto_tree_add_boolean(tree, hf_nt_acb_svrtrust,
579                 tvb, offset-4, 4, mask);
580         proto_tree_add_boolean(tree, hf_nt_acb_wstrust,
581                 tvb, offset-4, 4, mask);
582         proto_tree_add_boolean(tree, hf_nt_acb_domtrust,
583                 tvb, offset-4, 4, mask);
584         proto_tree_add_boolean(tree, hf_nt_acb_mns,
585                 tvb, offset-4, 4, mask);
586         proto_tree_add_boolean(tree, hf_nt_acb_normal,
587                 tvb, offset-4, 4, mask);
588         proto_tree_add_boolean(tree, hf_nt_acb_tempdup,
589                 tvb, offset-4, 4, mask);
590         proto_tree_add_boolean(tree, hf_nt_acb_pwnotreq,
591                 tvb, offset-4, 4, mask);
592         proto_tree_add_boolean(tree, hf_nt_acb_homedirreq,
593                 tvb, offset-4, 4, mask);
594         proto_tree_add_boolean(tree, hf_nt_acb_disabled,
595                 tvb, offset-4, 4, mask);
596
597         return offset;
598 }
599
600
601 /* above this line, just some general support routines which should be placed
602    in some more generic file common to all NT services dissectors
603 */
604
605 static int
606 samr_dissect_open_user_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
607                             proto_tree *tree, char *drep)
608 {
609         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
610         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
611         guint32 rid;
612
613         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
614                                        hf_samr_hnd, NULL, FALSE, FALSE);
615
616         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
617                         hf_samr_access, NULL);
618
619         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
620                         hf_samr_rid, &rid);
621
622         if (check_col(pinfo->cinfo, COL_INFO))
623                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
624
625         dcv->private_data = GINT_TO_POINTER(rid);
626
627         return offset;
628 }
629
630 static int
631 samr_dissect_open_user_reply(tvbuff_t *tvb, int offset,
632                              packet_info *pinfo, proto_tree *tree,
633                              char *drep)
634 {
635         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
636         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
637         e_ctx_hnd policy_hnd;
638         guint32 rid = GPOINTER_TO_INT(dcv->private_data);
639         char *pol_name;
640
641         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
642                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
643
644         if (rid)
645                 pol_name = g_strdup_printf("OpenUser(rid 0x%x)", rid);
646         else
647                 pol_name = g_strdup("OpenUser handle");
648
649         dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
650
651         g_free(pol_name);
652
653         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
654                                   hf_samr_rc, NULL);
655
656         return offset;
657 }
658
659 static int
660 samr_dissect_pointer_long(tvbuff_t *tvb, int offset,
661                              packet_info *pinfo, proto_tree *tree,
662                              char *drep)
663 {
664         dcerpc_info *di;
665
666         di=pinfo->private_data;
667         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
668                                      di->hf_index, NULL);
669         return offset;
670 }
671
672 static int
673 samr_dissect_pointer_STRING(tvbuff_t *tvb, int offset,
674                              packet_info *pinfo, proto_tree *tree,
675                              char *drep)
676 {
677         dcerpc_info *di;
678
679         di=pinfo->private_data;
680         if(di->conformant_run){
681                 /*just a run to handle conformant arrays, nothing to dissect */
682                 return offset;
683         }
684
685         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
686                         di->hf_index, 0);
687         return offset;
688 }
689
690 static int
691 samr_dissect_pointer_short(tvbuff_t *tvb, int offset,
692                              packet_info *pinfo, proto_tree *tree,
693                              char *drep)
694 {
695         dcerpc_info *di;
696
697         di=pinfo->private_data;
698         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
699                                      di->hf_index, NULL);
700         return offset;
701 }
702
703
704 static int
705 samr_dissect_query_dispinfo_rqst(tvbuff_t *tvb, int offset,
706                                  packet_info *pinfo, proto_tree *tree,
707                                  char *drep)
708 {
709         guint16 level;
710         guint32 start_idx;
711
712         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
713                                        hf_samr_hnd, NULL, FALSE, FALSE);
714
715         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
716                                      hf_samr_level, &level);
717         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
718                                      hf_samr_start_idx, &start_idx);
719         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
720                                      hf_samr_max_entries, NULL);
721         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
722                                      hf_samr_pref_maxsize, NULL);
723
724         if (check_col(pinfo->cinfo, COL_INFO))
725                 col_append_fstr(
726                         pinfo->cinfo, COL_INFO, ", level %d, start_idx %d", 
727                         level, start_idx);
728
729         return offset;
730 }
731
732 static int
733 samr_dissect_USER_DISPINFO_1(tvbuff_t *tvb, int offset,
734                         packet_info *pinfo, proto_tree *parent_tree,
735                         char *drep)
736 {
737         proto_item *item=NULL;
738         proto_tree *tree=NULL;
739         int old_offset=offset;
740
741         if(parent_tree){
742                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
743                         "User_DispInfo_1");
744                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
745         }
746
747         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
748                                 hf_samr_index, NULL);
749         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
750                                 hf_samr_rid, NULL);
751         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
752         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
753                                 hf_samr_acct_name, 0);
754         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
755                                 hf_samr_full_name, 0);
756         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
757                                 hf_samr_acct_desc, 0);
758
759         proto_item_set_len(item, offset-old_offset);
760         return offset;
761 }
762
763 static int
764 samr_dissect_USER_DISPINFO_1_ARRAY_users(tvbuff_t *tvb, int offset,
765                         packet_info *pinfo, proto_tree *tree,
766                         char *drep)
767 {
768         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
769                         samr_dissect_USER_DISPINFO_1);
770
771         return offset;
772 }
773
774 static int
775 samr_dissect_USER_DISPINFO_1_ARRAY (tvbuff_t *tvb, int offset,
776                              packet_info *pinfo, proto_tree *parent_tree,
777                              char *drep)
778 {
779         guint32 count;
780         proto_item *item=NULL;
781         proto_tree *tree=NULL;
782         int old_offset=offset;
783
784         if(parent_tree){
785                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
786                         "User_DispInfo_1 Array");
787                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1_array);
788         }
789
790
791         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
792                                      hf_samr_count, &count);
793         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
794                         samr_dissect_USER_DISPINFO_1_ARRAY_users, NDR_POINTER_PTR,
795                         "USER_DISPINFO_1_ARRAY", -1);
796
797         proto_item_set_len(item, offset-old_offset);
798         return offset;
799 }
800
801
802
803 static int
804 samr_dissect_USER_DISPINFO_2(tvbuff_t *tvb, int offset,
805                         packet_info *pinfo, proto_tree *parent_tree,
806                         char *drep)
807 {
808         proto_item *item=NULL;
809         proto_tree *tree=NULL;
810         int old_offset=offset;
811
812         if(parent_tree){
813                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
814                         "User_DispInfo_2");
815                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2);
816         }
817
818         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
819                         hf_samr_index, NULL);
820         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
821                         hf_samr_rid, NULL);
822         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
823         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
824                         hf_samr_acct_name, 0);
825         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
826                         hf_samr_acct_desc, 0);
827
828         proto_item_set_len(item, offset-old_offset);
829         return offset;
830 }
831
832 static int
833 samr_dissect_USER_DISPINFO_2_ARRAY_users (tvbuff_t *tvb, int offset,
834                              packet_info *pinfo, proto_tree *tree,
835                              char *drep)
836 {
837         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
838                         samr_dissect_USER_DISPINFO_2);
839
840         return offset;
841 }
842
843 static int
844 samr_dissect_USER_DISPINFO_2_ARRAY (tvbuff_t *tvb, int offset,
845                              packet_info *pinfo, proto_tree *parent_tree,
846                              char *drep)
847 {
848         guint32 count;
849         proto_item *item=NULL;
850         proto_tree *tree=NULL;
851         int old_offset=offset;
852
853         if(parent_tree){
854                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
855                         "User_DispInfo_2 Array");
856                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2_array);
857         }
858
859
860         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
861                                      hf_samr_count, &count);
862         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
863                         samr_dissect_USER_DISPINFO_2_ARRAY_users, NDR_POINTER_PTR,
864                         "USER_DISPINFO_2_ARRAY", -1);
865
866         proto_item_set_len(item, offset-old_offset);
867         return offset;
868 }
869
870 static int
871 samr_dissect_GROUP_DISPINFO(tvbuff_t *tvb, int offset,
872                         packet_info *pinfo, proto_tree *parent_tree,
873                         char *drep)
874 {
875         proto_item *item=NULL;
876         proto_tree *tree=NULL;
877         int old_offset=offset;
878
879         if(parent_tree){
880                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
881                         "Group_DispInfo");
882                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo);
883         }
884
885
886         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
887                         hf_samr_index, NULL);
888         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
889                         hf_samr_rid, NULL);
890         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
891         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
892                         hf_samr_acct_name, 0);
893         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
894                         hf_samr_acct_desc, 0);
895
896         proto_item_set_len(item, offset-old_offset);
897         return offset;
898 }
899
900 static int
901 samr_dissect_GROUP_DISPINFO_ARRAY_groups(tvbuff_t *tvb, int offset,
902                         packet_info *pinfo, proto_tree *tree,
903                         char *drep)
904 {
905         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
906                         samr_dissect_GROUP_DISPINFO);
907
908         return offset;
909 }
910
911 static int
912 samr_dissect_GROUP_DISPINFO_ARRAY(tvbuff_t *tvb, int offset,
913                         packet_info *pinfo, proto_tree *parent_tree,
914                         char *drep)
915 {
916         guint32 count;
917         proto_item *item=NULL;
918         proto_tree *tree=NULL;
919         int old_offset=offset;
920
921         if(parent_tree){
922                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
923                         "Group_DispInfo Array");
924                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo_array);
925         }
926
927         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
928                                      hf_samr_count, &count);
929         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
930                         samr_dissect_GROUP_DISPINFO_ARRAY_groups, NDR_POINTER_PTR,
931                         "GROUP_DISPINFO_ARRAY", -1);
932
933         proto_item_set_len(item, offset-old_offset);
934         return offset;
935 }
936
937
938
939 static int
940 samr_dissect_ASCII_DISPINFO(tvbuff_t *tvb, int offset,
941                         packet_info *pinfo, proto_tree *parent_tree,
942                         char *drep)
943 {
944         proto_item *item=NULL;
945         proto_tree *tree=NULL;
946         int old_offset=offset;
947
948         if(parent_tree){
949                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
950                         "Ascii_DispInfo");
951                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo);
952         }
953
954
955         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
956                         hf_samr_index, NULL);
957         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
958                         hf_samr_rid, NULL);
959         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
960         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
961                         hf_samr_acct_name, 0);
962         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
963                         hf_samr_acct_desc, 0);
964
965         proto_item_set_len(item, offset-old_offset);
966         return offset;
967 }
968
969 static int
970 samr_dissect_ASCII_DISPINFO_ARRAY_users(tvbuff_t *tvb, int offset,
971                         packet_info *pinfo, proto_tree *tree,
972                         char *drep)
973 {
974         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
975                         samr_dissect_ASCII_DISPINFO);
976
977         return offset;
978 }
979
980 static int
981 samr_dissect_ASCII_DISPINFO_ARRAY(tvbuff_t *tvb, int offset,
982                         packet_info *pinfo, proto_tree *parent_tree,
983                         char *drep)
984 {
985         guint32 count;
986         proto_item *item=NULL;
987         proto_tree *tree=NULL;
988         int old_offset=offset;
989
990         if(parent_tree){
991                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
992                         "Ascii_DispInfo Array");
993                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo_array);
994         }
995
996         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
997                                      hf_samr_count, &count);
998         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
999                         samr_dissect_ASCII_DISPINFO_ARRAY_users, NDR_POINTER_PTR,
1000                         "ACSII_DISPINFO_ARRAY", -1);
1001
1002         proto_item_set_len(item, offset-old_offset);
1003         return offset;
1004 }
1005
1006
1007 static int
1008 samr_dissect_DISPLAY_INFO (tvbuff_t *tvb, int offset,
1009                              packet_info *pinfo, proto_tree *parent_tree,
1010                              char *drep)
1011 {
1012         proto_item *item=NULL;
1013         proto_tree *tree=NULL;
1014         int old_offset=offset;
1015         guint16 level;
1016
1017         if(parent_tree){
1018                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1019                         "DISP_INFO:");
1020                 tree = proto_item_add_subtree(item, ett_samr_display_info);
1021         }
1022
1023         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1024                                      hf_samr_level, &level);
1025         switch(level){
1026         case 1:
1027                 offset = samr_dissect_USER_DISPINFO_1_ARRAY(
1028                                 tvb, offset, pinfo, tree, drep);
1029                 break;
1030         case 2:
1031                 offset = samr_dissect_USER_DISPINFO_2_ARRAY(
1032                                 tvb, offset, pinfo, tree, drep);
1033                 break;
1034         case 3:
1035                 offset = samr_dissect_GROUP_DISPINFO_ARRAY(
1036                                 tvb, offset, pinfo, tree, drep);
1037                 break;
1038         case 4:
1039                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
1040                                 tvb, offset, pinfo, tree, drep);
1041                 break;
1042         case 5:
1043                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
1044                                 tvb, offset, pinfo, tree, drep);
1045                 break;
1046         }
1047
1048         proto_item_set_len(item, offset-old_offset);
1049         return offset;
1050 }
1051
1052 static int
1053 samr_dissect_query_dispinfo_reply(tvbuff_t *tvb, int offset,
1054                                   packet_info *pinfo, proto_tree *tree,
1055                                   char *drep)
1056 {
1057         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1058                         samr_dissect_pointer_long, NDR_POINTER_REF,
1059                         "Total Size", hf_samr_total_size);
1060         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1061                         samr_dissect_pointer_long, NDR_POINTER_REF,
1062                         "Returned Size", hf_samr_ret_size);
1063         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1064                         samr_dissect_DISPLAY_INFO, NDR_POINTER_REF,
1065                         "DISPLAY_INFO:", -1);
1066         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1067                         hf_samr_rc, NULL);
1068
1069         return offset;
1070 }
1071
1072 static int
1073 samr_dissect_get_display_enumeration_index_rqst(tvbuff_t *tvb, int offset,
1074                                                 packet_info *pinfo,
1075                                                 proto_tree *tree,
1076                                                 char *drep)
1077 {
1078         guint16 level;
1079
1080         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1081                                        hf_samr_hnd, NULL, FALSE, FALSE);
1082
1083         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1084                                      hf_samr_level, &level);
1085
1086         if (check_col(pinfo->cinfo, COL_INFO))
1087                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
1088
1089         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
1090                         hf_samr_acct_name, 0);
1091
1092         return offset;
1093 }
1094
1095 static int
1096 samr_dissect_get_display_enumeration_index_reply(tvbuff_t *tvb, int offset,
1097                              packet_info *pinfo, proto_tree *tree,
1098                              char *drep)
1099 {
1100         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1101                         samr_dissect_pointer_long, NDR_POINTER_REF,
1102                         "Index", hf_samr_index);
1103
1104         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1105                                   hf_samr_rc, NULL);
1106
1107         return offset;
1108 }
1109
1110
1111
1112
1113 static int
1114 samr_dissect_PASSWORD_INFO(tvbuff_t *tvb, int offset,
1115                         packet_info *pinfo, proto_tree *parent_tree,
1116                         char *drep)
1117 {
1118         proto_item *item=NULL;
1119         proto_tree *tree=NULL;
1120         int old_offset=offset;
1121
1122         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
1123
1124         if(parent_tree){
1125                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1126                         "PASSWORD_INFO:");
1127                 tree = proto_item_add_subtree(item, ett_samr_password_info);
1128         }
1129
1130
1131         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1132                         hf_samr_unknown_short, NULL);
1133         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1134                         hf_samr_unknown_long, NULL);
1135
1136         proto_item_set_len(item, offset-old_offset);
1137         return offset;
1138 }
1139
1140 static int
1141 samr_dissect_get_usrdom_pwinfo_rqst(tvbuff_t *tvb, int offset,
1142                                     packet_info *pinfo, proto_tree *tree,
1143                                     char *drep)
1144 {
1145         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1146                                        hf_samr_hnd, NULL, FALSE, FALSE);
1147
1148         return offset;
1149 }
1150
1151 static int
1152 samr_dissect_get_usrdom_pwinfo_reply(tvbuff_t *tvb, int offset,
1153                              packet_info *pinfo, proto_tree *tree,
1154                              char *drep)
1155 {
1156         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1157                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
1158                         "PASSWORD_INFO:", -1);
1159
1160         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1161                                   hf_samr_rc, NULL);
1162         return offset;
1163 }
1164
1165 static int
1166 samr_dissect_connect2_rqst(tvbuff_t *tvb, int offset,
1167                            packet_info *pinfo, proto_tree *tree,
1168                            char *drep)
1169 {
1170         offset = dissect_ndr_pointer_cb(
1171                 tvb, offset, pinfo, tree, drep,
1172                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
1173                 "Server", hf_samr_server, cb_wstr_postprocess,
1174                 GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
1175
1176         offset = dissect_nt_access_mask(
1177                 tvb, offset, pinfo, tree, drep, hf_samr_access,
1178                 &samr_connect_access_mask_info);
1179
1180         return offset;
1181 }
1182
1183 static int
1184 samr_dissect_connect4_rqst(tvbuff_t *tvb, int offset,
1185                            packet_info *pinfo, proto_tree *tree,
1186                            char *drep)
1187 {
1188         offset = dissect_ndr_pointer_cb(
1189                 tvb, offset, pinfo, tree, drep,
1190                 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
1191                 "Server", hf_samr_server, cb_wstr_postprocess,
1192                 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
1193
1194         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1195                                      hf_samr_unknown_long, NULL);
1196
1197         offset = dissect_nt_access_mask(
1198                 tvb, offset, pinfo, tree, drep, hf_samr_access,
1199                 &samr_connect_access_mask_info);
1200
1201         return offset;
1202 }
1203
1204 static int
1205 samr_dissect_connect2_reply(tvbuff_t *tvb, int offset,
1206                              packet_info *pinfo, proto_tree *tree,
1207                              char *drep)
1208 {
1209         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
1210         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
1211         e_ctx_hnd policy_hnd;
1212         char *server = (char *)dcv->private_data, *pol_name;
1213         
1214         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1215                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
1216
1217         if (server)
1218                 pol_name = g_strdup_printf("Connect2(%s)", server);
1219         else
1220                 pol_name = g_strdup("Connect2 handle");
1221
1222         dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
1223
1224         g_free(pol_name);
1225
1226         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1227                                   hf_samr_rc, NULL);
1228         return offset;
1229 }
1230
1231 static int
1232 samr_dissect_connect_anon_rqst(tvbuff_t *tvb, int offset,
1233                                packet_info *pinfo, proto_tree *tree,
1234                                char *drep)
1235 {
1236         char str[2];
1237         guint16 server;
1238
1239         offset=dissect_ndr_uint16(tvb, offset, pinfo, NULL, drep,
1240                         hf_samr_server, &server);
1241         str[0]=server&0xff;
1242         str[1]=0;
1243         proto_tree_add_string_format(tree, hf_samr_server, tvb, offset-2, 2,
1244                 str, "Server: %s", str);
1245
1246         return offset;
1247 }
1248
1249 static int
1250 samr_dissect_connect_anon_reply(tvbuff_t *tvb, int offset,
1251                                 packet_info *pinfo, proto_tree *tree,
1252                                 char *drep)
1253 {
1254         e_ctx_hnd policy_hnd;
1255
1256         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1257                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
1258
1259         dcerpc_smb_store_pol_name(&policy_hnd, "ConnectAnon handle");
1260
1261         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1262                                   hf_samr_rc, NULL);
1263
1264         return offset;
1265 }
1266
1267 static int
1268 samr_dissect_USER_GROUP(tvbuff_t *tvb, int offset,
1269                              packet_info *pinfo, proto_tree *parent_tree,
1270                              char *drep)
1271 {
1272         proto_item *item=NULL;
1273         proto_tree *tree=NULL;
1274         int old_offset=offset;
1275
1276         if(parent_tree){
1277                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1278                         "USER_GROUP:");
1279                 tree = proto_item_add_subtree(item, ett_samr_user_group);
1280         }
1281
1282         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1283                                      hf_samr_rid, NULL);
1284         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1285                                      hf_samr_rid_attrib, NULL);
1286
1287         proto_item_set_len(item, offset-old_offset);
1288         return offset;
1289 }
1290
1291 static int
1292 samr_dissect_USER_GROUP_ARRAY_groups (tvbuff_t *tvb, int offset,
1293                              packet_info *pinfo, proto_tree *tree,
1294                              char *drep)
1295 {
1296         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
1297                         samr_dissect_USER_GROUP);
1298
1299         return offset;
1300 }
1301
1302 static int
1303 samr_dissect_USER_GROUP_ARRAY(tvbuff_t *tvb, int offset,
1304                         packet_info *pinfo, proto_tree *parent_tree,
1305                         char *drep)
1306 {
1307         guint32 count;
1308         proto_item *item=NULL;
1309         proto_tree *tree=NULL;
1310         int old_offset=offset;
1311
1312         if(parent_tree){
1313                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1314                         "USER_GROUP_ARRAY");
1315                 tree = proto_item_add_subtree(item, ett_samr_user_group_array);
1316         }
1317
1318         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1319                         hf_samr_count, &count);
1320         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1321                         samr_dissect_USER_GROUP_ARRAY_groups, NDR_POINTER_UNIQUE,
1322                         "USER_GROUP_ARRAY", -1);
1323
1324         proto_item_set_len(item, offset-old_offset);
1325         return offset;
1326 }
1327
1328 static int
1329 samr_dissect_USER_GROUP_ARRAY_ptr(tvbuff_t *tvb, int offset,
1330                         packet_info *pinfo, proto_tree *tree,
1331                         char *drep)
1332 {
1333         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1334                         samr_dissect_USER_GROUP_ARRAY, NDR_POINTER_UNIQUE,
1335                         "USER_GROUP_ARRAY", -1);
1336         return offset;
1337 }
1338
1339 static int
1340 samr_dissect_get_groups_for_user_rqst(tvbuff_t *tvb, int offset,
1341                                       packet_info *pinfo, proto_tree *tree,
1342                                       char *drep)
1343 {
1344         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1345                                        hf_samr_hnd, NULL, FALSE, FALSE);
1346
1347         return offset;
1348 }
1349
1350 static int
1351 samr_dissect_get_groups_for_user_reply(tvbuff_t *tvb, int offset,
1352                                        packet_info *pinfo, proto_tree *tree,
1353                                        char *drep)
1354 {
1355         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1356                         samr_dissect_USER_GROUP_ARRAY_ptr, NDR_POINTER_REF,
1357                         "USER_GROUP_ARRAY:", -1);
1358
1359         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1360                                   hf_samr_rc, NULL);
1361         return offset;
1362 }
1363
1364
1365 static void append_sid_col_info(packet_info *pinfo, proto_tree *tree _U_, 
1366                                 proto_item *item _U_, tvbuff_t *tvb _U_, 
1367                                 int start_offset _U_, int end_offset _U_, 
1368                                 void *callback_args _U_)
1369 {
1370         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
1371         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
1372         char *sid_str = dcv->private_data;
1373
1374         if (sid_str && check_col(pinfo->cinfo, COL_INFO))
1375                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", sid_str);
1376 }
1377
1378 static int
1379 samr_dissect_open_domain_rqst(tvbuff_t *tvb, int offset,
1380                               packet_info *pinfo, proto_tree *tree,
1381                               char *drep)
1382 {
1383         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1384                                        hf_samr_hnd, NULL, FALSE, FALSE);
1385
1386         offset = dissect_nt_access_mask(
1387                 tvb, offset, pinfo, tree, drep, hf_samr_access,
1388                 &samr_domain_access_mask_info);
1389
1390         offset = dissect_ndr_pointer_cb(
1391                 tvb, offset, pinfo, tree, drep, dissect_ndr_nt_SID, 
1392                 NDR_POINTER_REF, "SID:", -1, append_sid_col_info, NULL);
1393
1394         return offset;
1395 }
1396
1397 static int
1398 samr_dissect_open_domain_reply(tvbuff_t *tvb, int offset,
1399                              packet_info *pinfo, proto_tree *tree,
1400                              char *drep)
1401 {
1402         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
1403         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
1404         e_ctx_hnd policy_hnd;
1405         char *pol_name, *sid_str = (char *)dcv->private_data;
1406
1407         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1408                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
1409
1410         if (sid_str)
1411                 pol_name = g_strdup_printf("OpenDomain(%s)", sid_str);
1412         else
1413                 pol_name = g_strdup("OpenDomain handle");
1414
1415         dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
1416
1417         g_free(pol_name);
1418
1419         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1420                                   hf_samr_rc, NULL);
1421
1422         return offset;
1423 }
1424
1425 #if 0
1426 static int
1427 samr_dissect_context_handle_SID(tvbuff_t *tvb, int offset,
1428                              packet_info *pinfo, proto_tree *tree,
1429                              char *drep)
1430 {
1431         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1432                                        hf_samr_hnd, NULL, FALSE, FALSE);
1433
1434         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1435                         dissect_ndr_nt_SID, NDR_POINTER_REF,
1436                         "SID", -1, 0);
1437         return offset;
1438 }
1439 #endif
1440
1441 static int
1442 samr_dissect_add_member_to_group_rqst(tvbuff_t *tvb, int offset,
1443                                       packet_info *pinfo, proto_tree *tree,
1444                                       char *drep)
1445 {
1446         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1447                                        hf_samr_hnd, NULL, FALSE, FALSE);
1448
1449         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1450                                      hf_samr_group, NULL);
1451
1452         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1453                                      hf_samr_rid, NULL);
1454
1455         return offset;
1456 }
1457
1458 static int
1459 samr_dissect_add_member_to_group_reply(tvbuff_t *tvb, int offset,
1460                                        packet_info *pinfo, proto_tree *tree,
1461                                        char *drep)
1462 {
1463         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1464                                   hf_samr_rc, NULL);
1465
1466         return offset;
1467 }
1468
1469 static int
1470 samr_dissect_unknown_3c_rqst(tvbuff_t *tvb, int offset,
1471                              packet_info *pinfo, proto_tree *tree,
1472                              char *drep)
1473 {
1474         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1475                                        hf_samr_hnd, NULL, FALSE, FALSE);
1476
1477         return offset;
1478 }
1479
1480 static int
1481 samr_dissect_unknown_3c_reply(tvbuff_t *tvb, int offset,
1482                              packet_info *pinfo, proto_tree *tree,
1483                              char *drep)
1484 {
1485         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1486                         samr_dissect_pointer_short, NDR_POINTER_REF,
1487                         "unknown short", hf_samr_unknown_short);
1488
1489         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1490                                   hf_samr_rc, NULL);
1491         return offset;
1492 }
1493
1494 static int
1495 samr_dissect_create_alias_in_domain_rqst(tvbuff_t *tvb, int offset,
1496                                          packet_info *pinfo, proto_tree *tree,
1497                                          char *drep)
1498 {
1499         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1500                                        hf_samr_hnd, NULL, FALSE, FALSE);
1501
1502         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1503                         dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
1504                         "Account Name", hf_samr_acct_name);
1505
1506         offset = dissect_nt_access_mask(
1507                 tvb, offset, pinfo, tree, drep, hf_samr_access,
1508                 &samr_alias_access_mask_info);
1509
1510         return offset;
1511 }
1512
1513 static int
1514 samr_dissect_create_alias_in_domain_reply(tvbuff_t *tvb, int offset,
1515                              packet_info *pinfo, proto_tree *tree,
1516                              char *drep)
1517 {
1518         e_ctx_hnd policy_hnd;
1519
1520         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1521                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
1522
1523         dcerpc_smb_store_pol_name(&policy_hnd, "CreateAlias handle");
1524
1525         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1526                                      hf_samr_rid, NULL);
1527
1528         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1529                                   hf_samr_rc, NULL);
1530
1531         return offset;
1532 }
1533
1534 static int
1535 samr_dissect_query_information_alias_rqst(tvbuff_t *tvb, int offset,
1536                                           packet_info *pinfo,
1537                                           proto_tree *tree, char *drep)
1538 {
1539         guint16 level;
1540
1541         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1542                                        hf_samr_hnd, NULL, FALSE, FALSE);
1543
1544         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1545                         hf_samr_level, &level);
1546
1547         if (check_col(pinfo->cinfo, COL_INFO))
1548                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
1549
1550         return offset;
1551 }
1552
1553 static int
1554 samr_dissect_ALIAS_INFO_1 (tvbuff_t *tvb, int offset,
1555                              packet_info *pinfo, proto_tree *tree,
1556                              char *drep)
1557 {
1558         offset = dissect_ndr_counted_string(tvb, offset, pinfo,
1559                 tree, drep, hf_samr_acct_name, 0);
1560         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1561                                      hf_samr_rid, NULL);
1562         offset = dissect_ndr_counted_string(tvb, offset, pinfo,
1563                 tree, drep, hf_samr_acct_desc, 0);
1564         return offset;
1565 }
1566
1567 static int
1568 samr_dissect_ALIAS_INFO(tvbuff_t *tvb, int offset,
1569                         packet_info *pinfo, proto_tree *parent_tree,
1570                         char *drep)
1571 {
1572         proto_item *item=NULL;
1573         proto_tree *tree=NULL;
1574         int old_offset=offset;
1575         guint16 level;
1576
1577         if(parent_tree){
1578                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1579                         "ALIAS_INFO:");
1580                 tree = proto_item_add_subtree(item, ett_samr_alias_info);
1581         }
1582
1583         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1584                                      hf_samr_level, &level);
1585         switch(level){
1586         case 1:
1587                 offset = samr_dissect_ALIAS_INFO_1(
1588                                 tvb, offset, pinfo, tree, drep);
1589                 break;
1590         case 2:
1591                 offset = dissect_ndr_counted_string(tvb, offset, pinfo,
1592                         tree, drep, hf_samr_acct_name, 0);
1593                 break;
1594         case 3:
1595                 offset = dissect_ndr_counted_string(tvb, offset, pinfo,
1596                         tree, drep, hf_samr_acct_desc, 0);
1597                 break;
1598         }
1599
1600         proto_item_set_len(item, offset-old_offset);
1601         return offset;
1602 }
1603
1604 static int
1605 samr_dissect_ALIAS_INFO_ptr(tvbuff_t *tvb, int offset,
1606                         packet_info *pinfo, proto_tree *tree,
1607                         char *drep)
1608 {
1609         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1610                         samr_dissect_ALIAS_INFO, NDR_POINTER_UNIQUE,
1611                         "ALIAS_INFO", -1);
1612         return offset;
1613 }
1614
1615 static int
1616 samr_dissect_query_information_alias_reply(tvbuff_t *tvb, int offset,
1617                                            packet_info *pinfo,
1618                                            proto_tree *tree, char *drep)
1619 {
1620         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1621                         samr_dissect_ALIAS_INFO_ptr, NDR_POINTER_REF,
1622                         "ALIAS_INFO:", -1);
1623
1624         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1625                                   hf_samr_rc, NULL);
1626
1627         return offset;
1628 }
1629
1630 static int
1631 samr_dissect_set_information_alias_rqst(tvbuff_t *tvb, int offset,
1632                              packet_info *pinfo, proto_tree *tree,
1633                              char *drep)
1634 {
1635         guint16 level;
1636
1637         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1638                                        hf_samr_hnd, NULL, FALSE, FALSE);
1639
1640         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1641                                      hf_samr_level, &level);
1642
1643         if (check_col(pinfo->cinfo, COL_INFO))
1644                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
1645
1646         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1647                         samr_dissect_ALIAS_INFO, NDR_POINTER_REF,
1648                         "ALIAS_INFO:", -1);
1649         return offset;
1650 }
1651
1652 static int
1653 samr_dissect_set_information_alias_reply(tvbuff_t *tvb, int offset,
1654                                          packet_info *pinfo, proto_tree *tree,
1655                                          char *drep)
1656 {
1657         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1658                         samr_dissect_ALIAS_INFO_ptr, NDR_POINTER_REF,
1659                         "ALIAS_INFO", -1);
1660
1661         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1662                                   hf_samr_rc, NULL);
1663         return offset;
1664 }
1665
1666 static int
1667 samr_dissect_CRYPT_PASSWORD(tvbuff_t *tvb, int offset,
1668                         packet_info *pinfo _U_, proto_tree *tree,
1669                         char *drep _U_)
1670 {
1671         dcerpc_info *di;
1672
1673         di=pinfo->private_data;
1674         if(di->conformant_run){
1675                 /* just a run to handle conformant arrays, no scalars to dissect */
1676                 return offset;
1677         }
1678
1679         proto_tree_add_item(tree, hf_samr_crypt_password, tvb, offset, 516,
1680                 TRUE);
1681         offset += 516;
1682         return offset;
1683 }
1684
1685 static int
1686 samr_dissect_CRYPT_HASH(tvbuff_t *tvb, int offset,
1687                         packet_info *pinfo _U_, proto_tree *tree,
1688                         char *drep _U_)
1689 {
1690         dcerpc_info *di;
1691
1692         di=pinfo->private_data;
1693         if(di->conformant_run){
1694                 /* just a run to handle conformant arrays, no scalars to dissect */
1695                 return offset;
1696         }
1697
1698         proto_tree_add_item(tree, hf_samr_crypt_hash, tvb, offset, 16,
1699                 TRUE);
1700         offset += 16;
1701         return offset;
1702 }
1703
1704 #define NT_BLOCK_SIZE 516
1705
1706 static void
1707 samr_dissect_decrypted_NT_PASSCHANGE_BLOCK(tvbuff_t *tvb, int offset,
1708                                  packet_info *pinfo _U_, proto_tree *tree,
1709                                  char *drep _U_)
1710 {
1711   guint32 new_password_len = 0;
1712   guint32 pseudorandom_len = 0;
1713   const char *printable_password;
1714   guint16 bc;
1715   int result_length;
1716
1717   /* The length of the new password is represented in the last four 
1718      octets of the decrypted buffer.  Since the password length cannot
1719      exceed 512, we can check the contents of those bytes to determine 
1720      if decryption was successful.  If the decrypted contents of those 
1721      four bytes is less than 512, then there is a 99% chance that
1722      we decrypted the buffer successfully.  Of course, this isn't good
1723      enough for a security application, (NT uses the "verifier" field 
1724      to come to the same conclusion), but it should be good enough for
1725      our dissector. */
1726   
1727   new_password_len = tvb_get_letohl(tvb, 512);  
1728
1729   if (new_password_len <= 512)
1730     {
1731       /* Decryption successful */
1732       proto_tree_add_text (tree, tvb, offset, -1,
1733                            "Decryption of NT Password Encrypted block successful");
1734
1735       /* Whatever is before the password is pseudorandom data.  We calculate 
1736          the length by examining the password length (at the end), and working
1737          backward */    
1738       pseudorandom_len = NT_BLOCK_SIZE - new_password_len - 4;
1739
1740       /* Pseudorandom data padding up to password */
1741       proto_tree_add_item(tree, hf_samr_nt_passchange_block_pseudorandom, 
1742                           tvb, offset, pseudorandom_len, TRUE);
1743       offset += pseudorandom_len;
1744
1745       /* The new password itself */
1746       bc = new_password_len;
1747       printable_password = get_unicode_or_ascii_string(tvb, &offset,
1748                                                        TRUE,
1749                                                        &result_length,
1750                                                        FALSE, TRUE, &bc);
1751       proto_tree_add_string(tree, hf_samr_nt_passchange_block_newpass,
1752                             tvb, offset, result_length, 
1753                             printable_password);
1754       offset += new_password_len;
1755
1756       /* Length of password */
1757       proto_tree_add_item(tree, hf_samr_nt_passchange_block_newpass_len,
1758                           tvb, offset, 4, TRUE);
1759     }
1760   else
1761     {
1762       /* Decryption failure.  Just show the encrypted block */
1763       proto_tree_add_text (tree, tvb, offset, -1,
1764                            "Decryption of NT Passchange block failed");
1765       
1766       proto_tree_add_item(tree, hf_samr_nt_passchange_block_decrypted, tvb,
1767                           offset, NT_BLOCK_SIZE, TRUE);
1768     }
1769 }
1770
1771 static int
1772 samr_dissect_NT_PASSCHANGE_BLOCK(tvbuff_t *tvb, int offset,
1773                                  packet_info *pinfo _U_, proto_tree *tree,
1774                                  char *drep _U_)
1775 {
1776         dcerpc_info *di;
1777         size_t password_len;
1778         unsigned char *password_unicode;
1779         size_t password_len_unicode;
1780         unsigned char password_md4_hash[16];
1781         guint8 *block;
1782         tvbuff_t *decr_tvb; /* Used to store decrypted buffer */
1783         rc4_state_struct rc4_state;
1784         guint i;
1785         
1786         /* This implements the the algorithm discussed in lkcl -"DCE/RPC 
1787            over SMB" page 257.  Note that this code does not properly support
1788            Unicode. */
1789
1790         di=pinfo->private_data;
1791         if(di->conformant_run){
1792                 /* just a run to handle conformant arrays, no scalars to dissect */
1793                 return offset;
1794         }
1795
1796         /* Put in a protocol tree entry for the encrypted block. */
1797         proto_tree_add_text(tree, tvb, offset, NT_BLOCK_SIZE,
1798             "Encrypted NT Password Block");
1799
1800         if (nt_password[0] != '\0') {
1801                 /* We have an NT password, so we can decrypt the password
1802                    change block. */
1803
1804                 /* Convert the password provided in the Ethereal GUI to Unicode 
1805                    (UCS-2).  Since the input is always ASCII, we can just fake
1806                    it and pad every other byte with a NUL.  If we ever support
1807                    UTF-8 in the GUI, we would have to perform a real UTF-8 to
1808                    UCS-2 conversion */
1809                 password_len = strlen(nt_password);
1810                 password_len_unicode = password_len*2;
1811                 password_unicode = g_malloc(password_len_unicode);
1812                 for (i = 0; i < password_len; i++) {
1813                         password_unicode[i*2] = nt_password[i];
1814                         password_unicode[i*2+1] = 0;
1815                 }
1816
1817                 /* Run MD4 against the resulting Unicode password.  This will
1818                    be used to perform RC4 decryption on the password change
1819                    block.  Then free the Unicode password, as we're done
1820                    with it. */
1821                 crypt_md4(password_md4_hash, password_unicode,
1822                     password_len_unicode);
1823                 g_free(password_unicode);
1824         
1825                 /* Copy the block into a temporary buffer so we can decrypt
1826                    it */
1827                 block = g_malloc(NT_BLOCK_SIZE);
1828                 memset(block, 0, NT_BLOCK_SIZE);
1829                 tvb_memcpy(tvb, block, offset, NT_BLOCK_SIZE);
1830         
1831                 /* RC4 decrypt the block with the old NT password hash */
1832                 crypt_rc4_init(&rc4_state, password_md4_hash, 16);
1833                 crypt_rc4(&rc4_state, block, NT_BLOCK_SIZE);
1834
1835                 /* Show the decrypted buffer in a new window */
1836                 decr_tvb = tvb_new_real_data(block, NT_BLOCK_SIZE,
1837                     NT_BLOCK_SIZE);
1838                 tvb_set_free_cb(decr_tvb, g_free);
1839                 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1840                 add_new_data_source(pinfo, decr_tvb,
1841                     "Decrypted NT Password Block");
1842
1843                 /* Dissect the decrypted block */
1844                 samr_dissect_decrypted_NT_PASSCHANGE_BLOCK(decr_tvb, 0, pinfo,
1845                                                            tree, drep);
1846         }
1847         offset += NT_BLOCK_SIZE;
1848         return offset;
1849 }
1850
1851 static int
1852 samr_dissect_LM_PASSCHANGE_BLOCK(tvbuff_t *tvb, int offset,
1853                                  packet_info *pinfo _U_, proto_tree *tree,
1854                                  char *drep _U_)
1855 {
1856         dcerpc_info *di;
1857
1858         /* Right now, this just dumps the output.  In the long term, we can use
1859            the algorithm discussed in lkcl -"DCE/RPC over SMB" page 257 to
1860            actually decrypt the block */
1861
1862         di=pinfo->private_data;
1863         if(di->conformant_run){
1864                 /* just a run to handle conformant arrays, no scalars to dissect */
1865                 return offset;
1866         }
1867
1868         proto_tree_add_item(tree, hf_samr_lm_passchange_block, tvb, offset, 
1869                             516, TRUE);
1870         offset += 516;
1871         return offset;
1872 }
1873
1874 static int
1875 samr_dissect_LM_VERIFIER(tvbuff_t *tvb, int offset,
1876                          packet_info *pinfo _U_, proto_tree *tree,
1877                          char *drep _U_)
1878 {
1879         dcerpc_info *di;
1880
1881         /* Right now, this just dumps the output.  In the long term, we can use
1882            the algorithm discussed in lkcl -"DCE/RPC over SMB" page 257 to
1883            actually validate the verifier */
1884
1885         di=pinfo->private_data;
1886         if(di->conformant_run){
1887                 /* just a run to handle conformant arrays, no scalars to dissect */
1888                 return offset;
1889         }
1890
1891         proto_tree_add_item(tree, hf_samr_lm_verifier, tvb, offset, 16,
1892                 TRUE);
1893         offset += 16;
1894         return offset;
1895 }
1896
1897
1898 static int
1899 samr_dissect_NT_VERIFIER(tvbuff_t *tvb, int offset,
1900                          packet_info *pinfo _U_, proto_tree *tree,
1901                          char *drep _U_)
1902 {
1903         dcerpc_info *di;
1904
1905         /* Right now, this just dumps the output.  In the long term, we can use
1906            the algorithm discussed in lkcl -"DCE/RPC over SMB" page 257 to
1907            actually validate the verifier */
1908
1909         di=pinfo->private_data;
1910         if(di->conformant_run){
1911                 /* just a run to handle conformant arrays, no scalars to dissect */
1912                 return offset;
1913         }
1914
1915         proto_tree_add_item(tree, hf_samr_nt_verifier, tvb, offset, 16,
1916                 TRUE);
1917         offset += 16;
1918         return offset;
1919 }
1920
1921
1922 static int
1923 samr_dissect_oem_change_password_user2_rqst(tvbuff_t *tvb, int offset,
1924                                             packet_info *pinfo,
1925                                             proto_tree *tree, char *drep)
1926 {
1927         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1928                                        hf_samr_hnd, NULL, FALSE, FALSE);
1929
1930         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1931                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1932                         "Server", hf_samr_server);
1933
1934         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1935                         samr_dissect_pointer_STRING, NDR_POINTER_REF,
1936                         "Account Name", hf_samr_acct_name);
1937
1938         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1939                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1940                         "Password", -1);
1941
1942         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1943                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1944                         "Hash", -1);
1945         return offset;
1946 }
1947
1948 static int
1949 samr_dissect_oem_change_password_user2_reply(tvbuff_t *tvb, int offset,
1950                                              packet_info *pinfo,
1951                                              proto_tree *tree, char *drep)
1952 {
1953         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1954                                   hf_samr_rc, NULL);
1955
1956         return offset;
1957 }
1958
1959 static int
1960 samr_dissect_unicode_change_password_user2_rqst(tvbuff_t *tvb, int offset,
1961                                                 packet_info *pinfo,
1962                                                 proto_tree *tree, char *drep)
1963 {
1964         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1965                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
1966                         "PASSWORD_INFO:", -1);
1967
1968         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
1969                         NDR_POINTER_UNIQUE, "Server", hf_samr_server, 0);
1970
1971         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1972                         dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
1973                         "Account Name", hf_samr_acct_name);
1974
1975         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1976                         samr_dissect_NT_PASSCHANGE_BLOCK, NDR_POINTER_UNIQUE,
1977                         "New NT Password Encrypted Block", -1);
1978         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1979                         samr_dissect_NT_VERIFIER, NDR_POINTER_UNIQUE,
1980                         "NT Password Verifier", -1);
1981         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1982                                      hf_samr_lm_change, NULL);
1983         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1984                         samr_dissect_LM_PASSCHANGE_BLOCK, NDR_POINTER_UNIQUE,
1985                         "New Lan Manager Password Encrypted Block", -1);
1986         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1987                         samr_dissect_LM_VERIFIER, NDR_POINTER_UNIQUE,
1988                         "Lan Manager Password Verifier", -1);
1989         return offset;
1990 }
1991
1992 static int
1993 samr_dissect_unicode_change_password_user2_reply(tvbuff_t *tvb, int offset,
1994                                                  packet_info *pinfo,
1995                                                  proto_tree *tree, char *drep)
1996 {
1997         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1998                                   hf_samr_rc, NULL);
1999
2000         return offset;
2001 }
2002
2003 static int
2004 samr_dissect_unknown_3b_rqst(tvbuff_t *tvb, int offset,
2005                              packet_info *pinfo, proto_tree *tree,
2006                              char *drep)
2007 {
2008         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2009                                        hf_samr_hnd, NULL, FALSE, FALSE);
2010
2011         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2012                                      hf_samr_unknown_short, NULL);
2013         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2014                         dissect_ndr_counted_string_ptr, NDR_POINTER_UNIQUE,
2015                         "Unknown", hf_samr_unknown_string);
2016         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2017                         dissect_ndr_counted_string_ptr, NDR_POINTER_UNIQUE,
2018                         "Unknown", hf_samr_unknown_string);
2019         return offset;
2020 }
2021
2022 static int
2023 samr_dissect_unknown_3b_reply(tvbuff_t *tvb, int offset,
2024                               packet_info *pinfo, proto_tree *tree,
2025                               char *drep)
2026 {
2027         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2028                                   hf_samr_rc, NULL);
2029
2030         return offset;
2031 }
2032
2033 static int
2034 samr_dissect_create_user2_in_domain_rqst(tvbuff_t *tvb, int offset,
2035                                          packet_info *pinfo, proto_tree *tree,
2036                                          char *drep)
2037 {
2038         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2039                                        hf_samr_hnd, NULL, FALSE, FALSE);
2040
2041         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2042                         dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
2043                         "Account Name", hf_samr_acct_name);
2044
2045         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2046
2047         offset = dissect_nt_access_mask(
2048                 tvb, offset, pinfo, tree, drep, hf_samr_access,
2049                 &samr_user_access_mask_info);
2050
2051         return offset;
2052 }
2053
2054 static int
2055 samr_dissect_create_user2_in_domain_reply(tvbuff_t *tvb, int offset,
2056                              packet_info *pinfo, proto_tree *tree,
2057                              char *drep)
2058 {
2059         e_ctx_hnd policy_hnd;
2060
2061         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2062                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
2063
2064         dcerpc_smb_store_pol_name(&policy_hnd, "CreateUser2 handle");
2065
2066         offset = dissect_nt_access_mask(
2067                 tvb, offset, pinfo, tree, drep, hf_samr_access_granted,
2068                 &samr_user_access_mask_info);
2069
2070         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2071                                      hf_samr_rid, NULL);
2072
2073         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2074                                   hf_samr_rc, NULL);
2075         return offset;
2076 }
2077
2078 static int
2079 samr_dissect_get_display_enumeration_index2_rqst(tvbuff_t *tvb, int offset,
2080                                                  packet_info *pinfo,
2081                                                  proto_tree *tree, char *drep)
2082 {
2083         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2084                                        hf_samr_hnd, NULL, FALSE, FALSE);
2085
2086         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2087                                      hf_samr_level, NULL);
2088         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2089                         dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
2090                         "Account Name", hf_samr_acct_name);
2091         return offset;
2092 }
2093
2094 static int
2095 samr_dissect_get_display_enumeration_index2_reply(tvbuff_t *tvb, int offset,
2096                              packet_info *pinfo, proto_tree *tree,
2097                              char *drep)
2098 {
2099         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2100                                      hf_samr_index, NULL);
2101
2102         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2103                                   hf_samr_rc, NULL);
2104         return offset;
2105 }
2106
2107 static int
2108 samr_dissect_change_password_user_rqst(tvbuff_t *tvb, int offset,
2109                                        packet_info *pinfo, proto_tree *tree,
2110                                        char *drep)
2111 {
2112         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2113                                        hf_samr_hnd, NULL, FALSE, FALSE);
2114
2115         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2116                         hf_samr_unknown_char, NULL);
2117         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2118                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
2119                         "Hash", -1);
2120         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2121                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
2122                         "Hash", -1);
2123         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2124                         hf_samr_unknown_char, NULL);
2125         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2126                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
2127                         "Hash", -1);
2128         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2129                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
2130                         "Hash", -1);
2131         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2132                         hf_samr_unknown_char, NULL);
2133         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2134                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
2135                         "Hash", -1);
2136         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2137                         hf_samr_unknown_char, NULL);
2138         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2139                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
2140                         "Hash", -1);
2141
2142         return offset;
2143 }
2144
2145 static int
2146 samr_dissect_change_password_user_reply(tvbuff_t *tvb, int offset,
2147                                         packet_info *pinfo, proto_tree *tree,
2148                                         char *drep)
2149 {
2150         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2151                                   hf_samr_rc, NULL);
2152
2153         return offset;
2154 }
2155
2156 static int
2157 samr_dissect_set_member_attributes_of_group_rqst(tvbuff_t *tvb, int offset,
2158                                                  packet_info *pinfo,
2159                                                  proto_tree *tree, char *drep)
2160 {
2161         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2162                                        hf_samr_hnd, NULL, FALSE, FALSE);
2163
2164         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2165                                      hf_samr_attrib, NULL);
2166         return offset;
2167 }
2168
2169 static int
2170 samr_dissect_set_member_attributes_of_group_reply(tvbuff_t *tvb, int offset,
2171                              packet_info *pinfo, proto_tree *tree,
2172                              char *drep)
2173 {
2174         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2175                                   hf_samr_rc, NULL);
2176
2177         return offset;
2178 }
2179
2180 static int
2181 samr_dissect_GROUP_INFO_1 (tvbuff_t *tvb, int offset,
2182                              packet_info *pinfo, proto_tree *tree,
2183                              char *drep)
2184 {
2185         offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2186                 tree, drep, hf_samr_acct_name, 0);
2187         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2188                                      hf_samr_rid, NULL);
2189         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2190                                         hf_samr_attrib, NULL);
2191         offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2192                 tree, drep, hf_samr_acct_desc, 0);
2193         return offset;
2194 }
2195
2196 static int
2197 samr_dissect_GROUP_INFO(tvbuff_t *tvb, int offset,
2198                         packet_info *pinfo, proto_tree *parent_tree,
2199                         char *drep)
2200 {
2201         proto_item *item=NULL;
2202         proto_tree *tree=NULL;
2203         int old_offset=offset;
2204         guint16 level;
2205
2206         if(parent_tree){
2207                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2208                         "GROUP_INFO:");
2209                 tree = proto_item_add_subtree(item, ett_samr_group_info);
2210         }
2211
2212         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2213                                      hf_samr_level, &level);
2214         switch(level){
2215         case 1:
2216                 offset = samr_dissect_GROUP_INFO_1(
2217                                 tvb, offset, pinfo, tree, drep);
2218                 break;
2219         case 2:
2220                 offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2221                         tree, drep, hf_samr_acct_name, 0);
2222                 break;
2223         case 3:
2224                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2225                         hf_samr_attrib, NULL);
2226                 break;
2227         case 4:
2228                 offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2229                         tree, drep, hf_samr_acct_desc, 0);
2230                 break;
2231         }
2232
2233         proto_item_set_len(item, offset-old_offset);
2234         return offset;
2235 }
2236
2237 static int
2238 samr_dissect_GROUP_INFO_ptr(tvbuff_t *tvb, int offset,
2239                         packet_info *pinfo, proto_tree *tree,
2240                         char *drep)
2241 {
2242         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2243                         samr_dissect_GROUP_INFO, NDR_POINTER_UNIQUE,
2244                         "GROUP_INFO", -1);
2245         return offset;
2246 }
2247
2248 static int
2249 samr_dissect_query_information_group_rqst(tvbuff_t *tvb, int offset,
2250                                           packet_info *pinfo,
2251                                           proto_tree *tree, char *drep)
2252 {
2253         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2254                                        hf_samr_hnd, NULL, FALSE, FALSE);
2255
2256         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2257                                      hf_samr_level, NULL);
2258
2259         return offset;
2260 }
2261
2262 static int
2263 samr_dissect_query_information_group_reply(tvbuff_t *tvb, int offset,
2264                         packet_info *pinfo, proto_tree *tree,
2265                         char *drep)
2266 {
2267         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2268                         samr_dissect_GROUP_INFO_ptr, NDR_POINTER_REF,
2269                         "GROUP_INFO", -1);
2270
2271         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2272                                   hf_samr_rc, NULL);
2273         return offset;
2274 }
2275
2276 static int
2277 samr_dissect_set_information_group_rqst(tvbuff_t *tvb, int offset,
2278                                         packet_info *pinfo, proto_tree *tree,
2279                                         char *drep)
2280 {
2281         guint16 level;
2282
2283         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2284                                        hf_samr_hnd, NULL, FALSE, FALSE);
2285
2286         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2287                                      hf_samr_level, &level);
2288
2289         if (check_col(pinfo->cinfo, COL_INFO))
2290                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
2291
2292         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2293                         samr_dissect_GROUP_INFO, NDR_POINTER_REF,
2294                         "GROUP_INFO", -1);
2295         return offset;
2296 }
2297
2298 static int
2299 samr_dissect_set_information_group_reply(tvbuff_t *tvb, int offset,
2300                              packet_info *pinfo, proto_tree *tree,
2301                              char *drep)
2302 {
2303         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2304                                   hf_samr_rc, NULL);
2305
2306         return offset;
2307 }
2308
2309 static int
2310 samr_dissect_get_domain_password_information_rqst(tvbuff_t *tvb, int offset,
2311                                                   packet_info *pinfo,
2312                                                   proto_tree *tree,
2313                                                   char *drep)
2314 {
2315         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2316                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
2317                         "PASSWORD_INFO:", -1);
2318
2319         offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
2320                         NDR_POINTER_UNIQUE, "Domain", hf_samr_domain, 0);
2321
2322         return offset;
2323 }
2324
2325 static int
2326 samr_dissect_get_domain_password_information_reply(tvbuff_t *tvb, int offset,
2327                                                    packet_info *pinfo,
2328                                                    proto_tree *tree,
2329                                                    char *drep)
2330 {
2331         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2332                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
2333                         "PASSWORD_INFO:", -1);
2334
2335         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2336                                   hf_samr_rc, NULL);
2337
2338         return offset;
2339 }
2340
2341 static int
2342 samr_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset,
2343                              packet_info *pinfo, proto_tree *parent_tree,
2344                              char *drep)
2345 {
2346         proto_item *item=NULL;
2347         proto_tree *tree=NULL;
2348         int old_offset=offset;
2349
2350         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
2351
2352         if(parent_tree){
2353                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2354                         "DOMAIN_INFO_1:");
2355                 tree = proto_item_add_subtree(item, ett_samr_domain_info_1);
2356         }
2357
2358         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2359                                         hf_samr_min_pwd_len, NULL);
2360         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2361                                         hf_samr_pwd_history_len, NULL);
2362         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2363                                         hf_samr_unknown_long, NULL);
2364         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2365                                         hf_samr_max_pwd_age);
2366         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2367                                         hf_samr_min_pwd_age);
2368         proto_item_set_len(item, offset-old_offset);
2369         return offset;
2370 }
2371
2372 static int
2373 samr_dissect_DOMAIN_INFO_2(tvbuff_t *tvb, int offset,
2374                         packet_info *pinfo, proto_tree *parent_tree,
2375                         char *drep)
2376 {
2377         proto_item *item=NULL;
2378         proto_tree *tree=NULL;
2379         int old_offset=offset;
2380
2381         if(parent_tree){
2382                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2383                         "DOMAIN_INFO_2:");
2384                 tree = proto_item_add_subtree(item, ett_samr_domain_info_2);
2385         }
2386
2387         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2388                         hf_samr_unknown_time);
2389         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2390                         hf_samr_unknown_string, 0);
2391         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2392                         hf_samr_domain, 0);
2393         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
2394                         hf_samr_controller, 0);
2395         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2396                         hf_samr_unknown_time);
2397         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2398                         hf_samr_unknown_long, NULL);
2399         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2400                         hf_samr_unknown_long, NULL);
2401         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2402                         hf_samr_unknown_char, NULL);
2403         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2404                         hf_samr_num_users, NULL);
2405         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2406                         hf_samr_num_groups, NULL);
2407         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2408                         hf_samr_num_aliases, NULL);
2409
2410         proto_item_set_len(item, offset-old_offset);
2411         return offset;
2412 }
2413
2414 static int
2415 samr_dissect_DOMAIN_INFO_8(tvbuff_t *tvb, int offset,
2416                              packet_info *pinfo, proto_tree *parent_tree,
2417                              char *drep)
2418 {
2419         proto_item *item=NULL;
2420         proto_tree *tree=NULL;
2421         int old_offset=offset;
2422
2423         if(parent_tree){
2424                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2425                         "DOMAIN_INFO_8:");
2426                 tree = proto_item_add_subtree(item, ett_samr_domain_info_8);
2427         }
2428
2429         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2430                                         hf_samr_max_pwd_age);
2431         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2432                                         hf_samr_min_pwd_age);
2433
2434         proto_item_set_len(item, offset-old_offset);
2435         return offset;
2436 }
2437
2438 static int
2439 samr_dissect_REPLICATION_STATUS(tvbuff_t *tvb, int offset,
2440                         packet_info *pinfo, proto_tree *parent_tree,
2441                         char *drep)
2442 {
2443         proto_item *item=NULL;
2444         proto_tree *tree=NULL;
2445         int old_offset=offset;
2446
2447         if(parent_tree){
2448                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2449                         "REPLICATION_STATUS:");
2450                 tree = proto_item_add_subtree(item, ett_samr_replication_status);
2451         }
2452
2453         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
2454                         hf_samr_unknown_hyper, NULL);
2455         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
2456                         hf_samr_unknown_hyper, NULL);
2457         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2458                         hf_samr_unknown_short, NULL);
2459
2460         proto_item_set_len(item, offset-old_offset);
2461         return offset;
2462 }
2463
2464 static int
2465 samr_dissect_DOMAIN_INFO_11(tvbuff_t *tvb, int offset,
2466                              packet_info *pinfo, proto_tree *parent_tree,
2467                              char *drep)
2468 {
2469         proto_item *item=NULL;
2470         proto_tree *tree=NULL;
2471         int old_offset=offset;
2472
2473         if(parent_tree){
2474                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2475                         "DOMAIN_INFO_11:");
2476                 tree = proto_item_add_subtree(item, ett_samr_domain_info_11);
2477         }
2478
2479         offset = samr_dissect_DOMAIN_INFO_2(
2480                         tvb, offset, pinfo, tree, drep);
2481         offset = samr_dissect_REPLICATION_STATUS(
2482                         tvb, offset, pinfo, tree, drep);
2483
2484         proto_item_set_len(item, offset-old_offset);
2485         return offset;
2486 }
2487
2488 static int
2489 samr_dissect_DOMAIN_INFO_13(tvbuff_t *tvb, int offset,
2490                              packet_info *pinfo, proto_tree *parent_tree,
2491                              char *drep)
2492 {
2493         proto_item *item=NULL;
2494         proto_tree *tree=NULL;
2495         int old_offset=offset;
2496
2497         if(parent_tree){
2498                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2499                         "DOMAIN_INFO_13:");
2500                 tree = proto_item_add_subtree(item, ett_samr_domain_info_13);
2501         }
2502
2503         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2504                                         hf_samr_unknown_time);
2505         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2506                                         hf_samr_unknown_time);
2507         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2508                                         hf_samr_unknown_time);
2509
2510         proto_item_set_len(item, offset-old_offset);
2511         return offset;
2512 }
2513
2514
2515 static int
2516 samr_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
2517                         packet_info *pinfo, proto_tree *parent_tree,
2518                         char *drep)
2519 {
2520         proto_item *item=NULL;
2521         proto_tree *tree=NULL;
2522         int old_offset=offset;
2523         guint16 level;
2524
2525         if(parent_tree){
2526                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2527                         "DOMAIN_INFO:");
2528                 tree = proto_item_add_subtree(item, ett_samr_domain_info);
2529         }
2530
2531         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2532                                      hf_samr_level, &level);
2533
2534         ALIGN_TO_4_BYTES;  /* all union arms aligned to 4 bytes, case 7 and 9 need this  */
2535         switch(level){
2536         case 1:
2537                 offset = samr_dissect_DOMAIN_INFO_1(
2538                                 tvb, offset, pinfo, tree, drep);
2539                 break;
2540         case 2:
2541                 offset = samr_dissect_DOMAIN_INFO_2(
2542                                 tvb, offset, pinfo, tree, drep);
2543                 break;
2544
2545         case 3:
2546                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2547                                 hf_samr_unknown_time);
2548                 break;
2549         case 4:
2550                 offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2551                         tree, drep, hf_samr_unknown_string, 0);
2552                 break;
2553
2554         case 5:
2555                 offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2556                         tree, drep, hf_samr_domain, 0);
2557                 break;
2558
2559         case 6:
2560                 offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2561                         tree, drep, hf_samr_controller, 0);
2562                 break;
2563
2564         case 7:
2565                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2566                         hf_samr_unknown_short, NULL);
2567                 break;
2568         case 8:
2569                 offset = samr_dissect_DOMAIN_INFO_8(
2570                                 tvb, offset, pinfo, tree, drep);
2571                 break;
2572         case 9:
2573                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2574                         hf_samr_unknown_short, NULL);
2575                 break;
2576         case 11:
2577                 offset = samr_dissect_DOMAIN_INFO_11(
2578                                 tvb, offset, pinfo, tree, drep);
2579                 break;
2580         case 12:
2581                 offset = samr_dissect_REPLICATION_STATUS(
2582                                 tvb, offset, pinfo, tree, drep);
2583                 break;
2584         case 13:
2585                 offset = samr_dissect_DOMAIN_INFO_13(
2586                                 tvb, offset, pinfo, tree, drep);
2587                 break;
2588         }
2589
2590         proto_item_set_len(item, offset-old_offset);
2591         return offset;
2592 }
2593
2594 static int
2595 samr_dissect_set_information_domain_rqst(tvbuff_t *tvb, int offset,
2596                                          packet_info *pinfo, proto_tree *tree,
2597                                          char *drep)
2598 {
2599         guint16 level;
2600
2601         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2602                                        hf_samr_hnd, NULL, FALSE, FALSE);
2603
2604         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2605                                      hf_samr_level, &level);
2606
2607         if (check_col(pinfo->cinfo, COL_INFO))
2608                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
2609
2610         offset = samr_dissect_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
2611
2612         return offset;
2613 }
2614
2615 static int
2616 samr_dissect_set_information_domain_reply(tvbuff_t *tvb, int offset,
2617                                           packet_info *pinfo,
2618                                           proto_tree *tree, char *drep)
2619 {
2620         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2621                                   hf_samr_rc, NULL);
2622
2623         return offset;
2624 }
2625
2626 static int
2627 samr_dissect_lookup_domain_rqst(tvbuff_t *tvb, int offset,
2628                                 packet_info *pinfo, proto_tree *tree,
2629                                 char *drep)
2630 {
2631         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2632                                        hf_samr_hnd, NULL, FALSE, FALSE);
2633
2634         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2635                         dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
2636                         "Domain", hf_samr_domain);
2637
2638         return offset;
2639 }
2640
2641 static int
2642 samr_dissect_lookup_domain_reply(tvbuff_t *tvb, int offset,
2643                              packet_info *pinfo, proto_tree *tree,
2644                              char *drep)
2645 {
2646         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2647                         dissect_ndr_nt_SID_ptr, NDR_POINTER_REF,
2648                         "SID:", -1);
2649
2650         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2651                                   hf_samr_rc, NULL);
2652         return offset;
2653 }
2654
2655 int
2656 dissect_ndr_nt_PSID(tvbuff_t *tvb, int offset,
2657                              packet_info *pinfo, proto_tree *parent_tree,
2658                              char *drep, int hf_sid)
2659 {
2660         proto_item *item=NULL;
2661         proto_tree *tree=NULL;
2662         int old_offset=offset;
2663
2664         if(parent_tree){
2665                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2666                         "SID pointer:");
2667                 tree = proto_item_add_subtree(item, ett_samr_sid_pointer);
2668         }
2669
2670         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2671                         dissect_ndr_nt_SID, NDR_POINTER_UNIQUE,
2672                         "SID", -1);
2673
2674         proto_item_set_len(item, offset-old_offset);
2675         return offset;
2676 }
2677 static int
2678 dissect_ndr_nt_PSID_no_hf(tvbuff_t *tvb, int offset,
2679                              packet_info *pinfo, proto_tree *parent_tree,
2680                              char *drep)
2681 {
2682         offset=dissect_ndr_nt_PSID(tvb, offset, pinfo, parent_tree, drep, -1);
2683         return offset;
2684 }
2685
2686 static int
2687 dissect_ndr_nt_PSID_ARRAY_sids (tvbuff_t *tvb, int offset,
2688                              packet_info *pinfo, proto_tree *tree,
2689                              char *drep)
2690 {
2691         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2692                         dissect_ndr_nt_PSID_no_hf);
2693
2694         return offset;
2695 }
2696
2697
2698 int
2699 dissect_ndr_nt_PSID_ARRAY(tvbuff_t *tvb, int offset,
2700                         packet_info *pinfo, proto_tree *parent_tree,
2701                         char *drep)
2702 {
2703         guint32 count;
2704         proto_item *item=NULL;
2705         proto_tree *tree=NULL;
2706         int old_offset=offset;
2707
2708         if(parent_tree){
2709                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2710                         "SID array:");
2711                 tree = proto_item_add_subtree(item, ett_samr_sid_array);
2712         }
2713
2714         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2715                         hf_samr_count, &count);
2716         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2717                         dissect_ndr_nt_PSID_ARRAY_sids, NDR_POINTER_UNIQUE,
2718                         "PSID_ARRAY", -1);
2719
2720         proto_item_set_len(item, offset-old_offset);
2721         return offset;
2722 }
2723
2724 /* called from NETLOGON but placed here since where are where the hf_fields are defined */
2725 int
2726 dissect_ndr_nt_SID_AND_ATTRIBUTES(tvbuff_t *tvb, int offset,
2727                         packet_info *pinfo, proto_tree *parent_tree,
2728                         char *drep)
2729 {
2730         proto_item *item=NULL;
2731         proto_tree *tree=NULL;
2732
2733         if(parent_tree){
2734                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2735                         "SID_AND_ATTRIBUTES:");
2736                 tree = proto_item_add_subtree(item, ett_samr_sid_and_attributes);
2737         }
2738
2739         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, drep, -1);
2740
2741         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2742                                      hf_samr_attrib, NULL);
2743
2744         return offset;
2745 }
2746
2747 int
2748 dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY(tvbuff_t *tvb, int offset,
2749                         packet_info *pinfo, proto_tree *parent_tree,
2750                         char *drep)
2751 {
2752         guint32 count;
2753         proto_item *item=NULL;
2754         proto_tree *tree=NULL;
2755         int old_offset=offset;
2756
2757         if(parent_tree){
2758                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2759                         "SID_AND_ATTRIBUTES array:");
2760                 tree = proto_item_add_subtree(item, ett_samr_sid_and_attributes_array);
2761         }
2762
2763         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2764                         hf_samr_count, &count);
2765         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2766                         dissect_ndr_nt_SID_AND_ATTRIBUTES);
2767
2768         proto_item_set_len(item, offset-old_offset);
2769         return offset;
2770 }
2771
2772
2773 static int
2774 samr_dissect_index(tvbuff_t *tvb, int offset,
2775                              packet_info *pinfo, proto_tree *tree,
2776                              char *drep)
2777 {
2778         dcerpc_info *di;
2779
2780         di=pinfo->private_data;
2781
2782         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2783                         di->hf_index, NULL);
2784
2785         return offset;
2786 }
2787
2788
2789 static int
2790 samr_dissect_INDEX_ARRAY_value (tvbuff_t *tvb, int offset,
2791                              packet_info *pinfo, proto_tree *tree,
2792                              char *drep)
2793 {
2794         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2795                         samr_dissect_index);
2796
2797         return offset;
2798 }
2799
2800 static char *
2801 plural_ending(const char *string)
2802 {
2803         size_t string_len;
2804
2805         string_len = strlen(string);
2806         if (string_len > 0 && string[string_len - 1] == 's') {
2807                 /* String ends with "s" - pluralize by adding "es" */
2808                 return "es";
2809         } else {
2810                 /* Field name doesn't end with "s" - pluralize by adding "s" */
2811                 return "s";
2812         }
2813 }
2814
2815 static int
2816 samr_dissect_INDEX_ARRAY(tvbuff_t *tvb, int offset,
2817                         packet_info *pinfo, proto_tree *parent_tree,
2818                         char *drep)
2819 {
2820         char *field_name;
2821         guint32 count;
2822         proto_item *item=NULL;
2823         proto_tree *tree=NULL;
2824         int old_offset=offset;
2825         dcerpc_info *di;
2826         char str[256];
2827
2828         di=pinfo->private_data;
2829
2830         field_name = proto_registrar_get_name(di->hf_index);
2831         snprintf(str, 255, "INDEX_ARRAY: %s%s:", field_name,
2832             plural_ending(field_name));
2833         if(parent_tree){
2834                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2835                         "%s", str);
2836                 tree = proto_item_add_subtree(item, ett_samr_index_array);
2837         }
2838
2839         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2840                         hf_samr_count, &count);
2841         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2842                         samr_dissect_INDEX_ARRAY_value, NDR_POINTER_UNIQUE,
2843                         str, di->hf_index);
2844
2845         proto_item_set_len(item, offset-old_offset);
2846         return offset;
2847 }
2848
2849 static int
2850 samr_dissect_get_alias_membership_rqst(tvbuff_t *tvb, int offset,
2851                                        packet_info *pinfo, proto_tree *tree,
2852                                        char *drep)
2853 {
2854         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2855                                        hf_samr_hnd, NULL, FALSE, FALSE);
2856
2857         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2858                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
2859                         "PSID_ARRAY:", -1);
2860
2861         return offset;
2862 }
2863
2864 static int
2865 samr_dissect_get_alias_membership_reply(tvbuff_t *tvb, int offset,
2866                              packet_info *pinfo, proto_tree *tree,
2867                              char *drep)
2868 {
2869         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2870                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
2871                         "INDEX_ARRAY:", hf_samr_alias);
2872
2873         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2874                                   hf_samr_rc, NULL);
2875
2876         return offset;
2877 }
2878
2879 static int
2880 samr_dissect_IDX_AND_NAME(tvbuff_t *tvb, int offset,
2881                              packet_info *pinfo, proto_tree *parent_tree,
2882                              char *drep)
2883 {
2884         proto_item *item=NULL;
2885         proto_tree *tree=NULL;
2886         int old_offset=offset;
2887         char str[256];
2888         dcerpc_info *di;
2889
2890         di=pinfo->private_data;
2891
2892         snprintf(str, 255, "IDX_AND_NAME: %s:",proto_registrar_get_name(di->hf_index));
2893         if(parent_tree){
2894                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2895                                 "%s",str);
2896                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name);
2897         }
2898
2899         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2900                         hf_samr_index, NULL);
2901         offset = dissect_ndr_counted_string(tvb, offset, pinfo,
2902                         tree, drep, di->hf_index, 4);
2903
2904         proto_item_set_len(item, offset-old_offset);
2905         return offset;
2906 }
2907
2908 static int
2909 samr_dissect_IDX_AND_NAME_entry (tvbuff_t *tvb, int offset,
2910                              packet_info *pinfo, proto_tree *tree,
2911                              char *drep)
2912 {
2913         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2914                         samr_dissect_IDX_AND_NAME);
2915
2916         return offset;
2917 }
2918
2919
2920 static int
2921 samr_dissect_IDX_AND_NAME_ARRAY(tvbuff_t *tvb, int offset,
2922                         packet_info *pinfo, proto_tree *parent_tree,
2923                         char *drep)
2924 {
2925         char *field_name;
2926         guint32 count;
2927         proto_item *item=NULL;
2928         proto_tree *tree=NULL;
2929         int old_offset=offset;
2930         dcerpc_info *di;
2931         char str[256];
2932
2933         di=pinfo->private_data;
2934
2935         field_name = proto_registrar_get_name(di->hf_index);
2936
2937         if(parent_tree){
2938                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2939                         "IDX_AND_NAME_ARRAY: %s%s:", field_name,
2940                         plural_ending(field_name));
2941                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name_array);
2942         }
2943
2944
2945         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2946                         hf_samr_count, &count);
2947         snprintf(str, 255, "IDX_AND_NAME pointer: %s%s:", field_name,
2948             plural_ending(field_name));
2949         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2950                         samr_dissect_IDX_AND_NAME_entry, NDR_POINTER_UNIQUE,
2951                         str, di->hf_index);
2952
2953         proto_item_set_len(item, offset-old_offset);
2954         return offset;
2955 }
2956
2957 static int
2958 samr_dissect_IDX_AND_NAME_ARRAY_ptr(tvbuff_t *tvb, int offset,
2959                         packet_info *pinfo, proto_tree *tree,
2960                         char *drep)
2961 {
2962         char *field_name;
2963         char str[256];
2964         dcerpc_info *di;
2965
2966         di=pinfo->private_data;
2967
2968         field_name = proto_registrar_get_name(di->hf_index);
2969         snprintf(str, 255, "IDX_AND_NAME_ARRAY pointer: %s%s:", field_name,
2970             plural_ending(field_name));
2971         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2972                         samr_dissect_IDX_AND_NAME_ARRAY, NDR_POINTER_UNIQUE,
2973                         str, di->hf_index);
2974         return offset;
2975 }
2976
2977 static int
2978 samr_dissect_enum_domains_rqst(tvbuff_t *tvb, int offset,
2979                                packet_info *pinfo, proto_tree *tree,
2980                                char *drep)
2981 {
2982         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2983                                        hf_samr_hnd, NULL, FALSE, FALSE);
2984
2985         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2986                         samr_dissect_pointer_long, NDR_POINTER_REF,
2987                         "Resume Handle", hf_samr_resume_hnd);
2988
2989         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2990                         hf_samr_pref_maxsize, NULL);
2991
2992         return offset;
2993 }
2994
2995 static int
2996 samr_dissect_enum_domains_reply(tvbuff_t *tvb, int offset,
2997                              packet_info *pinfo, proto_tree *tree,
2998                              char *drep)
2999 {
3000         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3001                         samr_dissect_pointer_long, NDR_POINTER_REF,
3002                         "Resume Handle:", hf_samr_resume_hnd);
3003
3004         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3005                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
3006                         "IDX_AND_NAME_ARRAY:", hf_samr_domain);
3007
3008         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3009                         samr_dissect_pointer_long, NDR_POINTER_REF,
3010                         "Entries:", hf_samr_entries);
3011
3012         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3013                                   hf_samr_rc, NULL);
3014
3015         return offset;
3016 }
3017
3018 static int
3019 samr_dissect_enum_dom_groups_rqst(tvbuff_t *tvb, int offset,
3020                                   packet_info *pinfo, proto_tree *tree,
3021                                   char *drep)
3022 {
3023         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3024                                        hf_samr_hnd, NULL, FALSE, FALSE);
3025
3026         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3027                         samr_dissect_pointer_long, NDR_POINTER_REF,
3028                         "Resume Handle:", hf_samr_resume_hnd);
3029
3030         offset = dissect_ndr_nt_acct_ctrl(
3031                 tvb, offset, pinfo, tree, drep);
3032
3033         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3034                         hf_samr_pref_maxsize, NULL);
3035
3036         return offset;
3037 }
3038
3039 static int
3040 samr_dissect_enum_dom_groups_reply(tvbuff_t *tvb, int offset,
3041                              packet_info *pinfo, proto_tree *tree,
3042                              char *drep)
3043 {
3044         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3045                         samr_dissect_pointer_long, NDR_POINTER_REF,
3046                         "Resume Handle:", hf_samr_resume_hnd);
3047
3048         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3049                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
3050                         "IDX_AND_NAME_ARRAY:", hf_samr_group_name);
3051
3052         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3053                         samr_dissect_pointer_long, NDR_POINTER_REF,
3054                         "Entries:", hf_samr_entries);
3055
3056         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3057                                   hf_samr_rc, NULL);
3058
3059         return offset;
3060 }
3061
3062 static int
3063 samr_dissect_enum_dom_aliases_rqst(tvbuff_t *tvb, int offset,
3064                                  packet_info *pinfo, proto_tree *tree,
3065                                  char *drep)
3066 {
3067         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3068                                        hf_samr_hnd, NULL, FALSE, FALSE);
3069
3070         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3071                         samr_dissect_pointer_long, NDR_POINTER_REF,
3072                         "Resume Handle:", hf_samr_resume_hnd);
3073
3074         offset = dissect_ndr_nt_acct_ctrl(
3075                 tvb, offset, pinfo, tree, drep);
3076
3077         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3078                         hf_samr_pref_maxsize, NULL);
3079
3080         return offset;
3081 }
3082
3083 static int
3084 samr_dissect_enum_dom_aliases_reply(tvbuff_t *tvb, int offset,
3085                              packet_info *pinfo, proto_tree *tree,
3086                              char *drep)
3087 {
3088         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3089                         samr_dissect_pointer_long, NDR_POINTER_REF,
3090                         "Resume Handle:", hf_samr_resume_hnd);
3091
3092         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3093                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
3094                         "IDX_AND_NAME_ARRAY:", hf_samr_alias_name);
3095
3096         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3097                         samr_dissect_pointer_long, NDR_POINTER_REF,
3098                         "Entries:", hf_samr_entries);
3099
3100         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3101                                   hf_samr_rc, NULL);
3102
3103         return offset;
3104 }
3105
3106 static int
3107 samr_dissect_get_members_in_alias_rqst(tvbuff_t *tvb, int offset,
3108                                        packet_info *pinfo, proto_tree *tree,
3109                                        char *drep)
3110 {
3111         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3112                                        hf_samr_hnd, NULL, FALSE, FALSE);
3113
3114         return offset;
3115 }
3116
3117 static int
3118 samr_dissect_get_members_in_alias_reply(tvbuff_t *tvb, int offset,
3119                         packet_info *pinfo, proto_tree *tree,
3120                         char *drep)
3121 {
3122         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3123                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
3124                         "PSID_ARRAY:", -1);
3125
3126         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3127                                   hf_samr_rc, NULL);
3128
3129         return offset;
3130 }
3131
3132 static int
3133 samr_dissect_LOGON_HOURS_entry(tvbuff_t *tvb, int offset,
3134                              packet_info *pinfo, proto_tree *tree,
3135                              char *drep)
3136 {
3137         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
3138                         hf_samr_unknown_char, NULL);
3139         return offset;
3140 }
3141
3142 static int
3143 samr_dissect_LOGON_HOURS_hours(tvbuff_t *tvb, int offset,
3144                              packet_info *pinfo, proto_tree *parent_tree,
3145                              char *drep)
3146 {
3147         proto_item *item=NULL;
3148         proto_tree *tree=NULL;
3149         int old_offset=offset;
3150
3151         if(parent_tree){
3152                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3153                         "LOGON_HOURS:");
3154                 tree = proto_item_add_subtree(item, ett_samr_logon_hours_hours);
3155         }
3156
3157         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3158                         samr_dissect_LOGON_HOURS_entry);
3159
3160         proto_item_set_len(item, offset-old_offset);
3161         return offset;
3162
3163         return offset;
3164 }
3165
3166 int
3167 dissect_ndr_nt_LOGON_HOURS(tvbuff_t *tvb, int offset,
3168                         packet_info *pinfo, proto_tree *parent_tree,
3169                         char *drep)
3170 {
3171         proto_item *item=NULL;
3172         proto_tree *tree=NULL;
3173         int old_offset=offset;
3174
3175         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
3176
3177         if(parent_tree){
3178                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3179                         "LOGON_HOURS:");
3180                 tree = proto_item_add_subtree(item, ett_samr_logon_hours);
3181         }
3182
3183         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3184                                 hf_samr_divisions, NULL);
3185         /* XXX - is this a bitmask like the "logon hours" field in the
3186            Remote API call "NetUserGetInfo()" with an information level
3187            of 11? */
3188         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3189                         samr_dissect_LOGON_HOURS_hours, NDR_POINTER_UNIQUE,
3190                         "LOGON_HOURS", -1);
3191
3192         proto_item_set_len(item, offset-old_offset);
3193         return offset;
3194 }
3195
3196
3197 static int
3198 samr_dissect_USER_INFO_1(tvbuff_t *tvb, int offset,
3199                         packet_info *pinfo, proto_tree *parent_tree,
3200                         char *drep)
3201 {
3202         proto_item *item=NULL;
3203         proto_tree *tree=NULL;
3204         int old_offset=offset;
3205
3206         if(parent_tree){
3207                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3208                         "USER_INFO_1:");
3209                 tree = proto_item_add_subtree(item, ett_samr_user_info_1);
3210         }
3211
3212         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3213                                 hf_samr_acct_name, 0);
3214         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3215                                 hf_samr_full_name, 0);
3216         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
3217         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3218                                 hf_samr_home, 0);
3219         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3220                                 hf_samr_script, 0);
3221
3222         proto_item_set_len(item, offset-old_offset);
3223         return offset;
3224 }
3225
3226 static int
3227 samr_dissect_USER_INFO_2(tvbuff_t *tvb, int offset,
3228                         packet_info *pinfo, proto_tree *parent_tree,
3229                         char *drep)
3230 {
3231         proto_item *item=NULL;
3232         proto_tree *tree=NULL;
3233         int old_offset=offset;
3234
3235         if(parent_tree){
3236                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3237                         "USER_INFO_2:");
3238                 tree = proto_item_add_subtree(item, ett_samr_user_info_2);
3239         }
3240
3241         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3242                                 hf_samr_acct_name, 0);
3243         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3244                                 hf_samr_full_name, 0);
3245         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3246                                 hf_samr_bad_pwd_count, NULL);
3247         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3248                                 hf_samr_logon_count, NULL);
3249
3250         proto_item_set_len(item, offset-old_offset);
3251         return offset;
3252 }
3253
3254 static int
3255 samr_dissect_USER_INFO_3(tvbuff_t *tvb, int offset,
3256                         packet_info *pinfo, proto_tree *parent_tree,
3257                         char *drep)
3258 {
3259         proto_item *item=NULL;
3260         proto_tree *tree=NULL;
3261         int old_offset=offset;
3262
3263         if(parent_tree){
3264                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3265                         "USER_INFO_3:");
3266                 tree = proto_item_add_subtree(item, ett_samr_user_info_3);
3267         }
3268
3269         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3270                                 hf_samr_acct_name, 0);
3271         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3272                                 hf_samr_full_name, 0);
3273         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3274                                 hf_samr_rid, NULL);
3275         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3276                                 hf_samr_group, NULL);
3277         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3278                                 hf_samr_home, 0);
3279         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3280                                 hf_samr_home_drive, 0);
3281         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3282                                 hf_samr_script, 0);
3283         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3284                                 hf_samr_acct_desc, 0);
3285         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3286                                 hf_samr_workstations, 0);
3287         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3288                                 hf_samr_logon_time);
3289         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3290                                 hf_samr_logoff_time);
3291         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3292                                 hf_samr_pwd_last_set_time);
3293         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3294                                 hf_samr_pwd_can_change_time);
3295         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3296                                 hf_samr_pwd_must_change_time);
3297         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
3298         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3299                                 hf_samr_logon_count, NULL);
3300         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3301                                 hf_samr_bad_pwd_count, NULL);
3302         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
3303
3304         proto_item_set_len(item, offset-old_offset);
3305         return offset;
3306 }
3307
3308 static int
3309 samr_dissect_USER_INFO_5(tvbuff_t *tvb, int offset,
3310                         packet_info *pinfo, proto_tree *parent_tree,
3311                         char *drep)
3312 {
3313         proto_item *item=NULL;
3314         proto_tree *tree=NULL;
3315         int old_offset=offset;
3316
3317         if(parent_tree){
3318                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3319                         "USER_INFO_5:");
3320                 tree = proto_item_add_subtree(item, ett_samr_user_info_5);
3321         }
3322
3323         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3324                                 hf_samr_acct_name, 0);
3325         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3326                                 hf_samr_full_name, 0);
3327         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3328                                 hf_samr_rid, NULL);
3329         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3330                                 hf_samr_group, NULL);
3331         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3332                                 hf_samr_country, NULL);
3333         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3334                                 hf_samr_codepage, NULL);
3335         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3336                                 hf_samr_home, 0);
3337         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3338                                 hf_samr_home_drive, 0);
3339         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3340                                 hf_samr_script, 0);
3341         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3342                                 hf_samr_acct_desc, 0);
3343         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3344                                 hf_samr_workstations, 0);
3345         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3346                                 hf_samr_logon_time);
3347         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3348                                 hf_samr_logoff_time);
3349         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
3350         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3351                                 hf_samr_bad_pwd_count, NULL);
3352         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3353                                 hf_samr_logon_count, NULL);
3354         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3355                                 hf_samr_pwd_last_set_time);
3356         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3357                                 hf_samr_acct_expiry_time);
3358         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
3359
3360         proto_item_set_len(item, offset-old_offset);
3361         return offset;
3362 }
3363
3364 static int
3365 samr_dissect_USER_INFO_6(tvbuff_t *tvb, int offset,
3366                         packet_info *pinfo, proto_tree *parent_tree,
3367                         char *drep)
3368 {
3369         proto_item *item=NULL;
3370         proto_tree *tree=NULL;
3371         int old_offset=offset;
3372
3373         if(parent_tree){
3374                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3375                         "USER_INFO_6:");
3376                 tree = proto_item_add_subtree(item, ett_samr_user_info_6);
3377         }
3378
3379         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3380                                 hf_samr_acct_name, 0);
3381         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3382                                 hf_samr_full_name, 0);
3383
3384         proto_item_set_len(item, offset-old_offset);
3385         return offset;
3386 }
3387
3388 static int
3389 samr_dissect_USER_INFO_18(tvbuff_t *tvb, int offset,
3390                         packet_info *pinfo, proto_tree *parent_tree,
3391                         char *drep)
3392 {
3393         proto_item *item=NULL;
3394         proto_tree *tree=NULL;
3395         int old_offset=offset;
3396
3397         if(parent_tree){
3398                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3399                         "USER_INFO_18:");
3400                 tree = proto_item_add_subtree(item, ett_samr_user_info_18);
3401         }
3402
3403         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
3404         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
3405         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3406                         hf_samr_unknown_char, NULL);
3407         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3408                         hf_samr_unknown_char, NULL);
3409         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3410                         hf_samr_unknown_char, NULL);
3411
3412         proto_item_set_len(item, offset-old_offset);
3413         return offset;
3414 }
3415
3416 static int
3417 samr_dissect_USER_INFO_19(tvbuff_t *tvb, int offset,
3418                         packet_info *pinfo, proto_tree *parent_tree,
3419                         char *drep)
3420 {
3421         proto_item *item=NULL;
3422         proto_tree *tree=NULL;
3423         int old_offset=offset;
3424
3425         if(parent_tree){
3426                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3427                         "USER_INFO_19:");
3428                 tree = proto_item_add_subtree(item, ett_samr_user_info_19);
3429         }
3430
3431         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
3432         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3433                                 hf_samr_logon_time);
3434         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3435                                 hf_samr_logoff_time);
3436         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3437                                 hf_samr_bad_pwd_count, NULL);
3438         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3439                                 hf_samr_logon_count, NULL);
3440
3441         proto_item_set_len(item, offset-old_offset);
3442         return offset;
3443 }
3444
3445 static int
3446 samr_dissect_BUFFER_entry(tvbuff_t *tvb, int offset,
3447                              packet_info *pinfo, proto_tree *tree,
3448                              char *drep)
3449 {
3450         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3451                         hf_samr_unknown_char, NULL);
3452         return offset;
3453 }
3454
3455
3456 static int
3457 samr_dissect_BUFFER_buffer(tvbuff_t *tvb, int offset,
3458                              packet_info *pinfo, proto_tree *parent_tree,
3459                              char *drep)
3460 {
3461         proto_item *item=NULL;
3462         proto_tree *tree=NULL;
3463         int old_offset=offset;
3464
3465         if(parent_tree){
3466                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3467                         "BUFFER:");
3468                 tree = proto_item_add_subtree(item, ett_samr_buffer_buffer);
3469         }
3470
3471         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3472                         samr_dissect_BUFFER_entry);
3473
3474         proto_item_set_len(item, offset-old_offset);
3475         return offset;
3476
3477         return offset;
3478 }
3479
3480 static int
3481 samr_dissect_BUFFER(tvbuff_t *tvb, int offset,
3482                         packet_info *pinfo, proto_tree *parent_tree,
3483                         char *drep)
3484 {
3485         proto_item *item=NULL;
3486         proto_tree *tree=NULL;
3487         int old_offset=offset;
3488
3489         if(parent_tree){
3490                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3491                         "BUFFER:");
3492                 tree = proto_item_add_subtree(item, ett_samr_buffer);
3493         }
3494         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3495                                 hf_samr_count, NULL);
3496         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3497                         samr_dissect_BUFFER_buffer, NDR_POINTER_UNIQUE,
3498                         "BUFFER", -1);
3499
3500         proto_item_set_len(item, offset-old_offset);
3501         return offset;
3502 }
3503
3504 static int
3505 samr_dissect_USER_INFO_21(tvbuff_t *tvb, int offset,
3506                         packet_info *pinfo, proto_tree *parent_tree,
3507                         char *drep)
3508 {
3509         proto_item *item=NULL;
3510         proto_tree *tree=NULL;
3511         int old_offset=offset;
3512
3513         if(parent_tree){
3514                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3515                         "USER_INFO_21:");
3516                 tree = proto_item_add_subtree(item, ett_samr_user_info_21);
3517         }
3518
3519         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3520                                 hf_samr_logon_time);
3521         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3522                                 hf_samr_logoff_time);
3523         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3524                                 hf_samr_kickoff_time);
3525         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3526                                 hf_samr_pwd_last_set_time);
3527         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3528                                 hf_samr_pwd_can_change_time);
3529         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3530                                 hf_samr_pwd_must_change_time);
3531         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3532                                 hf_samr_acct_name, 2);
3533         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3534                                 hf_samr_full_name, 0);
3535         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3536                                 hf_samr_home, 0);
3537         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3538                                 hf_samr_home_drive, 0);
3539         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3540                                 hf_samr_script, 0);
3541         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3542                                 hf_samr_profile, 0);
3543         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3544                                 hf_samr_acct_desc, 0);
3545         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3546                                 hf_samr_workstations, 0);
3547         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3548                                 hf_samr_comment, 0);
3549         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3550                                 hf_samr_parameters, 0);
3551         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3552                                 hf_samr_unknown_string, 0);
3553         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3554                                 hf_samr_unknown_string, 0);
3555         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
3556                                 hf_samr_unknown_string, 0);
3557         offset = samr_dissect_BUFFER(tvb, offset, pinfo, tree, drep);
3558         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3559                                 hf_samr_rid, NULL);
3560         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3561                                 hf_samr_group, NULL);
3562         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
3563         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3564                                 hf_samr_unknown_long, NULL);
3565         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
3566         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3567                                 hf_samr_bad_pwd_count, NULL);
3568         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3569                                 hf_samr_logon_count, NULL);
3570         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3571                                 hf_samr_country, NULL);
3572         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3573                                 hf_samr_codepage, NULL);
3574         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3575                                 hf_samr_nt_pwd_set, NULL);
3576         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3577                                 hf_samr_lm_pwd_set, NULL);
3578         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3579                                 hf_samr_pwd_expired, NULL);
3580         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3581                                 hf_samr_unknown_char, NULL);
3582
3583         proto_item_set_len(item, offset-old_offset);
3584         return offset;
3585 }
3586
3587 static int
3588 samr_dissect_USER_INFO_22(tvbuff_t *tvb, int offset,
3589                         packet_info *pinfo, proto_tree *parent_tree,
3590                         char *drep)
3591 {
3592         proto_item *item=NULL;
3593         proto_tree *tree=NULL;
3594         int old_offset=offset;
3595
3596         if(parent_tree){
3597                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3598                         "USER_INFO_22:");
3599                 tree = proto_item_add_subtree(item, ett_samr_user_info_22);
3600         }
3601
3602         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
3603         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
3604                         hf_samr_revision, NULL);
3605
3606         proto_item_set_len(item, offset-old_offset);
3607         return offset;
3608 }
3609
3610 static int
3611 samr_dissect_USER_INFO_23(tvbuff_t *tvb, int offset,
3612                         packet_info *pinfo, proto_tree *parent_tree,
3613                         char *drep)
3614 {
3615         proto_item *item=NULL;
3616         proto_tree *tree=NULL;
3617         int old_offset=offset;
3618
3619         if(parent_tree){
3620                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3621                         "USER_INFO_23:");
3622                 tree = proto_item_add_subtree(item, ett_samr_user_info_23);
3623         }
3624
3625         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
3626         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
3627
3628         proto_item_set_len(item, offset-old_offset);
3629         return offset;
3630 }
3631
3632 static int
3633 samr_dissect_USER_INFO_24(tvbuff_t *tvb, int offset,
3634                         packet_info *pinfo, proto_tree *parent_tree,
3635                         char *drep)
3636 {
3637         proto_item *item=NULL;
3638         proto_tree *tree=NULL;
3639         int old_offset=offset;
3640
3641         if(parent_tree){
3642                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3643                         "USER_INFO_24:");
3644                 tree = proto_item_add_subtree(item, ett_samr_user_info_24);
3645         }
3646
3647         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
3648         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3649                                 hf_samr_unknown_char, NULL);
3650
3651         proto_item_set_len(item, offset-old_offset);
3652         return offset;
3653 }
3654
3655 static int
3656 samr_dissect_USER_INFO (tvbuff_t *tvb, int offset,
3657                              packet_info *pinfo, proto_tree *parent_tree,
3658                              char *drep)
3659 {
3660         proto_item *item=NULL;
3661         proto_tree *tree=NULL;
3662         int old_offset=offset;
3663         guint16 level;
3664
3665         if(parent_tree){
3666                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3667                         "USER_INFO:");
3668                 tree = proto_item_add_subtree(item, ett_samr_user_info);
3669         }
3670         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3671                                      hf_samr_level, &level);
3672
3673         switch(level){
3674         case 1:
3675                 offset = samr_dissect_USER_INFO_1(
3676                                 tvb, offset, pinfo, tree, drep);
3677                 break;
3678         case 2:
3679                 offset = samr_dissect_USER_INFO_2(
3680                                 tvb, offset, pinfo, tree, drep);
3681                 break;
3682         case 3:
3683                 offset = samr_dissect_USER_INFO_3(
3684                                 tvb, offset, pinfo, tree, drep);
3685                 break;
3686         case 4:
3687                 offset = dissect_ndr_nt_LOGON_HOURS(
3688                                 tvb, offset, pinfo, tree, drep);
3689                 break;
3690         case 5:
3691                 offset = samr_dissect_USER_INFO_5(
3692                                 tvb, offset, pinfo, tree, drep);
3693                 break;
3694         case 6:
3695                 offset = samr_dissect_USER_INFO_6(
3696                                 tvb, offset, pinfo, tree, drep);
3697                 break;
3698         case 7:
3699                 offset = dissect_ndr_counted_string(
3700                         tvb, offset, pinfo, tree, drep, hf_samr_full_name, 0);
3701                 break;
3702         case 8:
3703                 offset = dissect_ndr_counted_string(
3704                         tvb, offset, pinfo, tree, drep, hf_samr_acct_desc, 0);
3705                 break;
3706         case 9:
3707                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3708                                              hf_samr_unknown_long, NULL);
3709                 break;
3710         case 10:
3711                 offset = samr_dissect_USER_INFO_6(
3712                                 tvb, offset, pinfo, tree, drep);
3713                 break;
3714         case 11:
3715                 offset = dissect_ndr_counted_string(
3716                         tvb, offset, pinfo, tree, drep, hf_samr_home, 0);
3717                 break;
3718         case 12:
3719                 offset = dissect_ndr_counted_string(
3720                         tvb, offset, pinfo, tree, drep, hf_samr_home_drive, 0);
3721                 break;
3722         case 13:
3723                 offset = dissect_ndr_counted_string(
3724                         tvb, offset, pinfo, tree, drep, hf_samr_script, 0);
3725                 break;
3726         case 14:
3727                 offset = dissect_ndr_counted_string(
3728                         tvb, offset, pinfo, tree, drep, hf_samr_workstations, 0);
3729                 break;
3730         case 16:
3731                 offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree,
3732                                              drep);
3733                 break;
3734         case 17:
3735                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3736                                         hf_samr_unknown_time);
3737                 break;
3738         case 18:
3739                 offset = samr_dissect_USER_INFO_18(
3740                                 tvb, offset, pinfo, tree, drep);
3741                 break;
3742         case 19:
3743                 offset = samr_dissect_USER_INFO_19(
3744                                 tvb, offset, pinfo, tree, drep);
3745                 break;
3746         case 20:
3747                 offset = dissect_ndr_counted_string(
3748                         tvb, offset, pinfo, tree, drep, hf_samr_profile, 0);
3749                 break;
3750         case 21:
3751                 offset = samr_dissect_USER_INFO_21(
3752                                 tvb, offset, pinfo, tree, drep);
3753                 break;
3754         case 22:
3755                 offset = samr_dissect_USER_INFO_22(
3756                                 tvb, offset, pinfo, tree, drep);
3757                 break;
3758         case 23:
3759                 offset = samr_dissect_USER_INFO_23(
3760                                 tvb, offset, pinfo, tree, drep);
3761                 break;
3762         case 24:
3763                 offset = samr_dissect_USER_INFO_24(
3764                                 tvb, offset, pinfo, tree, drep);
3765                 break;
3766         }
3767
3768         proto_item_set_len(item, offset-old_offset);
3769         return offset;
3770 }
3771
3772 static int
3773 samr_dissect_USER_INFO_ptr(tvbuff_t *tvb, int offset,
3774                         packet_info *pinfo, proto_tree *tree,
3775                         char *drep)
3776 {
3777         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3778                         samr_dissect_USER_INFO, NDR_POINTER_UNIQUE,
3779                         "USER_INFO pointer", -1);
3780         return offset;
3781 }
3782
3783 static int
3784 samr_dissect_set_information_user2_rqst(tvbuff_t *tvb, int offset,
3785                                         packet_info *pinfo, proto_tree *tree,
3786                                         char *drep)
3787 {
3788         guint16 level;
3789
3790         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3791                                        hf_samr_hnd, NULL, FALSE, FALSE);
3792
3793         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3794                         hf_samr_level, &level);
3795
3796         if (check_col(pinfo->cinfo, COL_INFO))
3797                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3798
3799         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3800                         samr_dissect_USER_INFO, NDR_POINTER_REF,
3801                         "USER_INFO:", -1);
3802
3803         return offset;
3804 }
3805
3806 static int
3807 samr_dissect_set_information_user2_reply(tvbuff_t *tvb, int offset,
3808                                          packet_info *pinfo, proto_tree *tree,
3809                                          char *drep)
3810 {
3811         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3812                                   hf_samr_rc, NULL);
3813
3814         return offset;
3815 }
3816
3817 static int
3818 samr_dissect_unknown_2f_rqst(tvbuff_t *tvb, int offset,
3819                                  packet_info *pinfo, proto_tree *tree,
3820                                  char *drep)
3821 {
3822         guint16 level;
3823
3824         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3825                                        hf_samr_hnd, NULL, FALSE, FALSE);
3826
3827         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3828                         hf_samr_level, &level);
3829
3830         if (check_col(pinfo->cinfo, COL_INFO))
3831                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3832
3833         return offset;
3834 }
3835
3836 static int
3837 samr_dissect_unknown_2f_reply(tvbuff_t *tvb, int offset,
3838                         packet_info *pinfo, proto_tree *tree,
3839                         char *drep)
3840 {
3841         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3842                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
3843                         "USER_INFO:", -1);
3844
3845         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3846                         hf_samr_rc, NULL);
3847
3848         return offset;
3849 }
3850
3851 static int
3852 samr_dissect_MEMBER_ARRAY_type(tvbuff_t *tvb, int offset,
3853                         packet_info *pinfo, proto_tree *tree,
3854                         char *drep)
3855 {
3856         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3857                                 hf_samr_type, NULL);
3858
3859         return offset;
3860 }
3861
3862
3863 static int
3864 samr_dissect_MEMBER_ARRAY_types(tvbuff_t *tvb, int offset,
3865                         packet_info *pinfo, proto_tree *parent_tree,
3866                         char *drep)
3867 {
3868         proto_item *item=NULL;
3869         proto_tree *tree=NULL;
3870         int old_offset=offset;
3871
3872         if(parent_tree){
3873                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3874                         "MEMBER_ARRAY_types:");
3875                 tree = proto_item_add_subtree(item, ett_samr_member_array_types);
3876         }
3877
3878         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3879                         samr_dissect_MEMBER_ARRAY_type);
3880
3881         proto_item_set_len(item, offset-old_offset);
3882         return offset;
3883
3884         return offset;
3885 }
3886
3887 static int
3888 samr_dissect_MEMBER_ARRAY_rid(tvbuff_t *tvb, int offset,
3889                         packet_info *pinfo, proto_tree *tree,
3890                         char *drep)
3891 {
3892         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3893                                 hf_samr_rid, NULL);
3894
3895         return offset;
3896 }
3897
3898
3899 static int
3900 samr_dissect_MEMBER_ARRAY_rids(tvbuff_t *tvb, int offset,
3901                         packet_info *pinfo, proto_tree *parent_tree,
3902                         char *drep)
3903 {
3904         proto_item *item=NULL;
3905         proto_tree *tree=NULL;
3906         int old_offset=offset;
3907
3908         if(parent_tree){
3909                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3910                         "MEMBER_ARRAY_rids:");
3911                 tree = proto_item_add_subtree(item, ett_samr_member_array_rids);
3912         }
3913
3914         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3915                         samr_dissect_MEMBER_ARRAY_rid);
3916
3917         proto_item_set_len(item, offset-old_offset);
3918         return offset;
3919
3920         return offset;
3921 }
3922
3923 static int
3924 samr_dissect_MEMBER_ARRAY(tvbuff_t *tvb, int offset,
3925                         packet_info *pinfo, proto_tree *parent_tree,
3926                         char *drep)
3927 {
3928         guint32 count;
3929         proto_item *item=NULL;
3930         proto_tree *tree=NULL;
3931         int old_offset=offset;
3932
3933         if(parent_tree){
3934                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3935                         "MEMBER_ARRAY:");
3936                 tree = proto_item_add_subtree(item, ett_samr_member_array);
3937         }
3938
3939         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3940                         hf_samr_count, &count);
3941         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3942                         samr_dissect_MEMBER_ARRAY_rids, NDR_POINTER_UNIQUE,
3943                         "RIDs", -1);
3944         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3945                         samr_dissect_MEMBER_ARRAY_types, NDR_POINTER_UNIQUE,
3946                         "Types", -1);
3947
3948         proto_item_set_len(item, offset-old_offset);
3949         return offset;
3950 }
3951
3952 static int
3953 samr_dissect_MEMBER_ARRAY_ptr(tvbuff_t *tvb, int offset,
3954                         packet_info *pinfo, proto_tree *tree,
3955                         char *drep)
3956 {
3957         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3958                         samr_dissect_MEMBER_ARRAY, NDR_POINTER_UNIQUE,
3959                         "MEMBER_ARRAY", -1);
3960         return offset;
3961 }
3962
3963 static int
3964 samr_dissect_query_groupmem_rqst(tvbuff_t *tvb, int offset,
3965                                  packet_info *pinfo, proto_tree *tree,
3966                                  char *drep)
3967 {
3968         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3969                                       hf_samr_hnd, NULL);
3970
3971         return offset;
3972 }
3973
3974 static int
3975 samr_dissect_query_groupmem_reply(tvbuff_t *tvb, int offset,
3976                         packet_info *pinfo, proto_tree *tree,
3977                         char *drep)
3978 {
3979         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3980                         samr_dissect_MEMBER_ARRAY_ptr, NDR_POINTER_REF,
3981                         "MEMBER_ARRAY:", -1);
3982
3983         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3984                                   hf_samr_rc, NULL);
3985
3986         return offset;
3987 }
3988
3989 static int
3990 samr_dissect_set_sec_object_rqst(tvbuff_t *tvb, int offset,
3991                                  packet_info *pinfo, proto_tree *tree,
3992                                  char *drep)
3993 {
3994         guint32 info_type;
3995
3996         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3997                                        hf_samr_hnd, NULL, FALSE, FALSE);
3998
3999         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4000                         hf_samr_info_type, &info_type);
4001
4002         if (check_col(pinfo->cinfo, COL_INFO))
4003                 col_append_fstr(
4004                         pinfo->cinfo, COL_INFO, ", info type %d", info_type);
4005
4006         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4007                 lsa_dissect_LSA_SECURITY_DESCRIPTOR, NDR_POINTER_REF,
4008                 "LSA_SECURITY_DESCRIPTOR pointer: ", -1);
4009
4010         return offset;
4011 }
4012
4013 static int
4014 samr_dissect_set_sec_object_reply(tvbuff_t *tvb, int offset,
4015                                   packet_info *pinfo, proto_tree *tree,
4016                                   char *drep)
4017 {
4018         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4019                                   hf_samr_rc, NULL);
4020
4021         return offset;
4022 }
4023
4024 static int
4025 samr_dissect_query_sec_object_rqst(tvbuff_t *tvb, int offset,
4026                                    packet_info *pinfo, proto_tree *tree,
4027                                    char *drep)
4028 {
4029         guint32 info_type;
4030
4031         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4032                                        hf_samr_hnd, NULL, FALSE, FALSE);
4033
4034         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4035                         hf_samr_info_type, &info_type);
4036
4037         if (check_col(pinfo->cinfo, COL_INFO))
4038                 col_append_fstr(
4039                         pinfo->cinfo, COL_INFO, ", info_type %d", info_type);
4040
4041         return offset;
4042 }
4043
4044 static int
4045 samr_dissect_query_sec_object_reply(tvbuff_t *tvb, int offset,
4046                         packet_info *pinfo, proto_tree *tree,
4047                         char *drep)
4048 {
4049         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4050                 lsa_dissect_LSA_SECURITY_DESCRIPTOR, NDR_POINTER_UNIQUE,
4051                 "LSA_SECURITY_DESCRIPTOR pointer: ", -1);
4052
4053         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4054                                   hf_samr_rc, NULL);
4055
4056         return offset;
4057 }
4058
4059 static int
4060 samr_dissect_LOOKUP_NAMES_name(tvbuff_t *tvb, int offset,
4061                         packet_info *pinfo, proto_tree *tree,
4062                         char *drep)
4063 {
4064         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4065                                 hf_samr_acct_name, 1);
4066         return offset;
4067 }
4068
4069 static int
4070 samr_dissect_LOOKUP_NAMES(tvbuff_t *tvb, int offset,
4071                         packet_info *pinfo, proto_tree *parent_tree,
4072                         char *drep)
4073 {
4074         proto_item *item=NULL;
4075         proto_tree *tree=NULL;
4076         int old_offset=offset;
4077
4078         if(parent_tree){
4079                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
4080                         "NAMES:");
4081                 tree = proto_item_add_subtree(item, ett_samr_names);
4082         }
4083
4084         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
4085                         samr_dissect_LOOKUP_NAMES_name);
4086
4087         proto_item_set_len(item, offset-old_offset);
4088         return offset;
4089 }
4090
4091
4092 static int
4093 samr_dissect_lookup_names_rqst(tvbuff_t *tvb, int offset,
4094                                packet_info *pinfo, proto_tree *tree,
4095                                char *drep)
4096 {
4097         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4098                                        hf_samr_hnd, NULL, FALSE, FALSE);
4099
4100         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4101                         hf_samr_count, NULL);
4102
4103         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4104                         samr_dissect_LOOKUP_NAMES, NDR_POINTER_REF,
4105                         "LOOKUP_NAMES:", -1);
4106
4107         return offset;
4108 }
4109
4110 static int
4111 samr_dissect_lookup_names_reply(tvbuff_t *tvb, int offset,
4112                         packet_info *pinfo, proto_tree *tree,
4113                         char *drep)
4114 {
4115         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4116                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
4117                         "Rids:", hf_samr_rid);
4118
4119         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4120                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
4121                         "Types:", hf_samr_type);
4122
4123         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4124                                   hf_samr_rc, NULL);
4125
4126         return offset;
4127 }
4128
4129 static int
4130 samr_dissect_LOOKUP_RIDS_rid(tvbuff_t *tvb, int offset,
4131                         packet_info *pinfo, proto_tree *tree,
4132                         char *drep)
4133 {
4134         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4135                                 hf_samr_rid, NULL);
4136
4137         return offset;
4138 }
4139
4140 static int
4141 samr_dissect_LOOKUP_RIDS(tvbuff_t *tvb, int offset,
4142                         packet_info *pinfo, proto_tree *parent_tree,
4143                         char *drep)
4144 {
4145         proto_item *item=NULL;
4146         proto_tree *tree=NULL;
4147         int old_offset=offset;
4148
4149         if(parent_tree){
4150                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
4151                         "RIDS:");
4152                 tree = proto_item_add_subtree(item, ett_samr_rids);
4153         }
4154
4155         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
4156                         samr_dissect_LOOKUP_RIDS_rid);
4157
4158         proto_item_set_len(item, offset-old_offset);
4159         return offset;
4160 }
4161
4162
4163 static int
4164 samr_dissect_lookup_rids_rqst(tvbuff_t *tvb, int offset,
4165                               packet_info *pinfo, proto_tree *tree,
4166                               char *drep)
4167 {
4168         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4169                                        hf_samr_hnd, NULL, FALSE, FALSE);
4170
4171         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4172                         hf_samr_count, NULL);
4173
4174         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4175                         samr_dissect_LOOKUP_RIDS, NDR_POINTER_REF,
4176                         "LOOKUP_RIDS:", -1);
4177
4178         return offset;
4179 }
4180
4181 static int
4182 samr_dissect_UNICODE_STRING_ARRAY_name(tvbuff_t *tvb, int offset,
4183                         packet_info *pinfo, proto_tree *tree,
4184                         char *drep)
4185 {
4186         offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
4187                                 hf_samr_acct_name, 0);
4188         return offset;
4189 }
4190
4191 static int
4192 samr_dissect_UNICODE_STRING_ARRAY_names(tvbuff_t *tvb, int offset,
4193                         packet_info *pinfo, proto_tree *tree,
4194                         char *drep)
4195 {
4196         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
4197                         samr_dissect_UNICODE_STRING_ARRAY_name);
4198         return offset;
4199 }
4200
4201 static int
4202 samr_dissect_UNICODE_STRING_ARRAY(tvbuff_t *tvb, int offset,
4203                         packet_info *pinfo, proto_tree *parent_tree,
4204                         char *drep)
4205 {
4206         proto_item *item=NULL;
4207         proto_tree *tree=NULL;
4208         int old_offset=offset;
4209
4210         if(parent_tree){
4211                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
4212                         "NAMES:");
4213                 tree = proto_item_add_subtree(item, ett_samr_names);
4214         }
4215
4216         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
4217                         hf_samr_count, NULL);
4218
4219         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4220                         samr_dissect_UNICODE_STRING_ARRAY_names, NDR_POINTER_UNIQUE,
4221                         "Strings", -1);
4222
4223         proto_item_set_len(item, offset-old_offset);
4224         return offset;
4225
4226         return offset;
4227 }
4228
4229
4230 static int
4231 samr_dissect_lookup_rids_reply(tvbuff_t *tvb, int offset,
4232                         packet_info *pinfo, proto_tree *tree,
4233                         char *drep)
4234 {
4235         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4236                         samr_dissect_UNICODE_STRING_ARRAY, NDR_POINTER_REF,
4237                         "RIDs:", hf_samr_rid);
4238
4239         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4240                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
4241                         "Types:", hf_samr_type);
4242
4243         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4244                                   hf_samr_rc, NULL);
4245
4246         return offset;
4247 }
4248
4249 static int
4250 samr_dissect_close_hnd_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
4251                             proto_tree *tree, char *drep)
4252 {
4253         e_ctx_hnd policy_hnd;
4254         char *name;
4255
4256         offset = dissect_nt_policy_hnd(
4257                 tvb, offset, pinfo, tree, drep, hf_samr_hnd, &policy_hnd, 
4258                 FALSE, TRUE);
4259
4260         dcerpc_smb_fetch_pol(&policy_hnd, &name, NULL, NULL);
4261
4262         if (name != NULL && check_col(pinfo->cinfo, COL_INFO))
4263                 col_append_fstr(
4264                         pinfo->cinfo, COL_INFO, ", %s", name);
4265
4266         return offset;
4267 }
4268
4269 static int
4270 samr_dissect_close_hnd_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
4271                              proto_tree *tree, char *drep)
4272 {
4273         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4274                                        hf_samr_hnd, NULL, FALSE, FALSE);
4275
4276         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4277                         hf_samr_rc, NULL);
4278
4279         return offset;
4280 }
4281
4282 static int
4283 samr_dissect_shutdown_sam_server_rqst(tvbuff_t *tvb, int offset,
4284                                       packet_info *pinfo, proto_tree *tree,
4285                                       char *drep)
4286 {
4287         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
4288                                       hf_samr_hnd, NULL);
4289
4290         return offset;
4291 }
4292
4293 static int
4294 samr_dissect_shutdown_sam_server_reply(tvbuff_t *tvb, int offset,
4295                                       packet_info *pinfo, proto_tree *tree,
4296                                       char *drep)
4297 {
4298         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4299                                   hf_samr_rc, NULL);
4300
4301         return offset;
4302 }
4303
4304 static int
4305 samr_dissect_delete_dom_group_rqst(tvbuff_t *tvb, int offset,
4306                                    packet_info *pinfo, proto_tree *tree,
4307                                    char *drep)
4308 {
4309         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
4310                                       hf_samr_hnd, NULL);
4311
4312         return offset;
4313 }
4314
4315 static int
4316 samr_dissect_delete_dom_group_reply(tvbuff_t *tvb, int offset,
4317                                     packet_info *pinfo, proto_tree *tree,
4318                                     char *drep)
4319 {
4320         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4321                                   hf_samr_rc, NULL);
4322
4323         return offset;
4324 }
4325
4326 static int
4327 samr_dissect_remove_member_from_group_rqst(tvbuff_t *tvb, int offset,
4328                                            packet_info *pinfo,
4329                                            proto_tree *tree, char *drep)
4330 {
4331         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4332                                        hf_samr_hnd, NULL, FALSE, FALSE);
4333
4334         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4335                                      hf_samr_group, NULL);
4336
4337         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4338                                      hf_samr_rid, NULL);
4339
4340         return offset;
4341 }
4342
4343 static int
4344 samr_dissect_remove_member_from_group_reply(tvbuff_t *tvb, int offset,
4345                                             packet_info *pinfo,
4346                                             proto_tree *tree, char *drep)
4347 {
4348         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4349                                   hf_samr_rc, NULL);
4350
4351         return offset;
4352 }
4353
4354 static int
4355 samr_dissect_delete_dom_alias_rqst(tvbuff_t *tvb, int offset,
4356                                    packet_info *pinfo, proto_tree *tree,
4357                                    char *drep)
4358 {
4359         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
4360                                       hf_samr_hnd, NULL);
4361
4362         return offset;
4363 }
4364
4365 static int
4366 samr_dissect_delete_dom_alias_reply(tvbuff_t *tvb, int offset,
4367                                     packet_info *pinfo, proto_tree *tree,
4368                                     char *drep)
4369 {
4370         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4371                                   hf_samr_rc, NULL);
4372
4373         return offset;
4374 }
4375
4376 static int
4377 samr_dissect_add_alias_member_rqst(tvbuff_t *tvb, int offset,
4378                                    packet_info *pinfo, proto_tree *tree,
4379                                    char *drep)
4380 {
4381         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4382                                        hf_samr_hnd, NULL, FALSE, FALSE);
4383
4384         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4385                         dissect_ndr_nt_SID, NDR_POINTER_REF,
4386                         "SID:", -1);
4387
4388         return offset;
4389 }
4390
4391 static int
4392 samr_dissect_add_alias_member_reply(tvbuff_t *tvb, int offset,
4393                                     packet_info *pinfo, proto_tree *tree,
4394                                     char *drep)
4395 {
4396         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4397                                   hf_samr_rc, NULL);
4398
4399         return offset;
4400 }
4401
4402 static int
4403 samr_dissect_remove_alias_member_rqst(tvbuff_t *tvb, int offset,
4404                                       packet_info *pinfo, proto_tree *tree,
4405                                       char *drep)
4406 {
4407         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4408                                        hf_samr_hnd, NULL, FALSE, FALSE);
4409
4410         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4411                         dissect_ndr_nt_SID, NDR_POINTER_REF,
4412                         "SID:", -1);
4413         return offset;
4414 }
4415
4416 static int
4417 samr_dissect_remove_alias_member_reply(tvbuff_t *tvb, int offset,
4418                                        packet_info *pinfo, proto_tree *tree,
4419                                        char *drep)
4420 {
4421         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4422                                   hf_samr_rc, NULL);
4423
4424         return offset;
4425 }
4426
4427 static int
4428 samr_dissect_delete_dom_user_rqst(tvbuff_t *tvb, int offset,
4429                                   packet_info *pinfo, proto_tree *tree,
4430                                   char *drep)
4431 {
4432         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4433                                        hf_samr_hnd, NULL, FALSE, FALSE);
4434
4435         return offset;
4436 }
4437
4438 static int
4439 samr_dissect_delete_dom_user_reply(tvbuff_t *tvb, int offset,
4440                                    packet_info *pinfo, proto_tree *tree,
4441                                    char *drep)
4442 {
4443         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4444                                   hf_samr_rc, NULL);
4445
4446         return offset;
4447 }
4448
4449 static int
4450 samr_dissect_test_private_fns_domain_rqst(tvbuff_t *tvb, int offset,
4451                                           packet_info *pinfo, proto_tree *tree,
4452                                           char *drep)
4453 {
4454         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4455                                        hf_samr_hnd, NULL, FALSE, FALSE);
4456
4457         return offset;
4458 }
4459
4460 static int
4461 samr_dissect_test_private_fns_domain_reply(tvbuff_t *tvb, int offset,
4462                                            packet_info *pinfo,
4463                                            proto_tree *tree, char *drep)
4464 {
4465         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4466                                   hf_samr_rc, NULL);
4467
4468         return offset;
4469 }
4470
4471 static int
4472 samr_dissect_test_private_fns_user_rqst(tvbuff_t *tvb, int offset,
4473                                         packet_info *pinfo, proto_tree *tree,
4474                                         char *drep)
4475 {
4476         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4477                                        hf_samr_hnd, NULL, FALSE, FALSE);
4478
4479         return offset;
4480 }
4481
4482 static int
4483 samr_dissect_test_private_fns_user_reply(tvbuff_t *tvb, int offset,
4484                                          packet_info *pinfo,
4485                                          proto_tree *tree, char *drep)
4486 {
4487         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4488                                   hf_samr_rc, NULL);
4489
4490         return offset;
4491 }
4492
4493 static int
4494 samr_dissect_remove_member_from_foreign_domain_rqst(tvbuff_t *tvb, int offset,
4495                                                     packet_info *pinfo,
4496                                                     proto_tree *tree,
4497                                                     char *drep)
4498 {
4499         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4500                                        hf_samr_hnd, NULL, FALSE, FALSE);
4501
4502         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4503                         dissect_ndr_nt_SID, NDR_POINTER_REF,
4504                         "SID:", -1);
4505         return offset;
4506 }
4507
4508 static int
4509 samr_dissect_remove_member_from_foreign_domain_reply(tvbuff_t *tvb, int offset,
4510                                                      packet_info *pinfo,
4511                                                      proto_tree *tree,
4512                                                      char *drep)
4513 {
4514         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4515                                   hf_samr_rc, NULL);
4516
4517         return offset;
4518 }
4519
4520 static int
4521 samr_dissect_remove_multiple_members_from_alias_rqst(tvbuff_t *tvb,
4522                                                      int offset,
4523                                                      packet_info *pinfo,
4524                                                      proto_tree *tree,
4525                                                      char *drep)
4526 {
4527         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4528                                        hf_samr_hnd, NULL, FALSE, FALSE);
4529
4530         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4531                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
4532                         "PSID_ARRAY:", -1);
4533
4534         return offset;
4535 }
4536
4537 static int
4538 samr_dissect_remove_multiple_members_from_alias_reply(tvbuff_t *tvb,
4539                                                       int offset,
4540                                                       packet_info *pinfo,
4541                                                       proto_tree *tree,
4542                                                       char *drep)
4543 {
4544         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4545                                   hf_samr_rc, NULL);
4546
4547         return offset;
4548 }
4549
4550 static int
4551 samr_dissect_open_group_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
4552                             proto_tree *tree, char *drep)
4553 {
4554         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
4555         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4556         guint32 rid;
4557
4558         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4559                                        hf_samr_hnd, NULL, FALSE, FALSE);
4560
4561         offset = dissect_nt_access_mask(
4562                 tvb, offset, pinfo, tree, drep, hf_samr_access,
4563                 &samr_group_access_mask_info);
4564
4565         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4566                         hf_samr_rid, &rid);
4567
4568         if (check_col(pinfo->cinfo, COL_INFO))
4569                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
4570
4571         dcv->private_data = GINT_TO_POINTER(rid);
4572
4573         return offset;
4574 }
4575
4576 static int
4577 samr_dissect_open_group_reply(tvbuff_t *tvb, int offset,
4578                               packet_info *pinfo, proto_tree *tree,
4579                               char *drep)
4580 {
4581         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
4582         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4583         guint32 rid = GPOINTER_TO_INT(dcv->private_data);
4584         e_ctx_hnd policy_hnd;
4585         char *pol_name;
4586
4587         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4588                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
4589
4590         if (rid)
4591                 pol_name = g_strdup_printf("OpenGroup(rid 0x%x)", rid);
4592         else
4593                 pol_name = g_strdup("OpenGroup handle");
4594
4595         dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
4596
4597         g_free(pol_name);
4598
4599         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4600                         hf_samr_rc, NULL);
4601
4602         return offset;
4603 }
4604
4605 static int
4606 samr_dissect_open_alias_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
4607                              proto_tree *tree, char *drep)
4608 {
4609         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
4610         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4611         guint32 rid;
4612
4613         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4614                                        hf_samr_hnd, NULL, FALSE, FALSE);
4615
4616         offset = dissect_nt_access_mask(
4617                 tvb, offset, pinfo, tree, drep, hf_samr_access,
4618                 &samr_alias_access_mask_info);
4619
4620         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4621                         hf_samr_rid, &rid);
4622
4623         if (check_col(pinfo->cinfo, COL_INFO))
4624                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
4625
4626         dcv->private_data = GINT_TO_POINTER(rid);
4627
4628         return offset;
4629 }
4630
4631 static int
4632 samr_dissect_open_alias_reply(tvbuff_t *tvb, int offset,
4633                               packet_info *pinfo, proto_tree *tree,
4634                               char *drep)
4635 {
4636         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
4637         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4638         e_ctx_hnd policy_hnd;
4639         char *pol_name;
4640         guint32 rid;
4641
4642         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4643                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
4644
4645         rid = GPOINTER_TO_INT(dcv->private_data);
4646
4647         if (rid)
4648                 pol_name = g_strdup_printf("OpenAlias(rid 0x%x)", rid);
4649         else
4650                 pol_name = g_strdup_printf("OpenAlias handle");
4651
4652         dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
4653
4654         g_free(pol_name);
4655
4656         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4657                         hf_samr_rc, NULL);
4658
4659         return offset;
4660 }
4661
4662 static int
4663 samr_dissect_add_multiple_members_to_alias_rqst(tvbuff_t *tvb, int offset,
4664                                                 packet_info *pinfo,
4665                                                 proto_tree *tree, char *drep)
4666 {
4667         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4668                                        hf_samr_hnd, NULL, FALSE, FALSE);
4669
4670         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4671                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
4672                         "PSID_ARRAY:", -1);
4673
4674         return offset;
4675 }
4676
4677 static int
4678 samr_dissect_add_multiple_members_to_alias_reply(tvbuff_t *tvb, int offset,
4679                                                  packet_info *pinfo,
4680                                                  proto_tree *tree, char *drep)
4681 {
4682         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4683                                   hf_samr_rc, NULL);
4684
4685         return offset;
4686 }
4687
4688 static int
4689 samr_dissect_create_group_in_domain_rqst(tvbuff_t *tvb, int offset,
4690                                          packet_info *pinfo, proto_tree *tree,
4691                                          char *drep)
4692 {
4693         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4694                                        hf_samr_hnd, NULL, FALSE, FALSE);
4695
4696         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4697                         dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
4698                         "Account Name", hf_samr_acct_name);
4699
4700         offset = dissect_nt_access_mask(
4701                 tvb, offset, pinfo, tree, drep, hf_samr_access,
4702                 &samr_group_access_mask_info);
4703
4704         return offset;
4705 }
4706
4707 static int
4708 samr_dissect_create_group_in_domain_reply(tvbuff_t *tvb, int offset,
4709                                           packet_info *pinfo, proto_tree *tree,
4710                                           char *drep)
4711 {
4712         e_ctx_hnd policy_hnd;
4713         guint32 rid;
4714         char *pol_name;
4715
4716         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4717                                        hf_samr_hnd, &policy_hnd, TRUE, FALSE);
4718
4719         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4720                                      hf_samr_rid, &rid);
4721
4722         pol_name = g_strdup_printf("CreateGroup(rid 0x%x)", rid);
4723
4724         dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
4725
4726         g_free(pol_name);
4727
4728         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4729                                   hf_samr_rc, NULL);
4730
4731         return offset;
4732 }
4733
4734 static int
4735 samr_dissect_query_information_domain_rqst(tvbuff_t *tvb, int offset,
4736                                            packet_info *pinfo,
4737                                            proto_tree *tree, char *drep)
4738 {
4739         guint16 level;
4740
4741         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4742                                        hf_samr_hnd, NULL, FALSE, FALSE);
4743
4744         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
4745                         hf_samr_level, &level);
4746
4747         if (check_col(pinfo->cinfo, COL_INFO))
4748                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
4749
4750         return offset;
4751 }
4752
4753 static int
4754 samr_dissect_query_information_domain_reply(tvbuff_t *tvb, int offset,
4755                         packet_info *pinfo, proto_tree *tree,
4756                         char *drep)
4757 {
4758         /*
4759          * Yes, in at least one capture with replies from a W2K server,
4760          * this was, indeed, a UNIQUE pointer, not a REF pointer.
4761          */
4762         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4763                         samr_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
4764                         "DOMAIN_INFO pointer", hf_samr_domain);
4765
4766         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4767                         hf_samr_rc, NULL);
4768
4769         return offset;
4770 }
4771
4772 static int
4773 samr_dissect_query_information_user_rqst(tvbuff_t *tvb, int offset,
4774                                           packet_info *pinfo,
4775                                           proto_tree *tree, char *drep)
4776 {
4777         guint16 level;
4778
4779         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4780                                        hf_samr_hnd, NULL, FALSE, FALSE);
4781
4782         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
4783                         hf_samr_level, &level);
4784
4785         if (check_col(pinfo->cinfo, COL_INFO))
4786                 col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
4787
4788         return offset;
4789 }
4790
4791 static int
4792 samr_dissect_query_information_user_reply(tvbuff_t *tvb, int offset,
4793                                            packet_info *pinfo,
4794                                            proto_tree *tree, char *drep)
4795 {
4796         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4797                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
4798                         "USER_INFO:", -1);
4799
4800         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4801                                   hf_samr_rc, NULL);
4802
4803         return offset;
4804 }
4805
4806 static dcerpc_sub_dissector dcerpc_samr_dissectors[] = {
4807         { SAMR_CONNECT, "SamrConnect",
4808                 samr_dissect_connect_anon_rqst,
4809                 samr_dissect_connect_anon_reply },
4810         { SAMR_CLOSE_HND, "Close",
4811                 samr_dissect_close_hnd_rqst,
4812                 samr_dissect_close_hnd_reply },
4813         { SAMR_SET_SEC_OBJECT, "SetSecObject",
4814                 samr_dissect_set_sec_object_rqst,
4815                 samr_dissect_set_sec_object_reply },
4816         { SAMR_QUERY_SEC_OBJECT, "QuerySecObject",
4817                 samr_dissect_query_sec_object_rqst,
4818                 samr_dissect_query_sec_object_reply },
4819         { SAMR_SHUTDOWN_SAM_SERVER, "ShutdownSamServer",
4820                 samr_dissect_shutdown_sam_server_rqst,
4821                 samr_dissect_shutdown_sam_server_reply },
4822         { SAMR_LOOKUP_DOMAIN, "LookupDomain",
4823                 samr_dissect_lookup_domain_rqst,
4824                 samr_dissect_lookup_domain_reply },
4825         { SAMR_ENUM_DOMAINS, "EnumDomains",
4826                 samr_dissect_enum_domains_rqst,
4827                 samr_dissect_enum_domains_reply },
4828         { SAMR_OPEN_DOMAIN, "OpenDomain",
4829                 samr_dissect_open_domain_rqst,
4830                 samr_dissect_open_domain_reply },
4831         { SAMR_QUERY_DOMAIN_INFO, "QueryDomainInfo",
4832                 samr_dissect_query_information_alias_rqst,
4833                 samr_dissect_query_information_domain_reply },
4834         { SAMR_SET_DOMAIN_INFO, "SetDomainInfo",
4835                 samr_dissect_set_information_domain_rqst,
4836                 samr_dissect_set_information_domain_reply },
4837         { SAMR_CREATE_DOM_GROUP, "CreateGroup",
4838                 samr_dissect_create_alias_in_domain_rqst,
4839                 samr_dissect_create_alias_in_domain_reply },
4840         { SAMR_ENUM_DOM_GROUPS, "EnumDomainGroups",
4841                 samr_dissect_enum_dom_groups_rqst,
4842                 samr_dissect_enum_dom_groups_reply },
4843         { SAMR_CREATE_USER_IN_DOMAIN, "CreateUser",
4844                 samr_dissect_create_group_in_domain_rqst,
4845                 samr_dissect_create_group_in_domain_reply },
4846         { SAMR_ENUM_DOM_USERS, "EnumDomainUsers",
4847                 samr_dissect_enum_dom_groups_rqst,
4848                 samr_dissect_enum_dom_groups_reply },
4849         { SAMR_CREATE_DOM_ALIAS, "CreateAlias",
4850                 samr_dissect_create_alias_in_domain_rqst,
4851                 samr_dissect_create_alias_in_domain_reply },
4852         { SAMR_ENUM_DOM_ALIASES, "EnumAlises",
4853                 samr_dissect_enum_dom_aliases_rqst,
4854                 samr_dissect_enum_dom_aliases_reply },
4855         { SAMR_GET_ALIAS_MEMBERSHIP, "GetAliasMem",
4856                 samr_dissect_get_alias_membership_rqst,
4857                 samr_dissect_get_alias_membership_reply },
4858         { SAMR_LOOKUP_NAMES, "LookupNames",
4859                 samr_dissect_lookup_names_rqst,
4860                 samr_dissect_lookup_names_reply },
4861         { SAMR_LOOKUP_RIDS, "LookupRIDs",
4862                 samr_dissect_lookup_rids_rqst,
4863                 samr_dissect_lookup_rids_reply },
4864         { SAMR_OPEN_GROUP, "OpenGroup",
4865                 samr_dissect_open_group_rqst,
4866                 samr_dissect_open_group_reply },
4867         { SAMR_QUERY_GROUPINFO, "QueryGroupInfo",
4868                 samr_dissect_query_information_group_rqst,
4869                 samr_dissect_query_information_group_reply },
4870         { SAMR_SET_GROUPINFO, "SetGroupInfo",
4871                 samr_dissect_set_information_group_rqst,
4872                 samr_dissect_set_information_group_reply },
4873         { SAMR_ADD_GROUPMEM, "AddGroupMem",
4874                 samr_dissect_add_member_to_group_rqst,
4875                 samr_dissect_add_member_to_group_reply },
4876         { SAMR_DELETE_DOM_GROUP, "DeleteDomainGroup",
4877                 samr_dissect_delete_dom_group_rqst,
4878                 samr_dissect_delete_dom_group_reply },
4879         { SAMR_DEL_GROUPMEM, "RemoveGroupMem",
4880                 samr_dissect_remove_member_from_group_rqst,
4881                 samr_dissect_remove_member_from_group_reply },
4882         { SAMR_QUERY_GROUPMEM, "QueryGroupMem",
4883                 samr_dissect_query_groupmem_rqst,
4884                 samr_dissect_query_groupmem_reply },
4885         { SAMR_SET_MEMBER_ATTRIBUTES_OF_GROUP, "SetMemberAttrGroup",
4886                 samr_dissect_set_member_attributes_of_group_rqst,
4887                 samr_dissect_set_member_attributes_of_group_reply },
4888         { SAMR_OPEN_ALIAS, "OpenAlias",
4889                 samr_dissect_open_alias_rqst,
4890                 samr_dissect_open_alias_reply },
4891         { SAMR_QUERY_ALIASINFO, "QueryAliasInfo",
4892                 samr_dissect_query_information_alias_rqst,
4893                 samr_dissect_query_information_alias_reply },
4894         { SAMR_SET_ALIASINFO, "SetAliasInfo",
4895                 samr_dissect_set_information_alias_rqst,
4896                 samr_dissect_set_information_alias_reply },
4897         { SAMR_DELETE_DOM_ALIAS, "DeleteAlias",
4898                 samr_dissect_delete_dom_alias_rqst,
4899                 samr_dissect_delete_dom_alias_reply },
4900         { SAMR_ADD_ALIASMEM, "AddAliasMem",
4901                 samr_dissect_add_alias_member_rqst,
4902                 samr_dissect_add_alias_member_reply },
4903         { SAMR_DEL_ALIASMEM, "RemoveAliasMem",
4904                 samr_dissect_remove_alias_member_rqst,
4905                 samr_dissect_remove_alias_member_reply },
4906         { SAMR_GET_MEMBERS_IN_ALIAS, "GetAliasMem",
4907                 samr_dissect_get_members_in_alias_rqst,
4908                 samr_dissect_get_members_in_alias_reply },
4909         { SAMR_OPEN_USER, "OpenUser",
4910                 samr_dissect_open_user_rqst,
4911                 samr_dissect_open_user_reply },
4912         { SAMR_DELETE_DOM_USER, "DeleteUser",
4913                 samr_dissect_delete_dom_user_rqst,
4914                 samr_dissect_delete_dom_user_reply },
4915         { SAMR_QUERY_USERINFO, "QueryUserInfo",
4916                 samr_dissect_query_information_user_rqst,
4917                 samr_dissect_query_information_user_reply },
4918         { SAMR_SET_USERINFO2, "SetUserInfo2",
4919                 samr_dissect_set_information_user2_rqst,
4920                 samr_dissect_set_information_user2_reply },
4921         { SAMR_CHANGE_PASSWORD_USER, "ChangePassword",
4922                 samr_dissect_change_password_user_rqst,
4923                 samr_dissect_change_password_user_reply },
4924         { SAMR_GET_GROUPS_FOR_USER, "GetGroups",
4925                 samr_dissect_get_groups_for_user_rqst,
4926                 samr_dissect_get_groups_for_user_reply },
4927         { SAMR_QUERY_DISPINFO, "QueryDispinfo",
4928                 samr_dissect_query_dispinfo_rqst,
4929                 samr_dissect_query_dispinfo_reply },
4930         { SAMR_GET_DISPLAY_ENUMERATION_INDEX, "GetDispEnumNDX",
4931                 samr_dissect_get_display_enumeration_index_rqst,
4932                 samr_dissect_get_display_enumeration_index_reply },
4933         { SAMR_TEST_PRIVATE_FUNCTIONS_DOMAIN, "TestPrivateFnsDomain",
4934                 samr_dissect_test_private_fns_domain_rqst,
4935                 samr_dissect_test_private_fns_domain_reply },
4936         { SAMR_TEST_PRIVATE_FUNCTIONS_USER, "TestPrivateFnsUser",
4937                 samr_dissect_test_private_fns_user_rqst,
4938                 samr_dissect_test_private_fns_user_reply },
4939         { SAMR_GET_USRDOM_PWINFO, "GetUserDomPwInfo",
4940                 samr_dissect_get_usrdom_pwinfo_rqst,
4941                 samr_dissect_get_usrdom_pwinfo_reply },
4942         { SAMR_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN, "RemoveMemberForeignDomain",
4943                 samr_dissect_remove_member_from_foreign_domain_rqst,
4944                 samr_dissect_remove_member_from_foreign_domain_reply },
4945         { SAMR_QUERY_INFORMATION_DOMAIN2, "QueryDomInfo2",
4946                 samr_dissect_query_information_domain_rqst,
4947                 samr_dissect_query_information_domain_reply },
4948         { SAMR_UNKNOWN_2f, "Unknown 0x2f",
4949                 samr_dissect_unknown_2f_rqst,
4950                 samr_dissect_unknown_2f_reply },
4951         { SAMR_QUERY_DISPINFO2, "QueryDispinfo2",
4952                 samr_dissect_query_dispinfo_rqst,
4953                 samr_dissect_query_dispinfo_reply },
4954         { SAMR_GET_DISPLAY_ENUMERATION_INDEX2, "GetDispEnumNDX2",
4955                 samr_dissect_get_display_enumeration_index2_rqst,
4956                 samr_dissect_get_display_enumeration_index2_reply },
4957         { SAMR_CREATE_USER2_IN_DOMAIN, "CreateUser2",
4958                 samr_dissect_create_user2_in_domain_rqst,
4959                 samr_dissect_create_user2_in_domain_reply },
4960         { SAMR_QUERY_DISPINFO3, "QueryDispinfo3",
4961                 samr_dissect_query_dispinfo_rqst,
4962                 samr_dissect_query_dispinfo_reply },
4963         { SAMR_ADD_MULTIPLE_MEMBERS_TO_ALIAS, "AddAliasMemMultiple",
4964                 samr_dissect_add_multiple_members_to_alias_rqst,
4965                 samr_dissect_add_multiple_members_to_alias_reply },
4966         { SAMR_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS, "RemoveAliasMemMultiple",
4967                 samr_dissect_remove_multiple_members_from_alias_rqst,
4968                 samr_dissect_remove_multiple_members_from_alias_reply },
4969         { SAMR_OEM_CHANGE_PASSWORD_USER2, "OEMChangePassword2",
4970                 samr_dissect_oem_change_password_user2_rqst,
4971                 samr_dissect_oem_change_password_user2_reply },
4972         { SAMR_UNICODE_CHANGE_PASSWORD_USER2, "UnicodeChangePassword2",
4973                 samr_dissect_unicode_change_password_user2_rqst,
4974                 samr_dissect_unicode_change_password_user2_reply },
4975         { SAMR_GET_DOM_PWINFO, "GetDomainPasswordInfo",
4976                 samr_dissect_get_domain_password_information_rqst,
4977                 samr_dissect_get_domain_password_information_reply },
4978         { SAMR_CONNECT2, "Connect2",
4979                 samr_dissect_connect2_rqst,
4980                 samr_dissect_connect2_reply },
4981         { SAMR_SET_USERINFO, "SetUserInfo",
4982                 samr_dissect_set_information_user2_rqst,
4983                 samr_dissect_set_information_user2_reply },
4984         { SAMR_UNKNOWN_3B, "Unknown 0x3b",
4985                 samr_dissect_unknown_3b_rqst,
4986                 samr_dissect_unknown_3b_reply },
4987         { SAMR_UNKNOWN_3C, "Unknown 0x3c",
4988                 samr_dissect_unknown_3c_rqst,
4989                 samr_dissect_unknown_3c_reply },
4990         { SAMR_CONNECT4, "Connect4",
4991                 samr_dissect_connect4_rqst,
4992                 samr_dissect_connect2_reply },
4993         {0, NULL, NULL,  NULL }
4994 };
4995
4996 static const value_string samr_opnum_vals[] = {
4997         { SAMR_CONNECT, "SamrConnect" },
4998         { SAMR_CLOSE_HND, "Close" },
4999         { SAMR_SET_SEC_OBJECT, "SetSecObject" },
5000         { SAMR_QUERY_SEC_OBJECT, "QuerySecObject" },
5001         { SAMR_SHUTDOWN_SAM_SERVER, "ShutdownSamServer" },
5002         { SAMR_LOOKUP_DOMAIN, "LookupDomain" },
5003         { SAMR_ENUM_DOMAINS, "EnumDomains" },
5004         { SAMR_OPEN_DOMAIN, "OpenDomain" },
5005         { SAMR_QUERY_DOMAIN_INFO, "QueryDomainInfo" },
5006         { SAMR_SET_DOMAIN_INFO, "SetDomainInfo" },
5007         { SAMR_CREATE_DOM_GROUP, "CreateGroup" },
5008         { SAMR_ENUM_DOM_GROUPS, "EnumDomainGroups" },
5009         { SAMR_CREATE_USER_IN_DOMAIN, "CreateUser" },
5010         { SAMR_ENUM_DOM_USERS, "EnumDomainUsers" },
5011         { SAMR_CREATE_DOM_ALIAS, "CreateAlias" },
5012         { SAMR_ENUM_DOM_ALIASES, "EnumAlises" },
5013         { SAMR_GET_ALIAS_MEMBERSHIP, "GetAliasMem" },
5014         { SAMR_LOOKUP_NAMES, "LookupNames" },
5015         { SAMR_LOOKUP_RIDS, "LookupRIDs" },
5016         { SAMR_OPEN_GROUP, "OpenGroup" },
5017         { SAMR_QUERY_GROUPINFO, "QueryGroupInfo" },
5018         { SAMR_SET_GROUPINFO, "SetGroupInfo" },
5019         { SAMR_ADD_GROUPMEM, "AddGroupMem" },
5020         { SAMR_DELETE_DOM_GROUP, "DeleteDomainGroup" },
5021         { SAMR_DEL_GROUPMEM, "RemoveGroupMem" },
5022         { SAMR_QUERY_GROUPMEM, "QueryGroupMem" },
5023         { SAMR_SET_MEMBER_ATTRIBUTES_OF_GROUP, "SetMemberAttrGroup" },
5024         { SAMR_OPEN_ALIAS, "OpenAlias" },
5025         { SAMR_QUERY_ALIASINFO, "QueryAliasInfo" },
5026         { SAMR_SET_ALIASINFO, "SetAliasInfo" },
5027         { SAMR_DELETE_DOM_ALIAS, "DeleteAlias" },
5028         { SAMR_ADD_ALIASMEM, "AddAliasMem" },
5029         { SAMR_DEL_ALIASMEM, "RemoveAliasMem" },
5030         { SAMR_GET_MEMBERS_IN_ALIAS, "GetAliasMem" },
5031         { SAMR_OPEN_USER, "OpenUser" },
5032         { SAMR_DELETE_DOM_USER, "DeleteUser" },
5033         { SAMR_QUERY_USERINFO, "QueryUserInfo" },
5034         { SAMR_SET_USERINFO2, "SetUserInfo2" },
5035         { SAMR_CHANGE_PASSWORD_USER, "ChangePassword" },
5036         { SAMR_GET_GROUPS_FOR_USER, "GetGroups" },
5037         { SAMR_QUERY_DISPINFO, "QueryDispinfo" },
5038         { SAMR_GET_DISPLAY_ENUMERATION_INDEX, "GetDispEnumNDX" },
5039         { SAMR_TEST_PRIVATE_FUNCTIONS_DOMAIN, "TestPrivateFnsDomain" },
5040         { SAMR_TEST_PRIVATE_FUNCTIONS_USER, "TestPrivateFnsUser" },
5041         { SAMR_GET_USRDOM_PWINFO, "GetUserDomPwInfo" },
5042         { SAMR_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN, "RemoveMemberForeignDomain" },
5043         { SAMR_QUERY_INFORMATION_DOMAIN2, "QueryDomInfo2" },
5044         { SAMR_UNKNOWN_2f, "Unknown 0x2f" },
5045         { SAMR_QUERY_DISPINFO2, "QueryDispinfo2" },
5046         { SAMR_GET_DISPLAY_ENUMERATION_INDEX2, "GetDispEnumNDX2" },
5047         { SAMR_CREATE_USER2_IN_DOMAIN, "CreateUser2" },
5048         { SAMR_QUERY_DISPINFO3, "QueryDispinfo3" },
5049         { SAMR_ADD_MULTIPLE_MEMBERS_TO_ALIAS, "AddAliasMemMultiple" },
5050         { SAMR_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS, "RemoveAliasMemMultiple" },
5051         { SAMR_OEM_CHANGE_PASSWORD_USER2, "OEMChangePassword2" },
5052         { SAMR_UNICODE_CHANGE_PASSWORD_USER2, "UnicodeChangePassword2" },
5053         { SAMR_GET_DOM_PWINFO, "GetDomainPasswordInfo" },
5054         { SAMR_CONNECT2, "Connect2" },
5055         { SAMR_SET_USERINFO, "SetUserInfo" },
5056         { SAMR_UNKNOWN_3B, "Unknown 0x3b" },
5057         { SAMR_UNKNOWN_3C, "Unknown 0x3c" },
5058         { SAMR_CONNECT3, "Connect3" },
5059         { SAMR_CONNECT4, "Connect4" },
5060         { 0, NULL }
5061 };
5062
5063 void
5064 proto_register_dcerpc_samr(void)
5065 {
5066         static hf_register_info hf[] = {
5067
5068                 { &hf_samr_opnum,
5069                   { "Operation", "samr.opnum", FT_UINT16, BASE_DEC,
5070                     VALS(samr_opnum_vals), 0x0, "Operation", HFILL }},
5071
5072                 { &hf_samr_hnd,
5073                   { "Context Handle", "samr.hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
5074                 { &hf_samr_group,
5075                   { "Group", "samr.group", FT_UINT32, BASE_DEC, NULL, 0x0, "Group", HFILL }},
5076                 { &hf_samr_rid,
5077                   { "Rid", "samr.rid", FT_UINT32, BASE_DEC, NULL, 0x0, "RID", HFILL }},
5078                 { &hf_samr_type,
5079                   { "Type", "samr.type", FT_UINT32, BASE_HEX, NULL, 0x0, "Type", HFILL }},
5080                 { &hf_samr_alias,
5081                   { "Alias", "samr.alias", FT_UINT32, BASE_HEX, NULL, 0x0, "Alias", HFILL }},
5082                 { &hf_samr_rid_attrib,
5083                   { "Rid Attrib", "samr.rid.attrib", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
5084                 { &hf_samr_attrib,
5085                   { "Attributes", "samr.attr", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
5086                 { &hf_samr_rc,
5087                   { "Return code", "samr.rc", FT_UINT32, BASE_HEX, VALS (NT_errors), 0x0, "", HFILL }},
5088
5089         { &hf_samr_level,
5090                 { "Level", "samr.level", FT_UINT16, BASE_DEC,
5091                 NULL, 0x0, "Level requested/returned for Information", HFILL }},
5092         { &hf_samr_start_idx,
5093                 { "Start Idx", "samr.start_idx", FT_UINT32, BASE_DEC,
5094                 NULL, 0x0, "Start Index for returned Information", HFILL }},
5095
5096         { &hf_samr_entries,
5097                 { "Entries", "samr.entries", FT_UINT32, BASE_DEC,
5098                 NULL, 0x0, "Number of entries to return", HFILL }},
5099
5100         { &hf_samr_max_entries,
5101                 { "Max Entries", "samr.max_entries", FT_UINT32, BASE_DEC,
5102                 NULL, 0x0, "Maximum number of entries", HFILL }},
5103
5104         { &hf_samr_pref_maxsize,
5105                 { "Pref MaxSize", "samr.pref_maxsize", FT_UINT32, BASE_DEC,
5106                 NULL, 0x0, "Maximum Size of data to return", HFILL }},
5107
5108         { &hf_samr_total_size,
5109                 { "Total Size", "samr.total_size", FT_UINT32, BASE_DEC,
5110                 NULL, 0x0, "Total size of data", HFILL }},
5111
5112         { &hf_samr_bad_pwd_count,
5113                 { "Bad Pwd Count", "samr.bad_pwd_count", FT_UINT16, BASE_DEC,
5114                 NULL, 0x0, "Number of bad pwd entries for this user", HFILL }},
5115
5116         { &hf_samr_logon_count,
5117                 { "Logon Count", "samr.logon_count", FT_UINT16, BASE_DEC,
5118                 NULL, 0x0, "Number of logons for this user", HFILL }},
5119
5120         { &hf_samr_ret_size,
5121                 { "Returned Size", "samr.ret_size", FT_UINT32, BASE_DEC,
5122                 NULL, 0x0, "Number of returned objects in this PDU", HFILL }},
5123
5124         { &hf_samr_index,
5125                 { "Index", "samr.index", FT_UINT32, BASE_DEC,
5126                 NULL, 0x0, "Index", HFILL }},
5127
5128         { &hf_samr_count,
5129           { "Count", "samr.count", FT_UINT32, BASE_DEC, NULL, 0x0, "Number of elements in following array", HFILL }},
5130
5131         { &hf_samr_alias_name,
5132                 { "Alias Name", "samr.alias_name", FT_STRING, BASE_NONE,
5133                 NULL, 0, "Name of Alias", HFILL }},
5134
5135         { &hf_samr_group_name,
5136                 { "Group Name", "samr.group_name", FT_STRING, BASE_NONE,
5137                 NULL, 0, "Name of Group", HFILL }},
5138
5139         { &hf_samr_acct_name,
5140                 { "Account Name", "samr.acct_name", FT_STRING, BASE_NONE,
5141                 NULL, 0, "Name of Account", HFILL }},
5142
5143         { &hf_samr_server,
5144                 { "Server", "samr.server", FT_STRING, BASE_NONE,
5145                 NULL, 0, "Name of Server", HFILL }},
5146
5147         { &hf_samr_domain,
5148                 { "Domain", "samr.domain", FT_STRING, BASE_NONE,
5149                 NULL, 0, "Name of Domain", HFILL }},
5150
5151         { &hf_samr_controller,
5152                 { "DC", "samr.dc", FT_STRING, BASE_NONE,
5153                 NULL, 0, "Name of Domain Controller", HFILL }},
5154
5155         { &hf_samr_full_name,
5156                 { "Full Name", "samr.full_name", FT_STRING, BASE_NONE,
5157                 NULL, 0, "Full Name of Account", HFILL }},
5158
5159         { &hf_samr_home,
5160                 { "Home", "samr.home", FT_STRING, BASE_NONE,
5161                 NULL, 0, "Home directory for this user", HFILL }},
5162
5163         { &hf_samr_home_drive,
5164                 { "Home Drive", "samr.home_drive", FT_STRING, BASE_NONE,
5165                 NULL, 0, "Home drive for this user", HFILL }},
5166
5167         { &hf_samr_script,
5168                 { "Script", "samr.script", FT_STRING, BASE_NONE,
5169                 NULL, 0, "Login script for this user", HFILL }},
5170
5171         { &hf_samr_workstations,
5172                 { "Workstations", "samr.workstations", FT_STRING, BASE_NONE,
5173                 NULL, 0, "", HFILL }},
5174
5175         { &hf_samr_profile,
5176                 { "Profile", "samr.profile", FT_STRING, BASE_NONE,
5177                 NULL, 0, "Profile for this user", HFILL }},
5178
5179         { &hf_samr_acct_desc,
5180                 { "Account Desc", "samr.acct_desc", FT_STRING, BASE_NONE,
5181                 NULL, 0, "Account Description", HFILL }},
5182
5183         { &hf_samr_comment,
5184                 { "Comment", "samr.comment", FT_STRING, BASE_NONE,
5185                 NULL, 0, "Comment", HFILL }},
5186
5187         { &hf_samr_parameters,
5188                 { "Parameters", "samr.parameters", FT_STRING, BASE_NONE,
5189                 NULL, 0, "Parameters", HFILL }},
5190
5191         { &hf_samr_unknown_string,
5192                 { "Unknown string", "samr.unknown_string", FT_STRING, BASE_NONE,
5193                 NULL, 0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }},
5194
5195         { &hf_samr_unknown_hyper,
5196                 { "Unknown hyper", "samr.unknown.hyper", FT_UINT64, BASE_HEX,
5197                 NULL, 0x0, "Unknown hyper. If you know what this is, contact ethereal developers.", HFILL }},
5198         { &hf_samr_unknown_long,
5199                 { "Unknown long", "samr.unknown.long", FT_UINT32, BASE_HEX,
5200                 NULL, 0x0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
5201
5202         { &hf_samr_unknown_short,
5203                 { "Unknown short", "samr.unknown.short", FT_UINT16, BASE_HEX,
5204                 NULL, 0x0, "Unknown short. If you know what this is, contact ethereal developers.", HFILL }},
5205
5206         { &hf_samr_unknown_char,
5207                 { "Unknown char", "samr.unknown.char", FT_UINT8, BASE_HEX,
5208                 NULL, 0x0, "Unknown char. If you know what this is, contact ethereal developers.", HFILL }},
5209
5210         { &hf_samr_revision,
5211                 { "Revision", "samr.revision", FT_UINT64, BASE_HEX,
5212                 NULL, 0x0, "Revision number for this structure", HFILL }},
5213
5214         { &hf_samr_nt_pwd_set,
5215                 { "NT Pwd Set", "samr.nt_pwd_set", FT_UINT8, BASE_HEX,
5216                 NULL, 0x0, "Flag indicating whether the NT password has been set", HFILL }},
5217
5218         { &hf_samr_lm_pwd_set,
5219                 { "LM Pwd Set", "samr.lm_pwd_set", FT_UINT8, BASE_HEX,
5220                 NULL, 0x0, "Flag indicating whether the LanManager password has been set", HFILL }},
5221
5222         { &hf_samr_pwd_expired,
5223                 { "Expired flag", "samr.pwd_Expired", FT_UINT8, BASE_HEX,
5224                 NULL, 0x0, "Flag indicating if the password for this account has expired or not", HFILL }},
5225
5226         { &hf_samr_access,
5227                 { "Access Mask", "samr.access", FT_UINT32, BASE_HEX,
5228                 NULL, 0x0, "Access", HFILL }},
5229
5230         { &hf_samr_access_granted,
5231                 { "Access Granted", "samr.access_granted", FT_UINT32, BASE_HEX,
5232                 NULL, 0x0, "Access Granted", HFILL }},
5233
5234         { &hf_samr_crypt_password, {
5235                 "Password", "samr.crypt_password", FT_BYTES, BASE_HEX,
5236                 NULL, 0, "Encrypted Password", HFILL }},
5237
5238         { &hf_samr_crypt_hash, {
5239                 "Hash", "samr.crypt_hash", FT_BYTES, BASE_HEX,
5240                 NULL, 0, "Encrypted Hash", HFILL }},
5241
5242         { &hf_samr_lm_verifier, {
5243                 "Verifier", "samr.lm_password_verifier", FT_BYTES, BASE_HEX,
5244                 NULL, 0, "Lan Manager Password Verifier", HFILL }},
5245
5246         { &hf_samr_nt_verifier, {
5247                 "Verifier", "samr.nt_password_verifier", FT_BYTES, BASE_HEX,
5248                 NULL, 0, "NT Password Verifier", HFILL }},
5249
5250         { &hf_samr_lm_passchange_block, {
5251                 "Encrypted Block", "samr.lm_passchange_block", FT_BYTES, 
5252                 BASE_HEX, NULL, 0, "Lan Manager Password Change Block",
5253                 HFILL }},
5254
5255         { &hf_samr_nt_passchange_block, {
5256                 "Encrypted Block", "samr.nt_passchange_block", FT_BYTES, 
5257                 BASE_HEX, NULL, 0, "NT Password Change Block", HFILL }},
5258
5259         { &hf_samr_nt_passchange_block_decrypted, {
5260                 "Decrypted Block", "samr.nt_passchange_block_decrypted",
5261                 FT_BYTES, BASE_HEX, NULL, 0, 
5262                 "NT Password Change Decrypted Block", HFILL }},
5263
5264         { &hf_samr_nt_passchange_block_newpass, {
5265                 "New NT Password", "samr.nt_passchange_block_new_ntpassword", 
5266                 FT_STRING, BASE_NONE, NULL, 0, "New NT Password", HFILL }},
5267
5268         { &hf_samr_nt_passchange_block_newpass_len, {
5269                 "New NT Unicode Password length", 
5270                 "samr.nt_passchange_block_new_ntpassword_len", FT_UINT32, 
5271                 BASE_DEC, NULL, 0, "New NT Password Unicode Length", HFILL }},
5272
5273         { &hf_samr_nt_passchange_block_pseudorandom, {
5274                 "Pseudorandom data", "samr.nt_passchange_block_pseudorandom",
5275                 FT_BYTES, BASE_HEX, NULL, 0, "Pseudorandom data", HFILL }},
5276
5277         { &hf_samr_lm_change, {
5278                 "LM Change", "samr.lm_change", FT_UINT8, BASE_HEX,
5279                 NULL, 0, "LM Change value", HFILL }},
5280
5281         { &hf_samr_max_pwd_age,
5282                 { "Max Pwd Age", "samr.max_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
5283                 NULL, 0, "Maximum Password Age before it expires", HFILL }},
5284
5285         { &hf_samr_min_pwd_age,
5286                 { "Min Pwd Age", "samr.min_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
5287                 NULL, 0, "Minimum Password Age before it can be changed", HFILL }},
5288         { &hf_samr_unknown_time,
5289                 { "Unknown time", "samr.unknown_time", FT_ABSOLUTE_TIME, BASE_NONE,
5290                 NULL, 0, "Unknown NT TIME, contact ethereal developers if you know what this is", HFILL }},
5291         { &hf_samr_logon_time,
5292                 { "Logon Time", "samr.logon_time", FT_ABSOLUTE_TIME, BASE_NONE,
5293                 NULL, 0, "Time for last time this user logged on", HFILL }},
5294         { &hf_samr_kickoff_time,
5295                 { "Kickoff Time", "samr.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
5296                 NULL, 0, "Time when this user will be kicked off", HFILL }},
5297         { &hf_samr_logoff_time,
5298                 { "Logoff Time", "samr.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
5299                 NULL, 0, "Time for last time this user logged off", HFILL }},
5300         { &hf_samr_pwd_last_set_time,
5301                 { "PWD Last Set", "samr.pwd_last_set_time", FT_ABSOLUTE_TIME, BASE_NONE,
5302                 NULL, 0, "Last time this users password was changed", HFILL }},
5303         { &hf_samr_pwd_can_change_time,
5304                 { "PWD Can Change", "samr.pwd_can_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
5305                 NULL, 0, "When this users password may be changed", HFILL }},
5306         { &hf_samr_pwd_must_change_time,
5307                 { "PWD Must Change", "samr.pwd_must_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
5308                 NULL, 0, "When this users password must be changed", HFILL }},
5309         { &hf_samr_acct_expiry_time,
5310                 { "Acct Expiry", "samr.acct_expiry_time", FT_ABSOLUTE_TIME, BASE_NONE,
5311                 NULL, 0, "When this user account expires", HFILL }},
5312
5313         { &hf_samr_min_pwd_len, {
5314                 "Min Pwd Len", "samr.min_pwd_len", FT_UINT16, BASE_DEC,
5315                 NULL, 0, "Minimum Password Length", HFILL }},
5316         { &hf_samr_pwd_history_len, {
5317                 "Pwd History Len", "samr.pwd_history_len", FT_UINT16, BASE_DEC,
5318                 NULL, 0, "Password History Length", HFILL }},
5319         { &hf_samr_num_users, {
5320                 "Num Users", "samr.num_users", FT_UINT32, BASE_DEC,
5321                 NULL, 0, "Number of users in this domain", HFILL }},
5322         { &hf_samr_num_groups, {
5323                 "Num Groups", "samr.num_groups", FT_UINT32, BASE_DEC,
5324                 NULL, 0, "Number of groups in this domain", HFILL }},
5325         { &hf_samr_num_aliases, {
5326                 "Num Aliases", "samr.num_aliases", FT_UINT32, BASE_DEC,
5327                 NULL, 0, "Number of aliases in this domain", HFILL }},
5328         { &hf_samr_info_type, {
5329                 "Info Type", "samr.info_type", FT_UINT32, BASE_DEC,
5330                 NULL, 0, "Information Type", HFILL }},
5331         { &hf_samr_resume_hnd, {
5332                 "Resume Hnd", "samr.resume_hnd", FT_UINT32, BASE_DEC,
5333                 NULL, 0, "Resume handle", HFILL }},
5334         { &hf_samr_country, {
5335                 "Country", "samr.country", FT_UINT16, BASE_DEC,
5336                 VALS(ms_country_codes), 0, "Country setting for this user", HFILL }},
5337         { &hf_samr_codepage, {
5338                 "Codepage", "samr.codepage", FT_UINT16, BASE_DEC,
5339                 NULL, 0, "Codepage setting for this user", HFILL }},
5340         { &hf_samr_divisions, {
5341                 "Divisions", "samr.divisions", FT_UINT16, BASE_DEC,
5342                 NULL, 0, "Number of divisions for LOGON_HOURS", HFILL }},
5343
5344         { &hf_nt_acct_ctrl,
5345                 { "Acct Ctrl", "nt.acct_ctrl", FT_UINT32, BASE_HEX,
5346                 NULL, 0x0, "Acct CTRL", HFILL }},
5347
5348         { &hf_nt_acb_disabled, {
5349                 "", "nt.acb.disabled", FT_BOOLEAN, 32,
5350                 TFS(&tfs_nt_acb_disabled), 0x0001, "If this account is enabled or disabled", HFILL }},
5351
5352         { &hf_nt_acb_homedirreq, {
5353                 "", "nt.acb.homedirreq", FT_BOOLEAN, 32,
5354                 TFS(&tfs_nt_acb_homedirreq), 0x0002, "Is hom,edirs required for this account?", HFILL }},
5355
5356         { &hf_nt_acb_pwnotreq, {
5357                 "", "nt.acb.pwnotreq", FT_BOOLEAN, 32,
5358                 TFS(&tfs_nt_acb_pwnotreq), 0x0004, "If a password is required for this account?", HFILL }},
5359
5360         { &hf_nt_acb_tempdup, {
5361                 "", "nt.acb.tempdup", FT_BOOLEAN, 32,
5362                 TFS(&tfs_nt_acb_tempdup), 0x0008, "If this is a temporary duplicate account", HFILL }},
5363
5364         { &hf_nt_acb_normal, {
5365                 "", "nt.acb.normal", FT_BOOLEAN, 32,
5366                 TFS(&tfs_nt_acb_normal), 0x0010, "If this is a normal user account", HFILL }},
5367
5368         { &hf_nt_acb_mns, {
5369                 "", "nt.acb.mns", FT_BOOLEAN, 32,
5370                 TFS(&tfs_nt_acb_mns), 0x0020, "MNS logon user account", HFILL }},
5371
5372         { &hf_nt_acb_domtrust, {
5373                 "", "nt.acb.domtrust", FT_BOOLEAN, 32,
5374                 TFS(&tfs_nt_acb_domtrust), 0x0040, "Interdomain trust account", HFILL }},
5375
5376         { &hf_nt_acb_wstrust, {
5377                 "", "nt.acb.wstrust", FT_BOOLEAN, 32,
5378                 TFS(&tfs_nt_acb_wstrust), 0x0080, "Workstation trust account", HFILL }},
5379
5380         { &hf_nt_acb_svrtrust, {
5381                 "", "nt.acb.svrtrust", FT_BOOLEAN, 32,
5382                 TFS(&tfs_nt_acb_svrtrust), 0x0100, "Server trust account", HFILL }},
5383
5384         { &hf_nt_acb_pwnoexp, {
5385                 "", "nt.acb.pwnoexp", FT_BOOLEAN, 32,
5386                 TFS(&tfs_nt_acb_pwnoexp), 0x0200, "If this account expires or not", HFILL }},
5387
5388         { &hf_nt_acb_autolock, {
5389                 "", "nt.acb.autolock", FT_BOOLEAN, 32,
5390                 TFS(&tfs_nt_acb_autolock), 0x0400, "If this account has been autolocked", HFILL }},
5391
5392         /* Object specific access rights */
5393
5394         { &hf_access_domain_lookup_info1,
5395           { "Lookup info1", "samr_access_mask.domain_lookup_info1",
5396             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5397             DOMAIN_ACCESS_LOOKUP_INFO_1, "Lookup info1", HFILL }},
5398
5399         { &hf_access_domain_set_info1,
5400           { "Set info1", "samr_access_mask.domain_set_info1",
5401             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5402             DOMAIN_ACCESS_SET_INFO_1, "Set info1", HFILL }},
5403
5404         { &hf_access_domain_lookup_info2,
5405           { "Lookup info2", "samr_access_mask.domain_lookup_info2",
5406             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5407             DOMAIN_ACCESS_LOOKUP_INFO_2, "Lookup info2", HFILL }},
5408
5409         { &hf_access_domain_set_info2,
5410           { "Set info2", "samr_access_mask.domain_set_info2",
5411             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5412             DOMAIN_ACCESS_SET_INFO_2, "Set info2", HFILL }},
5413
5414         { &hf_access_domain_create_user,
5415           { "Create user", "samr_access_mask.domain_create_user",
5416             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5417             DOMAIN_ACCESS_CREATE_USER, "Create user", HFILL }},
5418
5419         { &hf_access_domain_create_group,
5420           { "Create group", "samr_access_mask.domain_create_group",
5421             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5422             DOMAIN_ACCESS_CREATE_GROUP, "Create group", HFILL }},
5423
5424         { &hf_access_domain_create_alias,
5425           { "Create alias", "samr_access_mask.domain_create_alias",
5426             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5427             DOMAIN_ACCESS_CREATE_ALIAS, "Create alias", HFILL }},
5428
5429         { &hf_access_domain_lookup_alias_by_mem,
5430           { "Lookup alias", "samr_access_mask.domain_lookup_alias_by_mem",
5431             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5432             DOMAIN_ACCESS_LOOKUP_ALIAS, "Lookup alias", HFILL }},
5433
5434         { &hf_access_domain_enum_accounts,
5435           { "Enum accounts", "samr_access_mask.domain_enum_accounts",
5436             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5437             DOMAIN_ACCESS_ENUM_ACCOUNTS, "Enum accounts", HFILL }},
5438
5439         { &hf_access_domain_open_account,
5440           { "Open account", "samr_access_mask.domain_open_account",
5441             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5442             DOMAIN_ACCESS_OPEN_ACCOUNT, "Open account", HFILL }},
5443
5444         { &hf_access_domain_set_info3,
5445           { "Set info3", "samr_access_mask.domain_set_info3",
5446             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5447             DOMAIN_ACCESS_SET_INFO_3, "Set info3", HFILL }},
5448
5449         { &hf_access_user_get_name_etc,
5450           { "Get name, etc", "samr_access_mask.user_get_name_etc",
5451             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5452             USER_ACCESS_GET_NAME_ETC, "Get name, etc", HFILL }},
5453
5454         { &hf_access_user_get_locale,
5455           { "Get locale", "samr_access_mask.user_get_locale",
5456             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5457             USER_ACCESS_GET_LOCALE, "Get locale", HFILL }},
5458
5459         { &hf_access_user_get_loc_com,
5460           { "Set loc com", "samr_access_mask.user_set_loc_com",
5461             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5462             USER_ACCESS_SET_LOC_COM, "Set loc com", HFILL }},
5463
5464         { &hf_access_user_get_logoninfo,
5465           { "Get logon info", "samr_access_mask.user_get_logoninfo",
5466             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5467             USER_ACCESS_GET_LOGONINFO, "Get logon info", HFILL }},
5468
5469         { &hf_access_user_unknown_10,
5470           { "Unknown 0x10", "samr_access_mask.user_unknown_10",
5471             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5472             USER_ACCESS_UNKNOWN_10, "Unknown 0x10", HFILL }},
5473
5474         { &hf_access_user_set_attributes,
5475           { "Set attributes", "samr_access_mask.user_set_attributes",
5476             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5477             USER_ACCESS_SET_ATTRIBUTES, "Set attributes", HFILL }},
5478
5479         { &hf_access_user_change_password,
5480           { "Change password", "samr_access_mask.user_change_password",
5481             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5482             USER_ACCESS_CHANGE_PASSWORD, "Change password", HFILL }},
5483
5484         { &hf_access_user_set_password,
5485           { "Set password", "samr_access_mask.user_set_password",
5486             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5487             USER_ACCESS_SET_PASSWORD, "Set password", HFILL }},
5488
5489         { &hf_access_user_get_groups,
5490           { "Get groups", "samr_access_mask.user_get_groups",
5491             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5492             USER_ACCESS_GET_GROUPS, "Get groups", HFILL }},
5493
5494         { &hf_access_user_unknown_200,
5495           { "Unknown 0x200", "samr_access_mask.user_unknown_200",
5496             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5497             USER_ACCESS_UNKNOWN_200, "Unknown 0x200", HFILL }},
5498
5499         { &hf_access_user_unknown_400,
5500           { "Unknown 0x400", "samr_access_mask.user_unknown_400",
5501             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5502             USER_ACCESS_UNKNOWN_400, "Unknown 0x400", HFILL }},
5503
5504         { &hf_access_group_lookup_info,
5505           { "Lookup info", "samr_access_mask.group_lookup_info",
5506             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5507             GROUP_ACCESS_LOOKUP_INFO, "Lookup info", HFILL }},
5508
5509         { &hf_access_group_set_info,
5510           { "Get info", "samr_access_mask.group_set_info",
5511             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5512             GROUP_ACCESS_SET_INFO, "Get info", HFILL }},
5513
5514         { &hf_access_group_add_member,
5515           { "Add member", "samr_access_mask.group_add_member",
5516             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5517             GROUP_ACCESS_ADD_MEMBER, "Add member", HFILL }},
5518
5519         { &hf_access_group_remove_member,
5520           { "Remove member", "samr_access_mask.group_remove_member",
5521             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5522             GROUP_ACCESS_REMOVE_MEMBER, "Remove member", HFILL }},
5523
5524         { &hf_access_group_get_members,
5525           { "Get members", "samr_access_mask.group_get_members",
5526             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5527             GROUP_ACCESS_GET_MEMBERS, "Get members", HFILL }},
5528
5529         { &hf_access_alias_add_member,
5530           { "Add member", "samr_access_mask.alias_add_member",
5531             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5532             ALIAS_ACCESS_ADD_MEMBER, "Add member", HFILL }},
5533
5534         { &hf_access_alias_remove_member,
5535           { "Remove member", "samr_access_mask.alias_remove_member",
5536             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5537             ALIAS_ACCESS_REMOVE_MEMBER, "Remove member", HFILL }},
5538
5539         { &hf_access_alias_get_members,
5540           { "Get members", "samr_access_mask.alias_get_members",
5541             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5542             ALIAS_ACCESS_GET_MEMBERS, "Get members", HFILL }},
5543
5544         { &hf_access_alias_lookup_info,
5545           { "Lookup info", "samr_access_mask.alias_lookup_info",
5546             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5547             ALIAS_ACCESS_LOOKUP_INFO, "Lookup info", HFILL }},
5548
5549         { &hf_access_alias_set_info,
5550           { "Set info", "samr_access_mask.alias_set_info",
5551             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5552             ALIAS_ACCESS_SET_INFO, "Set info", HFILL }},
5553
5554         { &hf_access_connect_unknown_01,
5555           { "Unknown 0x01", "samr_access_mask.connect_unknown_01",
5556             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5557             SAMR_ACCESS_UNKNOWN_1, "Unknown 0x01", HFILL }},
5558
5559         { &hf_access_connect_shutdown_server,
5560           { "Shutdown server", "samr_access_mask.connect_shutdown_server",
5561             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5562             SAMR_ACCESS_SHUTDOWN_SERVER, "Shutdown server", HFILL }},
5563
5564         { &hf_access_connect_unknown_04,
5565           { "Unknown 0x04", "samr_access_mask.connect_unknown_04",
5566             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5567             SAMR_ACCESS_UNKNOWN_4, "Unknown 0x04", HFILL }},
5568
5569         { &hf_access_connect_unknown_08,
5570           { "Unknown 0x08", "samr_access_mask.connect_unknown_08",
5571             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5572             SAMR_ACCESS_UNKNOWN_8, "Unknown 0x08", HFILL }},
5573
5574         { &hf_access_connect_enum_domains,
5575           { "Enum domains", "samr_access_mask.connect_enum_domains",
5576             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5577             SAMR_ACCESS_ENUM_DOMAINS, "Enum domains", HFILL }},
5578
5579         { &hf_access_connect_open_domain,
5580           { "Open domain", "samr_access_mask.connect_open_domain",
5581             FT_BOOLEAN, 32, TFS(&flags_set_truth),
5582             SAMR_ACCESS_OPEN_DOMAIN, "Open domain", HFILL }}
5583
5584         };
5585
5586         static gint *ett[] = {
5587                 &ett_dcerpc_samr,
5588                 &ett_samr_user_dispinfo_1,
5589                 &ett_samr_user_dispinfo_1_array,
5590                 &ett_samr_user_dispinfo_2,
5591                 &ett_samr_user_dispinfo_2_array,
5592                 &ett_samr_group_dispinfo,
5593                 &ett_samr_group_dispinfo_array,
5594                 &ett_samr_ascii_dispinfo,
5595                 &ett_samr_ascii_dispinfo_array,
5596                 &ett_samr_display_info,
5597                 &ett_samr_password_info,
5598                 &ett_samr_server,
5599                 &ett_samr_user_group,
5600                 &ett_samr_user_group_array,
5601                 &ett_samr_alias_info,
5602                 &ett_samr_group_info,
5603                 &ett_samr_domain_info_1,
5604                 &ett_samr_domain_info_2,
5605                 &ett_samr_domain_info_8,
5606                 &ett_samr_replication_status,
5607                 &ett_samr_domain_info_11,
5608                 &ett_samr_domain_info_13,
5609                 &ett_samr_domain_info,
5610                 &ett_samr_sid_pointer,
5611                 &ett_samr_sid_array,
5612                 &ett_samr_index_array,
5613                 &ett_samr_idx_and_name,
5614                 &ett_samr_idx_and_name_array,
5615                 &ett_samr_logon_hours,
5616                 &ett_samr_logon_hours_hours,
5617                 &ett_samr_user_info_1,
5618                 &ett_samr_user_info_2,
5619                 &ett_samr_user_info_3,
5620                 &ett_samr_user_info_5,
5621                 &ett_samr_user_info_6,
5622                 &ett_samr_user_info_18,
5623                 &ett_samr_user_info_19,
5624                 &ett_samr_buffer_buffer,
5625                 &ett_samr_buffer,
5626                 &ett_samr_user_info_21,
5627                 &ett_samr_user_info_22,
5628                 &ett_samr_user_info_23,
5629                 &ett_samr_user_info_24,
5630                 &ett_samr_user_info,
5631                 &ett_samr_member_array_types,
5632                 &ett_samr_member_array_rids,
5633                 &ett_samr_member_array,
5634                 &ett_samr_names,
5635                 &ett_samr_rids,
5636                 &ett_samr_sid_and_attributes_array,
5637                 &ett_samr_sid_and_attributes,
5638                 &ett_nt_acct_ctrl,
5639         };
5640         module_t *dcerpc_samr_module;
5641
5642         proto_dcerpc_samr = proto_register_protocol(
5643                 "Microsoft Security Account Manager", "SAMR", "samr");
5644
5645         proto_register_field_array (proto_dcerpc_samr, hf, array_length (hf));
5646         proto_register_subtree_array(ett, array_length(ett));
5647
5648         dcerpc_samr_module = prefs_register_protocol(proto_dcerpc_samr, NULL);
5649         
5650         prefs_register_string_preference(dcerpc_samr_module, "nt_password",
5651                                          "NT Password",
5652                                          "NT Password (used to verify password changes)",
5653                                          &nt_password);
5654 }
5655
5656 void
5657 proto_reg_handoff_dcerpc_samr(void)
5658 {
5659         /* Register protocol as dcerpc */
5660
5661         dcerpc_init_uuid(proto_dcerpc_samr, ett_dcerpc_samr, &uuid_dcerpc_samr,
5662                          ver_dcerpc_samr, dcerpc_samr_dissectors, hf_samr_opnum);
5663 }