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