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