a82c2ffd8439854b427b9243ca1c249419cda7a4
[obnox/wireshark/wip.git] / packet-dcerpc-samr.c
1 /* packet-dcerpc-samr.c
2  * Routines for SMB \\PIPE\\samr packet disassembly
3  * Copyright 2001, Tim Potter <tpot@samba.org>
4  *   2002 Added all command dissectors  Ronnie Sahlberg
5  *
6  * $Id: packet-dcerpc-samr.c,v 1.20 2002/03/10 22:04:25 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <glib.h>
32 #include <epan/packet.h>
33 #include "packet-dcerpc.h"
34 #include "packet-dcerpc-nt.h"
35 #include "packet-dcerpc-samr.h"
36 #include "smb.h"        /* for "NT_errors[]" */
37
38 int dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name);
39
40 static int proto_dcerpc_samr = -1;
41
42 static int hf_samr_hnd = -1;
43 static int hf_samr_group = -1;
44 static int hf_samr_rid = -1;
45 static int hf_samr_type = -1;
46 static int hf_samr_alias = -1;
47 static int hf_samr_rid_attrib = -1;
48 static int hf_samr_rc = -1;
49 static int hf_samr_index = -1;
50 static int hf_samr_count = -1;
51
52 static int hf_samr_level = -1;
53 static int hf_samr_start_idx = -1;
54 static int hf_samr_max_entries = -1;
55 static int hf_samr_entries = -1;
56 static int hf_samr_pref_maxsize = -1;
57 static int hf_samr_total_size = -1;
58 static int hf_samr_ret_size = -1;
59 static int hf_samr_alias_name = -1;
60 static int hf_samr_group_name = -1;
61 static int hf_samr_acct_name = -1;
62 static int hf_samr_full_name = -1;
63 static int hf_samr_acct_desc = -1;
64 static int hf_samr_home = -1;
65 static int hf_samr_home_drive = -1;
66 static int hf_samr_script = -1;
67 static int hf_samr_workstations = -1;
68 static int hf_samr_profile = -1;
69 static int hf_samr_server = -1;
70 static int hf_samr_domain = -1;
71 static int hf_samr_controller = -1;
72 static int hf_samr_access = -1;
73 static int hf_samr_mask = -1;
74 static int hf_samr_crypt_password = -1;
75 static int hf_samr_crypt_hash = -1;
76 static int hf_samr_lm_change = -1;
77 static int hf_samr_attrib = -1;
78 static int hf_samr_max_pwd_age = -1;
79 static int hf_samr_min_pwd_age = -1;
80 static int hf_samr_min_pwd_len = -1;
81 static int hf_samr_pwd_history_len = -1;
82 static int hf_samr_num_users = -1;
83 static int hf_samr_num_groups = -1;
84 static int hf_samr_num_aliases = -1;
85 static int hf_samr_resume_hnd = -1;
86 static int hf_samr_bad_pwd_count = -1;
87 static int hf_samr_logon_count = -1;
88 static int hf_samr_logon_time = -1;
89 static int hf_samr_logoff_time = -1;
90 static int hf_samr_kickoff_time = -1;
91 static int hf_samr_pwd_last_set_time = -1;
92 static int hf_samr_pwd_can_change_time = -1;
93 static int hf_samr_pwd_must_change_time = -1;
94 static int hf_samr_acct_expiry_time = -1;
95 static int hf_samr_country = -1;
96 static int hf_samr_codepage = -1;
97 static int hf_samr_comment = -1;
98 static int hf_samr_parameters = -1;
99 static int hf_samr_nt_pwd_set = -1;
100 static int hf_samr_lm_pwd_set = -1;
101 static int hf_samr_pwd_expired = -1;
102 static int hf_samr_revision = -1;
103 static int hf_samr_divisions = -1;
104 static int hf_samr_info_type = -1;
105
106 static int hf_samr_unknown_hyper = -1;
107 static int hf_samr_unknown_long = -1;
108 static int hf_samr_unknown_short = -1;
109 static int hf_samr_unknown_char = -1;
110 static int hf_samr_unknown_string = -1;
111 static int hf_samr_unknown_time = -1;
112
113 /* these are used by functions in packet-dcerpc-nt.c */
114 int hf_nt_str_len = -1;
115 int hf_nt_str_off = -1;
116 int hf_nt_str_max_len = -1;
117 int hf_nt_string_length = -1;
118 int hf_nt_string_size = -1;
119 static int hf_nt_acct_ctrl = -1;
120 static int hf_nt_acb_disabled = -1;
121 static int hf_nt_acb_homedirreq = -1;
122 static int hf_nt_acb_pwnotreq = -1;
123 static int hf_nt_acb_tempdup = -1;
124 static int hf_nt_acb_normal = -1;
125 static int hf_nt_acb_mns = -1;
126 static int hf_nt_acb_domtrust = -1;
127 static int hf_nt_acb_wstrust = -1;
128 static int hf_nt_acb_svrtrust = -1;
129 static int hf_nt_acb_pwnoexp = -1;
130 static int hf_nt_acb_autolock = -1;
131
132 static gint ett_dcerpc_samr = -1;
133 gint ett_nt_unicode_string = -1;        /* used by packet-dcerpc-nt.c*/
134 static gint ett_samr_user_dispinfo_1 = -1;
135 static gint ett_samr_user_dispinfo_1_array = -1;
136 static gint ett_samr_user_dispinfo_2 = -1;
137 static gint ett_samr_user_dispinfo_2_array = -1;
138 static gint ett_samr_group_dispinfo = -1;
139 static gint ett_samr_group_dispinfo_array = -1;
140 static gint ett_samr_ascii_dispinfo = -1;
141 static gint ett_samr_ascii_dispinfo_array = -1;
142 static gint ett_samr_display_info = -1;
143 static gint ett_samr_password_info = -1;
144 static gint ett_samr_server = -1;
145 static gint ett_samr_user_group = -1;
146 static gint ett_samr_user_group_array = -1;
147 static gint ett_samr_alias_info = -1;
148 static gint ett_samr_group_info = -1;
149 static gint ett_samr_domain_info_1 = -1;
150 static gint ett_samr_domain_info_2 = -1;
151 static gint ett_samr_domain_info_8 = -1;
152 static gint ett_samr_replication_status = -1;
153 static gint ett_samr_domain_info_11 = -1;
154 static gint ett_samr_domain_info_13 = -1;
155 static gint ett_samr_domain_info = -1;
156 static gint ett_samr_sid_pointer = -1;
157 static gint ett_samr_sid_array = -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_logon_hours = -1;
162 static gint ett_samr_logon_hours_hours = -1;
163 static gint ett_samr_user_info_1 = -1;
164 static gint ett_samr_user_info_2 = -1;
165 static gint ett_samr_user_info_3 = -1;
166 static gint ett_samr_user_info_5 = -1;
167 static gint ett_samr_user_info_6 = -1;
168 static gint ett_samr_user_info_18 = -1;
169 static gint ett_samr_user_info_19 = -1;
170 static gint ett_samr_buffer_buffer = -1;
171 static gint ett_samr_buffer = -1;
172 static gint ett_samr_user_info_21 = -1;
173 static gint ett_samr_user_info_22 = -1;
174 static gint ett_samr_user_info_23 = -1;
175 static gint ett_samr_user_info_24 = -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 static gint ett_nt_acct_ctrl = -1;
183
184
185 static e_uuid_t uuid_dcerpc_samr = {
186         0x12345778, 0x1234, 0xabcd, 
187         { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xac}
188 };
189
190 static guint16 ver_dcerpc_samr = 1;
191
192
193 /* functions to dissect a STRING structure, common to many 
194    NT services
195    struct {
196      short len;
197      short size;
198      [size_is(size), length_is(len), ptr] char *string;
199    } STRING;
200 */
201
202 static int
203 dissect_ndr_nt_STRING_string (tvbuff_t *tvb, int offset, 
204                              packet_info *pinfo, proto_tree *tree, 
205                              char *drep)
206 {
207         guint32 len, off, max_len;
208         guint8 *text;
209         int old_offset;
210         char *name;
211         dcerpc_info *di;
212
213         di=pinfo->private_data;
214         if(di->conformant_run){
215                 /*just a run to handle conformant arrays, nothing to dissect */
216                 return offset;
217         }
218
219         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
220                                      hf_nt_str_len, &len);
221         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
222                                      hf_nt_str_off, &off);
223         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
224                                      hf_nt_str_max_len, &max_len);
225
226         old_offset=offset;
227         offset = prs_uint8s(tvb, offset, pinfo, tree, max_len, &text, NULL);
228
229         name = proto_registrar_get_name(di->hf_index);
230         proto_tree_add_string(tree, di->hf_index, tvb, old_offset,
231                 offset-old_offset, text);
232
233         if(tree){
234                 proto_item_set_text(tree, "%s: %s", name, text);
235                 proto_item_set_text(tree->parent, "%s: %s", name, text);
236         }
237         return offset;
238 }
239
240 int
241 dissect_ndr_nt_STRING (tvbuff_t *tvb, int offset, 
242                              packet_info *pinfo, proto_tree *parent_tree, 
243                              char *drep, int hf_index)
244 {
245         proto_item *item=NULL;
246         proto_tree *tree=NULL;
247         int old_offset=offset;
248         char *name;
249         dcerpc_info *di;
250
251         di=pinfo->private_data;
252         if(di->conformant_run){
253                 /*just a run to handle conformant arrays, nothing to dissect */
254                 return offset;
255         }
256
257         name = proto_registrar_get_name(di->hf_index);
258         if(parent_tree){
259                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
260                         "%s", name);
261                 tree = proto_item_add_subtree(item, ett_nt_unicode_string);
262         }
263
264         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
265                                      hf_nt_string_length, NULL);
266         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
267                                      hf_nt_string_size, NULL);
268         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
269                         dissect_ndr_nt_STRING_string, NDR_POINTER_PTR,
270                         name, hf_index, 0);
271
272         proto_item_set_len(item, offset-old_offset);
273         return offset;
274 }
275
276 /* This should get fixed both here and in dissect_smb_64bit_time so
277    one can handle both BIG and LITTLE endian encodings 
278  */
279 int dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int hf_date);
280 int
281 dissect_ndr_nt_NTTIME (tvbuff_t *tvb, int offset, 
282                         packet_info *pinfo, proto_tree *tree, 
283                         char *drep, int hf_index)
284 {
285         dcerpc_info *di;
286
287         di=pinfo->private_data;
288         if(di->conformant_run){
289                 /*just a run to handle conformant arrays, nothing to dissect */
290                 return offset;
291         }
292
293         /* align to 4 byte boundary */
294         if(offset&0x03){
295                 offset = (offset&0xfffffffc)+4;
296         }
297
298         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
299                  hf_index);
300         return offset;
301 }
302
303 static int
304 samr_dissect_SID(tvbuff_t *tvb, int offset, 
305                         packet_info *pinfo, proto_tree *tree, 
306                         char *drep)
307 {
308         dcerpc_info *di;
309
310         di=pinfo->private_data;
311         if(di->conformant_run){
312                 /* just a run to handle conformant arrays, no scalars to dissect */
313                 return offset;
314         }
315
316         /* the SID contains a conformant array, first we must eat
317            the 4-byte max_count before we can hand it off */
318         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
319                         hf_samr_count, NULL);
320
321         offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Domain");
322         return offset;
323 }
324
325 static int
326 samr_dissect_SID_ptr(tvbuff_t *tvb, int offset, 
327                         packet_info *pinfo, proto_tree *tree, 
328                         char *drep)
329 {
330         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
331                         samr_dissect_SID, NDR_POINTER_UNIQUE,
332                         "SID pointer", -1, 1);
333         return offset;
334 }
335
336
337
338 static const true_false_string tfs_nt_acb_disabled = {
339         "Account is DISABLED",
340         "Account is NOT disabled"
341 };
342 static const true_false_string tfs_nt_acb_homedirreq = {
343         "Homedir is REQUIRED",
344         "Homedir is NOT required"
345 };
346 static const true_false_string tfs_nt_acb_pwnotreq = {
347         "Password is NOT required",
348         "Password is REQUIRED"
349 };
350 static const true_false_string tfs_nt_acb_tempdup = {
351         "This is a TEMPORARY DUPLICATE account",
352         "This is NOT a temporary duplicate account"
353 };
354 static const true_false_string tfs_nt_acb_normal = {
355         "This is a NORMAL USER account",
356         "This is NOT a normal user account"
357 };
358 static const true_false_string tfs_nt_acb_mns = {
359         "This is a MNS account",
360         "This is NOT a mns account"
361 };
362 static const true_false_string tfs_nt_acb_domtrust = {
363         "This is a DOMAIN TRUST account",
364         "This is NOT a domain trust account"
365 };
366 static const true_false_string tfs_nt_acb_wstrust = {
367         "This is a WORKSTATION TRUST account",
368         "This is NOT a workstation trust account"
369 };
370 static const true_false_string tfs_nt_acb_svrtrust = {
371         "This is a SERVER TRUST account",
372         "This is NOT a server trust account"
373 };
374 static const true_false_string tfs_nt_acb_pwnoexp = {
375         "Passwords does NOT expire",
376         "Password will EXPIRE"
377 };
378 static const true_false_string tfs_nt_acb_autolock = {
379         "This account has been AUTO LOCKED",
380         "This account has NOT been auto locked"
381 };
382 int
383 dissect_ndr_nt_acct_ctrl(tvbuff_t *tvb, int offset, packet_info *pinfo, 
384                         proto_tree *parent_tree, char *drep)
385 {
386         guint32 mask;
387         proto_item *item = NULL;
388         proto_tree *tree = NULL;
389
390         offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
391                         hf_nt_acct_ctrl, &mask);
392
393         if(parent_tree){
394                 item = proto_tree_add_uint(parent_tree, hf_nt_acct_ctrl,
395                         tvb, offset-4, 4, mask);
396                 tree = proto_item_add_subtree(item, ett_nt_acct_ctrl);
397         }
398
399         proto_tree_add_boolean(tree, hf_nt_acb_autolock,
400                 tvb, offset-4, 4, mask);
401         proto_tree_add_boolean(tree, hf_nt_acb_pwnoexp,
402                 tvb, offset-4, 4, mask);
403         proto_tree_add_boolean(tree, hf_nt_acb_svrtrust,
404                 tvb, offset-4, 4, mask);
405         proto_tree_add_boolean(tree, hf_nt_acb_wstrust,
406                 tvb, offset-4, 4, mask);
407         proto_tree_add_boolean(tree, hf_nt_acb_domtrust,
408                 tvb, offset-4, 4, mask);
409         proto_tree_add_boolean(tree, hf_nt_acb_mns,
410                 tvb, offset-4, 4, mask);
411         proto_tree_add_boolean(tree, hf_nt_acb_normal,
412                 tvb, offset-4, 4, mask);
413         proto_tree_add_boolean(tree, hf_nt_acb_tempdup,
414                 tvb, offset-4, 4, mask);
415         proto_tree_add_boolean(tree, hf_nt_acb_pwnotreq,
416                 tvb, offset-4, 4, mask);
417         proto_tree_add_boolean(tree, hf_nt_acb_homedirreq,
418                 tvb, offset-4, 4, mask);
419         proto_tree_add_boolean(tree, hf_nt_acb_disabled,
420                 tvb, offset-4, 4, mask);
421
422         return offset;
423 }
424
425
426 /* above this line, just some general support routines which should be placed
427    in some more generic file common to all NT services dissectors
428 */
429
430 static int
431 samr_dissect_context_handle_reply(tvbuff_t *tvb, int offset, 
432                         packet_info *pinfo, proto_tree *tree, 
433                         char *drep)
434 {
435         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
436                         hf_samr_hnd, NULL);
437         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
438                         hf_samr_rc, NULL);
439
440         return offset;
441 }
442
443
444 static int
445 samr_dissect_open_user_rqst(tvbuff_t *tvb, int offset, 
446                         packet_info *pinfo, proto_tree *tree, 
447                         char *drep)
448 {
449         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
450                         hf_samr_hnd, NULL);
451         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
452                         hf_samr_access, NULL);
453         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
454                         hf_samr_rid, NULL);
455
456         return offset;
457 }
458
459 static int
460 samr_dissect_pointer_long(tvbuff_t *tvb, int offset, 
461                              packet_info *pinfo, proto_tree *tree, 
462                              char *drep)
463 {
464         dcerpc_info *di;
465
466         di=pinfo->private_data;
467         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
468                                      di->hf_index, NULL);
469         return offset;
470 }
471
472 static int
473 samr_dissect_pointer_STRING(tvbuff_t *tvb, int offset, 
474                              packet_info *pinfo, proto_tree *tree, 
475                              char *drep)
476 {
477         dcerpc_info *di;
478
479         di=pinfo->private_data;
480         if(di->conformant_run){
481                 /*just a run to handle conformant arrays, nothing to dissect */
482                 return offset;
483         }
484
485         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
486                         di->hf_index);
487         return offset;
488 }
489
490 static int
491 samr_dissect_pointer_UNICODE_STRING(tvbuff_t *tvb, int offset, 
492                              packet_info *pinfo, proto_tree *tree, 
493                              char *drep)
494 {
495         dcerpc_info *di;
496
497         di=pinfo->private_data;
498         if(di->conformant_run){
499                 /*just a run to handle conformant arrays, nothing to dissect */
500                 return offset;
501         }
502
503         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
504                         di->hf_index, di->levels);
505         return offset;
506 }
507
508 static int
509 samr_dissect_pointer_short(tvbuff_t *tvb, int offset, 
510                              packet_info *pinfo, proto_tree *tree, 
511                              char *drep)
512 {
513         dcerpc_info *di;
514
515         di=pinfo->private_data;
516         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
517                                      di->hf_index, NULL);
518         return offset;
519 }
520
521
522 static int
523 samr_dissect_query_dispinfo_rqst (tvbuff_t *tvb, int offset, 
524                              packet_info *pinfo, proto_tree *tree, 
525                              char *drep)
526 {
527         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
528                                       hf_samr_hnd, NULL);
529         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
530                                      hf_samr_level, NULL);
531         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
532                                      hf_samr_start_idx, NULL);
533         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
534                                      hf_samr_max_entries, NULL);
535         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
536                                      hf_samr_pref_maxsize, NULL);
537         return offset;
538 }
539
540 static int
541 samr_dissect_USER_DISPINFO_1(tvbuff_t *tvb, int offset, 
542                         packet_info *pinfo, proto_tree *parent_tree, 
543                         char *drep)
544 {
545         proto_item *item=NULL;
546         proto_tree *tree=NULL;
547         int old_offset=offset;
548
549         if(parent_tree){
550                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
551                         "User_DispInfo_1");
552                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
553         }
554
555         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
556                                 hf_samr_index, NULL);
557         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
558                                 hf_samr_rid, NULL);
559         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
560         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
561                                 hf_samr_acct_name, 0);
562         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
563                                 hf_samr_full_name, 0);
564         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
565                                 hf_samr_acct_desc, 0);
566
567         proto_item_set_len(item, offset-old_offset);
568         return offset;
569 }
570
571 static int
572 samr_dissect_USER_DISPINFO_1_ARRAY_users(tvbuff_t *tvb, int offset, 
573                         packet_info *pinfo, proto_tree *tree, 
574                         char *drep)
575 {
576         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
577                         samr_dissect_USER_DISPINFO_1);
578
579         return offset;
580 }
581
582 static int
583 samr_dissect_USER_DISPINFO_1_ARRAY (tvbuff_t *tvb, int offset, 
584                              packet_info *pinfo, proto_tree *parent_tree, 
585                              char *drep)
586 {
587         guint32 count;
588         proto_item *item=NULL;
589         proto_tree *tree=NULL;
590         int old_offset=offset;
591
592         if(parent_tree){
593                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
594                         "User_DispInfo_1 Array");
595                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1_array);
596         }
597
598
599         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
600                                      hf_samr_count, &count);
601         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
602                         samr_dissect_USER_DISPINFO_1_ARRAY_users, NDR_POINTER_PTR,
603                         "USER_DISPINFO_1_ARRAY", -1, 0);
604
605         proto_item_set_len(item, offset-old_offset);
606         return offset;
607 }
608
609
610
611 static int
612 samr_dissect_USER_DISPINFO_2(tvbuff_t *tvb, int offset, 
613                         packet_info *pinfo, proto_tree *parent_tree, 
614                         char *drep)
615 {
616         proto_item *item=NULL;
617         proto_tree *tree=NULL;
618         int old_offset=offset;
619
620         if(parent_tree){
621                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
622                         "User_DispInfo_2");
623                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2);
624         }
625
626         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
627                         hf_samr_index, NULL);
628         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
629                         hf_samr_rid, NULL);
630         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
631         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
632                         hf_samr_acct_name, 0);
633         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
634                         hf_samr_acct_desc, 0);
635
636         proto_item_set_len(item, offset-old_offset);
637         return offset;
638 }
639
640 static int
641 samr_dissect_USER_DISPINFO_2_ARRAY_users (tvbuff_t *tvb, int offset, 
642                              packet_info *pinfo, proto_tree *tree, 
643                              char *drep)
644 {
645         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
646                         samr_dissect_USER_DISPINFO_2);
647
648         return offset;
649 }
650
651 static int
652 samr_dissect_USER_DISPINFO_2_ARRAY (tvbuff_t *tvb, int offset, 
653                              packet_info *pinfo, proto_tree *parent_tree, 
654                              char *drep)
655 {
656         guint32 count;
657         proto_item *item=NULL;
658         proto_tree *tree=NULL;
659         int old_offset=offset;
660
661         if(parent_tree){
662                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
663                         "User_DispInfo_2 Array");
664                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2_array);
665         }
666
667
668         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
669                                      hf_samr_count, &count);
670         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
671                         samr_dissect_USER_DISPINFO_2_ARRAY_users, NDR_POINTER_PTR,
672                         "USER_DISPINFO_2_ARRAY", -1, 0);
673
674         proto_item_set_len(item, offset-old_offset);
675         return offset;
676 }
677
678
679
680
681
682 static int
683 samr_dissect_GROUP_DISPINFO(tvbuff_t *tvb, int offset, 
684                         packet_info *pinfo, proto_tree *parent_tree, 
685                         char *drep)
686 {
687         proto_item *item=NULL;
688         proto_tree *tree=NULL;
689         int old_offset=offset;
690
691         if(parent_tree){
692                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
693                         "Group_DispInfo");
694                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo);
695         }
696
697         
698         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
699                         hf_samr_index, NULL);
700         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
701                         hf_samr_rid, NULL);
702         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
703         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
704                         hf_samr_acct_name, 0);
705         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
706                         hf_samr_acct_desc, 0);
707
708         proto_item_set_len(item, offset-old_offset);
709         return offset;
710 }
711
712 static int
713 samr_dissect_GROUP_DISPINFO_ARRAY_groups(tvbuff_t *tvb, int offset, 
714                         packet_info *pinfo, proto_tree *tree, 
715                         char *drep)
716 {
717         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
718                         samr_dissect_GROUP_DISPINFO);
719
720         return offset;
721 }
722
723 static int
724 samr_dissect_GROUP_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
725                         packet_info *pinfo, proto_tree *parent_tree, 
726                         char *drep)
727 {
728         guint32 count;
729         proto_item *item=NULL;
730         proto_tree *tree=NULL;
731         int old_offset=offset;
732
733         if(parent_tree){
734                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
735                         "Group_DispInfo Array");
736                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo_array);
737         }
738
739         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
740                                      hf_samr_count, &count);
741         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
742                         samr_dissect_GROUP_DISPINFO_ARRAY_groups, NDR_POINTER_PTR,
743                         "GROUP_DISPINFO_ARRAY", -1, 0);
744
745         proto_item_set_len(item, offset-old_offset);
746         return offset;
747 }
748
749
750
751 static int
752 samr_dissect_ASCII_DISPINFO(tvbuff_t *tvb, int offset, 
753                         packet_info *pinfo, proto_tree *parent_tree, 
754                         char *drep)
755 {
756         proto_item *item=NULL;
757         proto_tree *tree=NULL;
758         int old_offset=offset;
759
760         if(parent_tree){
761                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
762                         "Ascii_DispInfo");
763                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo);
764         }
765
766         
767         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
768                         hf_samr_index, NULL);
769         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
770                         hf_samr_rid, NULL);
771         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
772         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
773                         hf_samr_acct_name);
774         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
775                         hf_samr_acct_desc);
776
777         proto_item_set_len(item, offset-old_offset);
778         return offset;
779 }
780
781 static int
782 samr_dissect_ASCII_DISPINFO_ARRAY_users(tvbuff_t *tvb, int offset, 
783                         packet_info *pinfo, proto_tree *tree, 
784                         char *drep)
785 {
786         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
787                         samr_dissect_ASCII_DISPINFO);
788
789         return offset;
790 }
791
792 static int
793 samr_dissect_ASCII_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
794                         packet_info *pinfo, proto_tree *parent_tree,
795                         char *drep)
796 {
797         guint32 count;
798         proto_item *item=NULL;
799         proto_tree *tree=NULL;
800         int old_offset=offset;
801
802         if(parent_tree){
803                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
804                         "Ascii_DispInfo Array");
805                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo_array);
806         }
807
808         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
809                                      hf_samr_count, &count);
810         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
811                         samr_dissect_ASCII_DISPINFO_ARRAY_users, NDR_POINTER_PTR,
812                         "ACSII_DISPINFO_ARRAY", -1, 0);
813
814         proto_item_set_len(item, offset-old_offset);
815         return offset;
816 }
817
818
819 static int
820 samr_dissect_DISPLAY_INFO (tvbuff_t *tvb, int offset, 
821                              packet_info *pinfo, proto_tree *parent_tree,
822                              char *drep)
823 {
824         proto_item *item=NULL;
825         proto_tree *tree=NULL;
826         int old_offset=offset;
827         guint16 level;
828
829         if(parent_tree){
830                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
831                         "DISP_INFO:");
832                 tree = proto_item_add_subtree(item, ett_samr_display_info);
833         }
834
835         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
836                                      hf_samr_level, &level);
837         switch(level){
838         case 1: 
839                 offset = samr_dissect_USER_DISPINFO_1_ARRAY(
840                                 tvb, offset, pinfo, tree, drep);
841                 break;
842         case 2: 
843                 offset = samr_dissect_USER_DISPINFO_2_ARRAY(
844                                 tvb, offset, pinfo, tree, drep);
845                 break;
846         case 3: 
847                 offset = samr_dissect_GROUP_DISPINFO_ARRAY(
848                                 tvb, offset, pinfo, tree, drep);
849                 break;
850         case 4: 
851                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
852                                 tvb, offset, pinfo, tree, drep);
853                 break;
854         case 5: 
855                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
856                                 tvb, offset, pinfo, tree, drep);
857                 break;
858         }
859
860         proto_item_set_len(item, offset-old_offset);
861         return offset;
862 }
863
864 static int
865 samr_dissect_query_dispinfo_reply (tvbuff_t *tvb, int offset, 
866                              packet_info *pinfo, proto_tree *tree, 
867                              char *drep)
868 {
869         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
870                         samr_dissect_pointer_long, NDR_POINTER_REF,
871                         "", hf_samr_total_size, 0);
872         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
873                         samr_dissect_pointer_long, NDR_POINTER_REF,
874                         "", hf_samr_ret_size, 0);
875         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
876                         samr_dissect_DISPLAY_INFO, NDR_POINTER_REF,
877                         "", -1, 0);
878         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
879                                      hf_samr_rc, NULL);
880
881         return offset;
882 }
883
884
885 static int
886 samr_dissect_get_display_enumeration_index_rqst(tvbuff_t *tvb, int offset, 
887                              packet_info *pinfo, proto_tree *tree, 
888                              char *drep)
889 {
890         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
891                                       hf_samr_hnd, NULL);
892         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
893                                      hf_samr_level, NULL);
894         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
895                         hf_samr_acct_name);
896         return offset;
897 }
898
899
900 static int
901 samr_dissect_get_display_enumeration_index_reply(tvbuff_t *tvb, int offset, 
902                              packet_info *pinfo, proto_tree *tree, 
903                              char *drep)
904 {
905         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
906                         samr_dissect_pointer_long, NDR_POINTER_REF,
907                         "", hf_samr_index, 0);
908         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
909                                      hf_samr_rc, NULL);
910
911         return offset;
912 }
913
914
915
916
917 static int
918 samr_dissect_PASSWORD_INFO(tvbuff_t *tvb, int offset, 
919                         packet_info *pinfo, proto_tree *parent_tree,
920                         char *drep)
921 {
922         guint32 count;
923         proto_item *item=NULL;
924         proto_tree *tree=NULL;
925         int old_offset=offset;
926
927         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
928
929         if(parent_tree){
930                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
931                         "PASSWORD_INFO:");
932                 tree = proto_item_add_subtree(item, ett_samr_password_info);
933         }
934
935         
936         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
937                         hf_samr_unknown_short, NULL);
938         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
939                         hf_samr_unknown_long, NULL);
940
941         proto_item_set_len(item, offset-old_offset);
942         return offset;
943 }
944
945 static int
946 samr_dissect_get_usrdom_pwinfo_reply(tvbuff_t *tvb, int offset, 
947                              packet_info *pinfo, proto_tree *tree, 
948                              char *drep)
949 {
950         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
951                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
952                         "", -1, 0);
953         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
954                                      hf_samr_rc, NULL);
955         return offset;
956 }
957
958
959
960 static int
961 samr_dissect_connect2_server(tvbuff_t *tvb, int offset, 
962                              packet_info *pinfo, proto_tree *parent_tree, 
963                              char *drep)
964 {
965         proto_item *item=NULL;
966         proto_tree *tree=NULL;
967         int old_offset=offset;
968
969         if(parent_tree){
970                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
971                         "Server");
972                 tree = proto_item_add_subtree(item, ett_samr_server);
973         }
974
975         offset = dissect_ndr_nt_UNICODE_STRING_str(tvb, offset, pinfo, 
976                         tree, drep);
977
978         proto_item_set_len(item, offset-old_offset);
979         return offset;
980 }
981
982 static int
983 samr_dissect_connect2_rqst(tvbuff_t *tvb, int offset, 
984                              packet_info *pinfo, proto_tree *tree, 
985                              char *drep)
986 {
987         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
988                         samr_dissect_connect2_server, NDR_POINTER_UNIQUE,
989                         "Server", hf_samr_server, 0);
990
991         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
992                                      hf_samr_access, NULL);
993         return offset;
994 }
995
996 static int
997 samr_dissect_connect2_reply(tvbuff_t *tvb, int offset, 
998                              packet_info *pinfo, proto_tree *tree, 
999                              char *drep)
1000 {
1001         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1002                                       hf_samr_hnd, NULL);
1003         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1004                                      hf_samr_rc, NULL);
1005         return offset;
1006 }
1007
1008
1009
1010
1011 static int
1012 samr_dissect_USER_GROUP(tvbuff_t *tvb, int offset, 
1013                              packet_info *pinfo, proto_tree *parent_tree,
1014                              char *drep)
1015 {
1016         proto_item *item=NULL;
1017         proto_tree *tree=NULL;
1018         int old_offset=offset;
1019
1020         if(parent_tree){
1021                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1022                         "USER_GROUP:");
1023                 tree = proto_item_add_subtree(item, ett_samr_user_group);
1024         }
1025
1026         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1027                                      hf_samr_rid, NULL);
1028         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1029                                      hf_samr_rid_attrib, NULL);
1030
1031         proto_item_set_len(item, offset-old_offset);
1032         return offset;
1033 }
1034
1035 static int
1036 samr_dissect_USER_GROUP_ARRAY_groups (tvbuff_t *tvb, int offset, 
1037                              packet_info *pinfo, proto_tree *tree,
1038                              char *drep)
1039 {
1040         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
1041                         samr_dissect_USER_GROUP);
1042
1043         return offset;
1044 }
1045
1046 static int
1047 samr_dissect_USER_GROUP_ARRAY(tvbuff_t *tvb, int offset, 
1048                         packet_info *pinfo, proto_tree *parent_tree,
1049                         char *drep)
1050 {
1051         guint32 count;
1052         proto_item *item=NULL;
1053         proto_tree *tree=NULL;
1054         int old_offset=offset;
1055
1056         if(parent_tree){
1057                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1058                         "USER_GROUP_ARRAY");
1059                 tree = proto_item_add_subtree(item, ett_samr_user_group_array);
1060         }
1061
1062         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1063                         hf_samr_count, &count);
1064         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1065                         samr_dissect_USER_GROUP_ARRAY_groups, NDR_POINTER_UNIQUE,
1066                         "USER_GROUP_ARRAY", -1, 0);
1067
1068         proto_item_set_len(item, offset-old_offset);
1069         return offset;
1070 }
1071
1072 static int
1073 samr_dissect_USER_GROUP_ARRAY_ptr(tvbuff_t *tvb, int offset, 
1074                         packet_info *pinfo, proto_tree *tree,
1075                         char *drep)
1076 {
1077         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1078                         samr_dissect_USER_GROUP_ARRAY, NDR_POINTER_UNIQUE,
1079                         "USER_GROUP_ARRAY", -1, 0);
1080         return offset;
1081 }
1082
1083 static int
1084 samr_dissect_get_groups_for_user_reply(tvbuff_t *tvb, int offset, 
1085                              packet_info *pinfo, proto_tree *tree, 
1086                              char *drep)
1087 {
1088         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1089                         samr_dissect_USER_GROUP_ARRAY_ptr, NDR_POINTER_REF,
1090                         "", -1, 0);
1091         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1092                                      hf_samr_rc, NULL);
1093         return offset;
1094 }
1095
1096
1097
1098 static int
1099 samr_dissect_open_domain_rqst(tvbuff_t *tvb, int offset, 
1100                              packet_info *pinfo, proto_tree *tree, 
1101                              char *drep)
1102 {
1103         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1104                                       hf_samr_hnd, NULL);
1105         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1106                                      hf_samr_access, NULL);
1107         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1108                         samr_dissect_SID, NDR_POINTER_REF,
1109                         "", -1, 0);
1110         return offset;
1111 }
1112
1113 static int
1114 samr_dissect_open_domain_reply(tvbuff_t *tvb, int offset, 
1115                              packet_info *pinfo, proto_tree *tree, 
1116                              char *drep)
1117 {
1118         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1119                                       hf_samr_hnd, NULL);
1120         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1121                                      hf_samr_rc, NULL);
1122         return offset;
1123 }
1124
1125
1126
1127 static int
1128 samr_dissect_context_handle_SID(tvbuff_t *tvb, int offset, 
1129                              packet_info *pinfo, proto_tree *tree, 
1130                              char *drep)
1131 {
1132         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1133                                       hf_samr_hnd, NULL);
1134         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1135                         samr_dissect_SID, NDR_POINTER_REF,
1136                         "SID", -1, 0);
1137         return offset;
1138 }
1139
1140 static int
1141 samr_dissect_context_handle(tvbuff_t *tvb, int offset, 
1142                              packet_info *pinfo, proto_tree *tree, 
1143                              char *drep)
1144 {
1145         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1146                                       hf_samr_hnd, NULL);
1147         return offset;
1148 }
1149
1150
1151 static int
1152 samr_dissect_rc(tvbuff_t *tvb, int offset, 
1153                              packet_info *pinfo, proto_tree *tree, 
1154                              char *drep)
1155 {
1156         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1157                                      hf_samr_rc, NULL);
1158         return offset;
1159 }
1160
1161 static int
1162 samr_dissect_add_member_to_group_rqst(tvbuff_t *tvb, int offset, 
1163                              packet_info *pinfo, proto_tree *tree, 
1164                              char *drep)
1165 {
1166         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1167                                       hf_samr_hnd, NULL);
1168         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1169                                      hf_samr_group, NULL);
1170         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1171                                      hf_samr_rid, NULL);
1172         return offset;
1173 }
1174
1175 static int
1176 samr_dissect_unknown_3c_reply(tvbuff_t *tvb, int offset, 
1177                              packet_info *pinfo, proto_tree *tree, 
1178                              char *drep)
1179 {
1180         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1181                         samr_dissect_pointer_short, NDR_POINTER_REF,
1182                         "", hf_samr_unknown_short, 0);
1183         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1184                                      hf_samr_rc, NULL);
1185         return offset;
1186 }
1187
1188
1189
1190 static int
1191 samr_dissect_create_alias_in_domain_rqst(tvbuff_t *tvb, int offset, 
1192                              packet_info *pinfo, proto_tree *tree, 
1193                              char *drep)
1194 {
1195         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1196                                       hf_samr_hnd, NULL);
1197         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1198                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1199                         "Account Name", hf_samr_acct_name, 0);
1200         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1201                                      hf_samr_access, NULL);
1202         return offset;
1203 }
1204
1205 static int
1206 samr_dissect_create_alias_in_domain_reply(tvbuff_t *tvb, int offset, 
1207                              packet_info *pinfo, proto_tree *tree, 
1208                              char *drep)
1209 {
1210         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1211                                       hf_samr_hnd, NULL);
1212         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1213                                      hf_samr_rid, NULL);
1214         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1215                                      hf_samr_rc, NULL);
1216
1217         return offset;
1218 }
1219
1220
1221 static int
1222 samr_dissect_query_information_alias_rqst(tvbuff_t *tvb, int offset, 
1223                         packet_info *pinfo, proto_tree *tree, 
1224                         char *drep)
1225 {
1226         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1227                         hf_samr_hnd, NULL);
1228         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1229                         hf_samr_level, NULL);
1230
1231         return offset;
1232 }
1233
1234
1235 static int
1236 samr_dissect_ALIAS_INFO_1 (tvbuff_t *tvb, int offset, 
1237                              packet_info *pinfo, proto_tree *tree,
1238                              char *drep)
1239 {
1240         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1241                 tree, drep,
1242                 hf_samr_acct_name, 0);
1243         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1244                                      hf_samr_rid, NULL);
1245         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1246                 tree, drep,
1247                 hf_samr_acct_desc, 0);
1248         return offset;
1249 }
1250
1251 static int
1252 samr_dissect_ALIAS_INFO(tvbuff_t *tvb, int offset, 
1253                         packet_info *pinfo, proto_tree *parent_tree,
1254                         char *drep)
1255 {
1256         proto_item *item=NULL;
1257         proto_tree *tree=NULL;
1258         int old_offset=offset;
1259         guint16 level;
1260
1261         if(parent_tree){
1262                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1263                         "ALIAS_INFO:");
1264                 tree = proto_item_add_subtree(item, ett_samr_alias_info);
1265         }
1266
1267         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1268                                      hf_samr_level, &level);
1269         switch(level){
1270         case 1: 
1271                 offset = samr_dissect_ALIAS_INFO_1(
1272                                 tvb, offset, pinfo, tree, drep);
1273                 break;
1274         case 2: 
1275                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1276                         tree, drep,
1277                         hf_samr_acct_name, 0);
1278                 break;
1279         case 3: 
1280                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1281                         tree, drep,
1282                         hf_samr_acct_desc, 0);
1283                 break;
1284         }
1285
1286         proto_item_set_len(item, offset-old_offset);
1287         return offset;
1288 }
1289
1290 static int
1291 samr_dissect_ALIAS_INFO_ptr(tvbuff_t *tvb, int offset, 
1292                         packet_info *pinfo, proto_tree *tree,
1293                         char *drep)
1294 {
1295         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1296                         samr_dissect_ALIAS_INFO, NDR_POINTER_UNIQUE,
1297                         "ALIAS_INFO", -1, 0);
1298         return offset;
1299 }
1300
1301 static int
1302 samr_dissect_query_information_alias_reply(tvbuff_t *tvb, int offset, 
1303                         packet_info *pinfo, proto_tree *tree, 
1304                         char *drep)
1305 {
1306         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1307                         samr_dissect_ALIAS_INFO_ptr, NDR_POINTER_REF,
1308                         "", -1, 0);
1309         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1310                         hf_samr_rc, NULL);
1311         return offset;
1312 }
1313
1314 static int
1315 samr_dissect_set_information_alias_rqst(tvbuff_t *tvb, int offset, 
1316                              packet_info *pinfo, proto_tree *tree, 
1317                              char *drep)
1318 {
1319         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1320                                       hf_samr_hnd, NULL);
1321         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1322                                      hf_samr_level, NULL);
1323         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1324                         samr_dissect_ALIAS_INFO, NDR_POINTER_REF,
1325                         "", -1, 0);
1326         return offset;
1327 }
1328
1329
1330 static int
1331 samr_dissect_CRYPT_PASSWORD(tvbuff_t *tvb, int offset, 
1332                         packet_info *pinfo, proto_tree *tree, 
1333                         char *drep)
1334 {
1335         proto_tree_add_item(tree, hf_samr_crypt_password, tvb, offset, 516,
1336                 FALSE);
1337         offset += 516;
1338         return offset;
1339 }
1340
1341 static int
1342 samr_dissect_CRYPT_HASH(tvbuff_t *tvb, int offset, 
1343                         packet_info *pinfo, proto_tree *tree, 
1344                         char *drep)
1345 {
1346         proto_tree_add_item(tree, hf_samr_crypt_hash, tvb, offset, 16,
1347                 FALSE);
1348         offset += 16;
1349         return offset;
1350 }
1351
1352
1353 static int
1354 samr_dissect_oem_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1355                              packet_info *pinfo, proto_tree *tree, 
1356                              char *drep)
1357 {
1358         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1359                                       hf_samr_hnd, NULL);
1360         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1361                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1362                         "Server", hf_samr_server, 0);
1363         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1364                         samr_dissect_pointer_STRING, NDR_POINTER_REF,
1365                         "Account Name", hf_samr_acct_name, 0);
1366         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1367                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1368                         "Password", -1, 0);
1369         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1370                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1371                         "Hash", -1, 0);
1372         return offset;
1373 }
1374
1375 static int
1376 samr_dissect_unicode_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1377                              packet_info *pinfo, proto_tree *tree, 
1378                              char *drep)
1379 {
1380         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1381                                       hf_samr_hnd, NULL);
1382         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1383                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1384                         "Server", hf_samr_server, 0);
1385         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1386                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1387                         "Account Name", hf_samr_acct_name, 0);
1388         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1389                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1390                         "Password", -1, 0);
1391         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1392                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1393                         "Hash", -1, 0);
1394         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1395                                      hf_samr_lm_change, NULL);
1396         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1397                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1398                         "Password", -1, 0);
1399         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1400                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1401                         "Hash", -1, 0);
1402         return offset;
1403 }
1404
1405 static int
1406 samr_dissect_unknown_3b_rqst(tvbuff_t *tvb, int offset, 
1407                              packet_info *pinfo, proto_tree *tree, 
1408                              char *drep)
1409 {
1410         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1411                                       hf_samr_hnd, NULL);
1412         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1413                                      hf_samr_unknown_short, NULL);
1414         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1415                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1416                         "Unknown", hf_samr_unknown_string, 0);
1417         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1418                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1419                         "Unknown", hf_samr_unknown_string, 0);
1420         return offset;
1421 }
1422
1423
1424 static int
1425 samr_dissect_create_user2_in_domain_rqst(tvbuff_t *tvb, int offset, 
1426                         packet_info *pinfo, proto_tree *tree, 
1427                         char *drep)
1428 {
1429         
1430         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1431                         hf_samr_hnd, NULL);
1432         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1433                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1434                         "Account Name", hf_samr_acct_name, 0);
1435         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
1436         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1437                         hf_samr_access, NULL);
1438
1439         return offset;
1440 }
1441
1442 static int
1443 samr_dissect_create_user2_in_domain_reply(tvbuff_t *tvb, int offset, 
1444                              packet_info *pinfo, proto_tree *tree, 
1445                              char *drep)
1446 {
1447         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1448                                       hf_samr_hnd, NULL);
1449         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1450                                      hf_samr_unknown_long, NULL);
1451         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1452                                      hf_samr_rid, NULL);
1453         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1454                                      hf_samr_rc, NULL);
1455         return offset;
1456 }
1457
1458 static int
1459 samr_dissect_get_display_enumeration_index2_rqst(tvbuff_t *tvb, int offset, 
1460                              packet_info *pinfo, proto_tree *tree, 
1461                              char *drep)
1462 {
1463         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1464                                       hf_samr_hnd, NULL);
1465         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1466                                      hf_samr_level, NULL);
1467         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1468                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1469                         "Account Name", hf_samr_acct_name, 0);
1470         return offset;
1471 }
1472
1473 static int
1474 samr_dissect_get_display_enumeration_index2_reply(tvbuff_t *tvb, int offset, 
1475                              packet_info *pinfo, proto_tree *tree, 
1476                              char *drep)
1477 {
1478         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1479                                      hf_samr_index, NULL);
1480         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1481                                      hf_samr_rc, NULL);
1482         return offset;
1483 }
1484
1485 static int
1486 samr_dissect_change_password_user_rqst(tvbuff_t *tvb, int offset, 
1487                         packet_info *pinfo, proto_tree *tree, 
1488                         char *drep)
1489 {
1490         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1491                         hf_samr_hnd, NULL);
1492         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1493                         hf_samr_unknown_char, NULL);
1494         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1495                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1496                         "Hash", -1, 0);
1497         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1498                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1499                         "Hash", -1, 0);
1500         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1501                         hf_samr_unknown_char, NULL);
1502         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1503                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1504                         "Hash", -1, 0);
1505         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1506                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1507                         "Hash", -1, 0);
1508         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1509                         hf_samr_unknown_char, NULL);
1510         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1511                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1512                         "Hash", -1, 0);
1513         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1514                         hf_samr_unknown_char, NULL);
1515         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1516                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1517                         "Hash", -1, 0);
1518
1519         return offset;
1520 }
1521
1522 static int
1523 samr_dissect_set_member_attributes_of_group_rqst(tvbuff_t *tvb, int offset, 
1524                              packet_info *pinfo, proto_tree *tree, 
1525                              char *drep)
1526 {
1527         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1528                                       hf_samr_hnd, NULL);
1529         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1530                                      hf_samr_attrib, NULL);
1531         return offset;
1532 }
1533
1534
1535 static int
1536 samr_dissect_GROUP_INFO_1 (tvbuff_t *tvb, int offset, 
1537                              packet_info *pinfo, proto_tree *tree,
1538                              char *drep)
1539 {
1540         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1541                 tree, drep,
1542                 hf_samr_acct_name, 0);
1543         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1544                                      hf_samr_rid, NULL);
1545         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1546                                         hf_samr_attrib, NULL);
1547         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1548                 tree, drep,
1549                 hf_samr_acct_desc, 0);
1550         return offset;
1551 }
1552
1553 static int
1554 samr_dissect_GROUP_INFO(tvbuff_t *tvb, int offset, 
1555                         packet_info *pinfo, proto_tree *parent_tree,
1556                         char *drep)
1557 {
1558         proto_item *item=NULL;
1559         proto_tree *tree=NULL;
1560         int old_offset=offset;
1561         guint16 level;
1562
1563         if(parent_tree){
1564                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1565                         "GROUP_INFO:");
1566                 tree = proto_item_add_subtree(item, ett_samr_group_info);
1567         }
1568
1569         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1570                                      hf_samr_level, &level);
1571         switch(level){
1572         case 1: 
1573                 offset = samr_dissect_GROUP_INFO_1(
1574                                 tvb, offset, pinfo, tree, drep);
1575                 break;
1576         case 2: 
1577                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1578                         tree, drep,
1579                         hf_samr_acct_name, 0);
1580                 break;
1581         case 3:
1582                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1583                         hf_samr_attrib, NULL);
1584                 break;
1585         case 4: 
1586                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1587                         tree, drep,
1588                         hf_samr_acct_desc, 0);
1589                 break;
1590         }
1591
1592         proto_item_set_len(item, offset-old_offset);
1593         return offset;
1594 }
1595
1596 static int
1597 samr_dissect_GROUP_INFO_ptr(tvbuff_t *tvb, int offset, 
1598                         packet_info *pinfo, proto_tree *tree,
1599                         char *drep)
1600 {
1601         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1602                         samr_dissect_GROUP_INFO, NDR_POINTER_UNIQUE,
1603                         "GROUP_INFO", -1, 0);
1604         return offset;
1605 }
1606
1607 static int
1608 samr_dissect_query_information_group_rqst (tvbuff_t *tvb, int offset, 
1609                              packet_info *pinfo, proto_tree *tree,
1610                              char *drep)
1611 {
1612         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1613                                       hf_samr_hnd, NULL);
1614         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1615                                      hf_samr_level, NULL);
1616         return offset;
1617 }
1618
1619 static int
1620 samr_dissect_query_information_group_reply(tvbuff_t *tvb, int offset, 
1621                         packet_info *pinfo, proto_tree *tree,
1622                         char *drep)
1623 {
1624         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1625                         samr_dissect_GROUP_INFO_ptr, NDR_POINTER_REF,
1626                         "", -1, 0);
1627         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1628                         hf_samr_rc, NULL);
1629         return offset;
1630 }
1631
1632 static int
1633 samr_dissect_set_information_group_rqst (tvbuff_t *tvb, int offset, 
1634                              packet_info *pinfo, proto_tree *tree,
1635                              char *drep)
1636 {
1637         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1638                                       hf_samr_hnd, NULL);
1639         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1640                                      hf_samr_level, NULL);
1641         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1642                         samr_dissect_GROUP_INFO, NDR_POINTER_REF,
1643                         "", -1, 0);
1644         return offset;
1645 }
1646
1647
1648
1649 static int
1650 samr_dissect_get_domain_password_information_rqst (tvbuff_t *tvb, int offset, 
1651                              packet_info *pinfo, proto_tree *tree,
1652                              char *drep)
1653 {
1654         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1655                                       hf_samr_hnd, NULL);
1656
1657         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1658                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1659                         "Domain", hf_samr_domain, 0);
1660         return offset;
1661 }
1662
1663
1664 static int
1665 samr_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset, 
1666                              packet_info *pinfo, proto_tree *parent_tree,
1667                              char *drep)
1668 {
1669         proto_item *item=NULL;
1670         proto_tree *tree=NULL;
1671         int old_offset=offset;
1672
1673         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */ 
1674
1675         if(parent_tree){
1676                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1677                         "DOMAIN_INFO_1:");
1678                 tree = proto_item_add_subtree(item, ett_samr_domain_info_1);
1679         }
1680
1681         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1682                                         hf_samr_min_pwd_len, NULL);
1683         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1684                                         hf_samr_pwd_history_len, NULL);
1685         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1686                                         hf_samr_unknown_long, NULL);
1687         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1688                                         hf_samr_max_pwd_age);
1689         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1690                                         hf_samr_min_pwd_age);
1691         proto_item_set_len(item, offset-old_offset);
1692         return offset;
1693 }
1694
1695 static int
1696 samr_dissect_DOMAIN_INFO_2(tvbuff_t *tvb, int offset, 
1697                         packet_info *pinfo, proto_tree *parent_tree,
1698                         char *drep)
1699 {
1700         proto_item *item=NULL;
1701         proto_tree *tree=NULL;
1702         int old_offset=offset;
1703
1704         if(parent_tree){
1705                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1706                         "DOMAIN_INFO_2:");
1707                 tree = proto_item_add_subtree(item, ett_samr_domain_info_2);
1708         }
1709
1710         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1711                         hf_samr_unknown_time);
1712         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1713                         hf_samr_unknown_string, 0);
1714         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1715                         hf_samr_domain, 0);
1716         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1717                         hf_samr_controller, 0);
1718         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1719                         hf_samr_unknown_time);
1720         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1721                         hf_samr_unknown_long, NULL);
1722         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1723                         hf_samr_unknown_long, NULL);
1724         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1725                         hf_samr_unknown_char, NULL);
1726         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1727                         hf_samr_num_users, NULL);
1728         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1729                         hf_samr_num_groups, NULL);
1730         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1731                         hf_samr_num_aliases, NULL);
1732
1733         proto_item_set_len(item, offset-old_offset);
1734         return offset;
1735 }
1736
1737 static int
1738 samr_dissect_DOMAIN_INFO_8(tvbuff_t *tvb, int offset, 
1739                              packet_info *pinfo, proto_tree *parent_tree,
1740                              char *drep)
1741 {
1742         proto_item *item=NULL;
1743         proto_tree *tree=NULL;
1744         int old_offset=offset;
1745
1746         if(parent_tree){
1747                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1748                         "DOMAIN_INFO_8:");
1749                 tree = proto_item_add_subtree(item, ett_samr_domain_info_8);
1750         }
1751
1752         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1753                                         hf_samr_max_pwd_age);
1754         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1755                                         hf_samr_min_pwd_age);
1756
1757         proto_item_set_len(item, offset-old_offset);
1758         return offset;
1759 }
1760
1761 static int
1762 samr_dissect_REPLICATION_STATUS(tvbuff_t *tvb, int offset, 
1763                         packet_info *pinfo, proto_tree *parent_tree,
1764                         char *drep)
1765 {
1766         proto_item *item=NULL;
1767         proto_tree *tree=NULL;
1768         int old_offset=offset;
1769
1770         if(parent_tree){
1771                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1772                         "REPLICATION_STATUS:");
1773                 tree = proto_item_add_subtree(item, ett_samr_replication_status);
1774         }
1775
1776         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1777                         hf_samr_unknown_hyper, NULL);
1778         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1779                         hf_samr_unknown_hyper, NULL);
1780         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1781                         hf_samr_unknown_short, NULL);
1782
1783         proto_item_set_len(item, offset-old_offset);
1784         return offset;
1785 }
1786
1787 static int
1788 samr_dissect_DOMAIN_INFO_11(tvbuff_t *tvb, int offset, 
1789                              packet_info *pinfo, proto_tree *parent_tree,
1790                              char *drep)
1791 {
1792         proto_item *item=NULL;
1793         proto_tree *tree=NULL;
1794         int old_offset=offset;
1795
1796         if(parent_tree){
1797                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1798                         "DOMAIN_INFO_11:");
1799                 tree = proto_item_add_subtree(item, ett_samr_domain_info_11);
1800         }
1801
1802         offset = samr_dissect_DOMAIN_INFO_2(
1803                         tvb, offset, pinfo, tree, drep);
1804         offset = samr_dissect_REPLICATION_STATUS(
1805                         tvb, offset, pinfo, tree, drep);
1806
1807         proto_item_set_len(item, offset-old_offset);
1808         return offset;
1809 }
1810
1811 static int
1812 samr_dissect_DOMAIN_INFO_13(tvbuff_t *tvb, int offset, 
1813                              packet_info *pinfo, proto_tree *parent_tree,
1814                              char *drep)
1815 {
1816         proto_item *item=NULL;
1817         proto_tree *tree=NULL;
1818         int old_offset=offset;
1819
1820         if(parent_tree){
1821                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1822                         "DOMAIN_INFO_13:");
1823                 tree = proto_item_add_subtree(item, ett_samr_domain_info_13);
1824         }
1825
1826         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1827                                         hf_samr_unknown_time);
1828         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1829                                         hf_samr_unknown_time);
1830         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1831                                         hf_samr_unknown_time);
1832
1833         proto_item_set_len(item, offset-old_offset);
1834         return offset;
1835 }
1836
1837
1838 static int
1839 samr_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset, 
1840                         packet_info *pinfo, proto_tree *parent_tree,
1841                         char *drep)
1842 {
1843         proto_item *item=NULL;
1844         proto_tree *tree=NULL;
1845         int old_offset=offset;
1846         guint16 level;
1847
1848         if(parent_tree){
1849                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1850                         "DOMAIN_INFO:");
1851                 tree = proto_item_add_subtree(item, ett_samr_domain_info);
1852         }
1853
1854         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1855                                      hf_samr_level, &level);
1856
1857         ALIGN_TO_4_BYTES;  /* all union arms aligned to 4 bytes, case 7 and 9 need this  */
1858         switch(level){
1859         case 1: 
1860                 offset = samr_dissect_DOMAIN_INFO_1(
1861                                 tvb, offset, pinfo, tree, drep);
1862                 break;
1863         case 2: 
1864                 offset = samr_dissect_DOMAIN_INFO_2(
1865                                 tvb, offset, pinfo, tree, drep);
1866                 break;
1867
1868         case 3:
1869                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1870                                 hf_samr_unknown_time);
1871                 break;
1872         case 4:
1873                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1874                         tree, drep, hf_samr_unknown_string, 0);
1875                 break;
1876
1877         case 5:
1878                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1879                         tree, drep, hf_samr_domain, 0);
1880                 break;
1881
1882         case 6:
1883                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1884                         tree, drep, hf_samr_controller, 0);
1885                 break;
1886
1887         case 7:
1888                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1889                         hf_samr_unknown_short, NULL);
1890                 break;
1891         case 8: 
1892                 offset = samr_dissect_DOMAIN_INFO_8(
1893                                 tvb, offset, pinfo, tree, drep);
1894                 break;
1895         case 9:
1896                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1897                         hf_samr_unknown_short, NULL);
1898                 break;
1899         case 11:        
1900                 offset = samr_dissect_DOMAIN_INFO_11(
1901                                 tvb, offset, pinfo, tree, drep);
1902                 break;
1903         case 12:
1904                 offset = samr_dissect_REPLICATION_STATUS(
1905                                 tvb, offset, pinfo, tree, drep);
1906                 break;
1907         case 13:        
1908                 offset = samr_dissect_DOMAIN_INFO_13(
1909                                 tvb, offset, pinfo, tree, drep);
1910                 break;
1911         }
1912
1913         proto_item_set_len(item, offset-old_offset);
1914         return offset;
1915 }
1916
1917 static int
1918 samr_dissect_DOMAIN_INFO_ptr(tvbuff_t *tvb, int offset, 
1919                         packet_info *pinfo, proto_tree *tree,
1920                         char *drep)
1921 {
1922         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1923                         samr_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
1924                         "DOMAIN_INFO pointer", hf_samr_domain, 0);
1925         return offset;
1926 }
1927
1928 static int
1929 samr_dissect_query_information_domain_reply(tvbuff_t *tvb, int offset, 
1930                         packet_info *pinfo, proto_tree *tree,
1931                         char *drep)
1932 {
1933         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1934                         samr_dissect_DOMAIN_INFO_ptr, NDR_POINTER_REF,
1935                         "", hf_samr_domain, 0);
1936         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1937                                      hf_samr_rc, NULL);
1938         return offset;
1939 }
1940
1941
1942 static int
1943 samr_dissect_set_information_domain_rqst(tvbuff_t *tvb, int offset, 
1944                              packet_info *pinfo, proto_tree *tree,
1945                              char *drep)
1946 {
1947         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1948                                       hf_samr_hnd, NULL);
1949         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1950                                      hf_samr_level, NULL);
1951         offset = samr_dissect_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
1952         return offset;
1953 }
1954
1955
1956
1957 static int
1958 samr_dissect_lookup_domain_rqst(tvbuff_t *tvb, int offset, 
1959                         packet_info *pinfo, proto_tree *tree,
1960                         char *drep)
1961 {
1962         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1963                         hf_samr_hnd, NULL);
1964         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1965                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1966                         "", hf_samr_domain, 0);
1967         return offset;
1968 }
1969
1970 static int
1971 samr_dissect_lookup_domain_reply(tvbuff_t *tvb, int offset, 
1972                              packet_info *pinfo, proto_tree *tree,
1973                              char *drep)
1974 {
1975         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1976                         samr_dissect_SID_ptr, NDR_POINTER_REF,
1977                         "", -1, 0);
1978         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1979                                      hf_samr_rc, NULL);
1980         return offset;
1981 }
1982
1983 static int
1984 samr_dissect_PSID(tvbuff_t *tvb, int offset, 
1985                              packet_info *pinfo, proto_tree *parent_tree,
1986                              char *drep)
1987 {
1988         proto_item *item=NULL;
1989         proto_tree *tree=NULL;
1990         int old_offset=offset;
1991
1992         if(parent_tree){
1993                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1994                         "SID pointer:");
1995                 tree = proto_item_add_subtree(item, ett_samr_sid_pointer);
1996         }
1997
1998         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1999                         samr_dissect_SID, NDR_POINTER_UNIQUE,
2000                         "SID", -1, 0);
2001
2002         proto_item_set_len(item, offset-old_offset);
2003         return offset;
2004 }
2005
2006
2007 static int
2008 samr_dissect_PSID_ARRAY_sids (tvbuff_t *tvb, int offset, 
2009                              packet_info *pinfo, proto_tree *tree,
2010                              char *drep)
2011 {
2012         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2013                         samr_dissect_PSID);
2014
2015         return offset;
2016 }
2017
2018
2019 static int
2020 samr_dissect_PSID_ARRAY(tvbuff_t *tvb, int offset, 
2021                         packet_info *pinfo, proto_tree *parent_tree,
2022                         char *drep)
2023 {
2024         guint32 count;
2025         proto_item *item=NULL;
2026         proto_tree *tree=NULL;
2027         int old_offset=offset;
2028
2029         if(parent_tree){
2030                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2031                         "SID array:");
2032                 tree = proto_item_add_subtree(item, ett_samr_sid_array);
2033         }
2034
2035         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2036                         hf_samr_count, &count);
2037         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2038                         samr_dissect_PSID_ARRAY_sids, NDR_POINTER_UNIQUE,
2039                         "PSID_ARRAY", -1, 0);
2040
2041         proto_item_set_len(item, offset-old_offset);
2042         return offset;
2043 }
2044
2045 static int
2046 samr_dissect_index(tvbuff_t *tvb, int offset, 
2047                              packet_info *pinfo, proto_tree *tree,
2048                              char *drep)
2049 {
2050         int old_offset=offset;
2051         dcerpc_info *di;
2052
2053         di=pinfo->private_data;
2054
2055         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2056                         di->hf_index, NULL);
2057
2058         return offset;
2059 }
2060
2061
2062 static int
2063 samr_dissect_INDEX_ARRAY_value (tvbuff_t *tvb, int offset, 
2064                              packet_info *pinfo, proto_tree *tree,
2065                              char *drep)
2066 {
2067         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2068                         samr_dissect_index);
2069
2070         return offset;
2071 }
2072
2073 static char *
2074 plural_ending(const char *string)
2075 {
2076         size_t string_len;
2077
2078         string_len = strlen(string);
2079         if (string_len > 0 && string[string_len - 1] == 's') {
2080                 /* String ends with "s" - pluralize by adding "es" */
2081                 return "es";
2082         } else {
2083                 /* Field name doesn't end with "s" - pluralize by adding "s" */
2084                 return "s";
2085         }
2086 }
2087
2088 static int
2089 samr_dissect_INDEX_ARRAY(tvbuff_t *tvb, int offset, 
2090                         packet_info *pinfo, proto_tree *parent_tree,
2091                         char *drep)
2092 {
2093         char *field_name;
2094         guint32 count;
2095         proto_item *item=NULL;
2096         proto_tree *tree=NULL;
2097         int old_offset=offset;
2098         dcerpc_info *di;
2099         char str[256];
2100
2101         di=pinfo->private_data;
2102
2103         field_name = proto_registrar_get_name(di->hf_index);
2104         snprintf(str, 255, "INDEX_ARRAY: %s%s:", field_name,
2105             plural_ending(field_name));
2106         if(parent_tree){
2107                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2108                         "%s", str);
2109                 tree = proto_item_add_subtree(item, ett_samr_index_array);
2110         }
2111
2112         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2113                         hf_samr_count, &count);
2114         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2115                         samr_dissect_INDEX_ARRAY_value, NDR_POINTER_UNIQUE,
2116                         str, di->hf_index, 0);
2117
2118         proto_item_set_len(item, offset-old_offset);
2119         return offset;
2120 }
2121
2122
2123 static int
2124 samr_dissect_get_alias_membership_rqst(tvbuff_t *tvb, int offset, 
2125                              packet_info *pinfo, proto_tree *tree,
2126                              char *drep)
2127 {
2128         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2129                                       hf_samr_hnd, NULL);
2130         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2131                         samr_dissect_PSID_ARRAY, NDR_POINTER_REF,
2132                         "", -1, 0);
2133         return offset;
2134 }
2135
2136 static int
2137 samr_dissect_get_alias_membership_reply(tvbuff_t *tvb, int offset, 
2138                              packet_info *pinfo, proto_tree *tree,
2139                              char *drep)
2140 {
2141         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2142                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
2143                         "", hf_samr_alias, 0);
2144         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2145                         hf_samr_rc, NULL);
2146         return offset;
2147 }
2148
2149
2150 static int
2151 samr_dissect_IDX_AND_NAME(tvbuff_t *tvb, int offset, 
2152                              packet_info *pinfo, proto_tree *parent_tree,
2153                              char *drep)
2154 {
2155         proto_item *item=NULL;
2156         proto_tree *tree=NULL;
2157         int old_offset=offset;
2158         char str[256];
2159         dcerpc_info *di;
2160
2161         di=pinfo->private_data;
2162
2163         snprintf(str, 255, "IDX_AND_NAME: %s:",proto_registrar_get_name(di->hf_index));
2164         if(parent_tree){
2165                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2166                                 "%s",str);
2167                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name);
2168         }
2169
2170         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2171                         hf_samr_index, NULL);
2172         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
2173                         tree, drep, di->hf_index, 4);
2174
2175         proto_item_set_len(item, offset-old_offset);
2176         return offset;
2177 }
2178
2179 static int
2180 samr_dissect_IDX_AND_NAME_entry (tvbuff_t *tvb, int offset, 
2181                              packet_info *pinfo, proto_tree *tree,
2182                              char *drep)
2183 {
2184         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2185                         samr_dissect_IDX_AND_NAME);
2186
2187         return offset;
2188 }
2189
2190
2191 static int
2192 samr_dissect_IDX_AND_NAME_ARRAY(tvbuff_t *tvb, int offset, 
2193                         packet_info *pinfo, proto_tree *parent_tree,
2194                         char *drep)
2195 {
2196         char *field_name;
2197         guint32 count;
2198         proto_item *item=NULL;
2199         proto_tree *tree=NULL;
2200         int old_offset=offset;
2201         dcerpc_info *di;
2202         char str[256];
2203
2204         di=pinfo->private_data;
2205
2206         field_name = proto_registrar_get_name(di->hf_index);
2207
2208         if(parent_tree){
2209                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2210                         "IDX_AND_NAME_ARRAY: %s%s:", field_name,
2211                         plural_ending(field_name));
2212                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name_array);
2213         }
2214
2215         
2216         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2217                         hf_samr_count, &count);
2218         snprintf(str, 255, "IDX_AND_NAME pointer: %s%s:", field_name,
2219             plural_ending(field_name));
2220         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2221                         samr_dissect_IDX_AND_NAME_entry, NDR_POINTER_UNIQUE,
2222                         str, di->hf_index, 0);
2223
2224         proto_item_set_len(item, offset-old_offset);
2225         return offset;
2226 }
2227
2228 static int
2229 samr_dissect_IDX_AND_NAME_ARRAY_ptr(tvbuff_t *tvb, int offset, 
2230                         packet_info *pinfo, proto_tree *tree,
2231                         char *drep)
2232 {
2233         char *field_name;
2234         char str[256];
2235         dcerpc_info *di;
2236
2237         di=pinfo->private_data;
2238
2239         field_name = proto_registrar_get_name(di->hf_index);
2240         snprintf(str, 255, "IDX_AND_NAME_ARRAY pointer: %s%s:", field_name,
2241             plural_ending(field_name));
2242         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2243                         samr_dissect_IDX_AND_NAME_ARRAY, NDR_POINTER_UNIQUE,
2244                         str, di->hf_index, 0);
2245         return offset;
2246 }
2247
2248 static int
2249 samr_dissect_enum_domains_rqst(tvbuff_t *tvb, int offset, 
2250                              packet_info *pinfo, proto_tree *tree,
2251                              char *drep)
2252 {
2253         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2254                         hf_samr_hnd, NULL);
2255         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2256                         samr_dissect_pointer_long, NDR_POINTER_REF,
2257                         "", hf_samr_resume_hnd, 0);
2258         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2259                         hf_samr_pref_maxsize, NULL);
2260         return offset;
2261 }
2262
2263 static int
2264 samr_dissect_enum_domains_reply(tvbuff_t *tvb, int offset, 
2265                              packet_info *pinfo, proto_tree *tree,
2266                              char *drep)
2267 {
2268         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2269                         samr_dissect_pointer_long, NDR_POINTER_REF,
2270                         "", hf_samr_resume_hnd, 0);
2271         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2272                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2273                         "", hf_samr_domain, 0);
2274         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2275                         samr_dissect_pointer_long, NDR_POINTER_REF,
2276                         "", hf_samr_entries, 0);
2277         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2278                                      hf_samr_rc, NULL);
2279         return offset;
2280 }
2281
2282 static int
2283 samr_dissect_enum_dom_groups_rqst(tvbuff_t *tvb, int offset, 
2284                              packet_info *pinfo, proto_tree *tree,
2285                              char *drep)
2286 {
2287         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2288                         hf_samr_hnd, NULL);
2289         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2290                         samr_dissect_pointer_long, NDR_POINTER_REF,
2291                         "", hf_samr_resume_hnd, 0);
2292         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2293                         hf_samr_mask, NULL);
2294         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2295                         hf_samr_pref_maxsize, NULL);
2296         return offset;
2297 }
2298
2299 static int
2300 samr_dissect_enum_dom_groups_reply(tvbuff_t *tvb, int offset, 
2301                              packet_info *pinfo, proto_tree *tree,
2302                              char *drep)
2303 {
2304         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2305                         samr_dissect_pointer_long, NDR_POINTER_REF,
2306                         "", hf_samr_resume_hnd, 0);
2307         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2308                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2309                         "", hf_samr_group_name, 0);
2310         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2311                         samr_dissect_pointer_long, NDR_POINTER_REF,
2312                         "", hf_samr_entries, 0);
2313         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2314                         hf_samr_rc, NULL);
2315         return offset;
2316 }
2317
2318 static int
2319 samr_dissect_enum_dom_alias_reply(tvbuff_t *tvb, int offset, 
2320                              packet_info *pinfo, proto_tree *tree,
2321                              char *drep)
2322 {
2323         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2324                         samr_dissect_pointer_long, NDR_POINTER_REF,
2325                         "", hf_samr_resume_hnd, 0);
2326         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2327                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2328                         "", hf_samr_alias_name, 0);
2329         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2330                         samr_dissect_pointer_long, NDR_POINTER_REF,
2331                         "", hf_samr_entries, 0);
2332         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2333                         hf_samr_rc, NULL);
2334         return offset;
2335 }
2336
2337 static int
2338 samr_dissect_get_members_in_alias_reply(tvbuff_t *tvb, int offset, 
2339                         packet_info *pinfo, proto_tree *tree,
2340                         char *drep)
2341 {
2342         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2343                         samr_dissect_PSID_ARRAY, NDR_POINTER_REF,
2344                         "", -1, 0);
2345         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2346                         hf_samr_rc, NULL);
2347
2348         return offset;
2349 }
2350
2351 static int
2352 samr_dissect_LOGON_HOURS_entry(tvbuff_t *tvb, int offset, 
2353                              packet_info *pinfo, proto_tree *tree,
2354                              char *drep)
2355 {
2356         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
2357                         hf_samr_unknown_char, NULL);
2358         return offset;
2359 }
2360
2361 static int
2362 samr_dissect_LOGON_HOURS_hours(tvbuff_t *tvb, int offset, 
2363                              packet_info *pinfo, proto_tree *parent_tree,
2364                              char *drep)
2365 {
2366         proto_item *item=NULL;
2367         proto_tree *tree=NULL;
2368         int old_offset=offset;
2369
2370         if(parent_tree){
2371                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2372                         "LOGON_HOURS:");
2373                 tree = proto_item_add_subtree(item, ett_samr_logon_hours_hours);
2374         }
2375
2376         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
2377                         samr_dissect_LOGON_HOURS_entry);
2378
2379         proto_item_set_len(item, offset-old_offset);
2380         return offset;
2381
2382         return offset;
2383 }
2384
2385 static int
2386 samr_dissect_LOGON_HOURS(tvbuff_t *tvb, int offset, 
2387                         packet_info *pinfo, proto_tree *parent_tree,
2388                         char *drep)
2389 {
2390         proto_item *item=NULL;
2391         proto_tree *tree=NULL;
2392         int old_offset=offset;
2393
2394         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
2395
2396         if(parent_tree){
2397                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2398                         "LOGON_HOURS:");
2399                 tree = proto_item_add_subtree(item, ett_samr_logon_hours);
2400         }
2401
2402         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2403                                 hf_samr_divisions, NULL);
2404         /* XXX - is this a bitmask like the "logon hours" field in the
2405            Remote API call "NetUserGetInfo()" with an information level
2406            of 11? */
2407         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2408                         samr_dissect_LOGON_HOURS_hours, NDR_POINTER_UNIQUE,
2409                         "LOGON_HOURS", -1, 0);
2410
2411         proto_item_set_len(item, offset-old_offset);
2412         return offset;
2413 }
2414
2415
2416 static int
2417 samr_dissect_USER_INFO_1(tvbuff_t *tvb, int offset, 
2418                         packet_info *pinfo, proto_tree *parent_tree,
2419                         char *drep)
2420 {
2421         proto_item *item=NULL;
2422         proto_tree *tree=NULL;
2423         int old_offset=offset;
2424
2425         if(parent_tree){
2426                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2427                         "USER_INFO_1:");
2428                 tree = proto_item_add_subtree(item, ett_samr_user_info_1);
2429         }
2430
2431         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2432                                 hf_samr_acct_name, 0);
2433         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2434                                 hf_samr_full_name, 0);
2435         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2436         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2437                                 hf_samr_home, 0);
2438         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2439                                 hf_samr_script, 0);
2440
2441         proto_item_set_len(item, offset-old_offset);
2442         return offset;
2443 }
2444
2445 static int
2446 samr_dissect_USER_INFO_2(tvbuff_t *tvb, int offset, 
2447                         packet_info *pinfo, proto_tree *parent_tree,
2448                         char *drep)
2449 {
2450         proto_item *item=NULL;
2451         proto_tree *tree=NULL;
2452         int old_offset=offset;
2453
2454         if(parent_tree){
2455                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2456                         "USER_INFO_2:");
2457                 tree = proto_item_add_subtree(item, ett_samr_user_info_2);
2458         }
2459
2460         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2461                                 hf_samr_acct_name, 0);
2462         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2463                                 hf_samr_full_name, 0);
2464         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2465                                 hf_samr_bad_pwd_count, NULL);
2466         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2467                                 hf_samr_logon_count, NULL);
2468
2469         proto_item_set_len(item, offset-old_offset);
2470         return offset;
2471 }
2472
2473 static int
2474 samr_dissect_USER_INFO_3(tvbuff_t *tvb, int offset, 
2475                         packet_info *pinfo, proto_tree *parent_tree,
2476                         char *drep)
2477 {
2478         proto_item *item=NULL;
2479         proto_tree *tree=NULL;
2480         int old_offset=offset;
2481
2482         if(parent_tree){
2483                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2484                         "USER_INFO_3:");
2485                 tree = proto_item_add_subtree(item, ett_samr_user_info_3);
2486         }
2487
2488         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2489                                 hf_samr_acct_name, 0);
2490         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2491                                 hf_samr_full_name, 0);
2492         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2493                                 hf_samr_rid, NULL);
2494         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2495                                 hf_samr_group, NULL);
2496         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2497                                 hf_samr_home, 0);
2498         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2499                                 hf_samr_home_drive, 0);
2500         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2501                                 hf_samr_script, 0);
2502         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2503                                 hf_samr_acct_desc, 0);
2504         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2505                                 hf_samr_workstations, 0);
2506         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2507                                 hf_samr_logon_time);
2508         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2509                                 hf_samr_logoff_time);
2510         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2511                                 hf_samr_pwd_last_set_time);
2512         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2513                                 hf_samr_pwd_can_change_time);
2514         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2515                                 hf_samr_pwd_must_change_time);
2516         offset = samr_dissect_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2517         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2518                                 hf_samr_logon_count, NULL);
2519         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2520                                 hf_samr_bad_pwd_count, NULL);
2521         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2522
2523         proto_item_set_len(item, offset-old_offset);
2524         return offset;
2525 }
2526
2527 static int
2528 samr_dissect_USER_INFO_5(tvbuff_t *tvb, int offset, 
2529                         packet_info *pinfo, proto_tree *parent_tree,
2530                         char *drep)
2531 {
2532         proto_item *item=NULL;
2533         proto_tree *tree=NULL;
2534         int old_offset=offset;
2535
2536         if(parent_tree){
2537                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2538                         "USER_INFO_5:");
2539                 tree = proto_item_add_subtree(item, ett_samr_user_info_5);
2540         }
2541
2542         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2543                                 hf_samr_acct_name, 0);
2544         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2545                                 hf_samr_full_name, 0);
2546         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2547                                 hf_samr_rid, NULL);
2548         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2549                                 hf_samr_group, NULL);
2550         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2551                                 hf_samr_country, NULL);
2552         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2553                                 hf_samr_codepage, NULL);
2554         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2555                                 hf_samr_home, 0);
2556         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2557                                 hf_samr_home_drive, 0);
2558         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2559                                 hf_samr_script, 0);
2560         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2561                                 hf_samr_acct_desc, 0);
2562         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2563                                 hf_samr_workstations, 0);
2564         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2565                                 hf_samr_logon_time);
2566         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2567                                 hf_samr_logoff_time);
2568         offset = samr_dissect_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2569         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2570                                 hf_samr_bad_pwd_count, NULL);
2571         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2572                                 hf_samr_logon_count, NULL);
2573         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2574                                 hf_samr_pwd_last_set_time);
2575         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2576                                 hf_samr_acct_expiry_time);
2577         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2578
2579         proto_item_set_len(item, offset-old_offset);
2580         return offset;
2581 }
2582
2583 static int
2584 samr_dissect_USER_INFO_6(tvbuff_t *tvb, int offset, 
2585                         packet_info *pinfo, proto_tree *parent_tree,
2586                         char *drep)
2587 {
2588         proto_item *item=NULL;
2589         proto_tree *tree=NULL;
2590         int old_offset=offset;
2591
2592         if(parent_tree){
2593                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2594                         "USER_INFO_6:");
2595                 tree = proto_item_add_subtree(item, ett_samr_user_info_6);
2596         }
2597
2598         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2599                                 hf_samr_acct_name, 0);
2600         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2601                                 hf_samr_full_name, 0);
2602
2603         proto_item_set_len(item, offset-old_offset);
2604         return offset;
2605 }
2606
2607 static int
2608 samr_dissect_USER_INFO_18(tvbuff_t *tvb, int offset, 
2609                         packet_info *pinfo, proto_tree *parent_tree,
2610                         char *drep)
2611 {
2612         proto_item *item=NULL;
2613         proto_tree *tree=NULL;
2614         int old_offset=offset;
2615
2616         if(parent_tree){
2617                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2618                         "USER_INFO_18:");
2619                 tree = proto_item_add_subtree(item, ett_samr_user_info_18);
2620         }
2621
2622         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2623         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2624         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2625                         hf_samr_unknown_char, NULL);
2626         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2627                         hf_samr_unknown_char, NULL);
2628         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2629                         hf_samr_unknown_char, NULL);
2630
2631         proto_item_set_len(item, offset-old_offset);
2632         return offset;
2633 }
2634
2635 static int
2636 samr_dissect_USER_INFO_19(tvbuff_t *tvb, int offset, 
2637                         packet_info *pinfo, proto_tree *parent_tree,
2638                         char *drep)
2639 {
2640         proto_item *item=NULL;
2641         proto_tree *tree=NULL;
2642         int old_offset=offset;
2643
2644         if(parent_tree){
2645                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2646                         "USER_INFO_19:");
2647                 tree = proto_item_add_subtree(item, ett_samr_user_info_19);
2648         }
2649
2650         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2651         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2652                                 hf_samr_logon_time);
2653         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2654                                 hf_samr_logoff_time);
2655         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2656                                 hf_samr_bad_pwd_count, NULL);
2657         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2658                                 hf_samr_logon_count, NULL);
2659
2660         proto_item_set_len(item, offset-old_offset);
2661         return offset;
2662 }
2663
2664 static int
2665 samr_dissect_BUFFER_entry(tvbuff_t *tvb, int offset, 
2666                              packet_info *pinfo, proto_tree *tree,
2667                              char *drep)
2668 {
2669         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2670                         hf_samr_unknown_char, NULL);
2671         return offset;
2672 }
2673
2674
2675 static int
2676 samr_dissect_BUFFER_buffer(tvbuff_t *tvb, int offset, 
2677                              packet_info *pinfo, proto_tree *parent_tree,
2678                              char *drep)
2679 {
2680         proto_item *item=NULL;
2681         proto_tree *tree=NULL;
2682         int old_offset=offset;
2683
2684         if(parent_tree){
2685                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2686                         "BUFFER:");
2687                 tree = proto_item_add_subtree(item, ett_samr_buffer_buffer);
2688         }
2689
2690         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2691                         samr_dissect_BUFFER_entry);
2692
2693         proto_item_set_len(item, offset-old_offset);
2694         return offset;
2695
2696         return offset;
2697 }
2698
2699 static int
2700 samr_dissect_BUFFER(tvbuff_t *tvb, int offset, 
2701                         packet_info *pinfo, proto_tree *parent_tree,
2702                         char *drep)
2703 {
2704         proto_item *item=NULL;
2705         proto_tree *tree=NULL;
2706         int old_offset=offset;
2707
2708         if(parent_tree){
2709                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2710                         "BUFFER:");
2711                 tree = proto_item_add_subtree(item, ett_samr_buffer);
2712         }
2713         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2714                                 hf_samr_count, NULL);
2715         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2716                         samr_dissect_BUFFER_buffer, NDR_POINTER_UNIQUE,
2717                         "BUFFER", -1, 0);
2718
2719         proto_item_set_len(item, offset-old_offset);
2720         return offset;
2721 }
2722
2723 static int
2724 samr_dissect_BUFFER_ptr(tvbuff_t *tvb, int offset, 
2725                         packet_info *pinfo, proto_tree *tree,
2726                         char *drep)
2727 {
2728         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2729                         samr_dissect_BUFFER, NDR_POINTER_UNIQUE,
2730                         "BUFFER", -1, 0);
2731         return offset;
2732 }
2733
2734 static int
2735 samr_dissect_USER_INFO_21(tvbuff_t *tvb, int offset, 
2736                         packet_info *pinfo, proto_tree *parent_tree,
2737                         char *drep)
2738 {
2739         proto_item *item=NULL;
2740         proto_tree *tree=NULL;
2741         int old_offset=offset;
2742
2743         if(parent_tree){
2744                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2745                         "USER_INFO_21:");
2746                 tree = proto_item_add_subtree(item, ett_samr_user_info_21);
2747         }
2748
2749         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2750                                 hf_samr_logon_time);
2751         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2752                                 hf_samr_logoff_time);
2753         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2754                                 hf_samr_kickoff_time);
2755         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2756                                 hf_samr_pwd_last_set_time);
2757         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2758                                 hf_samr_pwd_can_change_time);
2759         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2760                                 hf_samr_pwd_must_change_time);
2761         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2762                                 hf_samr_acct_name, 2);
2763         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2764                                 hf_samr_full_name, 0);
2765         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2766                                 hf_samr_home, 0);
2767         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2768                                 hf_samr_home_drive, 0);
2769         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2770                                 hf_samr_script, 0);
2771         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2772                                 hf_samr_profile, 0);
2773         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2774                                 hf_samr_acct_desc, 0);
2775         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2776                                 hf_samr_workstations, 0);
2777         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2778                                 hf_samr_comment, 0);
2779         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2780                                 hf_samr_parameters, 0);
2781         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2782                                 hf_samr_unknown_string, 0);
2783         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2784                                 hf_samr_unknown_string, 0);
2785         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2786                                 hf_samr_unknown_string, 0);
2787         offset = samr_dissect_BUFFER(tvb, offset, pinfo, tree, drep);
2788         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2789                                 hf_samr_rid, NULL);
2790         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2791                                 hf_samr_group, NULL);
2792         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2793         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2794                                 hf_samr_unknown_long, NULL);
2795         offset = samr_dissect_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2796         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2797                                 hf_samr_bad_pwd_count, NULL);
2798         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2799                                 hf_samr_logon_count, NULL);
2800         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2801                                 hf_samr_country, NULL);
2802         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2803                                 hf_samr_codepage, NULL);
2804         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2805                                 hf_samr_nt_pwd_set, NULL);
2806         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2807                                 hf_samr_lm_pwd_set, NULL);
2808         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2809                                 hf_samr_pwd_expired, NULL);
2810         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2811                                 hf_samr_unknown_char, NULL);
2812
2813         proto_item_set_len(item, offset-old_offset);
2814         return offset;
2815 }
2816
2817 static int
2818 samr_dissect_USER_INFO_22(tvbuff_t *tvb, int offset, 
2819                         packet_info *pinfo, proto_tree *parent_tree,
2820                         char *drep)
2821 {
2822         proto_item *item=NULL;
2823         proto_tree *tree=NULL;
2824         int old_offset=offset;
2825
2826         if(parent_tree){
2827                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2828                         "USER_INFO_22:");
2829                 tree = proto_item_add_subtree(item, ett_samr_user_info_22);
2830         }
2831
2832         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
2833         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
2834                         hf_samr_revision, NULL);
2835
2836         proto_item_set_len(item, offset-old_offset);
2837         return offset;
2838 }
2839
2840 static int
2841 samr_dissect_USER_INFO_23(tvbuff_t *tvb, int offset, 
2842                         packet_info *pinfo, proto_tree *parent_tree,
2843                         char *drep)
2844 {
2845         proto_item *item=NULL;
2846         proto_tree *tree=NULL;
2847         int old_offset=offset;
2848
2849         if(parent_tree){
2850                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2851                         "USER_INFO_23:");
2852                 tree = proto_item_add_subtree(item, ett_samr_user_info_23);
2853         }
2854
2855         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
2856         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
2857
2858         proto_item_set_len(item, offset-old_offset);
2859         return offset;
2860 }
2861
2862 static int
2863 samr_dissect_USER_INFO_24(tvbuff_t *tvb, int offset, 
2864                         packet_info *pinfo, proto_tree *parent_tree,
2865                         char *drep)
2866 {
2867         proto_item *item=NULL;
2868         proto_tree *tree=NULL;
2869         int old_offset=offset;
2870
2871         if(parent_tree){
2872                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2873                         "USER_INFO_24:");
2874                 tree = proto_item_add_subtree(item, ett_samr_user_info_24);
2875         }
2876
2877         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
2878         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2879                                 hf_samr_unknown_char, NULL);
2880
2881         proto_item_set_len(item, offset-old_offset);
2882         return offset;
2883 }
2884
2885 static int
2886 samr_dissect_USER_INFO (tvbuff_t *tvb, int offset, 
2887                              packet_info *pinfo, proto_tree *parent_tree,
2888                              char *drep)
2889 {
2890         proto_item *item=NULL;
2891         proto_tree *tree=NULL;
2892         int old_offset=offset;
2893         guint16 level;
2894
2895         if(parent_tree){
2896                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2897                         "USER_INFO:");
2898                 tree = proto_item_add_subtree(item, ett_samr_user_info);
2899         }
2900         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2901                                      hf_samr_level, &level);
2902
2903         switch(level){
2904         case 1: 
2905                 offset = samr_dissect_USER_INFO_1(
2906                                 tvb, offset, pinfo, tree, drep);
2907                 break;
2908         case 2: 
2909                 offset = samr_dissect_USER_INFO_2(
2910                                 tvb, offset, pinfo, tree, drep);
2911                 break;
2912         case 3: 
2913                 offset = samr_dissect_USER_INFO_3(
2914                                 tvb, offset, pinfo, tree, drep);
2915                 break;
2916         case 4: 
2917                 offset = samr_dissect_LOGON_HOURS(
2918                                 tvb, offset, pinfo, tree, drep);
2919                 break;
2920         case 5: 
2921                 offset = samr_dissect_USER_INFO_5(
2922                                 tvb, offset, pinfo, tree, drep);
2923                 break;
2924         case 6: 
2925                 offset = samr_dissect_USER_INFO_6(
2926                                 tvb, offset, pinfo, tree, drep);
2927                 break;
2928         case 7:
2929                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2930                                 hf_samr_full_name, 0);
2931                 break;
2932         case 8:
2933                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2934                                 hf_samr_acct_desc, 0);
2935                 break;
2936         case 9:
2937                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2938                                              hf_samr_unknown_long, NULL);
2939                 break;
2940         case 10:        
2941                 offset = samr_dissect_USER_INFO_6(
2942                                 tvb, offset, pinfo, tree, drep);
2943                 break;
2944         case 11:
2945                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2946                                 hf_samr_home, 0);
2947                 break;
2948         case 12:
2949                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2950                                 hf_samr_home_drive, 0);
2951                 break;
2952         case 13:
2953                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2954                                 hf_samr_script, 0);
2955                 break;
2956         case 14:
2957                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2958                                 hf_samr_workstations, 0);
2959                 break;
2960         case 16:
2961                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2962                                              hf_samr_unknown_long, NULL);
2963                 break;
2964         case 17:
2965                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2966                                         hf_samr_unknown_time);
2967                 break;
2968         case 18:        
2969                 offset = samr_dissect_USER_INFO_18(
2970                                 tvb, offset, pinfo, tree, drep);
2971                 break;
2972         case 19:        
2973                 offset = samr_dissect_USER_INFO_19(
2974                                 tvb, offset, pinfo, tree, drep);
2975                 break;
2976         case 20:
2977                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2978                                 hf_samr_profile, 0);
2979                 break;
2980         case 21:        
2981                 offset = samr_dissect_USER_INFO_21(
2982                                 tvb, offset, pinfo, tree, drep);
2983                 break;
2984         case 22:        
2985                 offset = samr_dissect_USER_INFO_22(
2986                                 tvb, offset, pinfo, tree, drep);
2987                 break;
2988         case 23:        
2989                 offset = samr_dissect_USER_INFO_23(
2990                                 tvb, offset, pinfo, tree, drep);
2991                 break;
2992         case 24:        
2993                 offset = samr_dissect_USER_INFO_24(
2994                                 tvb, offset, pinfo, tree, drep);
2995                 break;
2996         }
2997
2998         proto_item_set_len(item, offset-old_offset);
2999         return offset;
3000 }
3001
3002 static int
3003 samr_dissect_USER_INFO_ptr(tvbuff_t *tvb, int offset, 
3004                         packet_info *pinfo, proto_tree *tree,
3005                         char *drep)
3006 {
3007         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3008                         samr_dissect_USER_INFO, NDR_POINTER_UNIQUE,
3009                         "USER_INFO pointer", -1, 0);
3010         return offset;
3011 }
3012
3013 static int
3014 samr_dissect_set_information_user2_rqst(tvbuff_t *tvb, int offset, 
3015                         packet_info *pinfo, proto_tree *tree,
3016                         char *drep)
3017 {
3018         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3019                         hf_samr_hnd, NULL);
3020         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3021                         hf_samr_level, NULL);
3022         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3023                         samr_dissect_USER_INFO, NDR_POINTER_REF,
3024                         "", -1, 0);
3025
3026         return offset;
3027 }
3028
3029 static int
3030 samr_dissect_query_userinfo_reply(tvbuff_t *tvb, int offset, 
3031                         packet_info *pinfo, proto_tree *tree,
3032                         char *drep)
3033 {
3034         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3035                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
3036                         "", -1, 0);
3037         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3038                         hf_samr_rc, NULL);
3039
3040         return offset;
3041 }
3042
3043 static int
3044 samr_dissect_MEMBER_ARRAY_type(tvbuff_t *tvb, int offset, 
3045                         packet_info *pinfo, proto_tree *tree,
3046                         char *drep)
3047 {
3048         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3049                                 hf_samr_type, NULL);
3050
3051         return offset;
3052 }
3053
3054
3055 static int
3056 samr_dissect_MEMBER_ARRAY_types(tvbuff_t *tvb, int offset, 
3057                         packet_info *pinfo, proto_tree *parent_tree,
3058                         char *drep)
3059 {
3060         proto_item *item=NULL;
3061         proto_tree *tree=NULL;
3062         int old_offset=offset;
3063
3064         if(parent_tree){
3065                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3066                         "MEMBER_ARRAY_types:");
3067                 tree = proto_item_add_subtree(item, ett_samr_member_array_types);
3068         }
3069
3070         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3071                         samr_dissect_MEMBER_ARRAY_type);
3072
3073         proto_item_set_len(item, offset-old_offset);
3074         return offset;
3075
3076         return offset;
3077 }
3078
3079 static int
3080 samr_dissect_MEMBER_ARRAY_rid(tvbuff_t *tvb, int offset, 
3081                         packet_info *pinfo, proto_tree *tree,
3082                         char *drep)
3083 {
3084         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3085                                 hf_samr_rid, NULL);
3086
3087         return offset;
3088 }
3089
3090
3091 static int
3092 samr_dissect_MEMBER_ARRAY_rids(tvbuff_t *tvb, int offset, 
3093                         packet_info *pinfo, proto_tree *parent_tree,
3094                         char *drep)
3095 {
3096         proto_item *item=NULL;
3097         proto_tree *tree=NULL;
3098         int old_offset=offset;
3099
3100         if(parent_tree){
3101                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3102                         "MEMBER_ARRAY_rids:");
3103                 tree = proto_item_add_subtree(item, ett_samr_member_array_rids);
3104         }
3105
3106         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3107                         samr_dissect_MEMBER_ARRAY_rid);
3108
3109         proto_item_set_len(item, offset-old_offset);
3110         return offset;
3111
3112         return offset;
3113 }
3114
3115 static int
3116 samr_dissect_MEMBER_ARRAY(tvbuff_t *tvb, int offset, 
3117                         packet_info *pinfo, proto_tree *parent_tree,
3118                         char *drep)
3119 {
3120         guint32 count;
3121         proto_item *item=NULL;
3122         proto_tree *tree=NULL;
3123         int old_offset=offset;
3124
3125         if(parent_tree){
3126                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3127                         "MEMBER_ARRAY:");
3128                 tree = proto_item_add_subtree(item, ett_samr_member_array);
3129         }
3130
3131         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3132                         hf_samr_count, &count);
3133         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3134                         samr_dissect_MEMBER_ARRAY_rids, NDR_POINTER_UNIQUE,
3135                         "RIDs", -1, 0);
3136         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3137                         samr_dissect_MEMBER_ARRAY_types, NDR_POINTER_UNIQUE,
3138                         "Types", -1, 0);
3139
3140         proto_item_set_len(item, offset-old_offset);
3141         return offset;
3142 }
3143
3144 static int
3145 samr_dissect_MEMBER_ARRAY_ptr(tvbuff_t *tvb, int offset, 
3146                         packet_info *pinfo, proto_tree *tree,
3147                         char *drep)
3148 {
3149         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3150                         samr_dissect_MEMBER_ARRAY, NDR_POINTER_UNIQUE,
3151                         "MEMBER_ARRAY", -1, 0);
3152         return offset;
3153 }
3154
3155 static int
3156 samr_dissect_query_groupmem_reply(tvbuff_t *tvb, int offset, 
3157                         packet_info *pinfo, proto_tree *tree,
3158                         char *drep)
3159 {
3160         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3161                         samr_dissect_MEMBER_ARRAY_ptr, NDR_POINTER_REF,
3162                         "", -1, 0);
3163         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3164                         hf_samr_rc, NULL);
3165
3166         return offset;
3167 }
3168
3169 static int
3170 samr_dissect_set_sec_object_rqst(tvbuff_t *tvb, int offset, 
3171                         packet_info *pinfo, proto_tree *tree,
3172                         char *drep)
3173 {
3174         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3175                         hf_samr_hnd, NULL);
3176         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3177                         hf_samr_info_type, NULL);
3178         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3179                         samr_dissect_BUFFER, NDR_POINTER_REF,
3180                         "", -1, 0);
3181
3182         return offset;
3183 }
3184
3185 static int
3186 samr_dissect_query_sec_object_rqst(tvbuff_t *tvb, int offset, 
3187                         packet_info *pinfo, proto_tree *tree,
3188                         char *drep)
3189 {
3190         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3191                         hf_samr_hnd, NULL);
3192         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3193                         hf_samr_info_type, NULL);
3194
3195         return offset;
3196 }
3197
3198 static int
3199 samr_dissect_query_sec_object_reply(tvbuff_t *tvb, int offset, 
3200                         packet_info *pinfo, proto_tree *tree,
3201                         char *drep)
3202 {
3203         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3204                         samr_dissect_BUFFER_ptr, NDR_POINTER_REF,
3205                         "", -1, 0);
3206         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3207                         hf_samr_rc, NULL);
3208
3209
3210         return offset;
3211 }
3212
3213 static int
3214 samr_dissect_LOOKUP_NAMES_name(tvbuff_t *tvb, int offset, 
3215                         packet_info *pinfo, proto_tree *tree,
3216                         char *drep)
3217 {
3218         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3219                                 hf_samr_acct_name, 1);
3220         return offset;
3221 }
3222
3223 static int
3224 samr_dissect_LOOKUP_NAMES(tvbuff_t *tvb, int offset, 
3225                         packet_info *pinfo, proto_tree *parent_tree,
3226                         char *drep)
3227 {
3228         proto_item *item=NULL;
3229         proto_tree *tree=NULL;
3230         int old_offset=offset;
3231
3232         if(parent_tree){
3233                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3234                         "NAMES:");
3235                 tree = proto_item_add_subtree(item, ett_samr_names);
3236         }
3237
3238         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3239                         samr_dissect_LOOKUP_NAMES_name);
3240
3241         proto_item_set_len(item, offset-old_offset);
3242         return offset;
3243 }
3244
3245
3246 static int
3247 samr_dissect_lookup_names_rqst(tvbuff_t *tvb, int offset, 
3248                         packet_info *pinfo, proto_tree *tree,
3249                         char *drep)
3250 {
3251         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3252                         hf_samr_hnd, NULL);
3253         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3254                         hf_samr_count, NULL);
3255         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3256                         samr_dissect_LOOKUP_NAMES, NDR_POINTER_REF,
3257                         "", -1, 0);
3258
3259         return offset;
3260 }
3261
3262 static int
3263 samr_dissect_lookup_names_reply(tvbuff_t *tvb, int offset, 
3264                         packet_info *pinfo, proto_tree *tree,
3265                         char *drep)
3266 {
3267         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3268                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3269                         "", hf_samr_rid, 0);
3270         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3271                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3272                         "", hf_samr_type, 0);
3273         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3274                         hf_samr_rc, NULL);
3275
3276         return offset;
3277 }
3278
3279 static int
3280 samr_dissect_LOOKUP_RIDS_rid(tvbuff_t *tvb, int offset, 
3281                         packet_info *pinfo, proto_tree *tree,
3282                         char *drep)
3283 {
3284         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3285                                 hf_samr_rid, NULL);
3286
3287         return offset;
3288 }
3289
3290 static int
3291 samr_dissect_LOOKUP_RIDS(tvbuff_t *tvb, int offset, 
3292                         packet_info *pinfo, proto_tree *parent_tree,
3293                         char *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                         "RIDS:");
3302                 tree = proto_item_add_subtree(item, ett_samr_rids);
3303         }
3304
3305         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3306                         samr_dissect_LOOKUP_RIDS_rid);
3307
3308         proto_item_set_len(item, offset-old_offset);
3309         return offset;
3310 }
3311
3312
3313 static int
3314 samr_dissect_lookup_rids_rqst(tvbuff_t *tvb, int offset, 
3315                         packet_info *pinfo, proto_tree *tree,
3316                         char *drep)
3317 {
3318         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3319                         hf_samr_hnd, NULL);
3320         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3321                         hf_samr_count, NULL);
3322         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3323                         samr_dissect_LOOKUP_RIDS, NDR_POINTER_REF,
3324                         "", -1, 0);
3325
3326         return offset;
3327 }
3328
3329 static int
3330 samr_dissect_UNICODE_STRING_ARRAY_name(tvbuff_t *tvb, int offset, 
3331                         packet_info *pinfo, proto_tree *tree,
3332                         char *drep)
3333 {
3334         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3335                                 hf_samr_acct_name, 0);
3336         return offset;
3337 }
3338
3339 static int
3340 samr_dissect_UNICODE_STRING_ARRAY_names(tvbuff_t *tvb, int offset, 
3341                         packet_info *pinfo, proto_tree *tree,
3342                         char *drep)
3343 {
3344         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3345                         samr_dissect_UNICODE_STRING_ARRAY_name);
3346         return offset;
3347 }
3348
3349 static int
3350 samr_dissect_UNICODE_STRING_ARRAY(tvbuff_t *tvb, int offset, 
3351                         packet_info *pinfo, proto_tree *parent_tree,
3352                         char *drep)
3353 {
3354         proto_item *item=NULL;
3355         proto_tree *tree=NULL;
3356         int old_offset=offset;
3357
3358         if(parent_tree){
3359                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3360                         "NAMES:");
3361                 tree = proto_item_add_subtree(item, ett_samr_names);
3362         }
3363
3364         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3365                         hf_samr_count, NULL);
3366
3367         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3368                         samr_dissect_UNICODE_STRING_ARRAY_names, NDR_POINTER_UNIQUE,
3369                         "Strings", -1, 0);
3370
3371         proto_item_set_len(item, offset-old_offset);
3372         return offset;
3373
3374         return offset;
3375 }
3376
3377
3378 static int
3379 samr_dissect_lookup_rids_reply(tvbuff_t *tvb, int offset, 
3380                         packet_info *pinfo, proto_tree *tree,
3381                         char *drep)
3382 {
3383         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3384                         samr_dissect_UNICODE_STRING_ARRAY, NDR_POINTER_REF,
3385                         "", hf_samr_rid, 0);
3386         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3387                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3388                         "", hf_samr_type, 0);
3389         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3390                         hf_samr_rc, NULL);
3391
3392         return offset;
3393 }
3394
3395
3396
3397 static dcerpc_sub_dissector dcerpc_samr_dissectors[] = {
3398         { SAMR_CONNECT_ANON, "CONNECT_ANON",
3399                 samr_dissect_connect2_rqst,
3400                 samr_dissect_context_handle_reply },
3401         { SAMR_CLOSE_HND, "CLOSE_HND",
3402                 samr_dissect_context_handle,
3403                 samr_dissect_context_handle_reply },
3404         { SAMR_SET_SEC_OBJECT, "SET_SEC_OBJECT",
3405                 samr_dissect_set_sec_object_rqst,
3406                 samr_dissect_rc },
3407         { SAMR_QUERY_SEC_OBJECT, "QUERY_SEC_OBJECT", 
3408                 samr_dissect_query_sec_object_rqst,
3409                 samr_dissect_query_sec_object_reply },
3410         { SAMR_SHUTDOWN_SAM_SERVER, "SHUTDOWN_SAM_SERVER",
3411                 samr_dissect_context_handle,
3412                 samr_dissect_rc },
3413         { SAMR_LOOKUP_DOMAIN, "LOOKUP_DOMAIN",
3414                 samr_dissect_lookup_domain_rqst,
3415                 samr_dissect_lookup_domain_reply },
3416         { SAMR_ENUM_DOMAINS, "ENUM_DOMAINS",
3417                 samr_dissect_enum_domains_rqst,
3418                 samr_dissect_enum_domains_reply },
3419         { SAMR_OPEN_DOMAIN, "OPEN_DOMAIN",
3420                 samr_dissect_open_domain_rqst,
3421                 samr_dissect_open_domain_reply },
3422         { SAMR_QUERY_DOMAIN_INFO, "QUERY_INFORMATION_DOMAIN",
3423                 samr_dissect_query_information_alias_rqst,
3424                 samr_dissect_query_information_domain_reply },
3425         { SAMR_SET_DOMAIN_INFO, "SET_INFORMATION_DOMAIN",
3426                 samr_dissect_set_information_domain_rqst,
3427                 samr_dissect_rc },
3428         { SAMR_CREATE_DOM_GROUP, "CREATE_GROUP_IN_DOMAIN",
3429                 samr_dissect_create_alias_in_domain_rqst,
3430                 samr_dissect_create_alias_in_domain_reply },
3431         { SAMR_ENUM_DOM_GROUPS, "ENUM_DOM_GROUPS",
3432                 samr_dissect_enum_dom_groups_rqst,
3433                 samr_dissect_enum_dom_groups_reply },
3434         { SAMR_CREATE_USER_IN_DOMAIN, "CREATE_USER_IN_DOMAIN",
3435                 samr_dissect_create_alias_in_domain_rqst,
3436                 samr_dissect_create_alias_in_domain_reply },
3437         { SAMR_ENUM_DOM_USERS, "ENUM_DOM_USERS",
3438                 samr_dissect_enum_dom_groups_rqst,
3439                 samr_dissect_enum_dom_groups_reply },
3440         { SAMR_CREATE_DOM_ALIAS, "CREATE_ALIAS_IN_DOMAIN",
3441                 samr_dissect_create_alias_in_domain_rqst,
3442                 samr_dissect_create_alias_in_domain_reply },
3443         { SAMR_ENUM_DOM_ALIASES, "ENUM_DOM_ALIASES",
3444                 samr_dissect_enum_dom_groups_rqst,
3445                 samr_dissect_enum_dom_alias_reply },
3446         { SAMR_GET_ALIAS_MEMBERSHIP, "GET_ALIAS_MEMBERSHIP",
3447                 samr_dissect_get_alias_membership_rqst,
3448                 samr_dissect_get_alias_membership_reply },
3449         { SAMR_LOOKUP_NAMES, "LOOKUP_NAMES", 
3450                 samr_dissect_lookup_names_rqst,
3451                 samr_dissect_lookup_names_reply },
3452         { SAMR_LOOKUP_RIDS, "LOOKUP_RIDS",
3453                 samr_dissect_lookup_rids_rqst,
3454                 samr_dissect_lookup_rids_reply },
3455         { SAMR_OPEN_GROUP, "OPEN_GROUP",
3456                 samr_dissect_open_user_rqst,
3457                 samr_dissect_context_handle_reply },
3458         { SAMR_QUERY_GROUPINFO, "QUERY_INFORMATION_GROUP",
3459                 samr_dissect_query_information_group_rqst,
3460                 samr_dissect_query_information_group_reply },
3461         { SAMR_SET_GROUPINFO, "SET_INFORMATION_GROUP",
3462                 samr_dissect_set_information_group_rqst,
3463                 samr_dissect_rc },
3464         { SAMR_ADD_GROUPMEM, "ADD_MEMBER_TO_GROUP",
3465                 samr_dissect_add_member_to_group_rqst,
3466                 samr_dissect_rc },
3467         { SAMR_DELETE_DOM_GROUP, "DELETE_DOM_GROUP",
3468                 samr_dissect_context_handle,
3469                 samr_dissect_rc },
3470         { SAMR_DEL_GROUPMEM, "REMOVE_MEMBER_FROM_GROUP",
3471                 samr_dissect_add_member_to_group_rqst,
3472                 samr_dissect_rc },
3473         { SAMR_QUERY_GROUPMEM, "QUERY_GROUPMEM",
3474                 samr_dissect_context_handle,
3475                 samr_dissect_query_groupmem_reply },
3476         { SAMR_SET_MEMBER_ATTRIBUTES_OF_GROUP, "SET_MEMBER_ATTRIBUTES_OF_GROUP",
3477                 samr_dissect_set_member_attributes_of_group_rqst,
3478                 samr_dissect_rc },
3479         { SAMR_OPEN_ALIAS, "OPEN_ALIAS",
3480                 samr_dissect_open_user_rqst,
3481                 samr_dissect_context_handle_reply },
3482         { SAMR_QUERY_ALIASINFO, "QUERY_INFORMATION_ALIAS",
3483                 samr_dissect_query_information_alias_rqst,
3484                 samr_dissect_query_information_alias_reply },
3485         { SAMR_SET_ALIASINFO, "SET_INFORMATION_ALIAS",
3486                 samr_dissect_set_information_alias_rqst,
3487                 samr_dissect_rc },
3488         { SAMR_DELETE_DOM_ALIAS, "DELETE_DOM_ALIAS",
3489                 samr_dissect_context_handle,
3490                 samr_dissect_rc },
3491         { SAMR_ADD_ALIASMEM, "ADD_MEMBER_TO_ALIAS",
3492                 samr_dissect_context_handle_SID,
3493                 samr_dissect_rc },
3494         { SAMR_DEL_ALIASMEM, "REMOVE_MEMBER_FROM_ALIAS",
3495                 samr_dissect_context_handle_SID,
3496                 samr_dissect_rc },
3497         { SAMR_GET_MEMBERS_IN_ALIAS, "GET_MEMBERS_IN_ALIAS",
3498                 samr_dissect_context_handle,
3499                 samr_dissect_get_members_in_alias_reply },
3500         { SAMR_OPEN_USER, "OPEN_USER", 
3501                 samr_dissect_open_user_rqst, 
3502                 samr_dissect_context_handle_reply },
3503         { SAMR_DELETE_DOM_USER, "DELETE_DOM_USER",
3504                 samr_dissect_context_handle,
3505                 samr_dissect_rc },
3506         { SAMR_QUERY_USERINFO, "QUERY_USERINFO",
3507                 samr_dissect_query_information_alias_rqst,
3508                 samr_dissect_query_userinfo_reply },
3509         { SAMR_SET_USERINFO2, "SET_USERINFO2",
3510                 samr_dissect_set_information_user2_rqst,
3511                 samr_dissect_rc },
3512         { SAMR_CHANGE_PASSWORD_USER, "CHANGE_PASSWORD_USER",
3513                 samr_dissect_change_password_user_rqst,
3514                 samr_dissect_rc },
3515         { SAMR_GET_GROUPS_FOR_USER, "GET_GROUPS_FOR_USER",
3516                 samr_dissect_context_handle,
3517                 samr_dissect_get_groups_for_user_reply },
3518         { SAMR_QUERY_DISPINFO, "QUERY_DISPINFO", 
3519                 samr_dissect_query_dispinfo_rqst, 
3520                 samr_dissect_query_dispinfo_reply },
3521         { SAMR_GET_DISPLAY_ENUMERATION_INDEX, "GET_DISPLAY_ENUMERATION_INDEX", 
3522                 samr_dissect_get_display_enumeration_index_rqst, 
3523                 samr_dissect_get_display_enumeration_index_reply },
3524         { SAMR_TEST_PRIVATE_FUNCTIONS_DOMAIN, "TEST_PRIVATE_FUNCTIONS_DOMAIN",
3525                 samr_dissect_context_handle,
3526                 samr_dissect_rc },
3527         { SAMR_TEST_PRIVATE_FUNCTIONS_USER, "TEST_PRIVATE_FUNCTIONS_USER",
3528                 samr_dissect_context_handle,
3529                 samr_dissect_rc },
3530         { SAMR_GET_USRDOM_PWINFO, "GET_USRDOM_PWINFO",
3531                 samr_dissect_context_handle,
3532                 samr_dissect_get_usrdom_pwinfo_reply },
3533         { SAMR_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN, "REMOVE_MEMBER_FROM_FOREIGN_DOMAIN",
3534                 samr_dissect_context_handle_SID,
3535                 samr_dissect_rc },
3536         { SAMR_QUERY_INFORMATION_DOMAIN2, "QUERY_INFORMATION_DOMAIN2",
3537                 samr_dissect_query_information_alias_rqst,
3538                 samr_dissect_query_information_domain_reply },
3539         { SAMR_UNKNOWN_2f, "UNKNOWN_2f",
3540                 samr_dissect_query_information_alias_rqst,
3541                 samr_dissect_query_userinfo_reply },
3542         { SAMR_QUERY_DISPINFO2, "QUERY_INFORMATION_DISPLAY2",
3543                 samr_dissect_query_dispinfo_rqst,
3544                 samr_dissect_query_dispinfo_reply },
3545         { SAMR_GET_DISPLAY_ENUMERATION_INDEX2, "GET_DISPLAY_ENUMERATION_INDEX2",
3546                 samr_dissect_get_display_enumeration_index2_rqst,
3547                 samr_dissect_get_display_enumeration_index2_reply },
3548         { SAMR_CREATE_USER2_IN_DOMAIN, "CREATE_USER2_IN_DOMAIN",
3549                 samr_dissect_create_user2_in_domain_rqst,
3550                 samr_dissect_create_user2_in_domain_reply },
3551         { SAMR_QUERY_DISPINFO3, "QUERY_INFORMATION_DISPLAY3",
3552                 samr_dissect_query_dispinfo_rqst,
3553                 samr_dissect_query_dispinfo_reply },
3554         { SAMR_ADD_MULTIPLE_MEMBERS_TO_ALIAS, "ADD_MULTIPLE_MEMBERS_TO_ALIAS",
3555                 samr_dissect_get_alias_membership_rqst,
3556                 samr_dissect_rc },
3557         { SAMR_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS, "REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS",
3558                 samr_dissect_get_alias_membership_rqst,
3559                 samr_dissect_rc },
3560         { SAMR_OEM_CHANGE_PASSWORD_USER2, "OEM_CHANGE_PASSWORD_USER2",
3561                 samr_dissect_oem_change_password_user2_rqst,
3562                 samr_dissect_rc },
3563         { SAMR_UNICODE_CHANGE_PASSWORD_USER2, "UNICODE_CHANGE_PASSWORD_USER2",
3564                 samr_dissect_unicode_change_password_user2_rqst,
3565                 samr_dissect_rc },
3566         { SAMR_GET_DOM_PWINFO, "GET_DOMAIN_PASSWORD_INFORMATION",
3567                 samr_dissect_get_domain_password_information_rqst,
3568                 samr_dissect_get_usrdom_pwinfo_reply },
3569        { SAMR_CONNECT2, "CONNECT2", 
3570                 samr_dissect_connect2_rqst,
3571                 samr_dissect_connect2_reply },
3572         { SAMR_SET_USERINFO, "SET_USERINFO",
3573                 samr_dissect_set_information_user2_rqst,
3574                 samr_dissect_rc },
3575         { SAMR_UNKNOWN_3B, "UNKNOWN_3B",
3576                 samr_dissect_unknown_3b_rqst,
3577                 samr_dissect_rc },
3578         { SAMR_UNKNOWN_3C, "SAMR_UNKNOWN_3C", 
3579                 samr_dissect_context_handle,
3580                 samr_dissect_unknown_3c_reply },
3581         {0, NULL, NULL,  NULL },
3582 };
3583
3584 void 
3585 proto_register_dcerpc_samr(void)
3586 {
3587         static hf_register_info hf[] = {
3588                 { &hf_samr_hnd,
3589                   { "Context Handle", "samr.hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
3590                 { &hf_samr_group,
3591                   { "Group", "samr.group", FT_UINT32, BASE_DEC, NULL, 0x0, "Group", HFILL }},
3592                 { &hf_samr_rid,
3593                   { "Rid", "samr.rid", FT_UINT32, BASE_DEC, NULL, 0x0, "RID", HFILL }},
3594                 { &hf_samr_type,
3595                   { "Type", "samr.type", FT_UINT32, BASE_HEX, NULL, 0x0, "Type", HFILL }},
3596                 { &hf_samr_alias,
3597                   { "Alias", "samr.alias", FT_UINT32, BASE_HEX, NULL, 0x0, "Alias", HFILL }},
3598                 { &hf_samr_rid_attrib,
3599                   { "Rid Attrib", "samr.rid.attrib", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
3600                 { &hf_samr_attrib,
3601                   { "Attributes", "samr.attr", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
3602                 { &hf_samr_rc,
3603                   { "Return code", "samr.rc", FT_UINT32, BASE_HEX, VALS (NT_errors), 0x0, "", HFILL }},
3604
3605         { &hf_samr_level,
3606                 { "Level", "samr.level", FT_UINT16, BASE_DEC, 
3607                 NULL, 0x0, "Level requested/returned for Information", HFILL }},
3608         { &hf_samr_start_idx,
3609                 { "Start Idx", "samr.start_idx", FT_UINT32, BASE_DEC, 
3610                 NULL, 0x0, "Start Index for returned Information", HFILL }},
3611
3612         { &hf_samr_entries,
3613                 { "Entries", "samr.entries", FT_UINT32, BASE_DEC, 
3614                 NULL, 0x0, "Number of entries to return", HFILL }},
3615
3616         { &hf_samr_max_entries,
3617                 { "Max Entries", "samr.max_entries", FT_UINT32, BASE_DEC, 
3618                 NULL, 0x0, "Maximum number of entries", HFILL }},
3619
3620         { &hf_samr_pref_maxsize,
3621                 { "Pref MaxSize", "samr.pref_maxsize", FT_UINT32, BASE_DEC, 
3622                 NULL, 0x0, "Maximum Size of data to return", HFILL }},
3623
3624         { &hf_samr_total_size,
3625                 { "Total Size", "samr.total_size", FT_UINT32, BASE_DEC, 
3626                 NULL, 0x0, "Total size of data", HFILL }},
3627
3628         { &hf_samr_bad_pwd_count,
3629                 { "Bad Pwd Count", "samr.bad_pwd_count", FT_UINT16, BASE_DEC, 
3630                 NULL, 0x0, "Number of bad pwd entries for this user", HFILL }},
3631
3632         { &hf_samr_logon_count,
3633                 { "Logon Count", "samr.logon_count", FT_UINT16, BASE_DEC, 
3634                 NULL, 0x0, "Number of logons for this user", HFILL }},
3635
3636         { &hf_samr_ret_size,
3637                 { "Returned Size", "samr.ret_size", FT_UINT32, BASE_DEC, 
3638                 NULL, 0x0, "Number of returned objects in this PDU", HFILL }},
3639
3640         { &hf_samr_index,
3641