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