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