Rename samr_dissect_LOGON_HOURS() to dissect_ndr_nt_LOGON_HOURS() and
[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.22 2002/03/11 00:00:15 sahlberg 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 static int
277 samr_dissect_SID(tvbuff_t *tvb, int offset, 
278                         packet_info *pinfo, proto_tree *tree, 
279                         char *drep)
280 {
281         dcerpc_info *di;
282
283         di=pinfo->private_data;
284         if(di->conformant_run){
285                 /* just a run to handle conformant arrays, no scalars to dissect */
286                 return offset;
287         }
288
289         /* the SID contains a conformant array, first we must eat
290            the 4-byte max_count before we can hand it off */
291         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
292                         hf_samr_count, NULL);
293
294         offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Domain");
295         return offset;
296 }
297
298 static int
299 samr_dissect_SID_ptr(tvbuff_t *tvb, int offset, 
300                         packet_info *pinfo, proto_tree *tree, 
301                         char *drep)
302 {
303         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
304                         samr_dissect_SID, NDR_POINTER_UNIQUE,
305                         "SID pointer", -1, 1);
306         return offset;
307 }
308
309
310
311 static const true_false_string tfs_nt_acb_disabled = {
312         "Account is DISABLED",
313         "Account is NOT disabled"
314 };
315 static const true_false_string tfs_nt_acb_homedirreq = {
316         "Homedir is REQUIRED",
317         "Homedir is NOT required"
318 };
319 static const true_false_string tfs_nt_acb_pwnotreq = {
320         "Password is NOT required",
321         "Password is REQUIRED"
322 };
323 static const true_false_string tfs_nt_acb_tempdup = {
324         "This is a TEMPORARY DUPLICATE account",
325         "This is NOT a temporary duplicate account"
326 };
327 static const true_false_string tfs_nt_acb_normal = {
328         "This is a NORMAL USER account",
329         "This is NOT a normal user account"
330 };
331 static const true_false_string tfs_nt_acb_mns = {
332         "This is a MNS account",
333         "This is NOT a mns account"
334 };
335 static const true_false_string tfs_nt_acb_domtrust = {
336         "This is a DOMAIN TRUST account",
337         "This is NOT a domain trust account"
338 };
339 static const true_false_string tfs_nt_acb_wstrust = {
340         "This is a WORKSTATION TRUST account",
341         "This is NOT a workstation trust account"
342 };
343 static const true_false_string tfs_nt_acb_svrtrust = {
344         "This is a SERVER TRUST account",
345         "This is NOT a server trust account"
346 };
347 static const true_false_string tfs_nt_acb_pwnoexp = {
348         "Passwords does NOT expire",
349         "Password will EXPIRE"
350 };
351 static const true_false_string tfs_nt_acb_autolock = {
352         "This account has been AUTO LOCKED",
353         "This account has NOT been auto locked"
354 };
355 int
356 dissect_ndr_nt_acct_ctrl(tvbuff_t *tvb, int offset, packet_info *pinfo, 
357                         proto_tree *parent_tree, char *drep)
358 {
359         guint32 mask;
360         proto_item *item = NULL;
361         proto_tree *tree = NULL;
362
363         offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
364                         hf_nt_acct_ctrl, &mask);
365
366         if(parent_tree){
367                 item = proto_tree_add_uint(parent_tree, hf_nt_acct_ctrl,
368                         tvb, offset-4, 4, mask);
369                 tree = proto_item_add_subtree(item, ett_nt_acct_ctrl);
370         }
371
372         proto_tree_add_boolean(tree, hf_nt_acb_autolock,
373                 tvb, offset-4, 4, mask);
374         proto_tree_add_boolean(tree, hf_nt_acb_pwnoexp,
375                 tvb, offset-4, 4, mask);
376         proto_tree_add_boolean(tree, hf_nt_acb_svrtrust,
377                 tvb, offset-4, 4, mask);
378         proto_tree_add_boolean(tree, hf_nt_acb_wstrust,
379                 tvb, offset-4, 4, mask);
380         proto_tree_add_boolean(tree, hf_nt_acb_domtrust,
381                 tvb, offset-4, 4, mask);
382         proto_tree_add_boolean(tree, hf_nt_acb_mns,
383                 tvb, offset-4, 4, mask);
384         proto_tree_add_boolean(tree, hf_nt_acb_normal,
385                 tvb, offset-4, 4, mask);
386         proto_tree_add_boolean(tree, hf_nt_acb_tempdup,
387                 tvb, offset-4, 4, mask);
388         proto_tree_add_boolean(tree, hf_nt_acb_pwnotreq,
389                 tvb, offset-4, 4, mask);
390         proto_tree_add_boolean(tree, hf_nt_acb_homedirreq,
391                 tvb, offset-4, 4, mask);
392         proto_tree_add_boolean(tree, hf_nt_acb_disabled,
393                 tvb, offset-4, 4, mask);
394
395         return offset;
396 }
397
398
399 /* above this line, just some general support routines which should be placed
400    in some more generic file common to all NT services dissectors
401 */
402
403 static int
404 samr_dissect_context_handle_reply(tvbuff_t *tvb, int offset, 
405                         packet_info *pinfo, proto_tree *tree, 
406                         char *drep)
407 {
408         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
409                         hf_samr_hnd, NULL);
410         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
411                         hf_samr_rc, NULL);
412
413         return offset;
414 }
415
416
417 static int
418 samr_dissect_open_user_rqst(tvbuff_t *tvb, int offset, 
419                         packet_info *pinfo, proto_tree *tree, 
420                         char *drep)
421 {
422         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
423                         hf_samr_hnd, NULL);
424         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
425                         hf_samr_access, NULL);
426         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
427                         hf_samr_rid, NULL);
428
429         return offset;
430 }
431
432 static int
433 samr_dissect_pointer_long(tvbuff_t *tvb, int offset, 
434                              packet_info *pinfo, proto_tree *tree, 
435                              char *drep)
436 {
437         dcerpc_info *di;
438
439         di=pinfo->private_data;
440         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
441                                      di->hf_index, NULL);
442         return offset;
443 }
444
445 static int
446 samr_dissect_pointer_STRING(tvbuff_t *tvb, int offset, 
447                              packet_info *pinfo, proto_tree *tree, 
448                              char *drep)
449 {
450         dcerpc_info *di;
451
452         di=pinfo->private_data;
453         if(di->conformant_run){
454                 /*just a run to handle conformant arrays, nothing to dissect */
455                 return offset;
456         }
457
458         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
459                         di->hf_index);
460         return offset;
461 }
462
463 static int
464 samr_dissect_pointer_UNICODE_STRING(tvbuff_t *tvb, int offset, 
465                              packet_info *pinfo, proto_tree *tree, 
466                              char *drep)
467 {
468         dcerpc_info *di;
469
470         di=pinfo->private_data;
471         if(di->conformant_run){
472                 /*just a run to handle conformant arrays, nothing to dissect */
473                 return offset;
474         }
475
476         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
477                         di->hf_index, di->levels);
478         return offset;
479 }
480
481 static int
482 samr_dissect_pointer_short(tvbuff_t *tvb, int offset, 
483                              packet_info *pinfo, proto_tree *tree, 
484                              char *drep)
485 {
486         dcerpc_info *di;
487
488         di=pinfo->private_data;
489         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
490                                      di->hf_index, NULL);
491         return offset;
492 }
493
494
495 static int
496 samr_dissect_query_dispinfo_rqst (tvbuff_t *tvb, int offset, 
497                              packet_info *pinfo, proto_tree *tree, 
498                              char *drep)
499 {
500         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
501                                       hf_samr_hnd, NULL);
502         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
503                                      hf_samr_level, NULL);
504         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
505                                      hf_samr_start_idx, NULL);
506         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
507                                      hf_samr_max_entries, NULL);
508         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
509                                      hf_samr_pref_maxsize, NULL);
510         return offset;
511 }
512
513 static int
514 samr_dissect_USER_DISPINFO_1(tvbuff_t *tvb, int offset, 
515                         packet_info *pinfo, proto_tree *parent_tree, 
516                         char *drep)
517 {
518         proto_item *item=NULL;
519         proto_tree *tree=NULL;
520         int old_offset=offset;
521
522         if(parent_tree){
523                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
524                         "User_DispInfo_1");
525                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
526         }
527
528         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
529                                 hf_samr_index, NULL);
530         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
531                                 hf_samr_rid, NULL);
532         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
533         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
534                                 hf_samr_acct_name, 0);
535         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
536                                 hf_samr_full_name, 0);
537         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
538                                 hf_samr_acct_desc, 0);
539
540         proto_item_set_len(item, offset-old_offset);
541         return offset;
542 }
543
544 static int
545 samr_dissect_USER_DISPINFO_1_ARRAY_users(tvbuff_t *tvb, int offset, 
546                         packet_info *pinfo, proto_tree *tree, 
547                         char *drep)
548 {
549         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
550                         samr_dissect_USER_DISPINFO_1);
551
552         return offset;
553 }
554
555 static int
556 samr_dissect_USER_DISPINFO_1_ARRAY (tvbuff_t *tvb, int offset, 
557                              packet_info *pinfo, proto_tree *parent_tree, 
558                              char *drep)
559 {
560         guint32 count;
561         proto_item *item=NULL;
562         proto_tree *tree=NULL;
563         int old_offset=offset;
564
565         if(parent_tree){
566                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
567                         "User_DispInfo_1 Array");
568                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1_array);
569         }
570
571
572         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
573                                      hf_samr_count, &count);
574         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
575                         samr_dissect_USER_DISPINFO_1_ARRAY_users, NDR_POINTER_PTR,
576                         "USER_DISPINFO_1_ARRAY", -1, 0);
577
578         proto_item_set_len(item, offset-old_offset);
579         return offset;
580 }
581
582
583
584 static int
585 samr_dissect_USER_DISPINFO_2(tvbuff_t *tvb, int offset, 
586                         packet_info *pinfo, proto_tree *parent_tree, 
587                         char *drep)
588 {
589         proto_item *item=NULL;
590         proto_tree *tree=NULL;
591         int old_offset=offset;
592
593         if(parent_tree){
594                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
595                         "User_DispInfo_2");
596                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2);
597         }
598
599         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
600                         hf_samr_index, NULL);
601         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
602                         hf_samr_rid, NULL);
603         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
604         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
605                         hf_samr_acct_name, 0);
606         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
607                         hf_samr_acct_desc, 0);
608
609         proto_item_set_len(item, offset-old_offset);
610         return offset;
611 }
612
613 static int
614 samr_dissect_USER_DISPINFO_2_ARRAY_users (tvbuff_t *tvb, int offset, 
615                              packet_info *pinfo, proto_tree *tree, 
616                              char *drep)
617 {
618         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
619                         samr_dissect_USER_DISPINFO_2);
620
621         return offset;
622 }
623
624 static int
625 samr_dissect_USER_DISPINFO_2_ARRAY (tvbuff_t *tvb, int offset, 
626                              packet_info *pinfo, proto_tree *parent_tree, 
627                              char *drep)
628 {
629         guint32 count;
630         proto_item *item=NULL;
631         proto_tree *tree=NULL;
632         int old_offset=offset;
633
634         if(parent_tree){
635                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
636                         "User_DispInfo_2 Array");
637                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2_array);
638         }
639
640
641         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
642                                      hf_samr_count, &count);
643         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
644                         samr_dissect_USER_DISPINFO_2_ARRAY_users, NDR_POINTER_PTR,
645                         "USER_DISPINFO_2_ARRAY", -1, 0);
646
647         proto_item_set_len(item, offset-old_offset);
648         return offset;
649 }
650
651
652
653
654
655 static int
656 samr_dissect_GROUP_DISPINFO(tvbuff_t *tvb, int offset, 
657                         packet_info *pinfo, proto_tree *parent_tree, 
658                         char *drep)
659 {
660         proto_item *item=NULL;
661         proto_tree *tree=NULL;
662         int old_offset=offset;
663
664         if(parent_tree){
665                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
666                         "Group_DispInfo");
667                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo);
668         }
669
670         
671         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
672                         hf_samr_index, NULL);
673         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
674                         hf_samr_rid, NULL);
675         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
676         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
677                         hf_samr_acct_name, 0);
678         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
679                         hf_samr_acct_desc, 0);
680
681         proto_item_set_len(item, offset-old_offset);
682         return offset;
683 }
684
685 static int
686 samr_dissect_GROUP_DISPINFO_ARRAY_groups(tvbuff_t *tvb, int offset, 
687                         packet_info *pinfo, proto_tree *tree, 
688                         char *drep)
689 {
690         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
691                         samr_dissect_GROUP_DISPINFO);
692
693         return offset;
694 }
695
696 static int
697 samr_dissect_GROUP_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
698                         packet_info *pinfo, proto_tree *parent_tree, 
699                         char *drep)
700 {
701         guint32 count;
702         proto_item *item=NULL;
703         proto_tree *tree=NULL;
704         int old_offset=offset;
705
706         if(parent_tree){
707                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
708                         "Group_DispInfo Array");
709                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo_array);
710         }
711
712         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
713                                      hf_samr_count, &count);
714         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
715                         samr_dissect_GROUP_DISPINFO_ARRAY_groups, NDR_POINTER_PTR,
716                         "GROUP_DISPINFO_ARRAY", -1, 0);
717
718         proto_item_set_len(item, offset-old_offset);
719         return offset;
720 }
721
722
723
724 static int
725 samr_dissect_ASCII_DISPINFO(tvbuff_t *tvb, int offset, 
726                         packet_info *pinfo, proto_tree *parent_tree, 
727                         char *drep)
728 {
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                         "Ascii_DispInfo");
736                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo);
737         }
738
739         
740         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
741                         hf_samr_index, NULL);
742         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
743                         hf_samr_rid, NULL);
744         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
745         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
746                         hf_samr_acct_name);
747         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
748                         hf_samr_acct_desc);
749
750         proto_item_set_len(item, offset-old_offset);
751         return offset;
752 }
753
754 static int
755 samr_dissect_ASCII_DISPINFO_ARRAY_users(tvbuff_t *tvb, int offset, 
756                         packet_info *pinfo, proto_tree *tree, 
757                         char *drep)
758 {
759         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
760                         samr_dissect_ASCII_DISPINFO);
761
762         return offset;
763 }
764
765 static int
766 samr_dissect_ASCII_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
767                         packet_info *pinfo, proto_tree *parent_tree,
768                         char *drep)
769 {
770         guint32 count;
771         proto_item *item=NULL;
772         proto_tree *tree=NULL;
773         int old_offset=offset;
774
775         if(parent_tree){
776                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
777                         "Ascii_DispInfo Array");
778                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo_array);
779         }
780
781         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
782                                      hf_samr_count, &count);
783         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
784                         samr_dissect_ASCII_DISPINFO_ARRAY_users, NDR_POINTER_PTR,
785                         "ACSII_DISPINFO_ARRAY", -1, 0);
786
787         proto_item_set_len(item, offset-old_offset);
788         return offset;
789 }
790
791
792 static int
793 samr_dissect_DISPLAY_INFO (tvbuff_t *tvb, int offset, 
794                              packet_info *pinfo, proto_tree *parent_tree,
795                              char *drep)
796 {
797         proto_item *item=NULL;
798         proto_tree *tree=NULL;
799         int old_offset=offset;
800         guint16 level;
801
802         if(parent_tree){
803                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
804                         "DISP_INFO:");
805                 tree = proto_item_add_subtree(item, ett_samr_display_info);
806         }
807
808         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
809                                      hf_samr_level, &level);
810         switch(level){
811         case 1: 
812                 offset = samr_dissect_USER_DISPINFO_1_ARRAY(
813                                 tvb, offset, pinfo, tree, drep);
814                 break;
815         case 2: 
816                 offset = samr_dissect_USER_DISPINFO_2_ARRAY(
817                                 tvb, offset, pinfo, tree, drep);
818                 break;
819         case 3: 
820                 offset = samr_dissect_GROUP_DISPINFO_ARRAY(
821                                 tvb, offset, pinfo, tree, drep);
822                 break;
823         case 4: 
824                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
825                                 tvb, offset, pinfo, tree, drep);
826                 break;
827         case 5: 
828                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
829                                 tvb, offset, pinfo, tree, drep);
830                 break;
831         }
832
833         proto_item_set_len(item, offset-old_offset);
834         return offset;
835 }
836
837 static int
838 samr_dissect_query_dispinfo_reply (tvbuff_t *tvb, int offset, 
839                              packet_info *pinfo, proto_tree *tree, 
840                              char *drep)
841 {
842         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
843                         samr_dissect_pointer_long, NDR_POINTER_REF,
844                         "", hf_samr_total_size, 0);
845         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
846                         samr_dissect_pointer_long, NDR_POINTER_REF,
847                         "", hf_samr_ret_size, 0);
848         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
849                         samr_dissect_DISPLAY_INFO, NDR_POINTER_REF,
850                         "", -1, 0);
851         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
852                                      hf_samr_rc, NULL);
853
854         return offset;
855 }
856
857
858 static int
859 samr_dissect_get_display_enumeration_index_rqst(tvbuff_t *tvb, int offset, 
860                              packet_info *pinfo, proto_tree *tree, 
861                              char *drep)
862 {
863         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
864                                       hf_samr_hnd, NULL);
865         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
866                                      hf_samr_level, NULL);
867         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
868                         hf_samr_acct_name);
869         return offset;
870 }
871
872
873 static int
874 samr_dissect_get_display_enumeration_index_reply(tvbuff_t *tvb, int offset, 
875                              packet_info *pinfo, proto_tree *tree, 
876                              char *drep)
877 {
878         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
879                         samr_dissect_pointer_long, NDR_POINTER_REF,
880                         "", hf_samr_index, 0);
881         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
882                                      hf_samr_rc, NULL);
883
884         return offset;
885 }
886
887
888
889
890 static int
891 samr_dissect_PASSWORD_INFO(tvbuff_t *tvb, int offset, 
892                         packet_info *pinfo, proto_tree *parent_tree,
893                         char *drep)
894 {
895         guint32 count;
896         proto_item *item=NULL;
897         proto_tree *tree=NULL;
898         int old_offset=offset;
899
900         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
901
902         if(parent_tree){
903                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
904                         "PASSWORD_INFO:");
905                 tree = proto_item_add_subtree(item, ett_samr_password_info);
906         }
907
908         
909         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
910                         hf_samr_unknown_short, NULL);
911         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
912                         hf_samr_unknown_long, NULL);
913
914         proto_item_set_len(item, offset-old_offset);
915         return offset;
916 }
917
918 static int
919 samr_dissect_get_usrdom_pwinfo_reply(tvbuff_t *tvb, int offset, 
920                              packet_info *pinfo, proto_tree *tree, 
921                              char *drep)
922 {
923         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
924                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
925                         "", -1, 0);
926         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
927                                      hf_samr_rc, NULL);
928         return offset;
929 }
930
931
932
933 static int
934 samr_dissect_connect2_server(tvbuff_t *tvb, int offset, 
935                              packet_info *pinfo, proto_tree *parent_tree, 
936                              char *drep)
937 {
938         proto_item *item=NULL;
939         proto_tree *tree=NULL;
940         int old_offset=offset;
941
942         if(parent_tree){
943                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
944                         "Server");
945                 tree = proto_item_add_subtree(item, ett_samr_server);
946         }
947
948         offset = dissect_ndr_nt_UNICODE_STRING_str(tvb, offset, pinfo, 
949                         tree, drep);
950
951         proto_item_set_len(item, offset-old_offset);
952         return offset;
953 }
954
955 static int
956 samr_dissect_connect2_rqst(tvbuff_t *tvb, int offset, 
957                              packet_info *pinfo, proto_tree *tree, 
958                              char *drep)
959 {
960         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
961                         samr_dissect_connect2_server, NDR_POINTER_UNIQUE,
962                         "Server", hf_samr_server, 0);
963
964         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
965                                      hf_samr_access, NULL);
966         return offset;
967 }
968
969 static int
970 samr_dissect_connect2_reply(tvbuff_t *tvb, int offset, 
971                              packet_info *pinfo, proto_tree *tree, 
972                              char *drep)
973 {
974         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
975                                       hf_samr_hnd, NULL);
976         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
977                                      hf_samr_rc, NULL);
978         return offset;
979 }
980
981
982
983
984 static int
985 samr_dissect_USER_GROUP(tvbuff_t *tvb, int offset, 
986                              packet_info *pinfo, proto_tree *parent_tree,
987                              char *drep)
988 {
989         proto_item *item=NULL;
990         proto_tree *tree=NULL;
991         int old_offset=offset;
992
993         if(parent_tree){
994                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
995                         "USER_GROUP:");
996                 tree = proto_item_add_subtree(item, ett_samr_user_group);
997         }
998
999         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1000                                      hf_samr_rid, NULL);
1001         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1002                                      hf_samr_rid_attrib, NULL);
1003
1004         proto_item_set_len(item, offset-old_offset);
1005         return offset;
1006 }
1007
1008 static int
1009 samr_dissect_USER_GROUP_ARRAY_groups (tvbuff_t *tvb, int offset, 
1010                              packet_info *pinfo, proto_tree *tree,
1011                              char *drep)
1012 {
1013         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
1014                         samr_dissect_USER_GROUP);
1015
1016         return offset;
1017 }
1018
1019 static int
1020 samr_dissect_USER_GROUP_ARRAY(tvbuff_t *tvb, int offset, 
1021                         packet_info *pinfo, proto_tree *parent_tree,
1022                         char *drep)
1023 {
1024         guint32 count;
1025         proto_item *item=NULL;
1026         proto_tree *tree=NULL;
1027         int old_offset=offset;
1028
1029         if(parent_tree){
1030                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1031                         "USER_GROUP_ARRAY");
1032                 tree = proto_item_add_subtree(item, ett_samr_user_group_array);
1033         }
1034
1035         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1036                         hf_samr_count, &count);
1037         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1038                         samr_dissect_USER_GROUP_ARRAY_groups, NDR_POINTER_UNIQUE,
1039                         "USER_GROUP_ARRAY", -1, 0);
1040
1041         proto_item_set_len(item, offset-old_offset);
1042         return offset;
1043 }
1044
1045 static int
1046 samr_dissect_USER_GROUP_ARRAY_ptr(tvbuff_t *tvb, int offset, 
1047                         packet_info *pinfo, proto_tree *tree,
1048                         char *drep)
1049 {
1050         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1051                         samr_dissect_USER_GROUP_ARRAY, NDR_POINTER_UNIQUE,
1052                         "USER_GROUP_ARRAY", -1, 0);
1053         return offset;
1054 }
1055
1056 static int
1057 samr_dissect_get_groups_for_user_reply(tvbuff_t *tvb, int offset, 
1058                              packet_info *pinfo, proto_tree *tree, 
1059                              char *drep)
1060 {
1061         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1062                         samr_dissect_USER_GROUP_ARRAY_ptr, NDR_POINTER_REF,
1063                         "", -1, 0);
1064         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1065                                      hf_samr_rc, NULL);
1066         return offset;
1067 }
1068
1069
1070
1071 static int
1072 samr_dissect_open_domain_rqst(tvbuff_t *tvb, int offset, 
1073                              packet_info *pinfo, proto_tree *tree, 
1074                              char *drep)
1075 {
1076         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1077                                       hf_samr_hnd, NULL);
1078         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1079                                      hf_samr_access, NULL);
1080         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1081                         samr_dissect_SID, NDR_POINTER_REF,
1082                         "", -1, 0);
1083         return offset;
1084 }
1085
1086 static int
1087 samr_dissect_open_domain_reply(tvbuff_t *tvb, int offset, 
1088                              packet_info *pinfo, proto_tree *tree, 
1089                              char *drep)
1090 {
1091         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1092                                       hf_samr_hnd, NULL);
1093         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1094                                      hf_samr_rc, NULL);
1095         return offset;
1096 }
1097
1098
1099
1100 static int
1101 samr_dissect_context_handle_SID(tvbuff_t *tvb, int offset, 
1102                              packet_info *pinfo, proto_tree *tree, 
1103                              char *drep)
1104 {
1105         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1106                                       hf_samr_hnd, NULL);
1107         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1108                         samr_dissect_SID, NDR_POINTER_REF,
1109                         "SID", -1, 0);
1110         return offset;
1111 }
1112
1113 static int
1114 samr_dissect_context_handle(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         return offset;
1121 }
1122
1123
1124 static int
1125 samr_dissect_rc(tvbuff_t *tvb, int offset, 
1126                              packet_info *pinfo, proto_tree *tree, 
1127                              char *drep)
1128 {
1129         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1130                                      hf_samr_rc, NULL);
1131         return offset;
1132 }
1133
1134 static int
1135 samr_dissect_add_member_to_group_rqst(tvbuff_t *tvb, int offset, 
1136                              packet_info *pinfo, proto_tree *tree, 
1137                              char *drep)
1138 {
1139         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1140                                       hf_samr_hnd, NULL);
1141         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1142                                      hf_samr_group, NULL);
1143         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1144                                      hf_samr_rid, NULL);
1145         return offset;
1146 }
1147
1148 static int
1149 samr_dissect_unknown_3c_reply(tvbuff_t *tvb, int offset, 
1150                              packet_info *pinfo, proto_tree *tree, 
1151                              char *drep)
1152 {
1153         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1154                         samr_dissect_pointer_short, NDR_POINTER_REF,
1155                         "", hf_samr_unknown_short, 0);
1156         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1157                                      hf_samr_rc, NULL);
1158         return offset;
1159 }
1160
1161
1162
1163 static int
1164 samr_dissect_create_alias_in_domain_rqst(tvbuff_t *tvb, int offset, 
1165                              packet_info *pinfo, proto_tree *tree, 
1166                              char *drep)
1167 {
1168         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1169                                       hf_samr_hnd, NULL);
1170         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1171                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1172                         "Account Name", hf_samr_acct_name, 0);
1173         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1174                                      hf_samr_access, NULL);
1175         return offset;
1176 }
1177
1178 static int
1179 samr_dissect_create_alias_in_domain_reply(tvbuff_t *tvb, int offset, 
1180                              packet_info *pinfo, proto_tree *tree, 
1181                              char *drep)
1182 {
1183         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1184                                       hf_samr_hnd, NULL);
1185         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1186                                      hf_samr_rid, NULL);
1187         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1188                                      hf_samr_rc, NULL);
1189
1190         return offset;
1191 }
1192
1193
1194 static int
1195 samr_dissect_query_information_alias_rqst(tvbuff_t *tvb, int offset, 
1196                         packet_info *pinfo, proto_tree *tree, 
1197                         char *drep)
1198 {
1199         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1200                         hf_samr_hnd, NULL);
1201         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1202                         hf_samr_level, NULL);
1203
1204         return offset;
1205 }
1206
1207
1208 static int
1209 samr_dissect_ALIAS_INFO_1 (tvbuff_t *tvb, int offset, 
1210                              packet_info *pinfo, proto_tree *tree,
1211                              char *drep)
1212 {
1213         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1214                 tree, drep,
1215                 hf_samr_acct_name, 0);
1216         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1217                                      hf_samr_rid, NULL);
1218         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1219                 tree, drep,
1220                 hf_samr_acct_desc, 0);
1221         return offset;
1222 }
1223
1224 static int
1225 samr_dissect_ALIAS_INFO(tvbuff_t *tvb, int offset, 
1226                         packet_info *pinfo, proto_tree *parent_tree,
1227                         char *drep)
1228 {
1229         proto_item *item=NULL;
1230         proto_tree *tree=NULL;
1231         int old_offset=offset;
1232         guint16 level;
1233
1234         if(parent_tree){
1235                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1236                         "ALIAS_INFO:");
1237                 tree = proto_item_add_subtree(item, ett_samr_alias_info);
1238         }
1239
1240         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1241                                      hf_samr_level, &level);
1242         switch(level){
1243         case 1: 
1244                 offset = samr_dissect_ALIAS_INFO_1(
1245                                 tvb, offset, pinfo, tree, drep);
1246                 break;
1247         case 2: 
1248                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1249                         tree, drep,
1250                         hf_samr_acct_name, 0);
1251                 break;
1252         case 3: 
1253                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1254                         tree, drep,
1255                         hf_samr_acct_desc, 0);
1256                 break;
1257         }
1258
1259         proto_item_set_len(item, offset-old_offset);
1260         return offset;
1261 }
1262
1263 static int
1264 samr_dissect_ALIAS_INFO_ptr(tvbuff_t *tvb, int offset, 
1265                         packet_info *pinfo, proto_tree *tree,
1266                         char *drep)
1267 {
1268         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1269                         samr_dissect_ALIAS_INFO, NDR_POINTER_UNIQUE,
1270                         "ALIAS_INFO", -1, 0);
1271         return offset;
1272 }
1273
1274 static int
1275 samr_dissect_query_information_alias_reply(tvbuff_t *tvb, int offset, 
1276                         packet_info *pinfo, proto_tree *tree, 
1277                         char *drep)
1278 {
1279         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1280                         samr_dissect_ALIAS_INFO_ptr, NDR_POINTER_REF,
1281                         "", -1, 0);
1282         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1283                         hf_samr_rc, NULL);
1284         return offset;
1285 }
1286
1287 static int
1288 samr_dissect_set_information_alias_rqst(tvbuff_t *tvb, int offset, 
1289                              packet_info *pinfo, proto_tree *tree, 
1290                              char *drep)
1291 {
1292         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1293                                       hf_samr_hnd, NULL);
1294         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1295                                      hf_samr_level, NULL);
1296         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1297                         samr_dissect_ALIAS_INFO, NDR_POINTER_REF,
1298                         "", -1, 0);
1299         return offset;
1300 }
1301
1302
1303 static int
1304 samr_dissect_CRYPT_PASSWORD(tvbuff_t *tvb, int offset, 
1305                         packet_info *pinfo, proto_tree *tree, 
1306                         char *drep)
1307 {
1308         proto_tree_add_item(tree, hf_samr_crypt_password, tvb, offset, 516,
1309                 FALSE);
1310         offset += 516;
1311         return offset;
1312 }
1313
1314 static int
1315 samr_dissect_CRYPT_HASH(tvbuff_t *tvb, int offset, 
1316                         packet_info *pinfo, proto_tree *tree, 
1317                         char *drep)
1318 {
1319         proto_tree_add_item(tree, hf_samr_crypt_hash, tvb, offset, 16,
1320                 FALSE);
1321         offset += 16;
1322         return offset;
1323 }
1324
1325
1326 static int
1327 samr_dissect_oem_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1328                              packet_info *pinfo, proto_tree *tree, 
1329                              char *drep)
1330 {
1331         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1332                                       hf_samr_hnd, NULL);
1333         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1334                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1335                         "Server", hf_samr_server, 0);
1336         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1337                         samr_dissect_pointer_STRING, NDR_POINTER_REF,
1338                         "Account Name", hf_samr_acct_name, 0);
1339         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1340                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1341                         "Password", -1, 0);
1342         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1343                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1344                         "Hash", -1, 0);
1345         return offset;
1346 }
1347
1348 static int
1349 samr_dissect_unicode_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1350                              packet_info *pinfo, proto_tree *tree, 
1351                              char *drep)
1352 {
1353         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1354                                       hf_samr_hnd, NULL);
1355         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1356                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1357                         "Server", hf_samr_server, 0);
1358         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1359                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1360                         "Account Name", hf_samr_acct_name, 0);
1361         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1362                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1363                         "Password", -1, 0);
1364         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1365                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1366                         "Hash", -1, 0);
1367         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1368                                      hf_samr_lm_change, NULL);
1369         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1370                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1371                         "Password", -1, 0);
1372         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1373                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1374                         "Hash", -1, 0);
1375         return offset;
1376 }
1377
1378 static int
1379 samr_dissect_unknown_3b_rqst(tvbuff_t *tvb, int offset, 
1380                              packet_info *pinfo, proto_tree *tree, 
1381                              char *drep)
1382 {
1383         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1384                                       hf_samr_hnd, NULL);
1385         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1386                                      hf_samr_unknown_short, NULL);
1387         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1388                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1389                         "Unknown", hf_samr_unknown_string, 0);
1390         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1391                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1392                         "Unknown", hf_samr_unknown_string, 0);
1393         return offset;
1394 }
1395
1396
1397 static int
1398 samr_dissect_create_user2_in_domain_rqst(tvbuff_t *tvb, int offset, 
1399                         packet_info *pinfo, proto_tree *tree, 
1400                         char *drep)
1401 {
1402         
1403         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1404                         hf_samr_hnd, NULL);
1405         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1406                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1407                         "Account Name", hf_samr_acct_name, 0);
1408         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
1409         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1410                         hf_samr_access, NULL);
1411
1412         return offset;
1413 }
1414
1415 static int
1416 samr_dissect_create_user2_in_domain_reply(tvbuff_t *tvb, int offset, 
1417                              packet_info *pinfo, proto_tree *tree, 
1418                              char *drep)
1419 {
1420         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1421                                       hf_samr_hnd, NULL);
1422         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1423                                      hf_samr_unknown_long, NULL);
1424         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1425                                      hf_samr_rid, NULL);
1426         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1427                                      hf_samr_rc, NULL);
1428         return offset;
1429 }
1430
1431 static int
1432 samr_dissect_get_display_enumeration_index2_rqst(tvbuff_t *tvb, int offset, 
1433                              packet_info *pinfo, proto_tree *tree, 
1434                              char *drep)
1435 {
1436         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1437                                       hf_samr_hnd, NULL);
1438         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1439                                      hf_samr_level, NULL);
1440         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1441                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1442                         "Account Name", hf_samr_acct_name, 0);
1443         return offset;
1444 }
1445
1446 static int
1447 samr_dissect_get_display_enumeration_index2_reply(tvbuff_t *tvb, int offset, 
1448                              packet_info *pinfo, proto_tree *tree, 
1449                              char *drep)
1450 {
1451         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1452                                      hf_samr_index, 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_change_password_user_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_uint8 (tvb, offset, pinfo, tree, drep,
1466                         hf_samr_unknown_char, NULL);
1467         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1468                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1469                         "Hash", -1, 0);
1470         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1471                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1472                         "Hash", -1, 0);
1473         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1474                         hf_samr_unknown_char, NULL);
1475         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1476                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1477                         "Hash", -1, 0);
1478         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1479                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1480                         "Hash", -1, 0);
1481         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1482                         hf_samr_unknown_char, NULL);
1483         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1484                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1485                         "Hash", -1, 0);
1486         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1487                         hf_samr_unknown_char, NULL);
1488         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1489                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1490                         "Hash", -1, 0);
1491
1492         return offset;
1493 }
1494
1495 static int
1496 samr_dissect_set_member_attributes_of_group_rqst(tvbuff_t *tvb, int offset, 
1497                              packet_info *pinfo, proto_tree *tree, 
1498                              char *drep)
1499 {
1500         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1501                                       hf_samr_hnd, NULL);
1502         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1503                                      hf_samr_attrib, NULL);
1504         return offset;
1505 }
1506
1507
1508 static int
1509 samr_dissect_GROUP_INFO_1 (tvbuff_t *tvb, int offset, 
1510                              packet_info *pinfo, proto_tree *tree,
1511                              char *drep)
1512 {
1513         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1514                 tree, drep,
1515                 hf_samr_acct_name, 0);
1516         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1517                                      hf_samr_rid, NULL);
1518         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1519                                         hf_samr_attrib, NULL);
1520         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1521                 tree, drep,
1522                 hf_samr_acct_desc, 0);
1523         return offset;
1524 }
1525
1526 static int
1527 samr_dissect_GROUP_INFO(tvbuff_t *tvb, int offset, 
1528                         packet_info *pinfo, proto_tree *parent_tree,
1529                         char *drep)
1530 {
1531         proto_item *item=NULL;
1532         proto_tree *tree=NULL;
1533         int old_offset=offset;
1534         guint16 level;
1535
1536         if(parent_tree){
1537                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1538                         "GROUP_INFO:");
1539                 tree = proto_item_add_subtree(item, ett_samr_group_info);
1540         }
1541
1542         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1543                                      hf_samr_level, &level);
1544         switch(level){
1545         case 1: 
1546                 offset = samr_dissect_GROUP_INFO_1(
1547                                 tvb, offset, pinfo, tree, drep);
1548                 break;
1549         case 2: 
1550                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1551                         tree, drep,
1552                         hf_samr_acct_name, 0);
1553                 break;
1554         case 3:
1555                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1556                         hf_samr_attrib, NULL);
1557                 break;
1558         case 4: 
1559                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1560                         tree, drep,
1561                         hf_samr_acct_desc, 0);
1562                 break;
1563         }
1564
1565         proto_item_set_len(item, offset-old_offset);
1566         return offset;
1567 }
1568
1569 static int
1570 samr_dissect_GROUP_INFO_ptr(tvbuff_t *tvb, int offset, 
1571                         packet_info *pinfo, proto_tree *tree,
1572                         char *drep)
1573 {
1574         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1575                         samr_dissect_GROUP_INFO, NDR_POINTER_UNIQUE,
1576                         "GROUP_INFO", -1, 0);
1577         return offset;
1578 }
1579
1580 static int
1581 samr_dissect_query_information_group_rqst (tvbuff_t *tvb, int offset, 
1582                              packet_info *pinfo, proto_tree *tree,
1583                              char *drep)
1584 {
1585         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1586                                       hf_samr_hnd, NULL);
1587         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1588                                      hf_samr_level, NULL);
1589         return offset;
1590 }
1591
1592 static int
1593 samr_dissect_query_information_group_reply(tvbuff_t *tvb, int offset, 
1594                         packet_info *pinfo, proto_tree *tree,
1595                         char *drep)
1596 {
1597         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1598                         samr_dissect_GROUP_INFO_ptr, NDR_POINTER_REF,
1599                         "", -1, 0);
1600         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1601                         hf_samr_rc, NULL);
1602         return offset;
1603 }
1604
1605 static int
1606 samr_dissect_set_information_group_rqst (tvbuff_t *tvb, int offset, 
1607                              packet_info *pinfo, proto_tree *tree,
1608                              char *drep)
1609 {
1610         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1611                                       hf_samr_hnd, NULL);
1612         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1613                                      hf_samr_level, NULL);
1614         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1615                         samr_dissect_GROUP_INFO, NDR_POINTER_REF,
1616                         "", -1, 0);
1617         return offset;
1618 }
1619
1620
1621
1622 static int
1623 samr_dissect_get_domain_password_information_rqst (tvbuff_t *tvb, int offset, 
1624                              packet_info *pinfo, proto_tree *tree,
1625                              char *drep)
1626 {
1627         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1628                                       hf_samr_hnd, NULL);
1629
1630         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1631                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1632                         "Domain", hf_samr_domain, 0);
1633         return offset;
1634 }
1635
1636
1637 static int
1638 samr_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset, 
1639                              packet_info *pinfo, proto_tree *parent_tree,
1640                              char *drep)
1641 {
1642         proto_item *item=NULL;
1643         proto_tree *tree=NULL;
1644         int old_offset=offset;
1645
1646         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */ 
1647
1648         if(parent_tree){
1649                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1650                         "DOMAIN_INFO_1:");
1651                 tree = proto_item_add_subtree(item, ett_samr_domain_info_1);
1652         }
1653
1654         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1655                                         hf_samr_min_pwd_len, NULL);
1656         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1657                                         hf_samr_pwd_history_len, NULL);
1658         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1659                                         hf_samr_unknown_long, NULL);
1660         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1661                                         hf_samr_max_pwd_age);
1662         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1663                                         hf_samr_min_pwd_age);
1664         proto_item_set_len(item, offset-old_offset);
1665         return offset;
1666 }
1667
1668 static int
1669 samr_dissect_DOMAIN_INFO_2(tvbuff_t *tvb, int offset, 
1670                         packet_info *pinfo, proto_tree *parent_tree,
1671                         char *drep)
1672 {
1673         proto_item *item=NULL;
1674         proto_tree *tree=NULL;
1675         int old_offset=offset;
1676
1677         if(parent_tree){
1678                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1679                         "DOMAIN_INFO_2:");
1680                 tree = proto_item_add_subtree(item, ett_samr_domain_info_2);
1681         }
1682
1683         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1684                         hf_samr_unknown_time);
1685         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1686                         hf_samr_unknown_string, 0);
1687         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1688                         hf_samr_domain, 0);
1689         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1690                         hf_samr_controller, 0);
1691         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1692                         hf_samr_unknown_time);
1693         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1694                         hf_samr_unknown_long, NULL);
1695         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1696                         hf_samr_unknown_long, NULL);
1697         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1698                         hf_samr_unknown_char, NULL);
1699         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1700                         hf_samr_num_users, NULL);
1701         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1702                         hf_samr_num_groups, NULL);
1703         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1704                         hf_samr_num_aliases, NULL);
1705
1706         proto_item_set_len(item, offset-old_offset);
1707         return offset;
1708 }
1709
1710 static int
1711 samr_dissect_DOMAIN_INFO_8(tvbuff_t *tvb, int offset, 
1712                              packet_info *pinfo, proto_tree *parent_tree,
1713                              char *drep)
1714 {
1715         proto_item *item=NULL;
1716         proto_tree *tree=NULL;
1717         int old_offset=offset;
1718
1719         if(parent_tree){
1720                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1721                         "DOMAIN_INFO_8:");
1722                 tree = proto_item_add_subtree(item, ett_samr_domain_info_8);
1723         }
1724
1725         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1726                                         hf_samr_max_pwd_age);
1727         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1728                                         hf_samr_min_pwd_age);
1729
1730         proto_item_set_len(item, offset-old_offset);
1731         return offset;
1732 }
1733
1734 static int
1735 samr_dissect_REPLICATION_STATUS(tvbuff_t *tvb, int offset, 
1736                         packet_info *pinfo, proto_tree *parent_tree,
1737                         char *drep)
1738 {
1739         proto_item *item=NULL;
1740         proto_tree *tree=NULL;
1741         int old_offset=offset;
1742
1743         if(parent_tree){
1744                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1745                         "REPLICATION_STATUS:");
1746                 tree = proto_item_add_subtree(item, ett_samr_replication_status);
1747         }
1748
1749         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1750                         hf_samr_unknown_hyper, NULL);
1751         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1752                         hf_samr_unknown_hyper, NULL);
1753         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1754                         hf_samr_unknown_short, NULL);
1755
1756         proto_item_set_len(item, offset-old_offset);
1757         return offset;
1758 }
1759
1760 static int
1761 samr_dissect_DOMAIN_INFO_11(tvbuff_t *tvb, int offset, 
1762                              packet_info *pinfo, proto_tree *parent_tree,
1763                              char *drep)
1764 {
1765         proto_item *item=NULL;
1766         proto_tree *tree=NULL;
1767         int old_offset=offset;
1768
1769         if(parent_tree){
1770                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1771                         "DOMAIN_INFO_11:");
1772                 tree = proto_item_add_subtree(item, ett_samr_domain_info_11);
1773         }
1774
1775         offset = samr_dissect_DOMAIN_INFO_2(
1776                         tvb, offset, pinfo, tree, drep);
1777         offset = samr_dissect_REPLICATION_STATUS(
1778                         tvb, offset, pinfo, tree, drep);
1779
1780         proto_item_set_len(item, offset-old_offset);
1781         return offset;
1782 }
1783
1784 static int
1785 samr_dissect_DOMAIN_INFO_13(tvbuff_t *tvb, int offset, 
1786                              packet_info *pinfo, proto_tree *parent_tree,
1787                              char *drep)
1788 {
1789         proto_item *item=NULL;
1790         proto_tree *tree=NULL;
1791         int old_offset=offset;
1792
1793         if(parent_tree){
1794                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1795                         "DOMAIN_INFO_13:");
1796                 tree = proto_item_add_subtree(item, ett_samr_domain_info_13);
1797         }
1798
1799         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1800                                         hf_samr_unknown_time);
1801         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1802                                         hf_samr_unknown_time);
1803         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1804                                         hf_samr_unknown_time);
1805
1806         proto_item_set_len(item, offset-old_offset);
1807         return offset;
1808 }
1809
1810
1811 static int
1812 samr_dissect_DOMAIN_INFO(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         guint16 level;
1820
1821         if(parent_tree){
1822                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1823                         "DOMAIN_INFO:");
1824                 tree = proto_item_add_subtree(item, ett_samr_domain_info);
1825         }
1826
1827         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1828                                      hf_samr_level, &level);
1829
1830         ALIGN_TO_4_BYTES;  /* all union arms aligned to 4 bytes, case 7 and 9 need this  */
1831         switch(level){
1832         case 1: 
1833                 offset = samr_dissect_DOMAIN_INFO_1(
1834                                 tvb, offset, pinfo, tree, drep);
1835                 break;
1836         case 2: 
1837                 offset = samr_dissect_DOMAIN_INFO_2(
1838                                 tvb, offset, pinfo, tree, drep);
1839                 break;
1840
1841         case 3:
1842                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1843                                 hf_samr_unknown_time);
1844                 break;
1845         case 4:
1846                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1847                         tree, drep, hf_samr_unknown_string, 0);
1848                 break;
1849
1850         case 5:
1851                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1852                         tree, drep, hf_samr_domain, 0);
1853                 break;
1854
1855         case 6:
1856                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1857                         tree, drep, hf_samr_controller, 0);
1858                 break;
1859
1860         case 7:
1861                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1862                         hf_samr_unknown_short, NULL);
1863                 break;
1864         case 8: 
1865                 offset = samr_dissect_DOMAIN_INFO_8(
1866                                 tvb, offset, pinfo, tree, drep);
1867                 break;
1868         case 9:
1869                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1870                         hf_samr_unknown_short, NULL);
1871                 break;
1872         case 11:        
1873                 offset = samr_dissect_DOMAIN_INFO_11(
1874                                 tvb, offset, pinfo, tree, drep);
1875                 break;
1876         case 12:
1877                 offset = samr_dissect_REPLICATION_STATUS(
1878                                 tvb, offset, pinfo, tree, drep);
1879                 break;
1880         case 13:        
1881                 offset = samr_dissect_DOMAIN_INFO_13(
1882                                 tvb, offset, pinfo, tree, drep);
1883                 break;
1884         }
1885
1886         proto_item_set_len(item, offset-old_offset);
1887         return offset;
1888 }
1889
1890 static int
1891 samr_dissect_DOMAIN_INFO_ptr(tvbuff_t *tvb, int offset, 
1892                         packet_info *pinfo, proto_tree *tree,
1893                         char *drep)
1894 {
1895         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1896                         samr_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
1897                         "DOMAIN_INFO pointer", hf_samr_domain, 0);
1898         return offset;
1899 }
1900
1901 static int
1902 samr_dissect_query_information_domain_reply(tvbuff_t *tvb, int offset, 
1903                         packet_info *pinfo, proto_tree *tree,
1904                         char *drep)
1905 {
1906         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1907                         samr_dissect_DOMAIN_INFO_ptr, NDR_POINTER_REF,
1908                         "", hf_samr_domain, 0);
1909         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1910                                      hf_samr_rc, NULL);
1911         return offset;
1912 }
1913
1914
1915 static int
1916 samr_dissect_set_information_domain_rqst(tvbuff_t *tvb, int offset, 
1917                              packet_info *pinfo, proto_tree *tree,
1918                              char *drep)
1919 {
1920         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1921                                       hf_samr_hnd, NULL);
1922         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1923                                      hf_samr_level, NULL);
1924         offset = samr_dissect_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
1925         return offset;
1926 }
1927
1928
1929
1930 static int
1931 samr_dissect_lookup_domain_rqst(tvbuff_t *tvb, int offset, 
1932                         packet_info *pinfo, proto_tree *tree,
1933                         char *drep)
1934 {
1935         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1936                         hf_samr_hnd, NULL);
1937         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1938                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1939                         "", hf_samr_domain, 0);
1940         return offset;
1941 }
1942
1943 static int
1944 samr_dissect_lookup_domain_reply(tvbuff_t *tvb, int offset, 
1945                              packet_info *pinfo, proto_tree *tree,
1946                              char *drep)
1947 {
1948         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1949                         samr_dissect_SID_ptr, NDR_POINTER_REF,
1950                         "", -1, 0);
1951         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1952                                      hf_samr_rc, NULL);
1953         return offset;
1954 }
1955
1956 static int
1957 samr_dissect_PSID(tvbuff_t *tvb, int offset, 
1958                              packet_info *pinfo, proto_tree *parent_tree,
1959                              char *drep)
1960 {
1961         proto_item *item=NULL;
1962         proto_tree *tree=NULL;
1963         int old_offset=offset;
1964
1965         if(parent_tree){
1966                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1967                         "SID pointer:");
1968                 tree = proto_item_add_subtree(item, ett_samr_sid_pointer);
1969         }
1970
1971         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1972                         samr_dissect_SID, NDR_POINTER_UNIQUE,
1973                         "SID", -1, 0);
1974
1975         proto_item_set_len(item, offset-old_offset);
1976         return offset;
1977 }
1978
1979
1980 static int
1981 samr_dissect_PSID_ARRAY_sids (tvbuff_t *tvb, int offset, 
1982                              packet_info *pinfo, proto_tree *tree,
1983                              char *drep)
1984 {
1985         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
1986                         samr_dissect_PSID);
1987
1988         return offset;
1989 }
1990
1991
1992 static int
1993 samr_dissect_PSID_ARRAY(tvbuff_t *tvb, int offset, 
1994                         packet_info *pinfo, proto_tree *parent_tree,
1995                         char *drep)
1996 {
1997         guint32 count;
1998         proto_item *item=NULL;
1999         proto_tree *tree=NULL;
2000         int old_offset=offset;
2001
2002         if(parent_tree){
2003                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2004                         "SID array:");
2005                 tree = proto_item_add_subtree(item, ett_samr_sid_array);
2006         }
2007
2008         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2009                         hf_samr_count, &count);
2010         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2011                         samr_dissect_PSID_ARRAY_sids, NDR_POINTER_UNIQUE,
2012                         "PSID_ARRAY", -1, 0);
2013
2014         proto_item_set_len(item, offset-old_offset);
2015         return offset;
2016 }
2017
2018 static int
2019 samr_dissect_index(tvbuff_t *tvb, int offset, 
2020                              packet_info *pinfo, proto_tree *tree,
2021                              char *drep)
2022 {
2023         int old_offset=offset;
2024         dcerpc_info *di;
2025
2026         di=pinfo->private_data;
2027
2028         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2029                         di->hf_index, NULL);
2030
2031         return offset;
2032 }
2033
2034
2035 static int
2036 samr_dissect_INDEX_ARRAY_value (tvbuff_t *tvb, int offset, 
2037                              packet_info *pinfo, proto_tree *tree,
2038                              char *drep)
2039 {
2040         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2041                         samr_dissect_index);
2042
2043         return offset;
2044 }
2045
2046 static char *
2047 plural_ending(const char *string)
2048 {
2049         size_t string_len;
2050
2051         string_len = strlen(string);
2052         if (string_len > 0 && string[string_len - 1] == 's') {
2053                 /* String ends with "s" - pluralize by adding "es" */
2054                 return "es";
2055         } else {
2056                 /* Field name doesn't end with "s" - pluralize by adding "s" */
2057                 return "s";
2058         }
2059 }
2060
2061 static int
2062 samr_dissect_INDEX_ARRAY(tvbuff_t *tvb, int offset, 
2063                         packet_info *pinfo, proto_tree *parent_tree,
2064                         char *drep)
2065 {
2066         char *field_name;
2067         guint32 count;
2068         proto_item *item=NULL;
2069         proto_tree *tree=NULL;
2070         int old_offset=offset;
2071         dcerpc_info *di;
2072         char str[256];
2073
2074         di=pinfo->private_data;
2075
2076         field_name = proto_registrar_get_name(di->hf_index);
2077         snprintf(str, 255, "INDEX_ARRAY: %s%s:", field_name,
2078             plural_ending(field_name));
2079         if(parent_tree){
2080                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2081                         "%s", str);
2082                 tree = proto_item_add_subtree(item, ett_samr_index_array);
2083         }
2084
2085         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2086                         hf_samr_count, &count);
2087         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2088                         samr_dissect_INDEX_ARRAY_value, NDR_POINTER_UNIQUE,
2089                         str, di->hf_index, 0);
2090
2091         proto_item_set_len(item, offset-old_offset);
2092         return offset;
2093 }
2094
2095
2096 static int
2097 samr_dissect_get_alias_membership_rqst(tvbuff_t *tvb, int offset, 
2098                              packet_info *pinfo, proto_tree *tree,
2099                              char *drep)
2100 {
2101         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2102                                       hf_samr_hnd, NULL);
2103         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2104                         samr_dissect_PSID_ARRAY, NDR_POINTER_REF,
2105                         "", -1, 0);
2106         return offset;
2107 }
2108
2109 static int
2110 samr_dissect_get_alias_membership_reply(tvbuff_t *tvb, int offset, 
2111                              packet_info *pinfo, proto_tree *tree,
2112                              char *drep)
2113 {
2114         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2115                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
2116                         "", hf_samr_alias, 0);
2117         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2118                         hf_samr_rc, NULL);
2119         return offset;
2120 }
2121
2122
2123 static int
2124 samr_dissect_IDX_AND_NAME(tvbuff_t *tvb, int offset, 
2125                              packet_info *pinfo, proto_tree *parent_tree,
2126                              char *drep)
2127 {
2128         proto_item *item=NULL;
2129         proto_tree *tree=NULL;
2130         int old_offset=offset;
2131         char str[256];
2132         dcerpc_info *di;
2133
2134         di=pinfo->private_data;
2135
2136         snprintf(str, 255, "IDX_AND_NAME: %s:",proto_registrar_get_name(di->hf_index));
2137         if(parent_tree){
2138                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2139                                 "%s",str);
2140                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name);
2141         }
2142
2143         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2144                         hf_samr_index, NULL);
2145         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
2146                         tree, drep, di->hf_index, 4);
2147
2148         proto_item_set_len(item, offset-old_offset);
2149         return offset;
2150 }
2151
2152 static int
2153 samr_dissect_IDX_AND_NAME_entry (tvbuff_t *tvb, int offset, 
2154                              packet_info *pinfo, proto_tree *tree,
2155                              char *drep)
2156 {
2157         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2158                         samr_dissect_IDX_AND_NAME);
2159
2160         return offset;
2161 }
2162
2163
2164 static int
2165 samr_dissect_IDX_AND_NAME_ARRAY(tvbuff_t *tvb, int offset, 
2166                         packet_info *pinfo, proto_tree *parent_tree,
2167                         char *drep)
2168 {
2169         char *field_name;
2170         guint32 count;
2171         proto_item *item=NULL;
2172         proto_tree *tree=NULL;
2173         int old_offset=offset;
2174         dcerpc_info *di;
2175         char str[256];
2176
2177         di=pinfo->private_data;
2178
2179         field_name = proto_registrar_get_name(di->hf_index);
2180
2181         if(parent_tree){
2182                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2183                         "IDX_AND_NAME_ARRAY: %s%s:", field_name,
2184                         plural_ending(field_name));
2185                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name_array);
2186         }
2187
2188         
2189         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2190                         hf_samr_count, &count);
2191         snprintf(str, 255, "IDX_AND_NAME pointer: %s%s:", field_name,
2192             plural_ending(field_name));
2193         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2194                         samr_dissect_IDX_AND_NAME_entry, NDR_POINTER_UNIQUE,
2195                         str, di->hf_index, 0);
2196
2197         proto_item_set_len(item, offset-old_offset);
2198         return offset;
2199 }
2200
2201 static int
2202 samr_dissect_IDX_AND_NAME_ARRAY_ptr(tvbuff_t *tvb, int offset, 
2203                         packet_info *pinfo, proto_tree *tree,
2204                         char *drep)
2205 {
2206         char *field_name;
2207         char str[256];
2208         dcerpc_info *di;
2209
2210         di=pinfo->private_data;
2211
2212         field_name = proto_registrar_get_name(di->hf_index);
2213         snprintf(str, 255, "IDX_AND_NAME_ARRAY pointer: %s%s:", field_name,
2214             plural_ending(field_name));
2215         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2216                         samr_dissect_IDX_AND_NAME_ARRAY, NDR_POINTER_UNIQUE,
2217                         str, di->hf_index, 0);
2218         return offset;
2219 }
2220
2221 static int
2222 samr_dissect_enum_domains_rqst(tvbuff_t *tvb, int offset, 
2223                              packet_info *pinfo, proto_tree *tree,
2224                              char *drep)
2225 {
2226         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2227                         hf_samr_hnd, NULL);
2228         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2229                         samr_dissect_pointer_long, NDR_POINTER_REF,
2230                         "", hf_samr_resume_hnd, 0);
2231         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2232                         hf_samr_pref_maxsize, NULL);
2233         return offset;
2234 }
2235
2236 static int
2237 samr_dissect_enum_domains_reply(tvbuff_t *tvb, int offset, 
2238                              packet_info *pinfo, proto_tree *tree,
2239                              char *drep)
2240 {
2241         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2242                         samr_dissect_pointer_long, NDR_POINTER_REF,
2243                         "", hf_samr_resume_hnd, 0);
2244         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2245                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2246                         "", hf_samr_domain, 0);
2247         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2248                         samr_dissect_pointer_long, NDR_POINTER_REF,
2249                         "", hf_samr_entries, 0);
2250         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2251                                      hf_samr_rc, NULL);
2252         return offset;
2253 }
2254
2255 static int
2256 samr_dissect_enum_dom_groups_rqst(tvbuff_t *tvb, int offset, 
2257                              packet_info *pinfo, proto_tree *tree,
2258                              char *drep)
2259 {
2260         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2261                         hf_samr_hnd, NULL);
2262         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2263                         samr_dissect_pointer_long, NDR_POINTER_REF,
2264                         "", hf_samr_resume_hnd, 0);
2265         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2266                         hf_samr_mask, NULL);
2267         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2268                         hf_samr_pref_maxsize, NULL);
2269         return offset;
2270 }
2271
2272 static int
2273 samr_dissect_enum_dom_groups_reply(tvbuff_t *tvb, int offset, 
2274                              packet_info *pinfo, proto_tree *tree,
2275                              char *drep)
2276 {
2277         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2278                         samr_dissect_pointer_long, NDR_POINTER_REF,
2279                         "", hf_samr_resume_hnd, 0);
2280         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2281                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2282                         "", hf_samr_group_name, 0);
2283         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2284                         samr_dissect_pointer_long, NDR_POINTER_REF,
2285                         "", hf_samr_entries, 0);
2286         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2287                         hf_samr_rc, NULL);
2288         return offset;
2289 }
2290
2291 static int
2292 samr_dissect_enum_dom_alias_reply(tvbuff_t *tvb, int offset, 
2293                              packet_info *pinfo, proto_tree *tree,
2294                              char *drep)
2295 {
2296         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2297                         samr_dissect_pointer_long, NDR_POINTER_REF,
2298                         "", hf_samr_resume_hnd, 0);
2299         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2300                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2301                         "", hf_samr_alias_name, 0);
2302         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2303                         samr_dissect_pointer_long, NDR_POINTER_REF,
2304                         "", hf_samr_entries, 0);
2305         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2306                         hf_samr_rc, NULL);
2307         return offset;
2308 }
2309
2310 static int
2311 samr_dissect_get_members_in_alias_reply(tvbuff_t *tvb, int offset, 
2312                         packet_info *pinfo, proto_tree *tree,
2313                         char *drep)
2314 {
2315         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2316                         samr_dissect_PSID_ARRAY, NDR_POINTER_REF,
2317                         "", -1, 0);
2318         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2319                         hf_samr_rc, NULL);
2320
2321         return offset;
2322 }
2323
2324 static int
2325 samr_dissect_LOGON_HOURS_entry(tvbuff_t *tvb, int offset, 
2326                              packet_info *pinfo, proto_tree *tree,
2327                              char *drep)
2328 {
2329         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
2330                         hf_samr_unknown_char, NULL);
2331         return offset;
2332 }
2333
2334 static int
2335 samr_dissect_LOGON_HOURS_hours(tvbuff_t *tvb, int offset, 
2336                              packet_info *pinfo, proto_tree *parent_tree,
2337                              char *drep)
2338 {
2339         proto_item *item=NULL;
2340         proto_tree *tree=NULL;
2341         int old_offset=offset;
2342
2343         if(parent_tree){
2344                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2345                         "LOGON_HOURS:");
2346                 tree = proto_item_add_subtree(item, ett_samr_logon_hours_hours);
2347         }
2348
2349         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
2350                         samr_dissect_LOGON_HOURS_entry);
2351
2352         proto_item_set_len(item, offset-old_offset);
2353         return offset;
2354
2355         return offset;
2356 }
2357
2358 int
2359 dissect_ndr_nt_LOGON_HOURS(tvbuff_t *tvb, int offset, 
2360                         packet_info *pinfo, proto_tree *parent_tree,
2361                         char *drep)
2362 {
2363         proto_item *item=NULL;
2364         proto_tree *tree=NULL;
2365         int old_offset=offset;
2366
2367         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
2368
2369         if(parent_tree){
2370                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2371                         "LOGON_HOURS:");
2372                 tree = proto_item_add_subtree(item, ett_samr_logon_hours);
2373         }
2374
2375         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2376                                 hf_samr_divisions, NULL);
2377         /* XXX - is this a bitmask like the "logon hours" field in the
2378            Remote API call "NetUserGetInfo()" with an information level
2379            of 11? */
2380         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2381                         samr_dissect_LOGON_HOURS_hours, NDR_POINTER_UNIQUE,
2382                         "LOGON_HOURS", -1, 0);
2383
2384         proto_item_set_len(item, offset-old_offset);
2385         return offset;
2386 }
2387
2388
2389 static int
2390 samr_dissect_USER_INFO_1(tvbuff_t *tvb, int offset, 
2391                         packet_info *pinfo, proto_tree *parent_tree,
2392                         char *drep)
2393 {
2394         proto_item *item=NULL;
2395         proto_tree *tree=NULL;
2396         int old_offset=offset;
2397
2398         if(parent_tree){
2399                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2400                         "USER_INFO_1:");
2401                 tree = proto_item_add_subtree(item, ett_samr_user_info_1);
2402         }
2403
2404         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2405                                 hf_samr_acct_name, 0);
2406         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2407                                 hf_samr_full_name, 0);
2408         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2409         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2410                                 hf_samr_home, 0);
2411         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2412                                 hf_samr_script, 0);
2413
2414         proto_item_set_len(item, offset-old_offset);
2415         return offset;
2416 }
2417
2418 static int
2419 samr_dissect_USER_INFO_2(tvbuff_t *tvb, int offset, 
2420                         packet_info *pinfo, proto_tree *parent_tree,
2421                         char *drep)
2422 {
2423         proto_item *item=NULL;
2424         proto_tree *tree=NULL;
2425         int old_offset=offset;
2426
2427         if(parent_tree){
2428                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2429                         "USER_INFO_2:");
2430                 tree = proto_item_add_subtree(item, ett_samr_user_info_2);
2431         }
2432
2433         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2434                                 hf_samr_acct_name, 0);
2435         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2436                                 hf_samr_full_name, 0);
2437         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2438                                 hf_samr_bad_pwd_count, NULL);
2439         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2440                                 hf_samr_logon_count, NULL);
2441
2442         proto_item_set_len(item, offset-old_offset);
2443         return offset;
2444 }
2445
2446 static int
2447 samr_dissect_USER_INFO_3(tvbuff_t *tvb, int offset, 
2448                         packet_info *pinfo, proto_tree *parent_tree,
2449                         char *drep)
2450 {
2451         proto_item *item=NULL;
2452         proto_tree *tree=NULL;
2453         int old_offset=offset;
2454
2455         if(parent_tree){
2456                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2457                         "USER_INFO_3:");
2458                 tree = proto_item_add_subtree(item, ett_samr_user_info_3);
2459         }
2460
2461         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2462                                 hf_samr_acct_name, 0);
2463         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2464                                 hf_samr_full_name, 0);
2465         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2466                                 hf_samr_rid, NULL);
2467         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2468                                 hf_samr_group, NULL);
2469         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2470                                 hf_samr_home, 0);
2471         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2472                                 hf_samr_home_drive, 0);
2473         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2474                                 hf_samr_script, 0);
2475         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2476                                 hf_samr_acct_desc, 0);
2477         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2478                                 hf_samr_workstations, 0);
2479         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2480                                 hf_samr_logon_time);
2481         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2482                                 hf_samr_logoff_time);
2483         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2484                                 hf_samr_pwd_last_set_time);
2485         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2486                                 hf_samr_pwd_can_change_time);
2487         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2488                                 hf_samr_pwd_must_change_time);
2489         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2490         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2491                                 hf_samr_logon_count, NULL);
2492         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2493                                 hf_samr_bad_pwd_count, NULL);
2494         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2495
2496         proto_item_set_len(item, offset-old_offset);
2497         return offset;
2498 }
2499
2500 static int
2501 samr_dissect_USER_INFO_5(tvbuff_t *tvb, int offset, 
2502                         packet_info *pinfo, proto_tree *parent_tree,
2503                         char *drep)
2504 {
2505         proto_item *item=NULL;
2506         proto_tree *tree=NULL;
2507         int old_offset=offset;
2508
2509         if(parent_tree){
2510                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2511                         "USER_INFO_5:");
2512                 tree = proto_item_add_subtree(item, ett_samr_user_info_5);
2513         }
2514
2515         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2516                                 hf_samr_acct_name, 0);
2517         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2518                                 hf_samr_full_name, 0);
2519         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2520                                 hf_samr_rid, NULL);
2521         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2522                                 hf_samr_group, NULL);
2523         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2524                                 hf_samr_country, NULL);
2525         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2526                                 hf_samr_codepage, NULL);
2527         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2528                                 hf_samr_home, 0);
2529         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2530                                 hf_samr_home_drive, 0);
2531         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2532                                 hf_samr_script, 0);
2533         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2534                                 hf_samr_acct_desc, 0);
2535         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2536                                 hf_samr_workstations, 0);
2537         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2538                                 hf_samr_logon_time);
2539         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2540                                 hf_samr_logoff_time);
2541         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2542         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2543                                 hf_samr_bad_pwd_count, NULL);
2544         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2545                                 hf_samr_logon_count, NULL);
2546         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2547                                 hf_samr_pwd_last_set_time);
2548         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2549                                 hf_samr_acct_expiry_time);
2550         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2551
2552         proto_item_set_len(item, offset-old_offset);
2553         return offset;
2554 }
2555
2556 static int
2557 samr_dissect_USER_INFO_6(tvbuff_t *tvb, int offset, 
2558                         packet_info *pinfo, proto_tree *parent_tree,
2559                         char *drep)
2560 {
2561         proto_item *item=NULL;
2562         proto_tree *tree=NULL;
2563         int old_offset=offset;
2564
2565         if(parent_tree){
2566                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2567                         "USER_INFO_6:");
2568                 tree = proto_item_add_subtree(item, ett_samr_user_info_6);
2569         }
2570
2571         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2572                                 hf_samr_acct_name, 0);
2573         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2574                                 hf_samr_full_name, 0);
2575
2576         proto_item_set_len(item, offset-old_offset);
2577         return offset;
2578 }
2579
2580 static int
2581 samr_dissect_USER_INFO_18(tvbuff_t *tvb, int offset, 
2582                         packet_info *pinfo, proto_tree *parent_tree,
2583                         char *drep)
2584 {
2585         proto_item *item=NULL;
2586         proto_tree *tree=NULL;
2587         int old_offset=offset;
2588
2589         if(parent_tree){
2590                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2591                         "USER_INFO_18:");
2592                 tree = proto_item_add_subtree(item, ett_samr_user_info_18);
2593         }
2594
2595         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2596         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2597         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2598                         hf_samr_unknown_char, NULL);
2599         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2600                         hf_samr_unknown_char, NULL);
2601         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2602                         hf_samr_unknown_char, NULL);
2603
2604         proto_item_set_len(item, offset-old_offset);
2605         return offset;
2606 }
2607
2608 static int
2609 samr_dissect_USER_INFO_19(tvbuff_t *tvb, int offset, 
2610                         packet_info *pinfo, proto_tree *parent_tree,
2611                         char *drep)
2612 {
2613         proto_item *item=NULL;
2614         proto_tree *tree=NULL;
2615         int old_offset=offset;
2616
2617         if(parent_tree){
2618                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2619                         "USER_INFO_19:");
2620                 tree = proto_item_add_subtree(item, ett_samr_user_info_19);
2621         }
2622
2623         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2624         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2625                                 hf_samr_logon_time);
2626         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2627                                 hf_samr_logoff_time);
2628         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2629                                 hf_samr_bad_pwd_count, NULL);
2630         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2631                                 hf_samr_logon_count, NULL);
2632
2633         proto_item_set_len(item, offset-old_offset);
2634         return offset;
2635 }
2636
2637 static int
2638 samr_dissect_BUFFER_entry(tvbuff_t *tvb, int offset, 
2639                              packet_info *pinfo, proto_tree *tree,
2640                              char *drep)
2641 {
2642         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2643                         hf_samr_unknown_char, NULL);
2644         return offset;
2645 }
2646
2647
2648 static int
2649 samr_dissect_BUFFER_buffer(tvbuff_t *tvb, int offset, 
2650                              packet_info *pinfo, proto_tree *parent_tree,
2651                              char *drep)
2652 {
2653         proto_item *item=NULL;
2654         proto_tree *tree=NULL;
2655         int old_offset=offset;
2656
2657         if(parent_tree){
2658                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2659                         "BUFFER:");
2660                 tree = proto_item_add_subtree(item, ett_samr_buffer_buffer);
2661         }
2662
2663         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2664                         samr_dissect_BUFFER_entry);
2665
2666         proto_item_set_len(item, offset-old_offset);
2667         return offset;
2668
2669         return offset;
2670 }
2671
2672 static int
2673 samr_dissect_BUFFER(tvbuff_t *tvb, int offset, 
2674                         packet_info *pinfo, proto_tree *parent_tree,
2675                         char *drep)
2676 {
2677         proto_item *item=NULL;
2678         proto_tree *tree=NULL;
2679         int old_offset=offset;
2680
2681         if(parent_tree){
2682                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2683                         "BUFFER:");
2684                 tree = proto_item_add_subtree(item, ett_samr_buffer);
2685         }
2686         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2687                                 hf_samr_count, NULL);
2688         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2689                         samr_dissect_BUFFER_buffer, NDR_POINTER_UNIQUE,
2690                         "BUFFER", -1, 0);
2691
2692         proto_item_set_len(item, offset-old_offset);
2693         return offset;
2694 }
2695
2696 static int
2697 samr_dissect_BUFFER_ptr(tvbuff_t *tvb, int offset, 
2698                         packet_info *pinfo, proto_tree *tree,
2699                         char *drep)
2700 {
2701         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2702                         samr_dissect_BUFFER, NDR_POINTER_UNIQUE,
2703                         "BUFFER", -1, 0);
2704         return offset;
2705 }
2706
2707 static int
2708 samr_dissect_USER_INFO_21(tvbuff_t *tvb, int offset, 
2709                         packet_info *pinfo, proto_tree *parent_tree,
2710                         char *drep)
2711 {
2712         proto_item *item=NULL;
2713         proto_tree *tree=NULL;
2714         int old_offset=offset;
2715
2716         if(parent_tree){
2717                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2718                         "USER_INFO_21:");
2719                 tree = proto_item_add_subtree(item, ett_samr_user_info_21);
2720         }
2721
2722         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2723                                 hf_samr_logon_time);
2724         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2725                                 hf_samr_logoff_time);
2726         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2727                                 hf_samr_kickoff_time);
2728         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2729                                 hf_samr_pwd_last_set_time);
2730         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2731                                 hf_samr_pwd_can_change_time);
2732         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2733                                 hf_samr_pwd_must_change_time);
2734         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2735                                 hf_samr_acct_name, 2);
2736         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2737                                 hf_samr_full_name, 0);
2738         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2739                                 hf_samr_home, 0);
2740         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2741                                 hf_samr_home_drive, 0);
2742         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2743                                 hf_samr_script, 0);
2744         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2745                                 hf_samr_profile, 0);
2746         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2747                                 hf_samr_acct_desc, 0);
2748         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2749                                 hf_samr_workstations, 0);
2750         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2751                                 hf_samr_comment, 0);
2752         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2753                                 hf_samr_parameters, 0);
2754         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2755                                 hf_samr_unknown_string, 0);
2756         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2757                                 hf_samr_unknown_string, 0);
2758         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2759                                 hf_samr_unknown_string, 0);
2760         offset = samr_dissect_BUFFER(tvb, offset, pinfo, tree, drep);
2761         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2762                                 hf_samr_rid, NULL);
2763         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2764                                 hf_samr_group, NULL);
2765         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2766         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2767                                 hf_samr_unknown_long, NULL);
2768         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2769         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2770                                 hf_samr_bad_pwd_count, NULL);
2771         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2772                                 hf_samr_logon_count, NULL);
2773         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2774                                 hf_samr_country, NULL);
2775         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2776                                 hf_samr_codepage, NULL);
2777         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2778                                 hf_samr_nt_pwd_set, NULL);
2779         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2780                                 hf_samr_lm_pwd_set, NULL);
2781         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2782                                 hf_samr_pwd_expired, NULL);
2783         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2784                                 hf_samr_unknown_char, NULL);
2785
2786         proto_item_set_len(item, offset-old_offset);
2787         return offset;
2788 }
2789
2790 static int
2791 samr_dissect_USER_INFO_22(tvbuff_t *tvb, int offset, 
2792                         packet_info *pinfo, proto_tree *parent_tree,
2793                         char *drep)
2794 {
2795         proto_item *item=NULL;
2796         proto_tree *tree=NULL;
2797         int old_offset=offset;
2798
2799         if(parent_tree){
2800                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2801                         "USER_INFO_22:");
2802                 tree = proto_item_add_subtree(item, ett_samr_user_info_22);
2803         }
2804
2805         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
2806         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
2807                         hf_samr_revision, NULL);
2808
2809         proto_item_set_len(item, offset-old_offset);
2810         return offset;
2811 }
2812
2813 static int
2814 samr_dissect_USER_INFO_23(tvbuff_t *tvb, int offset, 
2815                         packet_info *pinfo, proto_tree *parent_tree,
2816                         char *drep)
2817 {
2818         proto_item *item=NULL;
2819         proto_tree *tree=NULL;
2820         int old_offset=offset;
2821
2822         if(parent_tree){
2823                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2824                         "USER_INFO_23:");
2825                 tree = proto_item_add_subtree(item, ett_samr_user_info_23);
2826         }
2827
2828         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
2829         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
2830
2831         proto_item_set_len(item, offset-old_offset);
2832         return offset;
2833 }
2834
2835 static int
2836 samr_dissect_USER_INFO_24(tvbuff_t *tvb, int offset, 
2837                         packet_info *pinfo, proto_tree *parent_tree,
2838                         char *drep)
2839 {
2840         proto_item *item=NULL;
2841         proto_tree *tree=NULL;
2842         int old_offset=offset;
2843
2844         if(parent_tree){
2845                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2846                         "USER_INFO_24:");
2847                 tree = proto_item_add_subtree(item, ett_samr_user_info_24);
2848         }
2849
2850         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
2851         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2852                                 hf_samr_unknown_char, NULL);
2853
2854         proto_item_set_len(item, offset-old_offset);
2855         return offset;
2856 }
2857
2858 static int
2859 samr_dissect_USER_INFO (tvbuff_t *tvb, int offset, 
2860                              packet_info *pinfo, proto_tree *parent_tree,
2861                              char *drep)
2862 {
2863         proto_item *item=NULL;
2864         proto_tree *tree=NULL;
2865         int old_offset=offset;
2866         guint16 level;
2867
2868         if(parent_tree){
2869                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2870                         "USER_INFO:");
2871                 tree = proto_item_add_subtree(item, ett_samr_user_info);
2872         }
2873         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2874                                      hf_samr_level, &level);
2875
2876         switch(level){
2877         case 1: 
2878                 offset = samr_dissect_USER_INFO_1(
2879                                 tvb, offset, pinfo, tree, drep);
2880                 break;
2881         case 2: 
2882                 offset = samr_dissect_USER_INFO_2(
2883                                 tvb, offset, pinfo, tree, drep);
2884                 break;
2885         case 3: 
2886                 offset = samr_dissect_USER_INFO_3(
2887                                 tvb, offset, pinfo, tree, drep);
2888                 break;
2889         case 4: 
2890                 offset = dissect_ndr_nt_LOGON_HOURS(
2891                                 tvb, offset, pinfo, tree, drep);
2892                 break;
2893         case 5: 
2894                 offset = samr_dissect_USER_INFO_5(
2895                                 tvb, offset, pinfo, tree, drep);
2896                 break;
2897         case 6: 
2898                 offset = samr_dissect_USER_INFO_6(
2899                                 tvb, offset, pinfo, tree, drep);
2900                 break;
2901         case 7:
2902                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2903                                 hf_samr_full_name, 0);
2904                 break;
2905         case 8:
2906                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2907                                 hf_samr_acct_desc, 0);
2908                 break;
2909         case 9:
2910                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2911                                              hf_samr_unknown_long, NULL);
2912                 break;
2913         case 10:        
2914                 offset = samr_dissect_USER_INFO_6(
2915                                 tvb, offset, pinfo, tree, drep);
2916                 break;
2917         case 11:
2918                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2919                                 hf_samr_home, 0);
2920                 break;
2921         case 12:
2922                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2923                                 hf_samr_home_drive, 0);
2924                 break;
2925         case 13:
2926                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2927                                 hf_samr_script, 0);
2928                 break;
2929         case 14:
2930                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2931                                 hf_samr_workstations, 0);
2932                 break;
2933         case 16:
2934                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2935                                              hf_samr_unknown_long, NULL);
2936                 break;
2937         case 17:
2938                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2939                                         hf_samr_unknown_time);
2940                 break;
2941         case 18:        
2942                 offset = samr_dissect_USER_INFO_18(
2943                                 tvb, offset, pinfo, tree, drep);
2944                 break;
2945         case 19:        
2946                 offset = samr_dissect_USER_INFO_19(
2947                                 tvb, offset, pinfo, tree, drep);
2948                 break;
2949         case 20:
2950                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2951                                 hf_samr_profile, 0);
2952                 break;
2953         case 21:        
2954                 offset = samr_dissect_USER_INFO_21(
2955                                 tvb, offset, pinfo, tree, drep);
2956                 break;
2957         case 22:        
2958                 offset = samr_dissect_USER_INFO_22(
2959                                 tvb, offset, pinfo, tree, drep);
2960                 break;
2961         case 23:        
2962                 offset = samr_dissect_USER_INFO_23(
2963                                 tvb, offset, pinfo, tree, drep);
2964                 break;
2965         case 24:        
2966                 offset = samr_dissect_USER_INFO_24(
2967                                 tvb, offset, pinfo, tree, drep);
2968                 break;
2969         }
2970
2971         proto_item_set_len(item, offset-old_offset);
2972         return offset;
2973 }
2974
2975 static int
2976 samr_dissect_USER_INFO_ptr(tvbuff_t *tvb, int offset, 
2977                         packet_info *pinfo, proto_tree *tree,
2978                         char *drep)
2979 {
2980         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2981                         samr_dissect_USER_INFO, NDR_POINTER_UNIQUE,
2982                         "USER_INFO pointer", -1, 0);
2983         return offset;
2984 }
2985
2986 static int
2987 samr_dissect_set_information_user2_rqst(tvbuff_t *tvb, int offset, 
2988                         packet_info *pinfo, proto_tree *tree,
2989                         char *drep)
2990 {
2991         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2992                         hf_samr_hnd, NULL);
2993         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2994                         hf_samr_level, NULL);
2995         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2996                         samr_dissect_USER_INFO, NDR_POINTER_REF,
2997                         "", -1, 0);
2998
2999         return offset;
3000 }
3001
3002 static int
3003 samr_dissect_query_userinfo_reply(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_ptr, NDR_POINTER_REF,
3009                         "", -1, 0);
3010         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3011                         hf_samr_rc, NULL);
3012
3013         return offset;
3014 }
3015
3016 static int
3017 samr_dissect_MEMBER_ARRAY_type(tvbuff_t *tvb, int offset, 
3018                         packet_info *pinfo, proto_tree *tree,
3019                         char *drep)
3020 {
3021         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3022                                 hf_samr_type, NULL);
3023
3024         return offset;
3025 }
3026
3027
3028 static int
3029 samr_dissect_MEMBER_ARRAY_types(tvbuff_t *tvb, int offset, 
3030                         packet_info *pinfo, proto_tree *parent_tree,
3031                         char *drep)
3032 {
3033         proto_item *item=NULL;
3034         proto_tree *tree=NULL;
3035         int old_offset=offset;
3036
3037         if(parent_tree){
3038                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3039                         "MEMBER_ARRAY_types:");
3040                 tree = proto_item_add_subtree(item, ett_samr_member_array_types);
3041         }
3042
3043         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3044                         samr_dissect_MEMBER_ARRAY_type);
3045
3046         proto_item_set_len(item, offset-old_offset);
3047         return offset;
3048
3049         return offset;
3050 }
3051
3052 static int
3053 samr_dissect_MEMBER_ARRAY_rid(tvbuff_t *tvb, int offset, 
3054                         packet_info *pinfo, proto_tree *tree,
3055                         char *drep)
3056 {
3057         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3058                                 hf_samr_rid, NULL);
3059
3060         return offset;
3061 }
3062
3063
3064 static int
3065 samr_dissect_MEMBER_ARRAY_rids(tvbuff_t *tvb, int offset, 
3066                         packet_info *pinfo, proto_tree *parent_tree,
3067                         char *drep)
3068 {
3069         proto_item *item=NULL;
3070         proto_tree *tree=NULL;
3071         int old_offset=offset;
3072
3073         if(parent_tree){
3074                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3075                         "MEMBER_ARRAY_rids:");
3076                 tree = proto_item_add_subtree(item, ett_samr_member_array_rids);
3077         }
3078
3079         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3080                         samr_dissect_MEMBER_ARRAY_rid);
3081
3082         proto_item_set_len(item, offset-old_offset);
3083         return offset;
3084
3085         return offset;
3086 }
3087
3088 static int
3089 samr_dissect_MEMBER_ARRAY(tvbuff_t *tvb, int offset, 
3090                         packet_info *pinfo, proto_tree *parent_tree,
3091                         char *drep)
3092 {
3093         guint32 count;
3094         proto_item *item=NULL;
3095         proto_tree *tree=NULL;
3096         int old_offset=offset;
3097
3098         if(parent_tree){
3099                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3100                         "MEMBER_ARRAY:");
3101                 tree = proto_item_add_subtree(item, ett_samr_member_array);
3102         }
3103
3104         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3105                         hf_samr_count, &count);
3106         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3107                         samr_dissect_MEMBER_ARRAY_rids, NDR_POINTER_UNIQUE,
3108                         "RIDs", -1, 0);
3109         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3110                         samr_dissect_MEMBER_ARRAY_types, NDR_POINTER_UNIQUE,
3111                         "Types", -1, 0);
3112
3113         proto_item_set_len(item, offset-old_offset);
3114         return offset;
3115 }
3116
3117 static int
3118 samr_dissect_MEMBER_ARRAY_ptr(tvbuff_t *tvb, int offset, 
3119                         packet_info *pinfo, proto_tree *tree,
3120                         char *drep)
3121 {
3122         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3123                         samr_dissect_MEMBER_ARRAY, NDR_POINTER_UNIQUE,
3124                         "MEMBER_ARRAY", -1, 0);
3125         return offset;
3126 }
3127
3128 static int
3129 samr_dissect_query_groupmem_reply(tvbuff_t *tvb, int offset, 
3130                         packet_info *pinfo, proto_tree *tree,
3131                         char *drep)
3132 {
3133         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3134                         samr_dissect_MEMBER_ARRAY_ptr, NDR_POINTER_REF,
3135                         "", -1, 0);
3136         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3137                         hf_samr_rc, NULL);
3138
3139         return offset;
3140 }
3141
3142 static int
3143 samr_dissect_set_sec_object_rqst(tvbuff_t *tvb, int offset, 
3144                         packet_info *pinfo, proto_tree *tree,
3145                         char *drep)
3146 {
3147         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3148                         hf_samr_hnd, NULL);
3149         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3150                         hf_samr_info_type, NULL);
3151         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3152                         samr_dissect_BUFFER, NDR_POINTER_REF,
3153                         "", -1, 0);
3154
3155         return offset;
3156 }
3157
3158 static int
3159 samr_dissect_query_sec_object_rqst(tvbuff_t *tvb, int offset, 
3160                         packet_info *pinfo, proto_tree *tree,
3161                         char *drep)
3162 {
3163     &nbs