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