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