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, offset, pinfo, tree, drep,
3173                                 hf_samr_unknown_string, 0);
3174         offset = samr_dissect_BUFFER(tvb, offset, pinfo, tree, drep);
3175         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3176                                 hf_samr_rid, NULL);
3177         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3178                                 hf_samr_group, NULL);
3179         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
3180         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3181                                 hf_samr_unknown_long, NULL);
3182         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
3183         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3184                                 hf_samr_bad_pwd_count, NULL);
3185         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3186                                 hf_samr_logon_count, NULL);
3187         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3188                                 hf_samr_country, NULL);
3189         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
3190                                 hf_samr_codepage, NULL);
3191         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3192                                 hf_samr_nt_pwd_set, NULL);
3193         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3194                                 hf_samr_lm_pwd_set, NULL);
3195         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3196                                 hf_samr_pwd_expired, NULL);
3197         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3198                                 hf_samr_unknown_char, NULL);
3199
3200         proto_item_set_len(item, offset-old_offset);
3201         return offset;
3202 }
3203
3204 static int
3205 samr_dissect_USER_INFO_22(tvbuff_t *tvb, int offset, 
3206                         packet_info *pinfo, proto_tree *parent_tree,
3207                         char *drep)
3208 {
3209         proto_item *item=NULL;
3210         proto_tree *tree=NULL;
3211         int old_offset=offset;
3212
3213         if(parent_tree){
3214                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3215                         "USER_INFO_22:");
3216                 tree = proto_item_add_subtree(item, ett_samr_user_info_22);
3217         }
3218
3219         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
3220         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
3221                         hf_samr_revision, NULL);
3222
3223         proto_item_set_len(item, offset-old_offset);
3224         return offset;
3225 }
3226
3227 static int
3228 samr_dissect_USER_INFO_23(tvbuff_t *tvb, int offset, 
3229                         packet_info *pinfo, proto_tree *parent_tree,
3230                         char *drep)
3231 {
3232         proto_item *item=NULL;
3233         proto_tree *tree=NULL;
3234         int old_offset=offset;
3235
3236         if(parent_tree){
3237                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3238                         "USER_INFO_23:");
3239                 tree = proto_item_add_subtree(item, ett_samr_user_info_23);
3240         }
3241
3242         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
3243         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
3244
3245         proto_item_set_len(item, offset-old_offset);
3246         return offset;
3247 }
3248
3249 static int
3250 samr_dissect_USER_INFO_24(tvbuff_t *tvb, int offset, 
3251                         packet_info *pinfo, proto_tree *parent_tree,
3252                         char *drep)
3253 {
3254         proto_item *item=NULL;
3255         proto_tree *tree=NULL;
3256         int old_offset=offset;
3257
3258         if(parent_tree){
3259                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3260                         "USER_INFO_24:");
3261                 tree = proto_item_add_subtree(item, ett_samr_user_info_24);
3262         }
3263
3264         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
3265         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3266                                 hf_samr_unknown_char, NULL);
3267
3268         proto_item_set_len(item, offset-old_offset);
3269         return offset;
3270 }
3271
3272 static int
3273 samr_dissect_USER_INFO (tvbuff_t *tvb, int offset, 
3274                              packet_info *pinfo, proto_tree *parent_tree,
3275                              char *drep)
3276 {
3277         proto_item *item=NULL;
3278         proto_tree *tree=NULL;
3279         int old_offset=offset;
3280         guint16 level;
3281
3282         if(parent_tree){
3283                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3284                         "USER_INFO:");
3285                 tree = proto_item_add_subtree(item, ett_samr_user_info);
3286         }
3287         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3288                                      hf_samr_level, &level);
3289
3290         switch(level){
3291         case 1: 
3292                 offset = samr_dissect_USER_INFO_1(
3293                                 tvb, offset, pinfo, tree, drep);
3294                 break;
3295         case 2: 
3296                 offset = samr_dissect_USER_INFO_2(
3297                                 tvb, offset, pinfo, tree, drep);
3298                 break;
3299         case 3: 
3300                 offset = samr_dissect_USER_INFO_3(
3301                                 tvb, offset, pinfo, tree, drep);
3302                 break;
3303         case 4: 
3304                 offset = dissect_ndr_nt_LOGON_HOURS(
3305                                 tvb, offset, pinfo, tree, drep);
3306                 break;
3307         case 5: 
3308                 offset = samr_dissect_USER_INFO_5(
3309                                 tvb, offset, pinfo, tree, drep);
3310                 break;
3311         case 6: 
3312                 offset = samr_dissect_USER_INFO_6(
3313                                 tvb, offset, pinfo, tree, drep);
3314                 break;
3315         case 7:
3316                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3317                                 hf_samr_full_name, 0);
3318                 break;
3319         case 8:
3320                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3321                                 hf_samr_acct_desc, 0);
3322                 break;
3323         case 9:
3324                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3325                                              hf_samr_unknown_long, NULL);
3326                 break;
3327         case 10:        
3328                 offset = samr_dissect_USER_INFO_6(
3329                                 tvb, offset, pinfo, tree, drep);
3330                 break;
3331         case 11:
3332                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3333                                 hf_samr_home, 0);
3334                 break;
3335         case 12:
3336                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3337                                 hf_samr_home_drive, 0);
3338                 break;
3339         case 13:
3340                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3341                                 hf_samr_script, 0);
3342                 break;
3343         case 14:
3344                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3345                                 hf_samr_workstations, 0);
3346                 break;
3347         case 16:
3348                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3349                                              hf_samr_unknown_long, NULL);
3350                 break;
3351         case 17:
3352                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3353                                         hf_samr_unknown_time);
3354                 break;
3355         case 18:        
3356                 offset = samr_dissect_USER_INFO_18(
3357                                 tvb, offset, pinfo, tree, drep);
3358                 break;
3359         case 19:        
3360                 offset = samr_dissect_USER_INFO_19(
3361                                 tvb, offset, pinfo, tree, drep);
3362                 break;
3363         case 20:
3364                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3365                                 hf_samr_profile, 0);
3366                 break;
3367         case 21:        
3368                 offset = samr_dissect_USER_INFO_21(
3369                                 tvb, offset, pinfo, tree, drep);
3370                 break;
3371         case 22:        
3372                 offset = samr_dissect_USER_INFO_22(
3373                                 tvb, offset, pinfo, tree, drep);
3374                 break;
3375         case 23:        
3376                 offset = samr_dissect_USER_INFO_23(
3377                                 tvb, offset, pinfo, tree, drep);
3378                 break;
3379         case 24:        
3380                 offset = samr_dissect_USER_INFO_24(
3381                                 tvb, offset, pinfo, tree, drep);
3382                 break;
3383         }
3384
3385         proto_item_set_len(item, offset-old_offset);
3386         return offset;
3387 }
3388
3389 static int
3390 samr_dissect_USER_INFO_ptr(tvbuff_t *tvb, int offset, 
3391                         packet_info *pinfo, proto_tree *tree,
3392                         char *drep)
3393 {
3394         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3395                         samr_dissect_USER_INFO, NDR_POINTER_UNIQUE,
3396                         "USER_INFO pointer", -1, 0);
3397         return offset;
3398 }
3399
3400 static int
3401 samr_dissect_set_information_user2_rqst(tvbuff_t *tvb, int offset, 
3402                                         packet_info *pinfo, proto_tree *tree,
3403                                         char *drep)
3404 {
3405         if (check_col(pinfo->cinfo, COL_INFO))
3406                 col_set_str(pinfo->cinfo, COL_INFO, "SetUserInfo request");
3407
3408         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3409                                        hf_samr_hnd, NULL);
3410
3411         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3412                         hf_samr_level, NULL);
3413
3414         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3415                         samr_dissect_USER_INFO, NDR_POINTER_REF,
3416                         "", -1, 0);
3417
3418         return offset;
3419 }
3420
3421 static int
3422 samr_dissect_set_information_user2_reply(tvbuff_t *tvb, int offset, 
3423                                          packet_info *pinfo, proto_tree *tree, 
3424                                          char *drep)
3425 {
3426         if (check_col(pinfo->cinfo, COL_INFO))
3427                 col_set_str(pinfo->cinfo, COL_INFO, "SetUserInfo response");
3428
3429         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3430                                   hf_samr_rc, NULL);
3431
3432         return offset;
3433 }
3434
3435 static int
3436 samr_dissect_unknown_2f_rqst(tvbuff_t *tvb, int offset, 
3437                                  packet_info *pinfo, proto_tree *tree, 
3438                                  char *drep)
3439 {
3440         if (check_col(pinfo->cinfo, COL_INFO))
3441                 col_set_str(pinfo->cinfo, COL_INFO, "Unknown 0x2f request");
3442
3443         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3444                                        hf_samr_hnd, NULL);
3445
3446         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3447                         hf_samr_level, NULL);
3448
3449         return offset;
3450 }
3451
3452 static int
3453 samr_dissect_unknown_2f_reply(tvbuff_t *tvb, int offset, 
3454                         packet_info *pinfo, proto_tree *tree,
3455                         char *drep)
3456 {
3457         if (check_col(pinfo->cinfo, COL_INFO))
3458                 col_set_str(pinfo->cinfo, COL_INFO, "Unknown 0x2f response");
3459
3460         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3461                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
3462                         "", -1, 0);
3463
3464         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3465                         hf_samr_rc, NULL);
3466
3467         return offset;
3468 }
3469
3470 static int
3471 samr_dissect_MEMBER_ARRAY_type(tvbuff_t *tvb, int offset, 
3472                         packet_info *pinfo, proto_tree *tree,
3473                         char *drep)
3474 {
3475         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3476                                 hf_samr_type, NULL);
3477
3478         return offset;
3479 }
3480
3481
3482 static int
3483 samr_dissect_MEMBER_ARRAY_types(tvbuff_t *tvb, int offset, 
3484                         packet_info *pinfo, proto_tree *parent_tree,
3485                         char *drep)
3486 {
3487         proto_item *item=NULL;
3488         proto_tree *tree=NULL;
3489         int old_offset=offset;
3490
3491         if(parent_tree){
3492                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3493                         "MEMBER_ARRAY_types:");
3494                 tree = proto_item_add_subtree(item, ett_samr_member_array_types);
3495         }
3496
3497         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3498                         samr_dissect_MEMBER_ARRAY_type);
3499
3500         proto_item_set_len(item, offset-old_offset);
3501         return offset;
3502
3503         return offset;
3504 }
3505
3506 static int
3507 samr_dissect_MEMBER_ARRAY_rid(tvbuff_t *tvb, int offset, 
3508                         packet_info *pinfo, proto_tree *tree,
3509                         char *drep)
3510 {
3511         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3512                                 hf_samr_rid, NULL);
3513
3514         return offset;
3515 }
3516
3517
3518 static int
3519 samr_dissect_MEMBER_ARRAY_rids(tvbuff_t *tvb, int offset, 
3520                         packet_info *pinfo, proto_tree *parent_tree,
3521                         char *drep)
3522 {
3523         proto_item *item=NULL;
3524         proto_tree *tree=NULL;
3525         int old_offset=offset;
3526
3527         if(parent_tree){
3528                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3529                         "MEMBER_ARRAY_rids:");
3530                 tree = proto_item_add_subtree(item, ett_samr_member_array_rids);
3531         }
3532
3533         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3534                         samr_dissect_MEMBER_ARRAY_rid);
3535
3536         proto_item_set_len(item, offset-old_offset);
3537         return offset;
3538
3539         return offset;
3540 }
3541
3542 static int
3543 samr_dissect_MEMBER_ARRAY(tvbuff_t *tvb, int offset, 
3544                         packet_info *pinfo, proto_tree *parent_tree,
3545                         char *drep)
3546 {
3547         guint32 count;
3548         proto_item *item=NULL;
3549         proto_tree *tree=NULL;
3550         int old_offset=offset;
3551
3552         if(parent_tree){
3553                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3554                         "MEMBER_ARRAY:");
3555                 tree = proto_item_add_subtree(item, ett_samr_member_array);
3556         }
3557
3558         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3559                         hf_samr_count, &count);
3560         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3561                         samr_dissect_MEMBER_ARRAY_rids, NDR_POINTER_UNIQUE,
3562                         "RIDs", -1, 0);
3563         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3564                         samr_dissect_MEMBER_ARRAY_types, NDR_POINTER_UNIQUE,
3565                         "Types", -1, 0);
3566
3567         proto_item_set_len(item, offset-old_offset);
3568         return offset;
3569 }
3570
3571 static int
3572 samr_dissect_MEMBER_ARRAY_ptr(tvbuff_t *tvb, int offset, 
3573                         packet_info *pinfo, proto_tree *tree,
3574                         char *drep)
3575 {
3576         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3577                         samr_dissect_MEMBER_ARRAY, NDR_POINTER_UNIQUE,
3578                         "MEMBER_ARRAY", -1, 0);
3579         return offset;
3580 }
3581
3582 static int
3583 samr_dissect_query_groupmem_rqst(tvbuff_t *tvb, int offset, 
3584                                  packet_info *pinfo, proto_tree *tree, 
3585                                  char *drep)
3586 {
3587         if (check_col(pinfo->cinfo, COL_INFO))
3588                 col_set_str(pinfo->cinfo, COL_INFO, "QueryGroupMem request");
3589
3590         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3591                                       hf_samr_hnd, NULL);
3592         return offset;
3593 }
3594
3595 static int
3596 samr_dissect_query_groupmem_reply(tvbuff_t *tvb, int offset, 
3597                         packet_info *pinfo, proto_tree *tree,
3598                         char *drep)
3599 {
3600         if (check_col(pinfo->cinfo, COL_INFO))
3601                 col_set_str(pinfo->cinfo, COL_INFO, "QueryGroupMem response");
3602
3603         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3604                         samr_dissect_MEMBER_ARRAY_ptr, NDR_POINTER_REF,
3605                         "", -1, 0);
3606
3607         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3608                                   hf_samr_rc, NULL);
3609
3610         return offset;
3611 }
3612
3613 static int
3614 samr_dissect_set_sec_object_rqst(tvbuff_t *tvb, int offset, 
3615                                  packet_info *pinfo, proto_tree *tree,
3616                                  char *drep)
3617 {
3618         if (check_col(pinfo->cinfo, COL_INFO))
3619                 col_set_str(pinfo->cinfo, COL_INFO, "SetSecObject request");
3620
3621         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3622                                        hf_samr_hnd, NULL);
3623
3624         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3625                         hf_samr_info_type, NULL);
3626
3627         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3628                         samr_dissect_BUFFER, NDR_POINTER_REF,
3629                         "", -1, 0);
3630
3631         return offset;
3632 }
3633
3634 static int
3635 samr_dissect_set_sec_object_reply(tvbuff_t *tvb, int offset, 
3636                                   packet_info *pinfo, proto_tree *tree, 
3637                                   char *drep)
3638 {
3639         if (check_col(pinfo->cinfo, COL_INFO))
3640                 col_set_str(pinfo->cinfo, COL_INFO, "SetSecObject response");
3641
3642         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3643                                   hf_samr_rc, NULL);
3644
3645         return offset;
3646 }
3647
3648 static int
3649 samr_dissect_query_sec_object_rqst(tvbuff_t *tvb, int offset, 
3650                                    packet_info *pinfo, proto_tree *tree,
3651                                    char *drep)
3652 {
3653         if (check_col(pinfo->cinfo, COL_INFO))
3654                 col_set_str(pinfo->cinfo, COL_INFO, "QuerySecObject request");
3655
3656         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3657                                        hf_samr_hnd, NULL);
3658
3659         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3660                         hf_samr_info_type, NULL);
3661
3662         return offset;
3663 }
3664
3665 static int
3666 samr_dissect_query_sec_object_reply(tvbuff_t *tvb, int offset, 
3667                         packet_info *pinfo, proto_tree *tree,
3668                         char *drep)
3669 {
3670         if (check_col(pinfo->cinfo, COL_INFO))
3671                 col_set_str(pinfo->cinfo, COL_INFO, "QuerySecObject response");
3672
3673         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3674                         samr_dissect_BUFFER_ptr, NDR_POINTER_REF,
3675                         "", -1, 0);
3676
3677         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3678                                   hf_samr_rc, NULL);
3679
3680         return offset;
3681 }
3682
3683 static int
3684 samr_dissect_LOOKUP_NAMES_name(tvbuff_t *tvb, int offset, 
3685                         packet_info *pinfo, proto_tree *tree,
3686                         char *drep)
3687 {
3688         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3689                                 hf_samr_acct_name, 1);
3690         return offset;
3691 }
3692
3693 static int
3694 samr_dissect_LOOKUP_NAMES(tvbuff_t *tvb, int offset, 
3695                         packet_info *pinfo, proto_tree *parent_tree,
3696                         char *drep)
3697 {
3698         proto_item *item=NULL;
3699         proto_tree *tree=NULL;
3700         int old_offset=offset;
3701
3702         if(parent_tree){
3703                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3704                         "NAMES:");
3705                 tree = proto_item_add_subtree(item, ett_samr_names);
3706         }
3707
3708         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3709                         samr_dissect_LOOKUP_NAMES_name);
3710
3711         proto_item_set_len(item, offset-old_offset);
3712         return offset;
3713 }
3714
3715
3716 static int
3717 samr_dissect_lookup_names_rqst(tvbuff_t *tvb, int offset, 
3718                                packet_info *pinfo, proto_tree *tree,
3719                                char *drep)
3720 {
3721         if (check_col(pinfo->cinfo, COL_INFO))
3722                 col_set_str(pinfo->cinfo, COL_INFO, "LookupNames request");
3723
3724         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3725                                        hf_samr_hnd, NULL);
3726
3727         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3728                         hf_samr_count, NULL);
3729
3730         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3731                         samr_dissect_LOOKUP_NAMES, NDR_POINTER_REF,
3732                         "", -1, 0);
3733
3734         return offset;
3735 }
3736
3737 static int
3738 samr_dissect_lookup_names_reply(tvbuff_t *tvb, int offset, 
3739                         packet_info *pinfo, proto_tree *tree,
3740                         char *drep)
3741 {
3742         if (check_col(pinfo->cinfo, COL_INFO))
3743                 col_set_str(pinfo->cinfo, COL_INFO, "LookupNames response");
3744
3745         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3746                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3747                         "", hf_samr_rid, 0);
3748         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3749                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3750                         "", hf_samr_type, 0);
3751
3752         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3753                                   hf_samr_rc, NULL);
3754
3755         return offset;
3756 }
3757
3758 static int
3759 samr_dissect_LOOKUP_RIDS_rid(tvbuff_t *tvb, int offset, 
3760                         packet_info *pinfo, proto_tree *tree,
3761                         char *drep)
3762 {
3763         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3764                                 hf_samr_rid, NULL);
3765
3766         return offset;
3767 }
3768
3769 static int
3770 samr_dissect_LOOKUP_RIDS(tvbuff_t *tvb, int offset, 
3771                         packet_info *pinfo, proto_tree *parent_tree,
3772                         char *drep)
3773 {
3774         proto_item *item=NULL;
3775         proto_tree *tree=NULL;
3776         int old_offset=offset;
3777
3778         if(parent_tree){
3779                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3780                         "RIDS:");
3781                 tree = proto_item_add_subtree(item, ett_samr_rids);
3782         }
3783
3784         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3785                         samr_dissect_LOOKUP_RIDS_rid);
3786
3787         proto_item_set_len(item, offset-old_offset);
3788         return offset;
3789 }
3790
3791
3792 static int
3793 samr_dissect_lookup_rids_rqst(tvbuff_t *tvb, int offset, 
3794                               packet_info *pinfo, proto_tree *tree,
3795                               char *drep)
3796 {
3797         if (check_col(pinfo->cinfo, COL_INFO))
3798                 col_set_str(pinfo->cinfo, COL_INFO, "LookupRids request");
3799
3800         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3801                                        hf_samr_hnd, NULL);
3802
3803         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3804                         hf_samr_count, NULL);
3805
3806         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3807                         samr_dissect_LOOKUP_RIDS, NDR_POINTER_REF,
3808                         "", -1, 0);
3809
3810         return offset;
3811 }
3812
3813 static int
3814 samr_dissect_UNICODE_STRING_ARRAY_name(tvbuff_t *tvb, int offset, 
3815                         packet_info *pinfo, proto_tree *tree,
3816                         char *drep)
3817 {
3818         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3819                                 hf_samr_acct_name, 0);
3820         return offset;
3821 }
3822
3823 static int
3824 samr_dissect_UNICODE_STRING_ARRAY_names(tvbuff_t *tvb, int offset, 
3825                         packet_info *pinfo, proto_tree *tree,
3826                         char *drep)
3827 {
3828         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3829                         samr_dissect_UNICODE_STRING_ARRAY_name);
3830         return offset;
3831 }
3832
3833 static int
3834 samr_dissect_UNICODE_STRING_ARRAY(tvbuff_t *tvb, int offset, 
3835                         packet_info *pinfo, proto_tree *parent_tree,
3836                         char *drep)
3837 {
3838         proto_item *item=NULL;
3839         proto_tree *tree=NULL;
3840         int old_offset=offset;
3841
3842         if(parent_tree){
3843                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3844                         "NAMES:");
3845                 tree = proto_item_add_subtree(item, ett_samr_names);
3846         }
3847
3848         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3849                         hf_samr_count, NULL);
3850
3851         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3852                         samr_dissect_UNICODE_STRING_ARRAY_names, NDR_POINTER_UNIQUE,
3853                         "Strings", -1, 0);
3854
3855         proto_item_set_len(item, offset-old_offset);
3856         return offset;
3857
3858         return offset;
3859 }
3860
3861
3862 static int
3863 samr_dissect_lookup_rids_reply(tvbuff_t *tvb, int offset, 
3864                         packet_info *pinfo, proto_tree *tree,
3865                         char *drep)
3866 {
3867         if (check_col(pinfo->cinfo, COL_INFO))
3868                 col_set_str(pinfo->cinfo, COL_INFO, "LookupRids response");
3869
3870         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3871                         samr_dissect_UNICODE_STRING_ARRAY, NDR_POINTER_REF,
3872                         "", hf_samr_rid, 0);
3873         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3874                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3875                         "", hf_samr_type, 0);
3876
3877         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3878                                   hf_samr_rc, NULL);
3879
3880         return offset;
3881 }
3882
3883 static int
3884 samr_dissect_close_hnd_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, 
3885                             proto_tree *tree, char *drep)
3886 {
3887         if (check_col(pinfo->cinfo, COL_INFO))
3888                 col_set_str(pinfo->cinfo, COL_INFO, "Close request");
3889
3890         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3891                                        hf_samr_hnd, NULL);
3892
3893         return offset;
3894 }
3895
3896 static int
3897 samr_dissect_close_hnd_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
3898                              proto_tree *tree, char *drep)
3899 {
3900         if (check_col(pinfo->cinfo, COL_INFO))
3901                 col_set_str(pinfo->cinfo, COL_INFO, "Close response");
3902
3903         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3904                                        hf_samr_hnd, NULL);
3905
3906         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3907                         hf_samr_rc, NULL);
3908
3909         return offset;
3910 }
3911
3912 static int
3913 samr_dissect_shutdown_sam_server_rqst(tvbuff_t *tvb, int offset, 
3914                                       packet_info *pinfo, proto_tree *tree, 
3915                                       char *drep)
3916 {
3917         if (check_col(pinfo->cinfo, COL_INFO))
3918                 col_set_str(pinfo->cinfo, COL_INFO, "SamShutdown request");
3919
3920         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3921                                       hf_samr_hnd, NULL);
3922
3923         return offset;
3924 }
3925
3926 static int
3927 samr_dissect_shutdown_sam_server_reply(tvbuff_t *tvb, int offset, 
3928                                       packet_info *pinfo, proto_tree *tree, 
3929                                       char *drep)
3930 {
3931         if (check_col(pinfo->cinfo, COL_INFO))
3932                 col_set_str(pinfo->cinfo, COL_INFO, "SamShutdown response");
3933
3934         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3935                                   hf_samr_rc, NULL);
3936
3937         return offset;
3938 }
3939
3940 static int
3941 samr_dissect_delete_dom_group_rqst(tvbuff_t *tvb, int offset, 
3942                                    packet_info *pinfo, proto_tree *tree, 
3943                                    char *drep)
3944 {
3945         if (check_col(pinfo->cinfo, COL_INFO))
3946                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteGroup request");
3947
3948         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3949                                       hf_samr_hnd, NULL);
3950
3951         return offset;
3952 }
3953
3954 static int
3955 samr_dissect_delete_dom_group_reply(tvbuff_t *tvb, int offset, 
3956                                     packet_info *pinfo, proto_tree *tree, 
3957                                     char *drep)
3958 {
3959         if (check_col(pinfo->cinfo, COL_INFO))
3960                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteGroup response");
3961
3962         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3963                                   hf_samr_rc, NULL);
3964
3965         return offset;
3966 }
3967
3968 static int
3969 samr_dissect_remove_member_from_group_rqst(tvbuff_t *tvb, int offset, 
3970                                            packet_info *pinfo, 
3971                                            proto_tree *tree, char *drep)
3972 {
3973         if (check_col(pinfo->cinfo, COL_INFO))
3974                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteGroupMem request");
3975
3976         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3977                                        hf_samr_hnd, NULL);
3978
3979         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3980                                      hf_samr_group, NULL);
3981
3982         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3983                                      hf_samr_rid, NULL);
3984
3985         return offset;
3986 }
3987
3988 static int
3989 samr_dissect_remove_member_from_group_reply(tvbuff_t *tvb, int offset, 
3990                                             packet_info *pinfo, 
3991                                             proto_tree *tree, char *drep)
3992 {
3993         if (check_col(pinfo->cinfo, COL_INFO))
3994                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteGroupMem response");
3995
3996         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3997                                   hf_samr_rc, NULL);
3998
3999         return offset;
4000 }
4001
4002 static int
4003 samr_dissect_delete_dom_alias_rqst(tvbuff_t *tvb, int offset, 
4004                                    packet_info *pinfo, proto_tree *tree, 
4005                                    char *drep)
4006 {
4007         if (check_col(pinfo->cinfo, COL_INFO))
4008                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteAlias request");
4009
4010         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
4011                                       hf_samr_hnd, NULL);
4012
4013         return offset;
4014 }
4015
4016 static int
4017 samr_dissect_delete_dom_alias_reply(tvbuff_t *tvb, int offset, 
4018                                     packet_info *pinfo, proto_tree *tree, 
4019                                     char *drep)
4020 {
4021         if (check_col(pinfo->cinfo, COL_INFO))
4022                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteAlias response");
4023
4024         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4025                                   hf_samr_rc, NULL);
4026
4027         return offset;
4028 }
4029
4030 static int
4031 samr_dissect_add_alias_member_rqst(tvbuff_t *tvb, int offset, 
4032                                    packet_info *pinfo, proto_tree *tree, 
4033                                    char *drep)
4034 {
4035         if (check_col(pinfo->cinfo, COL_INFO))
4036                 col_set_str(pinfo->cinfo, COL_INFO, "AddAliasMem request");
4037
4038         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4039                                        hf_samr_hnd, NULL);
4040
4041         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4042                         dissect_ndr_nt_SID, NDR_POINTER_REF,
4043                         "SID", -1, 0);
4044         return offset;
4045 }
4046
4047 static int
4048 samr_dissect_add_alias_member_reply(tvbuff_t *tvb, int offset, 
4049                                     packet_info *pinfo, proto_tree *tree, 
4050                                     char *drep)
4051 {
4052         if (check_col(pinfo->cinfo, COL_INFO))
4053                 col_set_str(pinfo->cinfo, COL_INFO, "AddAliasMem response");
4054
4055         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4056                                   hf_samr_rc, NULL);
4057
4058         return offset;
4059 }
4060
4061 static int
4062 samr_dissect_remove_alias_member_rqst(tvbuff_t *tvb, int offset, 
4063                                       packet_info *pinfo, proto_tree *tree, 
4064                                       char *drep)
4065 {
4066         if (check_col(pinfo->cinfo, COL_INFO))
4067                 col_set_str(pinfo->cinfo, COL_INFO, "RemoveAliasMem request");
4068
4069         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4070                                        hf_samr_hnd, NULL);
4071
4072         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4073                         dissect_ndr_nt_SID, NDR_POINTER_REF,
4074                         "SID", -1, 0);
4075         return offset;
4076 }
4077
4078 static int
4079 samr_dissect_remove_alias_member_reply(tvbuff_t *tvb, int offset, 
4080                                        packet_info *pinfo, proto_tree *tree, 
4081                                        char *drep)
4082 {
4083         if (check_col(pinfo->cinfo, COL_INFO))
4084                 col_set_str(pinfo->cinfo, COL_INFO, "RemoveAliasMem response");
4085
4086         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4087                                   hf_samr_rc, NULL);
4088
4089         return offset;
4090 }
4091
4092 static int
4093 samr_dissect_delete_dom_user_rqst(tvbuff_t *tvb, int offset, 
4094                                   packet_info *pinfo, proto_tree *tree, 
4095                                   char *drep)
4096 {
4097         if (check_col(pinfo->cinfo, COL_INFO))
4098                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteDomUser request");
4099
4100         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4101                                        hf_samr_hnd, NULL);
4102
4103         return offset;
4104 }
4105
4106 static int
4107 samr_dissect_delete_dom_user_reply(tvbuff_t *tvb, int offset, 
4108                                    packet_info *pinfo, proto_tree *tree, 
4109                                    char *drep)
4110 {
4111         if (check_col(pinfo->cinfo, COL_INFO))
4112                 col_set_str(pinfo->cinfo, COL_INFO, "DeleteDomUser response");
4113
4114         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4115                                   hf_samr_rc, NULL);
4116
4117         return offset;
4118 }
4119
4120 static int
4121 samr_dissect_test_private_fns_domain_rqst(tvbuff_t *tvb, int offset, 
4122                                           packet_info *pinfo, proto_tree *tree,
4123                                           char *drep)
4124 {
4125         if (check_col(pinfo->cinfo, COL_INFO))
4126                 col_set_str(pinfo->cinfo, COL_INFO, 
4127                             "TestPrivateFnsDomain request");
4128
4129         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4130                                        hf_samr_hnd, NULL);
4131
4132         return offset;
4133 }
4134
4135 static int
4136 samr_dissect_test_private_fns_domain_reply(tvbuff_t *tvb, int offset, 
4137                                            packet_info *pinfo, 
4138                                            proto_tree *tree, char *drep)
4139 {
4140         if (check_col(pinfo->cinfo, COL_INFO))
4141                 col_set_str(pinfo->cinfo, COL_INFO, 
4142                             "TestPrivateFnsDomain response");
4143
4144         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4145                                   hf_samr_rc, NULL);
4146
4147         return offset;
4148 }
4149
4150 static int
4151 samr_dissect_test_private_fns_user_rqst(tvbuff_t *tvb, int offset, 
4152                                         packet_info *pinfo, proto_tree *tree, 
4153                                         char *drep)
4154 {
4155         if (check_col(pinfo->cinfo, COL_INFO))
4156                 col_set_str(pinfo->cinfo, COL_INFO, 
4157                             "TestPrivateFnsUser request");
4158
4159         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4160                                        hf_samr_hnd, NULL);
4161
4162         return offset;
4163 }
4164
4165 static int
4166 samr_dissect_test_private_fns_user_reply(tvbuff_t *tvb, int offset, 
4167                                          packet_info *pinfo, 
4168                                          proto_tree *tree, char *drep)
4169 {
4170         if (check_col(pinfo->cinfo, COL_INFO))
4171                 col_set_str(pinfo->cinfo, COL_INFO, 
4172                             "TestPrivateFnsUser response");
4173
4174         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4175                                   hf_samr_rc, NULL);
4176
4177         return offset;
4178 }
4179
4180 static int
4181 samr_dissect_remove_member_from_foreign_domain_rqst(tvbuff_t *tvb, int offset, 
4182                                                     packet_info *pinfo, 
4183                                                     proto_tree *tree, 
4184                                                     char *drep)
4185 {
4186         if (check_col(pinfo->cinfo, COL_INFO))
4187                 col_set_str(pinfo->cinfo, COL_INFO, 
4188                             "RemoveForeignMember request");
4189
4190         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4191                                        hf_samr_hnd, NULL);
4192
4193         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4194                         dissect_ndr_nt_SID, NDR_POINTER_REF,
4195                         "SID", -1, 0);
4196         return offset;
4197 }
4198
4199 static int
4200 samr_dissect_remove_member_from_foreign_domain_reply(tvbuff_t *tvb, int offset,
4201                                                      packet_info *pinfo, 
4202                                                      proto_tree *tree, 
4203                                                      char *drep)
4204 {
4205         if (check_col(pinfo->cinfo, COL_INFO))
4206                 col_set_str(pinfo->cinfo, COL_INFO, 
4207                             "RemoveForeignMember response");
4208
4209         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4210                                   hf_samr_rc, NULL);
4211
4212         return offset;
4213 }
4214
4215 static int
4216 samr_dissect_remove_multiple_members_from_alias_rqst(tvbuff_t *tvb, 
4217                                                      int offset, 
4218                                                      packet_info *pinfo, 
4219                                                      proto_tree *tree, 
4220                                                      char *drep)
4221 {
4222         if (check_col(pinfo->cinfo, COL_INFO))
4223                 col_set_str(pinfo->cinfo, COL_INFO, 
4224                             "RemoveMultipleMembersFromAlias request");
4225
4226         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4227                                        hf_samr_hnd, NULL);
4228
4229         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4230                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
4231                         "", -1, 0);
4232
4233         return offset;
4234 }
4235
4236 static int
4237 samr_dissect_remove_multiple_members_from_alias_reply(tvbuff_t *tvb, 
4238                                                       int offset, 
4239                                                       packet_info *pinfo, 
4240                                                       proto_tree *tree, 
4241                                                       char *drep)
4242 {
4243         if (check_col(pinfo->cinfo, COL_INFO))
4244                 col_set_str(pinfo->cinfo, COL_INFO, 
4245                             "RemoveMultipleMembersFromAlias response");
4246
4247         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4248                                   hf_samr_rc, NULL);
4249
4250         return offset;
4251 }
4252
4253 static int
4254 samr_dissect_open_group_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, 
4255                             proto_tree *tree, char *drep)
4256 {
4257         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
4258         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4259         guint32 rid;
4260
4261         if (check_col(pinfo->cinfo, COL_INFO))
4262                 col_set_str(pinfo->cinfo, COL_INFO, "OpenGroup request");
4263
4264         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4265                                        hf_samr_hnd, NULL);
4266
4267         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4268                         hf_samr_access, NULL);
4269
4270         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4271                         hf_samr_rid, &rid);
4272
4273         if (check_col(pinfo->cinfo, COL_INFO))
4274                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
4275
4276         dcv->private_data = (void *)rid;
4277
4278         return offset;
4279 }
4280
4281 static int
4282 samr_dissect_open_group_reply(tvbuff_t *tvb, int offset, 
4283                               packet_info *pinfo, proto_tree *tree, 
4284                               char *drep)
4285 {
4286         if (check_col(pinfo->cinfo, COL_INFO))
4287                 col_set_str(pinfo->cinfo, COL_INFO, "OpenGroup response");
4288
4289         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4290                                        hf_samr_hnd, NULL);
4291
4292         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4293                         hf_samr_rc, NULL);
4294
4295         return offset;
4296 }
4297
4298 static int
4299 samr_dissect_open_alias_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, 
4300                              proto_tree *tree, char *drep)
4301 {
4302         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
4303         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4304         guint32 rid;
4305
4306         if (check_col(pinfo->cinfo, COL_INFO))
4307                 col_set_str(pinfo->cinfo, COL_INFO, "OpenAlias request");
4308
4309         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4310                                        hf_samr_hnd, NULL);
4311
4312         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4313                         hf_samr_access, NULL);
4314
4315         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4316                         hf_samr_rid, &rid);
4317
4318         if (check_col(pinfo->cinfo, COL_INFO))
4319                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
4320
4321         dcv->private_data = (void *)rid;
4322
4323         return offset;
4324 }
4325
4326 static int
4327 samr_dissect_open_alias_reply(tvbuff_t *tvb, int offset, 
4328                               packet_info *pinfo, proto_tree *tree, 
4329                               char *drep)
4330 {
4331         if (check_col(pinfo->cinfo, COL_INFO))
4332                 col_set_str(pinfo->cinfo, COL_INFO, "OpenAlias response");
4333
4334         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4335                                        hf_samr_hnd, NULL);
4336
4337         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4338                         hf_samr_rc, NULL);
4339
4340         return offset;
4341 }
4342
4343 static int
4344 samr_dissect_add_multiple_members_to_alias_rqst(tvbuff_t *tvb, int offset, 
4345                                                 packet_info *pinfo, 
4346                                                 proto_tree *tree, char *drep)
4347 {
4348         if (check_col(pinfo->cinfo, COL_INFO))
4349                 col_set_str(pinfo->cinfo, COL_INFO, 
4350                             "AddMultipleMembersToAlias request");
4351
4352         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4353                                        hf_samr_hnd, NULL);
4354
4355         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4356                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
4357                         "", -1, 0);
4358
4359         return offset;
4360 }
4361
4362 static int
4363 samr_dissect_add_multiple_members_to_alias_reply(tvbuff_t *tvb, int offset, 
4364                                                  packet_info *pinfo, 
4365                                                  proto_tree *tree, char *drep)
4366 {
4367         if (check_col(pinfo->cinfo, COL_INFO))
4368                 col_set_str(pinfo->cinfo, COL_INFO, 
4369                             "AddMultipleMembersToAlias response");
4370
4371         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4372                                   hf_samr_rc, NULL);
4373
4374         return offset;
4375 }
4376
4377 static int
4378 samr_dissect_create_group_in_domain_rqst(tvbuff_t *tvb, int offset, 
4379                                          packet_info *pinfo, proto_tree *tree, 
4380                                          char *drep)
4381 {
4382         if (check_col(pinfo->cinfo, COL_INFO))
4383                 col_set_str(pinfo->cinfo, COL_INFO, "CreateGroup request");
4384
4385         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4386                                        hf_samr_hnd, NULL);
4387
4388         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4389                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
4390                         "Account Name", hf_samr_acct_name, 0);
4391
4392         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4393                                      hf_samr_access, NULL);
4394
4395         return offset;
4396 }
4397
4398 static int
4399 samr_dissect_create_group_in_domain_reply(tvbuff_t *tvb, int offset, 
4400                                           packet_info *pinfo, proto_tree *tree,
4401                                           char *drep)
4402 {
4403         if (check_col(pinfo->cinfo, COL_INFO))
4404                 col_set_str(pinfo->cinfo, COL_INFO, "CreateGroup response");
4405
4406         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4407                                        hf_samr_hnd, NULL);
4408
4409         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4410                                      hf_samr_rid, NULL);
4411
4412         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4413                                   hf_samr_rc, NULL);
4414
4415         return offset;
4416 }
4417
4418 static int
4419 samr_dissect_query_information_domain_rqst(tvbuff_t *tvb, int offset, 
4420                                            packet_info *pinfo, 
4421                                            proto_tree *tree, char *drep)
4422 {
4423         if (check_col(pinfo->cinfo, COL_INFO))
4424                 col_set_str(pinfo->cinfo, COL_INFO, "QueryDomInfo request");
4425
4426         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4427                                        hf_samr_hnd, NULL);
4428
4429         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
4430                         hf_samr_level, NULL);
4431
4432         return offset;
4433 }
4434
4435 static int
4436 samr_dissect_query_information_domain_reply(tvbuff_t *tvb, int offset, 
4437                         packet_info *pinfo, proto_tree *tree,
4438                         char *drep)
4439 {
4440         if (check_col(pinfo->cinfo, COL_INFO))
4441                 col_set_str(pinfo->cinfo, COL_INFO, "QueryDomInfo response");
4442
4443         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4444                         samr_dissect_DOMAIN_INFO_ptr, NDR_POINTER_REF,
4445                         "", hf_samr_domain, 0);
4446
4447         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4448                                      hf_samr_rc, NULL);
4449
4450         return offset;
4451 }
4452
4453 static int
4454 samr_dissect_query_information_user_rqst(tvbuff_t *tvb, int offset, 
4455                                           packet_info *pinfo, 
4456                                           proto_tree *tree, char *drep)
4457 {
4458         if (check_col(pinfo->cinfo, COL_INFO))
4459                 col_set_str(pinfo->cinfo, COL_INFO, "QueryUserInfo request");
4460
4461         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4462                                        hf_samr_hnd, NULL);
4463
4464         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
4465                         hf_samr_level, NULL);
4466
4467         return offset;
4468 }
4469
4470 static int
4471 samr_dissect_query_information_user_reply(tvbuff_t *tvb, int offset, 
4472                                            packet_info *pinfo, 
4473                                            proto_tree *tree, char *drep)
4474 {
4475         if (check_col(pinfo->cinfo, COL_INFO))
4476                 col_set_str(pinfo->cinfo, COL_INFO, "QueryUserInfo response");
4477
4478         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4479                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
4480                         "", -1, 0);
4481
4482         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4483                                   hf_samr_rc, NULL);
4484
4485         return offset;
4486 }
4487
4488 static dcerpc_sub_dissector dcerpc_samr_dissectors[] = {
4489         { SAMR_CONNECT_ANON, "CONNECT_ANON",
4490                 samr_dissect_connect_anon_rqst,
4491                 samr_dissect_connect_anon_reply },
4492         { SAMR_CLOSE_HND, "CLOSE_HND",
4493                 samr_dissect_close_hnd_rqst,
4494                 samr_dissect_close_hnd_reply },
4495         { SAMR_SET_SEC_OBJECT, "SET_SEC_OBJECT",
4496                 samr_dissect_set_sec_object_rqst,
4497                 samr_dissect_set_sec_object_reply },
4498         { SAMR_QUERY_SEC_OBJECT, "QUERY_SEC_OBJECT", 
4499                 samr_dissect_query_sec_object_rqst,
4500                 samr_dissect_query_sec_object_reply },
4501         { SAMR_SHUTDOWN_SAM_SERVER, "SHUTDOWN_SAM_SERVER",
4502                 samr_dissect_shutdown_sam_server_rqst,
4503                 samr_dissect_shutdown_sam_server_reply },
4504         { SAMR_LOOKUP_DOMAIN, "LOOKUP_DOMAIN",
4505                 samr_dissect_lookup_domain_rqst,
4506                 samr_dissect_lookup_domain_reply },
4507         { SAMR_ENUM_DOMAINS, "ENUM_DOMAINS",
4508                 samr_dissect_enum_domains_rqst,
4509                 samr_dissect_enum_domains_reply },
4510         { SAMR_OPEN_DOMAIN, "OPEN_DOMAIN",
4511                 samr_dissect_open_domain_rqst,
4512                 samr_dissect_open_domain_reply },
4513         { SAMR_QUERY_DOMAIN_INFO, "QUERY_INFORMATION_DOMAIN",
4514                 samr_dissect_query_information_alias_rqst,
4515                 samr_dissect_query_information_domain_reply },
4516         { SAMR_SET_DOMAIN_INFO, "SET_INFORMATION_DOMAIN",
4517                 samr_dissect_set_information_domain_rqst,
4518                 samr_dissect_set_information_domain_reply },
4519         { SAMR_CREATE_DOM_GROUP, "CREATE_GROUP_IN_DOMAIN",
4520                 samr_dissect_create_alias_in_domain_rqst,
4521                 samr_dissect_create_alias_in_domain_reply },
4522         { SAMR_ENUM_DOM_GROUPS, "ENUM_DOM_GROUPS",
4523                 samr_dissect_enum_dom_groups_rqst,
4524                 samr_dissect_enum_dom_groups_reply },
4525         { SAMR_CREATE_USER_IN_DOMAIN, "CREATE_USER_IN_DOMAIN",
4526                 samr_dissect_create_group_in_domain_rqst,
4527                 samr_dissect_create_group_in_domain_reply },
4528         { SAMR_ENUM_DOM_USERS, "ENUM_DOM_USERS",
4529                 samr_dissect_enum_dom_groups_rqst,
4530                 samr_dissect_enum_dom_groups_reply },
4531         { SAMR_CREATE_DOM_ALIAS, "CREATE_ALIAS_IN_DOMAIN",
4532                 samr_dissect_create_alias_in_domain_rqst,
4533                 samr_dissect_create_alias_in_domain_reply },
4534         { SAMR_ENUM_DOM_ALIASES, "ENUM_DOM_ALIASES",
4535                 samr_dissect_enum_dom_aliases_rqst,
4536                 samr_dissect_enum_dom_aliases_reply },
4537         { SAMR_GET_ALIAS_MEMBERSHIP, "GET_ALIAS_MEMBERSHIP",
4538                 samr_dissect_get_alias_membership_rqst,
4539                 samr_dissect_get_alias_membership_reply },
4540         { SAMR_LOOKUP_NAMES, "LOOKUP_NAMES", 
4541                 samr_dissect_lookup_names_rqst,
4542                 samr_dissect_lookup_names_reply },
4543         { SAMR_LOOKUP_RIDS, "LOOKUP_RIDS",
4544                 samr_dissect_lookup_rids_rqst,
4545                 samr_dissect_lookup_rids_reply },
4546         { SAMR_OPEN_GROUP, "OPEN_GROUP",
4547                 samr_dissect_open_group_rqst,
4548                 samr_dissect_open_group_reply },
4549         { SAMR_QUERY_GROUPINFO, "QUERY_INFORMATION_GROUP",
4550                 samr_dissect_query_information_group_rqst,
4551                 samr_dissect_query_information_group_reply },
4552         { SAMR_SET_GROUPINFO, "SET_INFORMATION_GROUP",
4553                 samr_dissect_set_information_group_rqst,
4554                 samr_dissect_set_information_group_reply },
4555         { SAMR_ADD_GROUPMEM, "ADD_MEMBER_TO_GROUP",
4556                 samr_dissect_add_member_to_group_rqst,
4557                 samr_dissect_add_member_to_group_reply },
4558         { SAMR_DELETE_DOM_GROUP, "DELETE_DOM_GROUP",
4559                 samr_dissect_delete_dom_group_rqst,
4560                 samr_dissect_delete_dom_group_reply },
4561         { SAMR_DEL_GROUPMEM, "REMOVE_MEMBER_FROM_GROUP",
4562                 samr_dissect_remove_member_from_group_rqst,
4563                 samr_dissect_remove_member_from_group_reply },
4564         { SAMR_QUERY_GROUPMEM, "QUERY_GROUPMEM",
4565                 samr_dissect_query_groupmem_rqst,
4566                 samr_dissect_query_groupmem_reply },
4567         { SAMR_SET_MEMBER_ATTRIBUTES_OF_GROUP, "SET_MEMBER_ATTRIBUTES_OF_GROUP",
4568                 samr_dissect_set_member_attributes_of_group_rqst,
4569                 samr_dissect_set_member_attributes_of_group_reply },
4570         { SAMR_OPEN_ALIAS, "OPEN_ALIAS",
4571                 samr_dissect_open_alias_rqst,
4572                 samr_dissect_open_alias_reply },
4573         { SAMR_QUERY_ALIASINFO, "QUERY_INFORMATION_ALIAS",
4574                 samr_dissect_query_information_alias_rqst,
4575                 samr_dissect_query_information_alias_reply },
4576         { SAMR_SET_ALIASINFO, "SET_INFORMATION_ALIAS",
4577                 samr_dissect_set_information_alias_rqst,
4578                 samr_dissect_set_information_alias_reply },
4579         { SAMR_DELETE_DOM_ALIAS, "DELETE_DOM_ALIAS",
4580                 samr_dissect_delete_dom_alias_rqst,
4581                 samr_dissect_delete_dom_alias_reply },
4582         { SAMR_ADD_ALIASMEM, "ADD_MEMBER_TO_ALIAS",
4583                 samr_dissect_add_alias_member_rqst,
4584                 samr_dissect_add_alias_member_reply },
4585         { SAMR_DEL_ALIASMEM, "REMOVE_MEMBER_FROM_ALIAS",
4586                 samr_dissect_remove_alias_member_rqst,
4587                 samr_dissect_remove_alias_member_reply },
4588         { SAMR_GET_MEMBERS_IN_ALIAS, "GET_MEMBERS_IN_ALIAS",
4589                 samr_dissect_get_members_in_alias_rqst,
4590                 samr_dissect_get_members_in_alias_reply },
4591         { SAMR_OPEN_USER, "OPEN_USER", 
4592                 samr_dissect_open_user_rqst, 
4593                 samr_dissect_open_user_reply },
4594         { SAMR_DELETE_DOM_USER, "DELETE_DOM_USER",
4595                 samr_dissect_delete_dom_user_rqst,
4596                 samr_dissect_delete_dom_user_reply },
4597         { SAMR_QUERY_USERINFO, "QUERY_USERINFO",
4598                 samr_dissect_query_information_user_rqst,
4599                 samr_dissect_query_information_user_reply },
4600         { SAMR_SET_USERINFO2, "SET_USERINFO2",
4601                 samr_dissect_set_information_user2_rqst,
4602                 samr_dissect_set_information_user2_reply },
4603         { SAMR_CHANGE_PASSWORD_USER, "CHANGE_PASSWORD_USER",
4604                 samr_dissect_change_password_user_rqst,
4605                 samr_dissect_change_password_user_reply },
4606         { SAMR_GET_GROUPS_FOR_USER, "GET_GROUPS_FOR_USER",
4607                 samr_dissect_get_groups_for_user_rqst,
4608                 samr_dissect_get_groups_for_user_reply },
4609         { SAMR_QUERY_DISPINFO, "QUERY_DISPINFO", 
4610                 samr_dissect_query_dispinfo_rqst, 
4611                 samr_dissect_query_dispinfo_reply },
4612         { SAMR_GET_DISPLAY_ENUMERATION_INDEX, "GET_DISPLAY_ENUMERATION_INDEX", 
4613                 samr_dissect_get_display_enumeration_index_rqst, 
4614                 samr_dissect_get_display_enumeration_index_reply },
4615         { SAMR_TEST_PRIVATE_FUNCTIONS_DOMAIN, "TEST_PRIVATE_FUNCTIONS_DOMAIN",
4616                 samr_dissect_test_private_fns_domain_rqst,
4617                 samr_dissect_test_private_fns_domain_reply },
4618         { SAMR_TEST_PRIVATE_FUNCTIONS_USER, "TEST_PRIVATE_FUNCTIONS_USER",
4619                 samr_dissect_test_private_fns_user_rqst,
4620                 samr_dissect_test_private_fns_user_reply },
4621         { SAMR_GET_USRDOM_PWINFO, "GET_USRDOM_PWINFO",
4622                 samr_dissect_get_usrdom_pwinfo_rqst,
4623                 samr_dissect_get_usrdom_pwinfo_reply },
4624         { SAMR_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN, "REMOVE_MEMBER_FROM_FOREIGN_DOMAIN",
4625                 samr_dissect_remove_member_from_foreign_domain_rqst,
4626                 samr_dissect_remove_member_from_foreign_domain_reply },
4627         { SAMR_QUERY_INFORMATION_DOMAIN2, "QUERY_INFORMATION_DOMAIN2",
4628                 samr_dissect_query_information_domain_rqst,
4629                 samr_dissect_query_information_domain_reply },
4630         { SAMR_UNKNOWN_2f, "UNKNOWN_2f",
4631                 samr_dissect_unknown_2f_rqst,
4632                 samr_dissect_unknown_2f_reply },
4633         { SAMR_QUERY_DISPINFO2, "QUERY_INFORMATION_DISPLAY2",
4634                 samr_dissect_query_dispinfo_rqst,
4635                 samr_dissect_query_dispinfo_reply },
4636         { SAMR_GET_DISPLAY_ENUMERATION_INDEX2, "GET_DISPLAY_ENUMERATION_INDEX2",
4637                 samr_dissect_get_display_enumeration_index2_rqst,
4638                 samr_dissect_get_display_enumeration_index2_reply },
4639         { SAMR_CREATE_USER2_IN_DOMAIN, "CREATE_USER2_IN_DOMAIN",
4640                 samr_dissect_create_user2_in_domain_rqst,
4641                 samr_dissect_create_user2_in_domain_reply },
4642         { SAMR_QUERY_DISPINFO3, "QUERY_INFORMATION_DISPLAY3",
4643                 samr_dissect_query_dispinfo_rqst,
4644                 samr_dissect_query_dispinfo_reply },
4645         { SAMR_ADD_MULTIPLE_MEMBERS_TO_ALIAS, "ADD_MULTIPLE_MEMBERS_TO_ALIAS",
4646                 samr_dissect_add_multiple_members_to_alias_rqst,
4647                 samr_dissect_add_multiple_members_to_alias_reply },
4648         { SAMR_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS, "REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS",
4649                 samr_dissect_remove_multiple_members_from_alias_rqst,
4650                 samr_dissect_remove_multiple_members_from_alias_reply },
4651         { SAMR_OEM_CHANGE_PASSWORD_USER2, "OEM_CHANGE_PASSWORD_USER2",
4652                 samr_dissect_oem_change_password_user2_rqst,
4653                 samr_dissect_oem_change_password_user2_reply },
4654         { SAMR_UNICODE_CHANGE_PASSWORD_USER2, "UNICODE_CHANGE_PASSWORD_USER2",
4655                 samr_dissect_unicode_change_password_user2_rqst,
4656                 samr_dissect_unicode_change_password_user2_reply },
4657         { SAMR_GET_DOM_PWINFO, "GET_DOMAIN_PASSWORD_INFORMATION",
4658                 samr_dissect_get_domain_password_information_rqst,
4659                 samr_dissect_get_domain_password_information_reply },
4660         { SAMR_CONNECT2, "CONNECT2", 
4661                 samr_dissect_connect2_rqst,
4662                 samr_dissect_connect2_reply },
4663         { SAMR_SET_USERINFO, "SET_USERINFO",
4664                 samr_dissect_set_information_user2_rqst,
4665                 samr_dissect_set_information_user2_reply },
4666         { SAMR_UNKNOWN_3B, "UNKNOWN_3B",
4667                 samr_dissect_unknown_3b_rqst,
4668                 samr_dissect_unknown_3b_reply },
4669         { SAMR_UNKNOWN_3C, "UNKNOWN_3C", 
4670                 samr_dissect_unknown_3c_rqst,
4671                 samr_dissect_unknown_3c_reply },
4672         {0, NULL, NULL,  NULL },
4673 };
4674
4675 void 
4676 proto_register_dcerpc_samr(void)
4677 {
4678         static hf_register_info hf[] = {
4679                 { &hf_samr_hnd,
4680                   { "Context Handle", "samr.hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
4681                 { &hf_samr_group,
4682                   { "Group", "samr.group", FT_UINT32, BASE_DEC, NULL, 0x0, "Group", HFILL }},
4683                 { &hf_samr_rid,
4684                   { "Rid", "samr.rid", FT_UINT32, BASE_DEC, NULL, 0x0, "RID", HFILL }},
4685                 { &hf_samr_type,
4686                   { "Type", "samr.type", FT_UINT32, BASE_HEX, NULL, 0x0, "Type", HFILL }},
4687                 { &hf_samr_alias,
4688                   { "Alias", "samr.alias", FT_UINT32, BASE_HEX, NULL, 0x0, "Alias", HFILL }},
4689                 { &hf_samr_rid_attrib,
4690                   { "Rid Attrib", "samr.rid.attrib", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
4691                 { &hf_samr_attrib,
4692                   { "Attributes", "samr.attr", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
4693                 { &hf_samr_rc,
4694                   { "Return code", "samr.rc", FT_UINT32, BASE_HEX, VALS (NT_errors), 0x0, "", HFILL }},
4695
4696         { &hf_samr_level,
4697                 { "Level", "samr.level", FT_UINT16, BASE_DEC, 
4698                 NULL, 0x0, "Level requested/returned for Information", HFILL }},
4699         { &hf_samr_start_idx,
4700                 { "Start Idx", "samr.start_idx", FT_UINT32, BASE_DEC, 
4701                 NULL, 0x0, "Start Index for returned Information", HFILL }},
4702
4703         { &hf_samr_entries,
4704                 { "Entries", "samr.entries", FT_UINT32, BASE_DEC, 
4705                 NULL, 0x0, "Number of entries to return", HFILL }},
4706
4707         { &hf_samr_max_entries,
4708                 { "Max Entries", "samr.max_entries", FT_UINT32, BASE_DEC, 
4709                 NULL, 0x0, "Maximum number of entries", HFILL }},
4710
4711         { &hf_samr_pref_maxsize,
4712                 { "Pref MaxSize", "samr.pref_maxsize", FT_UINT32, BASE_DEC, 
4713                 NULL, 0x0, "Maximum Size of data to return", HFILL }},
4714
4715         { &hf_samr_total_size,
4716                 { "Total Size", "samr.total_size", FT_UINT32, BASE_DEC, 
4717                 NULL, 0x0, "Total size of data", HFILL }},
4718
4719         { &hf_samr_bad_pwd_count,
4720                 { "Bad Pwd Count", "samr.bad_pwd_count", FT_UINT16, BASE_DEC, 
4721                 NULL, 0x0, "Number of bad pwd entries for this user", HFILL }},
4722
4723         { &hf_samr_logon_count,
4724                 { "Logon Count", "samr.logon_count", FT_UINT16, BASE_DEC, 
4725                 NULL, 0x0, "Number of logons for this user", HFILL }},
4726
4727         { &hf_samr_ret_size,
4728                 { "Returned Size", "samr.ret_size", FT_UINT32, BASE_DEC, 
4729                 NULL, 0x0, "Number of returned objects in this PDU", HFILL }},
4730
4731         { &hf_samr_index,
4732                 { "Index", "samr.index", FT_UINT32, BASE_DEC, 
4733                 NULL, 0x0, "Index", HFILL }},
4734
4735         { &hf_samr_count,
4736           { "Count", "samr.count", FT_UINT32, BASE_DEC, NULL, 0x0, "Number of elements in following array", HFILL }},
4737
4738         { &hf_samr_alias_name,
4739                 { "Alias Name", "samr.alias_name", FT_STRING, BASE_NONE,
4740                 NULL, 0, "Name of Alias", HFILL }},
4741
4742         { &hf_samr_group_name,
4743                 { "Group Name", "samr.group_name", FT_STRING, BASE_NONE,
4744                 NULL, 0, "Name of Group", HFILL }},
4745
4746         { &hf_samr_acct_name,
4747                 { "Account Name", "samr.acct_name", FT_STRING, BASE_NONE,
4748                 NULL, 0, "Name of Account", HFILL }},
4749
4750         { &hf_samr_server,
4751                 { "Server", "samr.server", FT_STRING, BASE_NONE,
4752                 NULL, 0, "Name of Server", HFILL }},
4753
4754         { &hf_samr_domain,
4755                 { "Domain", "samr.domain", FT_STRING, BASE_NONE,
4756                 NULL, 0, "Name of Domain", HFILL }},
4757
4758         { &hf_samr_controller,
4759                 { "DC", "samr.dc", FT_STRING, BASE_NONE,
4760                 NULL, 0, "Name of Domain Controller", HFILL }},
4761
4762         { &hf_samr_full_name,
4763                 { "Full Name", "samr.full_name", FT_STRING, BASE_NONE,
4764                 NULL, 0, "Full Name of Account", HFILL }},
4765
4766         { &hf_samr_home,
4767                 { "Home", "samr.home", FT_STRING, BASE_NONE,
4768                 NULL, 0, "Home directory for this user", HFILL }},
4769
4770         { &hf_samr_home_drive,
4771                 { "Home Drive", "samr.home_drive", FT_STRING, BASE_NONE,
4772                 NULL, 0, "Home drive for this user", HFILL }},
4773
4774         { &hf_samr_script,
4775                 { "Script", "samr.script", FT_STRING, BASE_NONE,
4776                 NULL, 0, "Login script for this user", HFILL }},
4777
4778         { &hf_samr_workstations,
4779                 { "Workstations", "samr.workstations", FT_STRING, BASE_NONE,
4780                 NULL, 0, "", HFILL }},
4781
4782         { &hf_samr_profile,
4783                 { "Profile", "samr.profile", FT_STRING, BASE_NONE,
4784                 NULL, 0, "Profile for this user", HFILL }},
4785
4786         { &hf_samr_acct_desc,
4787                 { "Account Desc", "samr.acct_desc", FT_STRING, BASE_NONE,
4788                 NULL, 0, "Account Description", HFILL }},
4789
4790         { &hf_samr_comment,
4791                 { "Comment", "samr.comment", FT_STRING, BASE_NONE,
4792                 NULL, 0, "Comment", HFILL }},
4793
4794         { &hf_samr_parameters,
4795                 { "Parameters", "samr.parameters", FT_STRING, BASE_NONE,
4796                 NULL, 0, "Parameters", HFILL }},
4797
4798         { &hf_samr_unknown_string,
4799                 { "Unknown string", "samr.unknown_string", FT_STRING, BASE_NONE,
4800                 NULL, 0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }},
4801
4802         { &hf_samr_unknown_hyper,
4803                 { "Unknown hyper", "samr.unknown.hyper", FT_UINT64, BASE_HEX, 
4804                 NULL, 0x0, "Unknown hyper. If you know what this is, contact ethereal developers.", HFILL }},
4805         { &hf_samr_unknown_long,
4806                 { "Unknown long", "samr.unknown.long", FT_UINT32, BASE_HEX, 
4807                 NULL, 0x0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
4808
4809         { &hf_samr_unknown_short,
4810                 { "Unknown short", "samr.unknown.short", FT_UINT16, BASE_HEX, 
4811                 NULL, 0x0, "Unknown short. If you know what this is, contact ethereal developers.", HFILL }},
4812
4813         { &hf_samr_unknown_char,
4814                 { "Unknown char", "samr.unknown.char", FT_UINT8, BASE_HEX, 
4815                 NULL, 0x0, "Unknown char. If you know what this is, contact ethereal developers.", HFILL }},
4816
4817         { &hf_samr_revision,
4818                 { "Revision", "samr.revision", FT_UINT64, BASE_HEX, 
4819                 NULL, 0x0, "Revision number for this structure", HFILL }},
4820  
4821         { &hf_samr_nt_pwd_set,
4822                 { "NT Pwd Set", "samr.nt_pwd_set", FT_UINT8, BASE_HEX, 
4823                 NULL, 0x0, "Flag indicating whether the NT password has been set", HFILL }},
4824  
4825         { &hf_samr_lm_pwd_set,
4826                 { "LM Pwd Set", "samr.lm_pwd_set", FT_UINT8, BASE_HEX, 
4827                 NULL, 0x0, "Flag indicating whether the LanManager password has been set", HFILL }},
4828  
4829         { &hf_samr_pwd_expired,
4830                 { "Expired flag", "samr.pwd_Expired", FT_UINT8, BASE_HEX, 
4831                 NULL, 0x0, "Flag indicating if the password for this account has expired or not", HFILL }},
4832
4833         /* XXX - is this a standard NT access mask? */
4834         { &hf_samr_access,
4835                 { "Access Mask", "samr.access", FT_UINT32, BASE_HEX, 
4836                 NULL, 0x0, "Access", HFILL }},
4837
4838         { &hf_samr_mask,
4839                 { "Mask", "samr.mask", FT_UINT32, BASE_HEX, 
4840                 NULL, 0x0, "Mask", HFILL }},
4841
4842         { &hf_samr_crypt_password, {
4843                 "Password", "samr.crypt_password", FT_BYTES, BASE_HEX,
4844                 NULL, 0, "Encrypted Password", HFILL }},
4845
4846         { &hf_samr_crypt_hash, {
4847                 "Hash", "samr.crypt_hash", FT_BYTES, BASE_HEX,
4848                 NULL, 0, "Encrypted Hash", HFILL }},
4849
4850         { &hf_samr_lm_change, {
4851                 "LM Change", "samr.lm_change", FT_UINT8, BASE_HEX,
4852                 NULL, 0, "LM Change value", HFILL }},
4853
4854         { &hf_samr_max_pwd_age,
4855                 { "Max Pwd Age", "samr.max_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
4856                 NULL, 0, "Maximum Password Age before it expires", HFILL }},
4857
4858         { &hf_samr_min_pwd_age,
4859                 { "Min Pwd Age", "samr.min_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
4860                 NULL, 0, "Minimum Password Age before it can be changed", HFILL }},
4861         { &hf_samr_unknown_time,
4862                 { "Unknown time", "samr.unknown_time", FT_ABSOLUTE_TIME, BASE_NONE,
4863                 NULL, 0, "Unknown NT TIME, contact ethereal developers if you know what this is", HFILL }},
4864         { &hf_samr_logon_time,
4865                 { "Logon Time", "samr.logon_time", FT_ABSOLUTE_TIME, BASE_NONE,
4866                 NULL, 0, "Time for last time this user logged on", HFILL }},
4867         { &hf_samr_kickoff_time,
4868                 { "Kickoff Time", "samr.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
4869                 NULL, 0, "Time when this user will be kicked off", HFILL }},
4870         { &hf_samr_logoff_time,
4871                 { "Logoff Time", "samr.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
4872                 NULL, 0, "Time for last time this user logged off", HFILL }},
4873         { &hf_samr_pwd_last_set_time,
4874                 { "PWD Last Set", "samr.pwd_last_set_time", FT_ABSOLUTE_TIME, BASE_NONE,
4875                 NULL, 0, "Last time this users password was changed", HFILL }},
4876         { &hf_samr_pwd_can_change_time,
4877                 { "PWD Can Change", "samr.pwd_can_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
4878                 NULL, 0, "When this users password may be changed", HFILL }},
4879         { &hf_samr_pwd_must_change_time,
4880                 { "PWD Must Change", "samr.pwd_must_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
4881                 NULL, 0, "When this users password must be changed", HFILL }},
4882         { &hf_samr_acct_expiry_time,
4883                 { "Acct Expiry", "samr.acct_expiry_time", FT_ABSOLUTE_TIME, BASE_NONE,
4884                 NULL, 0, "When this user account expires", HFILL }},
4885
4886         { &hf_samr_min_pwd_len, {
4887                 "Min Pwd Len", "samr.min_pwd_len", FT_UINT16, BASE_DEC,
4888                 NULL, 0, "Minimum Password Length", HFILL }},
4889         { &hf_samr_pwd_history_len, {
4890                 "Pwd History Len", "samr.pwd_history_len", FT_UINT16, BASE_DEC,
4891                 NULL, 0, "Password History Length", HFILL }},
4892         { &hf_samr_num_users, {
4893                 "Num Users", "samr.num_users", FT_UINT32, BASE_DEC,
4894                 NULL, 0, "Number of users in this domain", HFILL }},
4895         { &hf_samr_num_groups, {
4896                 "Num Groups", "samr.num_groups", FT_UINT32, BASE_DEC,
4897                 NULL, 0, "Number of groups in this domain", HFILL }},
4898         { &hf_samr_num_aliases, {
4899                 "Num Aliases", "samr.num_aliases", FT_UINT32, BASE_DEC,
4900                 NULL, 0, "Number of aliases in this domain", HFILL }},
4901         { &hf_samr_info_type, {
4902                 "Info Type", "samr.info_type", FT_UINT32, BASE_DEC,
4903                 NULL, 0, "Information Type", HFILL }},
4904         { &hf_samr_resume_hnd, {
4905                 "Resume Hnd", "samr.resume_hnd", FT_UINT32, BASE_DEC,
4906                 NULL, 0, "Resume handle", HFILL }},
4907         { &hf_samr_country, {
4908                 "Country", "samr.country", FT_UINT16, BASE_DEC,
4909                 VALS(ms_country_codes), 0, "Country setting for this user", HFILL }},
4910         { &hf_samr_codepage, {
4911                 "Codepage", "samr.codepage", FT_UINT16, BASE_DEC,
4912                 NULL, 0, "Codepage setting for this user", HFILL }},
4913         { &hf_samr_divisions, {
4914                 "Divisions", "samr.divisions", FT_UINT16, BASE_DEC,
4915                 NULL, 0, "Number of divisions for LOGON_HOURS", HFILL }},
4916
4917         /* these are used by packet-dcerpc-nt.c */
4918         { &hf_nt_string_length,
4919                 { "Length", "nt.string.length", FT_UINT16, BASE_DEC, 
4920                 NULL, 0x0, "Length of string in bytes", HFILL }},
4921
4922         { &hf_nt_string_size,
4923                 { "Size", "nt.string.size", FT_UINT16, BASE_DEC, 
4924                 NULL, 0x0, "Size of string in bytes", HFILL }},
4925
4926         { &hf_nt_str_len,
4927                 { "Length", "nt.str.len", FT_UINT32, BASE_DEC, 
4928                 NULL, 0x0, "Length of string in short integers", HFILL }},
4929
4930         { &hf_nt_str_off,
4931                 { "Offset", "nt.str.offset", FT_UINT32, BASE_DEC, 
4932                 NULL, 0x0, "Offset into string in short integers", HFILL }},
4933
4934         { &hf_nt_str_max_len,
4935                 { "Max Length", "nt.str.max_len", FT_UINT32, BASE_DEC, 
4936                 NULL, 0x0, "Max Length of string in short integers", HFILL }},
4937
4938         { &hf_nt_acct_ctrl,
4939                 { "Acct Ctrl", "nt.acct_ctrl", FT_UINT32, BASE_HEX, 
4940                 NULL, 0x0, "Acct CTRL", HFILL }},
4941
4942         { &hf_nt_acb_disabled, {
4943                 "", "nt.acb.disabled", FT_BOOLEAN, 32,
4944                 TFS(&tfs_nt_acb_disabled), 0x0001, "If this account is enabled or disabled", HFILL }},
4945
4946         { &hf_nt_acb_homedirreq, {
4947                 "", "nt.acb.homedirreq", FT_BOOLEAN, 32,
4948                 TFS(&tfs_nt_acb_homedirreq), 0x0002, "Is hom,edirs required for this account?", HFILL }},
4949
4950         { &hf_nt_acb_pwnotreq, {
4951                 "", "nt.acb.pwnotreq", FT_BOOLEAN, 32,
4952                 TFS(&tfs_nt_acb_pwnotreq), 0x0004, "If a password is required for this account?", HFILL }},
4953
4954         { &hf_nt_acb_tempdup, {
4955                 "", "nt.acb.tempdup", FT_BOOLEAN, 32,
4956                 TFS(&tfs_nt_acb_tempdup), 0x0008, "If this is a temporary duplicate account", HFILL }},
4957
4958         { &hf_nt_acb_normal, {
4959                 "", "nt.acb.normal", FT_BOOLEAN, 32,
4960                 TFS(&tfs_nt_acb_normal), 0x0010, "If this is a normal user account", HFILL }},
4961
4962         { &hf_nt_acb_mns, {
4963                 "", "nt.acb.mns", FT_BOOLEAN, 32,
4964                 TFS(&tfs_nt_acb_mns), 0x0020, "MNS logon user account", HFILL }},
4965
4966         { &hf_nt_acb_domtrust, {
4967                 "", "nt.acb.domtrust", FT_BOOLEAN, 32,
4968                 TFS(&tfs_nt_acb_domtrust), 0x0040, "Interdomain trust account", HFILL }},
4969
4970         { &hf_nt_acb_wstrust, {
4971                 "", "nt.acb.wstrust", FT_BOOLEAN, 32,
4972                 TFS(&tfs_nt_acb_wstrust), 0x0080, "Workstation trust account", HFILL }},
4973
4974         { &hf_nt_acb_svrtrust, {
4975                 "", "nt.acb.svrtrust", FT_BOOLEAN, 32,
4976                 TFS(&tfs_nt_acb_svrtrust), 0x0100, "Server trust account", HFILL }},
4977
4978         { &hf_nt_acb_pwnoexp, {
4979                 "", "nt.acb.pwnoexp", FT_BOOLEAN, 32,
4980                 TFS(&tfs_nt_acb_pwnoexp), 0x0200, "If this account expires or not", HFILL }},
4981
4982         { &hf_nt_acb_autolock, {
4983                 "", "nt.acb.autolock", FT_BOOLEAN, 32,
4984                 TFS(&tfs_nt_acb_autolock), 0x0400, "If this account has been autolocked", HFILL }},
4985         };
4986         static gint *ett[] = {
4987                 &ett_dcerpc_samr,
4988                 &ett_samr_user_dispinfo_1,
4989                 &ett_samr_user_dispinfo_1_array,
4990                 &ett_samr_user_dispinfo_2,
4991                 &ett_samr_user_dispinfo_2_array,
4992                 &ett_samr_group_dispinfo,
4993                 &ett_samr_group_dispinfo_array,
4994                 &ett_samr_ascii_dispinfo,
4995                 &ett_samr_ascii_dispinfo_array,
4996                 &ett_samr_display_info,
4997                 &ett_samr_password_info,
4998                 &ett_samr_server,
4999                 &ett_samr_user_group,
5000                 &ett_samr_user_group_array,
5001                 &ett_samr_alias_info,
5002                 &ett_samr_group_info,
5003                 &ett_samr_domain_info_1,
5004                 &ett_samr_domain_info_2,
5005                 &ett_samr_domain_info_8,
5006                 &ett_samr_replication_status,
5007                 &ett_samr_domain_info_11,
5008                 &ett_samr_domain_info_13,
5009                 &ett_samr_domain_info,
5010                 &ett_samr_sid_pointer,
5011                 &ett_samr_sid_array,
5012                 &ett_samr_index_array,
5013                 &ett_samr_idx_and_name,
5014                 &ett_samr_idx_and_name_array,
5015                 &ett_samr_logon_hours,
5016                 &ett_samr_logon_hours_hours,
5017                 &ett_samr_user_info_1,
5018                 &ett_samr_user_info_2,
5019                 &ett_samr_user_info_3,
5020                 &ett_samr_user_info_5,
5021                 &ett_samr_user_info_6,
5022                 &ett_samr_user_info_18,
5023                 &ett_samr_user_info_19,
5024                 &ett_samr_buffer_buffer,
5025                 &ett_samr_buffer,
5026                 &ett_samr_user_info_21,
5027                 &ett_samr_user_info_22,
5028                 &ett_samr_user_info_23,
5029                 &ett_samr_user_info_24,
5030                 &ett_samr_user_info,
5031                 &ett_samr_member_array_types,
5032                 &ett_samr_member_array_rids,
5033                 &ett_samr_member_array,
5034                 &ett_samr_names,
5035                 &ett_samr_rids,
5036                 &ett_samr_sid_and_attributes_array,
5037                 &ett_samr_sid_and_attributes,
5038                 &ett_nt_acct_ctrl,
5039         };
5040
5041         proto_dcerpc_samr = proto_register_protocol(
5042                 "Microsoft Security Account Manager", "SAMR", "samr");
5043
5044         proto_register_field_array (proto_dcerpc_samr, hf, array_length (hf));
5045         proto_register_subtree_array(ett, array_length(ett));
5046 }
5047
5048 void
5049 proto_reg_handoff_dcerpc_samr(void)
5050 {
5051         /* Register protocol as dcerpc */
5052
5053         dcerpc_init_uuid(proto_dcerpc_samr, ett_dcerpc_samr, &uuid_dcerpc_samr,
5054                          ver_dcerpc_samr, dcerpc_samr_dissectors);
5055 }