DirectoryBase should be a uint32.
[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.45 2002/05/11 22:28:05 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 "packet-dcerpc-lsa.h"
38 #include "smb.h"        /* for "NT_errors[]" */
39 #include "packet-smb-common.h"
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 #ifdef SAMR_UNUSED_HANDLES
186 static gint ett_samr_hnd = -1;
187 #endif
188
189 static e_uuid_t uuid_dcerpc_samr = {
190         0x12345778, 0x1234, 0xabcd, 
191         { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xac}
192 };
193
194 static guint16 ver_dcerpc_samr = 1;
195
196
197 int
198 dissect_ndr_nt_SID(tvbuff_t *tvb, int offset, 
199                         packet_info *pinfo, proto_tree *tree, 
200                         char *drep)
201 {
202         dcerpc_info *di;
203
204         di=pinfo->private_data;
205         if(di->conformant_run){
206                 /* just a run to handle conformant arrays, no scalars to dissect */
207                 return offset;
208         }
209
210         /* the SID contains a conformant array, first we must eat
211            the 4-byte max_count before we can hand it off */
212         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
213                         hf_samr_count, NULL);
214
215         offset = dissect_nt_sid(tvb, offset, tree, "Domain");
216         return offset;
217 }
218
219 static int
220 dissect_ndr_nt_SID_ptr(tvbuff_t *tvb, int offset, 
221                         packet_info *pinfo, proto_tree *tree, 
222                         char *drep)
223 {
224         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
225                         dissect_ndr_nt_SID, NDR_POINTER_UNIQUE,
226                         "SID pointer", -1, 1);
227         return offset;
228 }
229
230
231
232 static const true_false_string tfs_nt_acb_disabled = {
233         "Account is DISABLED",
234         "Account is NOT disabled"
235 };
236 static const true_false_string tfs_nt_acb_homedirreq = {
237         "Homedir is REQUIRED",
238         "Homedir is NOT required"
239 };
240 static const true_false_string tfs_nt_acb_pwnotreq = {
241         "Password is NOT required",
242         "Password is REQUIRED"
243 };
244 static const true_false_string tfs_nt_acb_tempdup = {
245         "This is a TEMPORARY DUPLICATE account",
246         "This is NOT a temporary duplicate account"
247 };
248 static const true_false_string tfs_nt_acb_normal = {
249         "This is a NORMAL USER account",
250         "This is NOT a normal user account"
251 };
252 static const true_false_string tfs_nt_acb_mns = {
253         "This is a MNS account",
254         "This is NOT a mns account"
255 };
256 static const true_false_string tfs_nt_acb_domtrust = {
257         "This is a DOMAIN TRUST account",
258         "This is NOT a domain trust account"
259 };
260 static const true_false_string tfs_nt_acb_wstrust = {
261         "This is a WORKSTATION TRUST account",
262         "This is NOT a workstation trust account"
263 };
264 static const true_false_string tfs_nt_acb_svrtrust = {
265         "This is a SERVER TRUST account",
266         "This is NOT a server trust account"
267 };
268 static const true_false_string tfs_nt_acb_pwnoexp = {
269         "Passwords does NOT expire",
270         "Password will EXPIRE"
271 };
272 static const true_false_string tfs_nt_acb_autolock = {
273         "This account has been AUTO LOCKED",
274         "This account has NOT been auto locked"
275 };
276 int
277 dissect_ndr_nt_acct_ctrl(tvbuff_t *tvb, int offset, packet_info *pinfo, 
278                         proto_tree *parent_tree, char *drep)
279 {
280         guint32 mask;
281         proto_item *item = NULL;
282         proto_tree *tree = NULL;
283
284         offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
285                         hf_nt_acct_ctrl, &mask);
286
287         if(parent_tree){
288                 item = proto_tree_add_uint(parent_tree, hf_nt_acct_ctrl,
289                         tvb, offset-4, 4, mask);
290                 tree = proto_item_add_subtree(item, ett_nt_acct_ctrl);
291         }
292
293         proto_tree_add_boolean(tree, hf_nt_acb_autolock,
294                 tvb, offset-4, 4, mask);
295         proto_tree_add_boolean(tree, hf_nt_acb_pwnoexp,
296                 tvb, offset-4, 4, mask);
297         proto_tree_add_boolean(tree, hf_nt_acb_svrtrust,
298                 tvb, offset-4, 4, mask);
299         proto_tree_add_boolean(tree, hf_nt_acb_wstrust,
300                 tvb, offset-4, 4, mask);
301         proto_tree_add_boolean(tree, hf_nt_acb_domtrust,
302                 tvb, offset-4, 4, mask);
303         proto_tree_add_boolean(tree, hf_nt_acb_mns,
304                 tvb, offset-4, 4, mask);
305         proto_tree_add_boolean(tree, hf_nt_acb_normal,
306                 tvb, offset-4, 4, mask);
307         proto_tree_add_boolean(tree, hf_nt_acb_tempdup,
308                 tvb, offset-4, 4, mask);
309         proto_tree_add_boolean(tree, hf_nt_acb_pwnotreq,
310                 tvb, offset-4, 4, mask);
311         proto_tree_add_boolean(tree, hf_nt_acb_homedirreq,
312                 tvb, offset-4, 4, mask);
313         proto_tree_add_boolean(tree, hf_nt_acb_disabled,
314                 tvb, offset-4, 4, mask);
315
316         return offset;
317 }
318
319
320 /* above this line, just some general support routines which should be placed
321    in some more generic file common to all NT services dissectors
322 */
323
324 static int
325 samr_dissect_open_user_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, 
326                             proto_tree *tree, char *drep)
327 {
328         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
329         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
330         guint32 rid;
331
332         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
333                                        hf_samr_hnd, NULL, FALSE, FALSE);
334
335         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
336                         hf_samr_access, NULL);
337
338         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
339                         hf_samr_rid, &rid);
340
341         if (check_col(pinfo->cinfo, COL_INFO))
342                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
343
344         dcv->private_data = (void *)rid;
345
346         return offset;
347 }
348
349 static int
350 samr_dissect_open_user_reply(tvbuff_t *tvb, int offset, 
351                              packet_info *pinfo, proto_tree *tree, 
352                              char *drep)
353 {
354         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
355                                        hf_samr_hnd, NULL, FALSE, FALSE);
356
357         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
358                         hf_samr_rc, NULL);
359
360         return offset;
361 }
362
363 static int
364 samr_dissect_pointer_long(tvbuff_t *tvb, int offset, 
365                              packet_info *pinfo, proto_tree *tree, 
366                              char *drep)
367 {
368         dcerpc_info *di;
369
370         di=pinfo->private_data;
371         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
372                                      di->hf_index, NULL);
373         return offset;
374 }
375
376 static int
377 samr_dissect_pointer_STRING(tvbuff_t *tvb, int offset, 
378                              packet_info *pinfo, proto_tree *tree, 
379                              char *drep)
380 {
381         dcerpc_info *di;
382
383         di=pinfo->private_data;
384         if(di->conformant_run){
385                 /*just a run to handle conformant arrays, nothing to dissect */
386                 return offset;
387         }
388
389         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
390                         di->hf_index, 0);
391         return offset;
392 }
393
394 static int
395 samr_dissect_pointer_UNICODE_STRING(tvbuff_t *tvb, int offset, 
396                              packet_info *pinfo, proto_tree *tree, 
397                              char *drep)
398 {
399         dcerpc_info *di;
400
401         di=pinfo->private_data;
402         if(di->conformant_run){
403                 /*just a run to handle conformant arrays, nothing to dissect */
404                 return offset;
405         }
406
407         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
408                         di->hf_index, di->levels);
409         return offset;
410 }
411
412 static int
413 samr_dissect_pointer_short(tvbuff_t *tvb, int offset, 
414                              packet_info *pinfo, proto_tree *tree, 
415                              char *drep)
416 {
417         dcerpc_info *di;
418
419         di=pinfo->private_data;
420         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
421                                      di->hf_index, NULL);
422         return offset;
423 }
424
425
426 static int
427 samr_dissect_query_dispinfo_rqst(tvbuff_t *tvb, int offset, 
428                                  packet_info *pinfo, proto_tree *tree, 
429                                  char *drep)
430 {
431         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
432                                        hf_samr_hnd, NULL, FALSE, FALSE);
433
434         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
435                                      hf_samr_level, NULL);
436         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
437                                      hf_samr_start_idx, NULL);
438         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
439                                      hf_samr_max_entries, NULL);
440         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
441                                      hf_samr_pref_maxsize, NULL);
442
443         return offset;
444 }
445
446 static int
447 samr_dissect_USER_DISPINFO_1(tvbuff_t *tvb, int offset, 
448                         packet_info *pinfo, proto_tree *parent_tree, 
449                         char *drep)
450 {
451         proto_item *item=NULL;
452         proto_tree *tree=NULL;
453         int old_offset=offset;
454
455         if(parent_tree){
456                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
457                         "User_DispInfo_1");
458                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
459         }
460
461         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
462                                 hf_samr_index, NULL);
463         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
464                                 hf_samr_rid, NULL);
465         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
466         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
467                                 hf_samr_acct_name, 0);
468         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
469                                 hf_samr_full_name, 0);
470         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
471                                 hf_samr_acct_desc, 0);
472
473         proto_item_set_len(item, offset-old_offset);
474         return offset;
475 }
476
477 static int
478 samr_dissect_USER_DISPINFO_1_ARRAY_users(tvbuff_t *tvb, int offset, 
479                         packet_info *pinfo, proto_tree *tree, 
480                         char *drep)
481 {
482         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
483                         samr_dissect_USER_DISPINFO_1);
484
485         return offset;
486 }
487
488 static int
489 samr_dissect_USER_DISPINFO_1_ARRAY (tvbuff_t *tvb, int offset, 
490                              packet_info *pinfo, proto_tree *parent_tree, 
491                              char *drep)
492 {
493         guint32 count;
494         proto_item *item=NULL;
495         proto_tree *tree=NULL;
496         int old_offset=offset;
497
498         if(parent_tree){
499                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
500                         "User_DispInfo_1 Array");
501                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1_array);
502         }
503
504
505         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
506                                      hf_samr_count, &count);
507         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
508                         samr_dissect_USER_DISPINFO_1_ARRAY_users, NDR_POINTER_PTR,
509                         "USER_DISPINFO_1_ARRAY", -1, 0);
510
511         proto_item_set_len(item, offset-old_offset);
512         return offset;
513 }
514
515
516
517 static int
518 samr_dissect_USER_DISPINFO_2(tvbuff_t *tvb, int offset, 
519                         packet_info *pinfo, proto_tree *parent_tree, 
520                         char *drep)
521 {
522         proto_item *item=NULL;
523         proto_tree *tree=NULL;
524         int old_offset=offset;
525
526         if(parent_tree){
527                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
528                         "User_DispInfo_2");
529                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2);
530         }
531
532         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
533                         hf_samr_index, NULL);
534         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
535                         hf_samr_rid, NULL);
536         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
537         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
538                         hf_samr_acct_name, 0);
539         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
540                         hf_samr_acct_desc, 0);
541
542         proto_item_set_len(item, offset-old_offset);
543         return offset;
544 }
545
546 static int
547 samr_dissect_USER_DISPINFO_2_ARRAY_users (tvbuff_t *tvb, int offset, 
548                              packet_info *pinfo, proto_tree *tree, 
549                              char *drep)
550 {
551         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
552                         samr_dissect_USER_DISPINFO_2);
553
554         return offset;
555 }
556
557 static int
558 samr_dissect_USER_DISPINFO_2_ARRAY (tvbuff_t *tvb, int offset, 
559                              packet_info *pinfo, proto_tree *parent_tree, 
560                              char *drep)
561 {
562         guint32 count;
563         proto_item *item=NULL;
564         proto_tree *tree=NULL;
565         int old_offset=offset;
566
567         if(parent_tree){
568                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
569                         "User_DispInfo_2 Array");
570                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_2_array);
571         }
572
573
574         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
575                                      hf_samr_count, &count);
576         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
577                         samr_dissect_USER_DISPINFO_2_ARRAY_users, NDR_POINTER_PTR,
578                         "USER_DISPINFO_2_ARRAY", -1, 0);
579
580         proto_item_set_len(item, offset-old_offset);
581         return offset;
582 }
583
584
585
586
587
588 static int
589 samr_dissect_GROUP_DISPINFO(tvbuff_t *tvb, int offset, 
590                         packet_info *pinfo, proto_tree *parent_tree, 
591                         char *drep)
592 {
593         proto_item *item=NULL;
594         proto_tree *tree=NULL;
595         int old_offset=offset;
596
597         if(parent_tree){
598                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
599                         "Group_DispInfo");
600                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo);
601         }
602
603         
604         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
605                         hf_samr_index, NULL);
606         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
607                         hf_samr_rid, NULL);
608         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
609         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
610                         hf_samr_acct_name, 0);
611         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
612                         hf_samr_acct_desc, 0);
613
614         proto_item_set_len(item, offset-old_offset);
615         return offset;
616 }
617
618 static int
619 samr_dissect_GROUP_DISPINFO_ARRAY_groups(tvbuff_t *tvb, int offset, 
620                         packet_info *pinfo, proto_tree *tree, 
621                         char *drep)
622 {
623         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
624                         samr_dissect_GROUP_DISPINFO);
625
626         return offset;
627 }
628
629 static int
630 samr_dissect_GROUP_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
631                         packet_info *pinfo, proto_tree *parent_tree, 
632                         char *drep)
633 {
634         guint32 count;
635         proto_item *item=NULL;
636         proto_tree *tree=NULL;
637         int old_offset=offset;
638
639         if(parent_tree){
640                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
641                         "Group_DispInfo Array");
642                 tree = proto_item_add_subtree(item, ett_samr_group_dispinfo_array);
643         }
644
645         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
646                                      hf_samr_count, &count);
647         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
648                         samr_dissect_GROUP_DISPINFO_ARRAY_groups, NDR_POINTER_PTR,
649                         "GROUP_DISPINFO_ARRAY", -1, 0);
650
651         proto_item_set_len(item, offset-old_offset);
652         return offset;
653 }
654
655
656
657 static int
658 samr_dissect_ASCII_DISPINFO(tvbuff_t *tvb, int offset, 
659                         packet_info *pinfo, proto_tree *parent_tree, 
660                         char *drep)
661 {
662         proto_item *item=NULL;
663         proto_tree *tree=NULL;
664         int old_offset=offset;
665
666         if(parent_tree){
667                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
668                         "Ascii_DispInfo");
669                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo);
670         }
671
672         
673         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
674                         hf_samr_index, NULL);
675         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
676                         hf_samr_rid, NULL);
677         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
678         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
679                         hf_samr_acct_name, 0);
680         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
681                         hf_samr_acct_desc,0 );
682
683         proto_item_set_len(item, offset-old_offset);
684         return offset;
685 }
686
687 static int
688 samr_dissect_ASCII_DISPINFO_ARRAY_users(tvbuff_t *tvb, int offset, 
689                         packet_info *pinfo, proto_tree *tree, 
690                         char *drep)
691 {
692         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
693                         samr_dissect_ASCII_DISPINFO);
694
695         return offset;
696 }
697
698 static int
699 samr_dissect_ASCII_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
700                         packet_info *pinfo, proto_tree *parent_tree,
701                         char *drep)
702 {
703         guint32 count;
704         proto_item *item=NULL;
705         proto_tree *tree=NULL;
706         int old_offset=offset;
707
708         if(parent_tree){
709                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
710                         "Ascii_DispInfo Array");
711                 tree = proto_item_add_subtree(item, ett_samr_ascii_dispinfo_array);
712         }
713
714         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
715                                      hf_samr_count, &count);
716         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
717                         samr_dissect_ASCII_DISPINFO_ARRAY_users, NDR_POINTER_PTR,
718                         "ACSII_DISPINFO_ARRAY", -1, 0);
719
720         proto_item_set_len(item, offset-old_offset);
721         return offset;
722 }
723
724
725 static int
726 samr_dissect_DISPLAY_INFO (tvbuff_t *tvb, int offset, 
727                              packet_info *pinfo, proto_tree *parent_tree,
728                              char *drep)
729 {
730         proto_item *item=NULL;
731         proto_tree *tree=NULL;
732         int old_offset=offset;
733         guint16 level;
734
735         if(parent_tree){
736                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
737                         "DISP_INFO:");
738                 tree = proto_item_add_subtree(item, ett_samr_display_info);
739         }
740
741         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
742                                      hf_samr_level, &level);
743         switch(level){
744         case 1: 
745                 offset = samr_dissect_USER_DISPINFO_1_ARRAY(
746                                 tvb, offset, pinfo, tree, drep);
747                 break;
748         case 2: 
749                 offset = samr_dissect_USER_DISPINFO_2_ARRAY(
750                                 tvb, offset, pinfo, tree, drep);
751                 break;
752         case 3: 
753                 offset = samr_dissect_GROUP_DISPINFO_ARRAY(
754                                 tvb, offset, pinfo, tree, drep);
755                 break;
756         case 4: 
757                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
758                                 tvb, offset, pinfo, tree, drep);
759                 break;
760         case 5: 
761                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
762                                 tvb, offset, pinfo, tree, drep);
763                 break;
764         }
765
766         proto_item_set_len(item, offset-old_offset);
767         return offset;
768 }
769
770 static int
771 samr_dissect_query_dispinfo_reply(tvbuff_t *tvb, int offset, 
772                                   packet_info *pinfo, proto_tree *tree, 
773                                   char *drep)
774 {
775         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
776                         samr_dissect_pointer_long, NDR_POINTER_REF,
777                         "", hf_samr_total_size, 0);
778         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
779                         samr_dissect_pointer_long, NDR_POINTER_REF,
780                         "", hf_samr_ret_size, 0);
781         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
782                         samr_dissect_DISPLAY_INFO, NDR_POINTER_REF,
783                         "", -1, 0);
784         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
785                                      hf_samr_rc, NULL);
786
787         return offset;
788 }
789
790 static int
791 samr_dissect_get_display_enumeration_index_rqst(tvbuff_t *tvb, int offset, 
792                                                 packet_info *pinfo, 
793                                                 proto_tree *tree, 
794                                                 char *drep)
795 {
796         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
797                                        hf_samr_hnd, NULL, FALSE, FALSE);
798
799         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
800                                      hf_samr_level, NULL);
801
802         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
803                         hf_samr_acct_name, 0);
804
805         return offset;
806 }
807
808 static int
809 samr_dissect_get_display_enumeration_index_reply(tvbuff_t *tvb, int offset, 
810                              packet_info *pinfo, proto_tree *tree, 
811                              char *drep)
812 {
813         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
814                         samr_dissect_pointer_long, NDR_POINTER_REF,
815                         "", hf_samr_index, 0);
816
817         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
818                                   hf_samr_rc, NULL);
819
820         return offset;
821 }
822
823
824
825
826 static int
827 samr_dissect_PASSWORD_INFO(tvbuff_t *tvb, int offset, 
828                         packet_info *pinfo, proto_tree *parent_tree,
829                         char *drep)
830 {
831         proto_item *item=NULL;
832         proto_tree *tree=NULL;
833         int old_offset=offset;
834
835         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
836
837         if(parent_tree){
838                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
839                         "PASSWORD_INFO:");
840                 tree = proto_item_add_subtree(item, ett_samr_password_info);
841         }
842
843         
844         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
845                         hf_samr_unknown_short, NULL);
846         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
847                         hf_samr_unknown_long, NULL);
848
849         proto_item_set_len(item, offset-old_offset);
850         return offset;
851 }
852
853 static int
854 samr_dissect_get_usrdom_pwinfo_rqst(tvbuff_t *tvb, int offset, 
855                                     packet_info *pinfo, proto_tree *tree, 
856                                     char *drep)
857 {
858         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
859                                        hf_samr_hnd, NULL, FALSE, FALSE);
860
861         return offset;
862 }
863
864 static int
865 samr_dissect_get_usrdom_pwinfo_reply(tvbuff_t *tvb, int offset, 
866                              packet_info *pinfo, proto_tree *tree, 
867                              char *drep)
868 {
869         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
870                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
871                         "", -1, 0);
872
873         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
874                                   hf_samr_rc, NULL);
875         return offset;
876 }
877
878
879
880 static int
881 samr_dissect_connect2_server(tvbuff_t *tvb, int offset, 
882                              packet_info *pinfo, proto_tree *parent_tree, 
883                              char *drep)
884 {
885         proto_item *item=NULL;
886         proto_tree *tree=NULL;
887         int old_offset=offset;
888
889         if(parent_tree){
890                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
891                         "Server");
892                 tree = proto_item_add_subtree(item, ett_samr_server);
893         }
894
895         offset = dissect_ndr_nt_UNICODE_STRING_str(tvb, offset, pinfo, 
896                         tree, drep);
897
898         proto_item_set_len(item, offset-old_offset);
899         return offset;
900 }
901
902 static int
903 samr_dissect_connect2_rqst(tvbuff_t *tvb, int offset, 
904                            packet_info *pinfo, proto_tree *tree, 
905                            char *drep)
906 {
907         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
908                         samr_dissect_connect2_server, NDR_POINTER_UNIQUE,
909                         "Server", hf_samr_server, 1);
910
911         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
912                                      hf_samr_access, NULL);
913         return offset;
914 }
915
916 static int
917 samr_dissect_connect2_reply(tvbuff_t *tvb, int offset, 
918                              packet_info *pinfo, proto_tree *tree, 
919                              char *drep)
920 {
921         /*
922          * XXX - does this open the handle?
923          */
924         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
925                                        hf_samr_hnd, NULL, TRUE, FALSE);
926
927         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
928                                   hf_samr_rc, NULL);
929         return offset;
930 }
931
932 static int
933 samr_dissect_connect_anon_rqst(tvbuff_t *tvb, int offset, 
934                                packet_info *pinfo, proto_tree *tree, 
935                                char *drep)
936 {
937         char str[2];
938         guint16 server;
939
940         offset=dissect_ndr_uint16(tvb, offset, pinfo, NULL, drep,
941                         hf_samr_server, &server);
942         str[0]=server&0xff;
943         str[1]=0;
944         proto_tree_add_string_format(tree, hf_samr_server, tvb, offset-2, 2,
945                 str, "Server: %s", str);
946
947         return offset;
948 }
949
950 static int
951 samr_dissect_connect_anon_reply(tvbuff_t *tvb, int offset, 
952                                 packet_info *pinfo, proto_tree *tree, 
953                                 char *drep)
954 {
955         /*
956          * XXX - does this open the handle?
957          */
958         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
959                                        hf_samr_hnd, NULL, TRUE, FALSE);
960
961         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
962                                   hf_samr_rc, NULL);
963
964         return offset;
965 }
966
967 static int
968 samr_dissect_USER_GROUP(tvbuff_t *tvb, int offset, 
969                              packet_info *pinfo, proto_tree *parent_tree,
970                              char *drep)
971 {
972         proto_item *item=NULL;
973         proto_tree *tree=NULL;
974         int old_offset=offset;
975
976         if(parent_tree){
977                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
978                         "USER_GROUP:");
979                 tree = proto_item_add_subtree(item, ett_samr_user_group);
980         }
981
982         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
983                                      hf_samr_rid, NULL);
984         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
985                                      hf_samr_rid_attrib, NULL);
986
987         proto_item_set_len(item, offset-old_offset);
988         return offset;
989 }
990
991 static int
992 samr_dissect_USER_GROUP_ARRAY_groups (tvbuff_t *tvb, int offset, 
993                              packet_info *pinfo, proto_tree *tree,
994                              char *drep)
995 {
996         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
997                         samr_dissect_USER_GROUP);
998
999         return offset;
1000 }
1001
1002 static int
1003 samr_dissect_USER_GROUP_ARRAY(tvbuff_t *tvb, int offset, 
1004                         packet_info *pinfo, proto_tree *parent_tree,
1005                         char *drep)
1006 {
1007         guint32 count;
1008         proto_item *item=NULL;
1009         proto_tree *tree=NULL;
1010         int old_offset=offset;
1011
1012         if(parent_tree){
1013                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1014                         "USER_GROUP_ARRAY");
1015                 tree = proto_item_add_subtree(item, ett_samr_user_group_array);
1016         }
1017
1018         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1019                         hf_samr_count, &count);
1020         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1021                         samr_dissect_USER_GROUP_ARRAY_groups, NDR_POINTER_UNIQUE,
1022                         "USER_GROUP_ARRAY", -1, 0);
1023
1024         proto_item_set_len(item, offset-old_offset);
1025         return offset;
1026 }
1027
1028 static int
1029 samr_dissect_USER_GROUP_ARRAY_ptr(tvbuff_t *tvb, int offset, 
1030                         packet_info *pinfo, proto_tree *tree,
1031                         char *drep)
1032 {
1033         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1034                         samr_dissect_USER_GROUP_ARRAY, NDR_POINTER_UNIQUE,
1035                         "USER_GROUP_ARRAY", -1, 0);
1036         return offset;
1037 }
1038
1039 static int
1040 samr_dissect_get_groups_for_user_rqst(tvbuff_t *tvb, int offset, 
1041                                       packet_info *pinfo, proto_tree *tree, 
1042                                       char *drep)
1043 {
1044         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1045                                        hf_samr_hnd, NULL, FALSE, FALSE);
1046
1047         return offset;
1048 }
1049
1050 static int
1051 samr_dissect_get_groups_for_user_reply(tvbuff_t *tvb, int offset, 
1052                                        packet_info *pinfo, proto_tree *tree, 
1053                                        char *drep)
1054 {
1055         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1056                         samr_dissect_USER_GROUP_ARRAY_ptr, NDR_POINTER_REF,
1057                         "", -1, 0);
1058
1059         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1060                                   hf_samr_rc, NULL);
1061         return offset;
1062 }
1063
1064
1065
1066 static int
1067 samr_dissect_open_domain_rqst(tvbuff_t *tvb, int offset, 
1068                               packet_info *pinfo, proto_tree *tree, 
1069                               char *drep)
1070 {
1071         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1072                                        hf_samr_hnd, NULL, FALSE, FALSE);
1073
1074         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1075                                      hf_samr_access, NULL);
1076         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1077                         dissect_ndr_nt_SID, NDR_POINTER_REF,
1078                         "", -1, 0);
1079         return offset;
1080 }
1081
1082 static int
1083 samr_dissect_open_domain_reply(tvbuff_t *tvb, int offset, 
1084                              packet_info *pinfo, proto_tree *tree, 
1085                              char *drep)
1086 {
1087         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1088                                        hf_samr_hnd, NULL, FALSE, FALSE);
1089
1090         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1091                                   hf_samr_rc, NULL);
1092
1093         return offset;
1094 }
1095
1096 static int
1097 samr_dissect_context_handle_SID(tvbuff_t *tvb, int offset, 
1098                              packet_info *pinfo, proto_tree *tree, 
1099                              char *drep)
1100 {
1101         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1102                                        hf_samr_hnd, NULL, FALSE, FALSE);
1103
1104         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1105                         dissect_ndr_nt_SID, NDR_POINTER_REF,
1106                         "SID", -1, 0);
1107         return offset;
1108 }
1109
1110 static int
1111 samr_dissect_add_member_to_group_rqst(tvbuff_t *tvb, int offset, 
1112                                       packet_info *pinfo, proto_tree *tree, 
1113                                       char *drep)
1114 {
1115         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1116                                        hf_samr_hnd, NULL, FALSE, FALSE);
1117
1118         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1119                                      hf_samr_group, NULL);
1120
1121         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1122                                      hf_samr_rid, NULL);
1123
1124         return offset;
1125 }
1126
1127 static int
1128 samr_dissect_add_member_to_group_reply(tvbuff_t *tvb, int offset, 
1129                                        packet_info *pinfo, proto_tree *tree, 
1130                                        char *drep)
1131 {
1132         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1133                                   hf_samr_rc, NULL);
1134
1135         return offset;
1136 }
1137
1138 static int
1139 samr_dissect_unknown_3c_rqst(tvbuff_t *tvb, int offset, 
1140                              packet_info *pinfo, proto_tree *tree, 
1141                              char *drep)
1142 {
1143         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1144                                        hf_samr_hnd, NULL, FALSE, FALSE);
1145
1146         return offset;
1147 }
1148
1149 static int
1150 samr_dissect_unknown_3c_reply(tvbuff_t *tvb, int offset, 
1151                              packet_info *pinfo, proto_tree *tree, 
1152                              char *drep)
1153 {
1154         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1155                         samr_dissect_pointer_short, NDR_POINTER_REF,
1156                         "", hf_samr_unknown_short, 0);
1157
1158         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1159                                   hf_samr_rc, NULL);
1160         return offset;
1161 }
1162
1163 static int
1164 samr_dissect_create_alias_in_domain_rqst(tvbuff_t *tvb, int offset, 
1165                                          packet_info *pinfo, proto_tree *tree, 
1166                                          char *drep)
1167 {
1168         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1169                                        hf_samr_hnd, NULL, FALSE, FALSE);
1170
1171         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1172                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1173                         "Account Name", hf_samr_acct_name, 0);
1174
1175         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1176                                      hf_samr_access, NULL);
1177
1178         return offset;
1179 }
1180
1181 static int
1182 samr_dissect_create_alias_in_domain_reply(tvbuff_t *tvb, int offset, 
1183                              packet_info *pinfo, proto_tree *tree, 
1184                              char *drep)
1185 {
1186         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1187                                        hf_samr_hnd, NULL, FALSE, FALSE);
1188
1189         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1190                                      hf_samr_rid, NULL);
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_query_information_alias_rqst(tvbuff_t *tvb, int offset, 
1200                                           packet_info *pinfo, 
1201                                           proto_tree *tree, char *drep)
1202 {
1203         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1204                                        hf_samr_hnd, NULL, FALSE, FALSE);
1205
1206         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1207                         hf_samr_level, NULL);
1208
1209         return offset;
1210 }
1211
1212 static int
1213 samr_dissect_ALIAS_INFO_1 (tvbuff_t *tvb, int offset, 
1214                              packet_info *pinfo, proto_tree *tree,
1215                              char *drep)
1216 {
1217         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1218                 tree, drep,
1219                 hf_samr_acct_name, 0);
1220         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1221                                      hf_samr_rid, NULL);
1222         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1223                 tree, drep,
1224                 hf_samr_acct_desc, 0);
1225         return offset;
1226 }
1227
1228 static int
1229 samr_dissect_ALIAS_INFO(tvbuff_t *tvb, int offset, 
1230                         packet_info *pinfo, proto_tree *parent_tree,
1231                         char *drep)
1232 {
1233         proto_item *item=NULL;
1234         proto_tree *tree=NULL;
1235         int old_offset=offset;
1236         guint16 level;
1237
1238         if(parent_tree){
1239                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1240                         "ALIAS_INFO:");
1241                 tree = proto_item_add_subtree(item, ett_samr_alias_info);
1242         }
1243
1244         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1245                                      hf_samr_level, &level);
1246         switch(level){
1247         case 1: 
1248                 offset = samr_dissect_ALIAS_INFO_1(
1249                                 tvb, offset, pinfo, tree, drep);
1250                 break;
1251         case 2: 
1252                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1253                         tree, drep,
1254                         hf_samr_acct_name, 0);
1255                 break;
1256         case 3: 
1257                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1258                         tree, drep,
1259                         hf_samr_acct_desc, 0);
1260                 break;
1261         }
1262
1263         proto_item_set_len(item, offset-old_offset);
1264         return offset;
1265 }
1266
1267 static int
1268 samr_dissect_ALIAS_INFO_ptr(tvbuff_t *tvb, int offset, 
1269                         packet_info *pinfo, proto_tree *tree,
1270                         char *drep)
1271 {
1272         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1273                         samr_dissect_ALIAS_INFO, NDR_POINTER_UNIQUE,
1274                         "ALIAS_INFO", -1, 0);
1275         return offset;
1276 }
1277
1278 static int
1279 samr_dissect_query_information_alias_reply(tvbuff_t *tvb, int offset, 
1280                                            packet_info *pinfo, 
1281                                            proto_tree *tree, char *drep)
1282 {
1283         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1284                         samr_dissect_ALIAS_INFO_ptr, NDR_POINTER_REF,
1285                         "", -1, 0);
1286
1287         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1288                                   hf_samr_rc, NULL);
1289
1290         return offset;
1291 }
1292
1293 static int
1294 samr_dissect_set_information_alias_rqst(tvbuff_t *tvb, int offset, 
1295                              packet_info *pinfo, proto_tree *tree, 
1296                              char *drep)
1297 {
1298         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1299                                        hf_samr_hnd, NULL, FALSE, FALSE);
1300
1301         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1302                                      hf_samr_level, NULL);
1303         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1304                         samr_dissect_ALIAS_INFO, NDR_POINTER_REF,
1305                         "", -1, 0);
1306         return offset;
1307 }
1308
1309 static int
1310 samr_dissect_set_information_alias_reply(tvbuff_t *tvb, int offset, 
1311                                          packet_info *pinfo, proto_tree *tree, 
1312                                          char *drep)
1313 {
1314         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1315                         samr_dissect_ALIAS_INFO_ptr, NDR_POINTER_REF,
1316                         "", -1, 0);
1317
1318         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1319                                   hf_samr_rc, NULL);
1320         return offset;
1321 }
1322
1323 static int
1324 samr_dissect_CRYPT_PASSWORD(tvbuff_t *tvb, int offset, 
1325                         packet_info *pinfo _U_, proto_tree *tree, 
1326                         char *drep _U_)
1327 {
1328         proto_tree_add_item(tree, hf_samr_crypt_password, tvb, offset, 516,
1329                 FALSE);
1330         offset += 516;
1331         return offset;
1332 }
1333
1334 static int
1335 samr_dissect_CRYPT_HASH(tvbuff_t *tvb, int offset, 
1336                         packet_info *pinfo _U_, proto_tree *tree, 
1337                         char *drep _U_)
1338 {
1339         proto_tree_add_item(tree, hf_samr_crypt_hash, tvb, offset, 16,
1340                 FALSE);
1341         offset += 16;
1342         return offset;
1343 }
1344
1345
1346 static int
1347 samr_dissect_oem_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1348                                             packet_info *pinfo, 
1349                                             proto_tree *tree, char *drep)
1350 {
1351         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1352                                        hf_samr_hnd, NULL, FALSE, FALSE);
1353
1354         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1355                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1356                         "Server", hf_samr_server, 0);
1357         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1358                         samr_dissect_pointer_STRING, NDR_POINTER_REF,
1359                         "Account Name", hf_samr_acct_name, 0);
1360         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1361                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1362                         "Password", -1, 0);
1363         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1364                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1365                         "Hash", -1, 0);
1366         return offset;
1367 }
1368
1369 static int
1370 samr_dissect_oem_change_password_user2_reply(tvbuff_t *tvb, int offset, 
1371                                              packet_info *pinfo, 
1372                                              proto_tree *tree, char *drep)
1373 {
1374         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1375                                   hf_samr_rc, NULL);
1376
1377         return offset;
1378 }
1379
1380 static int
1381 samr_dissect_unicode_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1382                                                 packet_info *pinfo, 
1383                                                 proto_tree *tree, char *drep)
1384 {
1385         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1386                                        hf_samr_hnd, NULL, FALSE, FALSE);
1387
1388         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1389                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1390                         "Server", hf_samr_server, 0);
1391         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1392                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1393                         "Account Name", hf_samr_acct_name, 0);
1394         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1395                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1396                         "Password", -1, 0);
1397         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1398                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1399                         "Hash", -1, 0);
1400         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1401                                      hf_samr_lm_change, NULL);
1402         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1403                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1404                         "Password", -1, 0);
1405         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1406                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1407                         "Hash", -1, 0);
1408         return offset;
1409 }
1410
1411 static int
1412 samr_dissect_unicode_change_password_user2_reply(tvbuff_t *tvb, int offset, 
1413                                                  packet_info *pinfo, 
1414                                                  proto_tree *tree, char *drep)
1415 {
1416         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1417                                   hf_samr_rc, NULL);
1418
1419         return offset;
1420 }
1421
1422 static int
1423 samr_dissect_unknown_3b_rqst(tvbuff_t *tvb, int offset, 
1424                              packet_info *pinfo, proto_tree *tree, 
1425                              char *drep)
1426 {
1427         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1428                                        hf_samr_hnd, NULL, FALSE, FALSE);
1429
1430         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1431                                      hf_samr_unknown_short, NULL);
1432         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1433                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1434                         "Unknown", hf_samr_unknown_string, 0);
1435         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1436                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1437                         "Unknown", hf_samr_unknown_string, 0);
1438         return offset;
1439 }
1440
1441 static int
1442 samr_dissect_unknown_3b_reply(tvbuff_t *tvb, int offset, 
1443                               packet_info *pinfo, proto_tree *tree, 
1444                               char *drep)
1445 {
1446         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1447                                   hf_samr_rc, NULL);
1448
1449         return offset;
1450 }
1451
1452 static int
1453 samr_dissect_create_user2_in_domain_rqst(tvbuff_t *tvb, int offset, 
1454                                          packet_info *pinfo, proto_tree *tree, 
1455                                          char *drep)
1456 {
1457         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1458                                        hf_samr_hnd, NULL, FALSE, FALSE);
1459
1460         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1461                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1462                         "Account Name", hf_samr_acct_name, 0);
1463         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
1464         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1465                         hf_samr_access, NULL);
1466
1467         return offset;
1468 }
1469
1470 static int
1471 samr_dissect_create_user2_in_domain_reply(tvbuff_t *tvb, int offset, 
1472                              packet_info *pinfo, proto_tree *tree, 
1473                              char *drep)
1474 {
1475         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1476                                        hf_samr_hnd, NULL, FALSE, FALSE);
1477
1478         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1479                                      hf_samr_unknown_long, NULL);
1480         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1481                                      hf_samr_rid, NULL);
1482
1483         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1484                                   hf_samr_rc, NULL);
1485         return offset;
1486 }
1487
1488 static int
1489 samr_dissect_get_display_enumeration_index2_rqst(tvbuff_t *tvb, int offset, 
1490                                                  packet_info *pinfo, 
1491                                                  proto_tree *tree, char *drep)
1492 {
1493         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1494                                        hf_samr_hnd, NULL, FALSE, FALSE);
1495
1496         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1497                                      hf_samr_level, NULL);
1498         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1499                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1500                         "Account Name", hf_samr_acct_name, 0);
1501         return offset;
1502 }
1503
1504 static int
1505 samr_dissect_get_display_enumeration_index2_reply(tvbuff_t *tvb, int offset, 
1506                              packet_info *pinfo, proto_tree *tree, 
1507                              char *drep)
1508 {
1509         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1510                                      hf_samr_index, NULL);
1511
1512         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1513                                   hf_samr_rc, NULL);
1514         return offset;
1515 }
1516
1517 static int
1518 samr_dissect_change_password_user_rqst(tvbuff_t *tvb, int offset, 
1519                                        packet_info *pinfo, proto_tree *tree, 
1520                                        char *drep)
1521 {
1522         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1523                                        hf_samr_hnd, NULL, FALSE, FALSE);
1524
1525         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1526                         hf_samr_unknown_char, NULL);
1527         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1528                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1529                         "Hash", -1, 0);
1530         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1531                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1532                         "Hash", -1, 0);
1533         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1534                         hf_samr_unknown_char, NULL);
1535         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1536                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1537                         "Hash", -1, 0);
1538         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1539                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1540                         "Hash", -1, 0);
1541         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1542                         hf_samr_unknown_char, NULL);
1543         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1544                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1545                         "Hash", -1, 0);
1546         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1547                         hf_samr_unknown_char, NULL);
1548         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1549                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1550                         "Hash", -1, 0);
1551
1552         return offset;
1553 }
1554
1555 static int
1556 samr_dissect_change_password_user_reply(tvbuff_t *tvb, int offset, 
1557                                         packet_info *pinfo, proto_tree *tree, 
1558                                         char *drep)
1559 {
1560         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1561                                   hf_samr_rc, NULL);
1562
1563         return offset;
1564 }
1565
1566 static int
1567 samr_dissect_set_member_attributes_of_group_rqst(tvbuff_t *tvb, int offset, 
1568                                                  packet_info *pinfo, 
1569                                                  proto_tree *tree, char *drep)
1570 {
1571         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1572                                        hf_samr_hnd, NULL, FALSE, FALSE);
1573
1574         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1575                                      hf_samr_attrib, NULL);
1576         return offset;
1577 }
1578
1579 static int
1580 samr_dissect_set_member_attributes_of_group_reply(tvbuff_t *tvb, int offset, 
1581                              packet_info *pinfo, proto_tree *tree, 
1582                              char *drep)
1583 {
1584         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1585                                   hf_samr_rc, NULL);
1586
1587         return offset;
1588 }
1589
1590 static int
1591 samr_dissect_GROUP_INFO_1 (tvbuff_t *tvb, int offset, 
1592                              packet_info *pinfo, proto_tree *tree,
1593                              char *drep)
1594 {
1595         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1596                 tree, drep,
1597                 hf_samr_acct_name, 0);
1598         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1599                                      hf_samr_rid, NULL);
1600         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1601                                         hf_samr_attrib, NULL);
1602         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1603                 tree, drep,
1604                 hf_samr_acct_desc, 0);
1605         return offset;
1606 }
1607
1608 static int
1609 samr_dissect_GROUP_INFO(tvbuff_t *tvb, int offset, 
1610                         packet_info *pinfo, proto_tree *parent_tree,
1611                         char *drep)
1612 {
1613         proto_item *item=NULL;
1614         proto_tree *tree=NULL;
1615         int old_offset=offset;
1616         guint16 level;
1617
1618         if(parent_tree){
1619                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1620                         "GROUP_INFO:");
1621                 tree = proto_item_add_subtree(item, ett_samr_group_info);
1622         }
1623
1624         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1625                                      hf_samr_level, &level);
1626         switch(level){
1627         case 1: 
1628                 offset = samr_dissect_GROUP_INFO_1(
1629                                 tvb, offset, pinfo, tree, drep);
1630                 break;
1631         case 2: 
1632                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1633                         tree, drep,
1634                         hf_samr_acct_name, 0);
1635                 break;
1636         case 3:
1637                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1638                         hf_samr_attrib, NULL);
1639                 break;
1640         case 4: 
1641                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1642                         tree, drep,
1643                         hf_samr_acct_desc, 0);
1644                 break;
1645         }
1646
1647         proto_item_set_len(item, offset-old_offset);
1648         return offset;
1649 }
1650
1651 static int
1652 samr_dissect_GROUP_INFO_ptr(tvbuff_t *tvb, int offset, 
1653                         packet_info *pinfo, proto_tree *tree,
1654                         char *drep)
1655 {
1656         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1657                         samr_dissect_GROUP_INFO, NDR_POINTER_UNIQUE,
1658                         "GROUP_INFO", -1, 0);
1659         return offset;
1660 }
1661
1662 static int
1663 samr_dissect_query_information_group_rqst(tvbuff_t *tvb, int offset, 
1664                                           packet_info *pinfo, 
1665                                           proto_tree *tree, char *drep)
1666 {
1667         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1668                                        hf_samr_hnd, NULL, FALSE, FALSE);
1669
1670         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1671                                      hf_samr_level, NULL);
1672
1673         return offset;
1674 }
1675
1676 static int
1677 samr_dissect_query_information_group_reply(tvbuff_t *tvb, int offset, 
1678                         packet_info *pinfo, proto_tree *tree,
1679                         char *drep)
1680 {
1681         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1682                         samr_dissect_GROUP_INFO_ptr, NDR_POINTER_REF,
1683                         "", -1, 0);
1684
1685         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1686                                   hf_samr_rc, NULL);
1687         return offset;
1688 }
1689
1690 static int
1691 samr_dissect_set_information_group_rqst(tvbuff_t *tvb, int offset, 
1692                                         packet_info *pinfo, proto_tree *tree,
1693                                         char *drep)
1694 {
1695         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1696                                        hf_samr_hnd, NULL, FALSE, FALSE);
1697
1698         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1699                                      hf_samr_level, NULL);
1700         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1701                         samr_dissect_GROUP_INFO, NDR_POINTER_REF,
1702                         "", -1, 0);
1703         return offset;
1704 }
1705
1706 static int
1707 samr_dissect_set_information_group_reply(tvbuff_t *tvb, int offset, 
1708                              packet_info *pinfo, proto_tree *tree, 
1709                              char *drep)
1710 {
1711         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
1712                                   hf_samr_rc, NULL);
1713
1714         return offset;
1715 }
1716
1717
1718 static int
1719 samr_dissect_get_domain_password_information_rqst(tvbuff_t *tvb, int offset, 
1720                                                   packet_info *pinfo, 
1721                                                   proto_tree *tree,
1722                                                   char *drep)
1723 {
1724         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1725                                        hf_samr_hnd, NULL, FALSE, FALSE);
1726
1727         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1728                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1729                         "Domain", hf_samr_domain, 0);
1730         return offset;
1731 }
1732
1733 static int
1734 samr_dissect_get_domain_password_information_reply(tvbuff_t *tvb, int offset, 
1735                                                    packet_info *pinfo, 
1736                                                    proto_tree *tree, 
1737                                                    char *drep)
1738 {
1739         /*
1740          * XXX - really?  Not the same as
1741          * "samr_dissect_get_usrdom_pwinfo_reply()"?
1742          */
1743         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
1744                                        hf_samr_hnd, NULL, FALSE, FALSE);
1745
1746         return offset;
1747 }
1748
1749 static int
1750 samr_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset, 
1751                              packet_info *pinfo, proto_tree *parent_tree,
1752                              char *drep)
1753 {
1754         proto_item *item=NULL;
1755         proto_tree *tree=NULL;
1756         int old_offset=offset;
1757
1758         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */ 
1759
1760         if(parent_tree){
1761                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1762                         "DOMAIN_INFO_1:");
1763                 tree = proto_item_add_subtree(item, ett_samr_domain_info_1);
1764         }
1765
1766         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1767                                         hf_samr_min_pwd_len, NULL);
1768         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1769                                         hf_samr_pwd_history_len, NULL);
1770         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1771                                         hf_samr_unknown_long, NULL);
1772         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1773                                         hf_samr_max_pwd_age);
1774         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1775                                         hf_samr_min_pwd_age);
1776         proto_item_set_len(item, offset-old_offset);
1777         return offset;
1778 }
1779
1780 static int
1781 samr_dissect_DOMAIN_INFO_2(tvbuff_t *tvb, int offset, 
1782                         packet_info *pinfo, proto_tree *parent_tree,
1783                         char *drep)
1784 {
1785         proto_item *item=NULL;
1786         proto_tree *tree=NULL;
1787         int old_offset=offset;
1788
1789         if(parent_tree){
1790                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1791                         "DOMAIN_INFO_2:");
1792                 tree = proto_item_add_subtree(item, ett_samr_domain_info_2);
1793         }
1794
1795         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1796                         hf_samr_unknown_time);
1797         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1798                         hf_samr_unknown_string, 0);
1799         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1800                         hf_samr_domain, 0);
1801         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1802                         hf_samr_controller, 0);
1803         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1804                         hf_samr_unknown_time);
1805         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1806                         hf_samr_unknown_long, NULL);
1807         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1808                         hf_samr_unknown_long, NULL);
1809         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1810                         hf_samr_unknown_char, NULL);
1811         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1812                         hf_samr_num_users, NULL);
1813         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1814                         hf_samr_num_groups, NULL);
1815         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1816                         hf_samr_num_aliases, NULL);
1817
1818         proto_item_set_len(item, offset-old_offset);
1819         return offset;
1820 }
1821
1822 static int
1823 samr_dissect_DOMAIN_INFO_8(tvbuff_t *tvb, int offset, 
1824                              packet_info *pinfo, proto_tree *parent_tree,
1825                              char *drep)
1826 {
1827         proto_item *item=NULL;
1828         proto_tree *tree=NULL;
1829         int old_offset=offset;
1830
1831         if(parent_tree){
1832                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1833                         "DOMAIN_INFO_8:");
1834                 tree = proto_item_add_subtree(item, ett_samr_domain_info_8);
1835         }
1836
1837         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1838                                         hf_samr_max_pwd_age);
1839         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1840                                         hf_samr_min_pwd_age);
1841
1842         proto_item_set_len(item, offset-old_offset);
1843         return offset;
1844 }
1845
1846 static int
1847 samr_dissect_REPLICATION_STATUS(tvbuff_t *tvb, int offset, 
1848                         packet_info *pinfo, proto_tree *parent_tree,
1849                         char *drep)
1850 {
1851         proto_item *item=NULL;
1852         proto_tree *tree=NULL;
1853         int old_offset=offset;
1854
1855         if(parent_tree){
1856                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1857                         "REPLICATION_STATUS:");
1858                 tree = proto_item_add_subtree(item, ett_samr_replication_status);
1859         }
1860
1861         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1862                         hf_samr_unknown_hyper, NULL);
1863         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1864                         hf_samr_unknown_hyper, NULL);
1865         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1866                         hf_samr_unknown_short, NULL);
1867
1868         proto_item_set_len(item, offset-old_offset);
1869         return offset;
1870 }
1871
1872 static int
1873 samr_dissect_DOMAIN_INFO_11(tvbuff_t *tvb, int offset, 
1874                              packet_info *pinfo, proto_tree *parent_tree,
1875                              char *drep)
1876 {
1877         proto_item *item=NULL;
1878         proto_tree *tree=NULL;
1879         int old_offset=offset;
1880
1881         if(parent_tree){
1882                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1883                         "DOMAIN_INFO_11:");
1884                 tree = proto_item_add_subtree(item, ett_samr_domain_info_11);
1885         }
1886
1887         offset = samr_dissect_DOMAIN_INFO_2(
1888                         tvb, offset, pinfo, tree, drep);
1889         offset = samr_dissect_REPLICATION_STATUS(
1890                         tvb, offset, pinfo, tree, drep);
1891
1892         proto_item_set_len(item, offset-old_offset);
1893         return offset;
1894 }
1895
1896 static int
1897 samr_dissect_DOMAIN_INFO_13(tvbuff_t *tvb, int offset, 
1898                              packet_info *pinfo, proto_tree *parent_tree,
1899                              char *drep)
1900 {
1901         proto_item *item=NULL;
1902         proto_tree *tree=NULL;
1903         int old_offset=offset;
1904
1905         if(parent_tree){
1906                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1907                         "DOMAIN_INFO_13:");
1908                 tree = proto_item_add_subtree(item, ett_samr_domain_info_13);
1909         }
1910
1911         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1912                                         hf_samr_unknown_time);
1913         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1914                                         hf_samr_unknown_time);
1915         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1916                                         hf_samr_unknown_time);
1917
1918         proto_item_set_len(item, offset-old_offset);
1919         return offset;
1920 }
1921
1922
1923 static int
1924 samr_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset, 
1925                         packet_info *pinfo, proto_tree *parent_tree,
1926                         char *drep)
1927 {
1928         proto_item *item=NULL;
1929         proto_tree *tree=NULL;
1930         int old_offset=offset;
1931         guint16 level;
1932
1933         if(parent_tree){
1934                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
1935                         "DOMAIN_INFO:");
1936                 tree = proto_item_add_subtree(item, ett_samr_domain_info);
1937         }
1938
1939         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1940                                      hf_samr_level, &level);
1941
1942         ALIGN_TO_4_BYTES;  /* all union arms aligned to 4 bytes, case 7 and 9 need this  */
1943         switch(level){
1944         case 1: 
1945                 offset = samr_dissect_DOMAIN_INFO_1(
1946                                 tvb, offset, pinfo, tree, drep);
1947                 break;
1948         case 2: 
1949                 offset = samr_dissect_DOMAIN_INFO_2(
1950                                 tvb, offset, pinfo, tree, drep);
1951                 break;
1952
1953         case 3:
1954                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1955                                 hf_samr_unknown_time);
1956                 break;
1957         case 4:
1958                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1959                         tree, drep, hf_samr_unknown_string, 0);
1960                 break;
1961
1962         case 5:
1963                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1964                         tree, drep, hf_samr_domain, 0);
1965                 break;
1966
1967         case 6:
1968                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1969                         tree, drep, hf_samr_controller, 0);
1970                 break;
1971
1972         case 7:
1973                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1974                         hf_samr_unknown_short, NULL);
1975                 break;
1976         case 8: 
1977                 offset = samr_dissect_DOMAIN_INFO_8(
1978                                 tvb, offset, pinfo, tree, drep);
1979                 break;
1980         case 9:
1981                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1982                         hf_samr_unknown_short, NULL);
1983                 break;
1984         case 11:        
1985                 offset = samr_dissect_DOMAIN_INFO_11(
1986                                 tvb, offset, pinfo, tree, drep);
1987                 break;
1988         case 12:
1989                 offset = samr_dissect_REPLICATION_STATUS(
1990                                 tvb, offset, pinfo, tree, drep);
1991                 break;
1992         case 13:        
1993                 offset = samr_dissect_DOMAIN_INFO_13(
1994                                 tvb, offset, pinfo, tree, drep);
1995                 break;
1996         }
1997
1998         proto_item_set_len(item, offset-old_offset);
1999         return offset;
2000 }
2001
2002 static int
2003 samr_dissect_set_information_domain_rqst(tvbuff_t *tvb, int offset, 
2004                                          packet_info *pinfo, proto_tree *tree,
2005                                          char *drep)
2006 {
2007         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2008                                        hf_samr_hnd, NULL, FALSE, FALSE);
2009
2010         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2011                                      hf_samr_level, NULL);
2012         offset = samr_dissect_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
2013
2014         return offset;
2015 }
2016
2017 static int
2018 samr_dissect_set_information_domain_reply(tvbuff_t *tvb, int offset, 
2019                                           packet_info *pinfo, 
2020                                           proto_tree *tree, char *drep)
2021 {
2022         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2023                                   hf_samr_rc, NULL);
2024
2025         return offset;
2026 }
2027
2028 static int
2029 samr_dissect_lookup_domain_rqst(tvbuff_t *tvb, int offset, 
2030                                 packet_info *pinfo, proto_tree *tree,
2031                                 char *drep)
2032 {
2033         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2034                                        hf_samr_hnd, NULL, FALSE, FALSE);
2035
2036         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2037                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
2038                         "", hf_samr_domain, 0);
2039
2040         return offset;
2041 }
2042
2043 static int
2044 samr_dissect_lookup_domain_reply(tvbuff_t *tvb, int offset, 
2045                              packet_info *pinfo, proto_tree *tree,
2046                              char *drep)
2047 {
2048         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2049                         dissect_ndr_nt_SID_ptr, NDR_POINTER_REF,
2050                         "", -1, 0);
2051
2052         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2053                                   hf_samr_rc, NULL);
2054         return offset;
2055 }
2056
2057 int
2058 dissect_ndr_nt_PSID(tvbuff_t *tvb, int offset, 
2059                              packet_info *pinfo, proto_tree *parent_tree,
2060                              char *drep)
2061 {
2062         proto_item *item=NULL;
2063         proto_tree *tree=NULL;
2064         int old_offset=offset;
2065
2066         if(parent_tree){
2067                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2068                         "SID pointer:");
2069                 tree = proto_item_add_subtree(item, ett_samr_sid_pointer);
2070         }
2071
2072         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2073                         dissect_ndr_nt_SID, NDR_POINTER_UNIQUE,
2074                         "SID", -1, 0);
2075
2076         proto_item_set_len(item, offset-old_offset);
2077         return offset;
2078 }
2079
2080
2081 static int
2082 dissect_ndr_nt_PSID_ARRAY_sids (tvbuff_t *tvb, int offset, 
2083                              packet_info *pinfo, proto_tree *tree,
2084                              char *drep)
2085 {
2086         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2087                         dissect_ndr_nt_PSID);
2088
2089         return offset;
2090 }
2091
2092
2093 int
2094 dissect_ndr_nt_PSID_ARRAY(tvbuff_t *tvb, int offset, 
2095                         packet_info *pinfo, proto_tree *parent_tree,
2096                         char *drep)
2097 {
2098         guint32 count;
2099         proto_item *item=NULL;
2100         proto_tree *tree=NULL;
2101         int old_offset=offset;
2102
2103         if(parent_tree){
2104                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2105                         "SID array:");
2106                 tree = proto_item_add_subtree(item, ett_samr_sid_array);
2107         }
2108
2109         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2110                         hf_samr_count, &count);
2111         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2112                         dissect_ndr_nt_PSID_ARRAY_sids, NDR_POINTER_UNIQUE,
2113                         "PSID_ARRAY", -1, 0);
2114
2115         proto_item_set_len(item, offset-old_offset);
2116         return offset;
2117 }
2118
2119 /* called from NETLOGON but placed here since where are where the hf_fields are defined */
2120 int
2121 dissect_ndr_nt_SID_AND_ATTRIBUTES(tvbuff_t *tvb, int offset, 
2122                         packet_info *pinfo, proto_tree *parent_tree,
2123                         char *drep)
2124 {
2125         proto_item *item=NULL;
2126         proto_tree *tree=NULL;
2127
2128         if(parent_tree){
2129                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2130                         "SID_AND_ATTRIBUTES:");
2131                 tree = proto_item_add_subtree(item, ett_samr_sid_and_attributes);
2132         }
2133
2134         offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, drep);
2135
2136         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2137                                      hf_samr_attrib, NULL);
2138
2139         return offset;
2140 }
2141
2142 int
2143 dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY(tvbuff_t *tvb, int offset, 
2144                         packet_info *pinfo, proto_tree *parent_tree,
2145                         char *drep)
2146 {
2147         guint32 count;
2148         proto_item *item=NULL;
2149         proto_tree *tree=NULL;
2150         int old_offset=offset;
2151
2152         if(parent_tree){
2153                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2154                         "SID_AND_ATTRIBUTES array:");
2155                 tree = proto_item_add_subtree(item, ett_samr_sid_and_attributes_array);
2156         }
2157
2158         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2159                         hf_samr_count, &count);
2160         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2161                         dissect_ndr_nt_SID_AND_ATTRIBUTES);
2162
2163         proto_item_set_len(item, offset-old_offset);
2164         return offset;
2165 }
2166
2167
2168 static int
2169 samr_dissect_index(tvbuff_t *tvb, int offset, 
2170                              packet_info *pinfo, proto_tree *tree,
2171                              char *drep)
2172 {
2173         dcerpc_info *di;
2174
2175         di=pinfo->private_data;
2176
2177         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2178                         di->hf_index, NULL);
2179
2180         return offset;
2181 }
2182
2183
2184 static int
2185 samr_dissect_INDEX_ARRAY_value (tvbuff_t *tvb, int offset, 
2186                              packet_info *pinfo, proto_tree *tree,
2187                              char *drep)
2188 {
2189         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2190                         samr_dissect_index);
2191
2192         return offset;
2193 }
2194
2195 static char *
2196 plural_ending(const char *string)
2197 {
2198         size_t string_len;
2199
2200         string_len = strlen(string);
2201         if (string_len > 0 && string[string_len - 1] == 's') {
2202                 /* String ends with "s" - pluralize by adding "es" */
2203                 return "es";
2204         } else {
2205                 /* Field name doesn't end with "s" - pluralize by adding "s" */
2206                 return "s";
2207         }
2208 }
2209
2210 static int
2211 samr_dissect_INDEX_ARRAY(tvbuff_t *tvb, int offset, 
2212                         packet_info *pinfo, proto_tree *parent_tree,
2213                         char *drep)
2214 {
2215         char *field_name;
2216         guint32 count;
2217         proto_item *item=NULL;
2218         proto_tree *tree=NULL;
2219         int old_offset=offset;
2220         dcerpc_info *di;
2221         char str[256];
2222
2223         di=pinfo->private_data;
2224
2225         field_name = proto_registrar_get_name(di->hf_index);
2226         snprintf(str, 255, "INDEX_ARRAY: %s%s:", field_name,
2227             plural_ending(field_name));
2228         if(parent_tree){
2229                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2230                         "%s", str);
2231                 tree = proto_item_add_subtree(item, ett_samr_index_array);
2232         }
2233
2234         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2235                         hf_samr_count, &count);
2236         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2237                         samr_dissect_INDEX_ARRAY_value, NDR_POINTER_UNIQUE,
2238                         str, di->hf_index, 0);
2239
2240         proto_item_set_len(item, offset-old_offset);
2241         return offset;
2242 }
2243
2244 static int
2245 samr_dissect_get_alias_membership_rqst(tvbuff_t *tvb, int offset, 
2246                                        packet_info *pinfo, proto_tree *tree,
2247                                        char *drep)
2248 {
2249         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2250                                        hf_samr_hnd, NULL, FALSE, FALSE);
2251
2252         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2253                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
2254                         "", -1, 0);
2255
2256         return offset;
2257 }
2258
2259 static int
2260 samr_dissect_get_alias_membership_reply(tvbuff_t *tvb, int offset, 
2261                              packet_info *pinfo, proto_tree *tree,
2262                              char *drep)
2263 {
2264         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2265                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
2266                         "", hf_samr_alias, 0);
2267
2268         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2269                                   hf_samr_rc, NULL);
2270
2271         return offset;
2272 }
2273
2274 static int
2275 samr_dissect_IDX_AND_NAME(tvbuff_t *tvb, int offset, 
2276                              packet_info *pinfo, proto_tree *parent_tree,
2277                              char *drep)
2278 {
2279         proto_item *item=NULL;
2280         proto_tree *tree=NULL;
2281         int old_offset=offset;
2282         char str[256];
2283         dcerpc_info *di;
2284
2285         di=pinfo->private_data;
2286
2287         snprintf(str, 255, "IDX_AND_NAME: %s:",proto_registrar_get_name(di->hf_index));
2288         if(parent_tree){
2289                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2290                                 "%s",str);
2291                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name);
2292         }
2293
2294         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2295                         hf_samr_index, NULL);
2296         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
2297                         tree, drep, di->hf_index, 4);
2298
2299         proto_item_set_len(item, offset-old_offset);
2300         return offset;
2301 }
2302
2303 static int
2304 samr_dissect_IDX_AND_NAME_entry (tvbuff_t *tvb, int offset, 
2305                              packet_info *pinfo, proto_tree *tree,
2306                              char *drep)
2307 {
2308         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2309                         samr_dissect_IDX_AND_NAME);
2310
2311         return offset;
2312 }
2313
2314
2315 static int
2316 samr_dissect_IDX_AND_NAME_ARRAY(tvbuff_t *tvb, int offset, 
2317                         packet_info *pinfo, proto_tree *parent_tree,
2318                         char *drep)
2319 {
2320         char *field_name;
2321         guint32 count;
2322         proto_item *item=NULL;
2323         proto_tree *tree=NULL;
2324         int old_offset=offset;
2325         dcerpc_info *di;
2326         char str[256];
2327
2328         di=pinfo->private_data;
2329
2330         field_name = proto_registrar_get_name(di->hf_index);
2331
2332         if(parent_tree){
2333                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2334                         "IDX_AND_NAME_ARRAY: %s%s:", field_name,
2335                         plural_ending(field_name));
2336                 tree = proto_item_add_subtree(item, ett_samr_idx_and_name_array);
2337         }
2338
2339         
2340         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2341                         hf_samr_count, &count);
2342         snprintf(str, 255, "IDX_AND_NAME pointer: %s%s:", field_name,
2343             plural_ending(field_name));
2344         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2345                         samr_dissect_IDX_AND_NAME_entry, NDR_POINTER_UNIQUE,
2346                         str, di->hf_index, 0);
2347
2348         proto_item_set_len(item, offset-old_offset);
2349         return offset;
2350 }
2351
2352 static int
2353 samr_dissect_IDX_AND_NAME_ARRAY_ptr(tvbuff_t *tvb, int offset, 
2354                         packet_info *pinfo, proto_tree *tree,
2355                         char *drep)
2356 {
2357         char *field_name;
2358         char str[256];
2359         dcerpc_info *di;
2360
2361         di=pinfo->private_data;
2362
2363         field_name = proto_registrar_get_name(di->hf_index);
2364         snprintf(str, 255, "IDX_AND_NAME_ARRAY pointer: %s%s:", field_name,
2365             plural_ending(field_name));
2366         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2367                         samr_dissect_IDX_AND_NAME_ARRAY, NDR_POINTER_UNIQUE,
2368                         str, di->hf_index, 0);
2369         return offset;
2370 }
2371
2372 static int
2373 samr_dissect_enum_domains_rqst(tvbuff_t *tvb, int offset, 
2374                                packet_info *pinfo, proto_tree *tree,
2375                                char *drep)
2376 {
2377         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2378                                        hf_samr_hnd, NULL, FALSE, FALSE);
2379
2380         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2381                         samr_dissect_pointer_long, NDR_POINTER_REF,
2382                         "", hf_samr_resume_hnd, 0);
2383
2384         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2385                         hf_samr_pref_maxsize, NULL);
2386
2387         return offset;
2388 }
2389
2390 static int
2391 samr_dissect_enum_domains_reply(tvbuff_t *tvb, int offset, 
2392                              packet_info *pinfo, proto_tree *tree,
2393                              char *drep)
2394 {
2395         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2396                         samr_dissect_pointer_long, NDR_POINTER_REF,
2397                         "", hf_samr_resume_hnd, 0);
2398         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2399                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2400                         "", hf_samr_domain, 0);
2401         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2402                         samr_dissect_pointer_long, NDR_POINTER_REF,
2403                         "", hf_samr_entries, 0);
2404
2405         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2406                                   hf_samr_rc, NULL);
2407
2408         return offset;
2409 }
2410
2411 static int
2412 samr_dissect_enum_dom_groups_rqst(tvbuff_t *tvb, int offset, 
2413                                   packet_info *pinfo, proto_tree *tree,
2414                                   char *drep)
2415 {
2416         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2417                                        hf_samr_hnd, NULL, FALSE, FALSE);
2418
2419         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2420                         samr_dissect_pointer_long, NDR_POINTER_REF,
2421                         "", hf_samr_resume_hnd, 0);
2422         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2423                         hf_samr_mask, NULL);
2424         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2425                         hf_samr_pref_maxsize, NULL);
2426
2427         return offset;
2428 }
2429
2430 static int
2431 samr_dissect_enum_dom_groups_reply(tvbuff_t *tvb, int offset, 
2432                              packet_info *pinfo, proto_tree *tree,
2433                              char *drep)
2434 {
2435         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2436                         samr_dissect_pointer_long, NDR_POINTER_REF,
2437                         "", hf_samr_resume_hnd, 0);
2438         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2439                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2440                         "", hf_samr_group_name, 0);
2441         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2442                         samr_dissect_pointer_long, NDR_POINTER_REF,
2443                         "", hf_samr_entries, 0);
2444
2445         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2446                                   hf_samr_rc, NULL);
2447
2448         return offset;
2449 }
2450
2451 static int
2452 samr_dissect_enum_dom_aliases_rqst(tvbuff_t *tvb, int offset, 
2453                                  packet_info *pinfo, proto_tree *tree,
2454                                  char *drep)
2455 {
2456         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2457                                        hf_samr_hnd, NULL, FALSE, FALSE);
2458
2459         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2460                         samr_dissect_pointer_long, NDR_POINTER_REF,
2461                         "", hf_samr_resume_hnd, 0);
2462
2463         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2464                         hf_samr_mask, NULL);
2465
2466         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2467                         hf_samr_pref_maxsize, NULL);
2468
2469         return offset;
2470 }
2471
2472 static int
2473 samr_dissect_enum_dom_aliases_reply(tvbuff_t *tvb, int offset, 
2474                              packet_info *pinfo, proto_tree *tree,
2475                              char *drep)
2476 {
2477         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2478                         samr_dissect_pointer_long, NDR_POINTER_REF,
2479                         "", hf_samr_resume_hnd, 0);
2480
2481         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2482                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2483                         "", hf_samr_alias_name, 0);
2484
2485         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2486                         samr_dissect_pointer_long, NDR_POINTER_REF,
2487                         "", hf_samr_entries, 0);
2488
2489         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2490                                   hf_samr_rc, NULL);
2491
2492         return offset;
2493 }
2494
2495 static int
2496 samr_dissect_get_members_in_alias_rqst(tvbuff_t *tvb, int offset, 
2497                                        packet_info *pinfo, proto_tree *tree, 
2498                                        char *drep)
2499 {
2500         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
2501                                        hf_samr_hnd, NULL, FALSE, FALSE);
2502
2503         return offset;
2504 }
2505
2506 static int
2507 samr_dissect_get_members_in_alias_reply(tvbuff_t *tvb, int offset, 
2508                         packet_info *pinfo, proto_tree *tree,
2509                         char *drep)
2510 {
2511         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2512                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
2513                         "", -1, 0);
2514
2515         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
2516                                   hf_samr_rc, NULL);
2517
2518         return offset;
2519 }
2520
2521 static int
2522 samr_dissect_LOGON_HOURS_entry(tvbuff_t *tvb, int offset, 
2523                              packet_info *pinfo, proto_tree *tree,
2524                              char *drep)
2525 {
2526         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
2527                         hf_samr_unknown_char, NULL);
2528         return offset;
2529 }
2530
2531 static int
2532 samr_dissect_LOGON_HOURS_hours(tvbuff_t *tvb, int offset, 
2533                              packet_info *pinfo, proto_tree *parent_tree,
2534                              char *drep)
2535 {
2536         proto_item *item=NULL;
2537         proto_tree *tree=NULL;
2538         int old_offset=offset;
2539
2540         if(parent_tree){
2541                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2542                         "LOGON_HOURS:");
2543                 tree = proto_item_add_subtree(item, ett_samr_logon_hours_hours);
2544         }
2545
2546         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
2547                         samr_dissect_LOGON_HOURS_entry);
2548
2549         proto_item_set_len(item, offset-old_offset);
2550         return offset;
2551
2552         return offset;
2553 }
2554
2555 int
2556 dissect_ndr_nt_LOGON_HOURS(tvbuff_t *tvb, int offset, 
2557                         packet_info *pinfo, proto_tree *parent_tree,
2558                         char *drep)
2559 {
2560         proto_item *item=NULL;
2561         proto_tree *tree=NULL;
2562         int old_offset=offset;
2563
2564         ALIGN_TO_4_BYTES;  /* strcture starts with short, but is aligned for longs */
2565
2566         if(parent_tree){
2567                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2568                         "LOGON_HOURS:");
2569                 tree = proto_item_add_subtree(item, ett_samr_logon_hours);
2570         }
2571
2572         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2573                                 hf_samr_divisions, NULL);
2574         /* XXX - is this a bitmask like the "logon hours" field in the
2575            Remote API call "NetUserGetInfo()" with an information level
2576            of 11? */
2577         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2578                         samr_dissect_LOGON_HOURS_hours, NDR_POINTER_UNIQUE,
2579                         "LOGON_HOURS", -1, 0);
2580
2581         proto_item_set_len(item, offset-old_offset);
2582         return offset;
2583 }
2584
2585
2586 static int
2587 samr_dissect_USER_INFO_1(tvbuff_t *tvb, int offset, 
2588                         packet_info *pinfo, proto_tree *parent_tree,
2589                         char *drep)
2590 {
2591         proto_item *item=NULL;
2592         proto_tree *tree=NULL;
2593         int old_offset=offset;
2594
2595         if(parent_tree){
2596                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2597                         "USER_INFO_1:");
2598                 tree = proto_item_add_subtree(item, ett_samr_user_info_1);
2599         }
2600
2601         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2602                                 hf_samr_acct_name, 0);
2603         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2604                                 hf_samr_full_name, 0);
2605         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2606         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2607                                 hf_samr_home, 0);
2608         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2609                                 hf_samr_script, 0);
2610
2611         proto_item_set_len(item, offset-old_offset);
2612         return offset;
2613 }
2614
2615 static int
2616 samr_dissect_USER_INFO_2(tvbuff_t *tvb, int offset, 
2617                         packet_info *pinfo, proto_tree *parent_tree,
2618                         char *drep)
2619 {
2620         proto_item *item=NULL;
2621         proto_tree *tree=NULL;
2622         int old_offset=offset;
2623
2624         if(parent_tree){
2625                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2626                         "USER_INFO_2:");
2627                 tree = proto_item_add_subtree(item, ett_samr_user_info_2);
2628         }
2629
2630         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2631                                 hf_samr_acct_name, 0);
2632         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2633                                 hf_samr_full_name, 0);
2634         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2635                                 hf_samr_bad_pwd_count, NULL);
2636         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2637                                 hf_samr_logon_count, NULL);
2638
2639         proto_item_set_len(item, offset-old_offset);
2640         return offset;
2641 }
2642
2643 static int
2644 samr_dissect_USER_INFO_3(tvbuff_t *tvb, int offset, 
2645                         packet_info *pinfo, proto_tree *parent_tree,
2646                         char *drep)
2647 {
2648         proto_item *item=NULL;
2649         proto_tree *tree=NULL;
2650         int old_offset=offset;
2651
2652         if(parent_tree){
2653                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2654                         "USER_INFO_3:");
2655                 tree = proto_item_add_subtree(item, ett_samr_user_info_3);
2656         }
2657
2658         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2659                                 hf_samr_acct_name, 0);
2660         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2661                                 hf_samr_full_name, 0);
2662         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2663                                 hf_samr_rid, NULL);
2664         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2665                                 hf_samr_group, NULL);
2666         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2667                                 hf_samr_home, 0);
2668         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2669                                 hf_samr_home_drive, 0);
2670         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2671                                 hf_samr_script, 0);
2672         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2673                                 hf_samr_acct_desc, 0);
2674         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2675                                 hf_samr_workstations, 0);
2676         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2677                                 hf_samr_logon_time);
2678         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2679                                 hf_samr_logoff_time);
2680         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2681                                 hf_samr_pwd_last_set_time);
2682         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2683                                 hf_samr_pwd_can_change_time);
2684         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2685                                 hf_samr_pwd_must_change_time);
2686         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2687         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2688                                 hf_samr_logon_count, NULL);
2689         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2690                                 hf_samr_bad_pwd_count, NULL);
2691         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2692
2693         proto_item_set_len(item, offset-old_offset);
2694         return offset;
2695 }
2696
2697 static int
2698 samr_dissect_USER_INFO_5(tvbuff_t *tvb, int offset, 
2699                         packet_info *pinfo, proto_tree *parent_tree,
2700                         char *drep)
2701 {
2702         proto_item *item=NULL;
2703         proto_tree *tree=NULL;
2704         int old_offset=offset;
2705
2706         if(parent_tree){
2707                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2708                         "USER_INFO_5:");
2709                 tree = proto_item_add_subtree(item, ett_samr_user_info_5);
2710         }
2711
2712         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2713                                 hf_samr_acct_name, 0);
2714         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2715                                 hf_samr_full_name, 0);
2716         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2717                                 hf_samr_rid, NULL);
2718         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2719                                 hf_samr_group, NULL);
2720         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2721                                 hf_samr_country, NULL);
2722         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2723                                 hf_samr_codepage, NULL);
2724         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2725                                 hf_samr_home, 0);
2726         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2727                                 hf_samr_home_drive, 0);
2728         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2729                                 hf_samr_script, 0);
2730         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2731                                 hf_samr_acct_desc, 0);
2732         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2733                                 hf_samr_workstations, 0);
2734         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2735                                 hf_samr_logon_time);
2736         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2737                                 hf_samr_logoff_time);
2738         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2739         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2740                                 hf_samr_bad_pwd_count, NULL);
2741         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2742                                 hf_samr_logon_count, NULL);
2743         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2744                                 hf_samr_pwd_last_set_time);
2745         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2746                                 hf_samr_acct_expiry_time);
2747         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2748
2749         proto_item_set_len(item, offset-old_offset);
2750         return offset;
2751 }
2752
2753 static int
2754 samr_dissect_USER_INFO_6(tvbuff_t *tvb, int offset, 
2755                         packet_info *pinfo, proto_tree *parent_tree,
2756                         char *drep)
2757 {
2758         proto_item *item=NULL;
2759         proto_tree *tree=NULL;
2760         int old_offset=offset;
2761
2762         if(parent_tree){
2763                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2764                         "USER_INFO_6:");
2765                 tree = proto_item_add_subtree(item, ett_samr_user_info_6);
2766         }
2767
2768         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2769                                 hf_samr_acct_name, 0);
2770         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2771                                 hf_samr_full_name, 0);
2772
2773         proto_item_set_len(item, offset-old_offset);
2774         return offset;
2775 }
2776
2777 static int
2778 samr_dissect_USER_INFO_18(tvbuff_t *tvb, int offset, 
2779                         packet_info *pinfo, proto_tree *parent_tree,
2780                         char *drep)
2781 {
2782         proto_item *item=NULL;
2783         proto_tree *tree=NULL;
2784         int old_offset=offset;
2785
2786         if(parent_tree){
2787                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2788                         "USER_INFO_18:");
2789                 tree = proto_item_add_subtree(item, ett_samr_user_info_18);
2790         }
2791
2792         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2793         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2794         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2795                         hf_samr_unknown_char, NULL);
2796         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2797                         hf_samr_unknown_char, NULL);
2798         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2799                         hf_samr_unknown_char, NULL);
2800
2801         proto_item_set_len(item, offset-old_offset);
2802         return offset;
2803 }
2804
2805 static int
2806 samr_dissect_USER_INFO_19(tvbuff_t *tvb, int offset, 
2807                         packet_info *pinfo, proto_tree *parent_tree,
2808                         char *drep)
2809 {
2810         proto_item *item=NULL;
2811         proto_tree *tree=NULL;
2812         int old_offset=offset;
2813
2814         if(parent_tree){
2815                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2816                         "USER_INFO_19:");
2817                 tree = proto_item_add_subtree(item, ett_samr_user_info_19);
2818         }
2819
2820         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2821         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2822                                 hf_samr_logon_time);
2823         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2824                                 hf_samr_logoff_time);
2825         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2826                                 hf_samr_bad_pwd_count, NULL);
2827         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2828                                 hf_samr_logon_count, NULL);
2829
2830         proto_item_set_len(item, offset-old_offset);
2831         return offset;
2832 }
2833
2834 static int
2835 samr_dissect_BUFFER_entry(tvbuff_t *tvb, int offset, 
2836                              packet_info *pinfo, proto_tree *tree,
2837                              char *drep)
2838 {
2839         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2840                         hf_samr_unknown_char, NULL);
2841         return offset;
2842 }
2843
2844
2845 static int
2846 samr_dissect_BUFFER_buffer(tvbuff_t *tvb, int offset, 
2847                              packet_info *pinfo, proto_tree *parent_tree,
2848                              char *drep)
2849 {
2850         proto_item *item=NULL;
2851         proto_tree *tree=NULL;
2852         int old_offset=offset;
2853
2854         if(parent_tree){
2855                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2856                         "BUFFER:");
2857                 tree = proto_item_add_subtree(item, ett_samr_buffer_buffer);
2858         }
2859
2860         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2861                         samr_dissect_BUFFER_entry);
2862
2863         proto_item_set_len(item, offset-old_offset);
2864         return offset;
2865
2866         return offset;
2867 }
2868
2869 static int
2870 samr_dissect_BUFFER(tvbuff_t *tvb, int offset, 
2871                         packet_info *pinfo, proto_tree *parent_tree,
2872                         char *drep)
2873 {
2874         proto_item *item=NULL;
2875         proto_tree *tree=NULL;
2876         int old_offset=offset;
2877
2878         if(parent_tree){
2879                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2880                         "BUFFER:");
2881                 tree = proto_item_add_subtree(item, ett_samr_buffer);
2882         }
2883         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2884                                 hf_samr_count, NULL);
2885         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2886                         samr_dissect_BUFFER_buffer, NDR_POINTER_UNIQUE,
2887                         "BUFFER", -1, 0);
2888
2889         proto_item_set_len(item, offset-old_offset);
2890         return offset;
2891 }
2892
2893 static int
2894 samr_dissect_USER_INFO_21(tvbuff_t *tvb, int offset, 
2895                         packet_info *pinfo, proto_tree *parent_tree,
2896                         char *drep)
2897 {
2898         proto_item *item=NULL;
2899         proto_tree *tree=NULL;
2900         int old_offset=offset;
2901
2902         if(parent_tree){
2903                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2904                         "USER_INFO_21:");
2905                 tree = proto_item_add_subtree(item, ett_samr_user_info_21);
2906         }
2907
2908         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2909                                 hf_samr_logon_time);
2910         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2911                                 hf_samr_logoff_time);
2912         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2913                                 hf_samr_kickoff_time);
2914         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2915                                 hf_samr_pwd_last_set_time);
2916         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2917                                 hf_samr_pwd_can_change_time);
2918         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2919                                 hf_samr_pwd_must_change_time);
2920         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2921                                 hf_samr_acct_name, 2);
2922         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2923                                 hf_samr_full_name, 0);
2924         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2925                                 hf_samr_home, 0);
2926         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2927                                 hf_samr_home_drive, 0);
2928         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2929                                 hf_samr_script, 0);
2930         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2931                                 hf_samr_profile, 0);
2932         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2933                                 hf_samr_acct_desc, 0);
2934         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2935                                 hf_samr_workstations, 0);
2936         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2937                                 hf_samr_comment, 0);
2938         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2939                                 hf_samr_parameters, 0);
2940         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2941                                 hf_samr_unknown_string, 0);
2942         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2943                                 hf_samr_unknown_string, 0);
2944         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2945                                 hf_samr_unknown_string, 0);
2946         offset = samr_dissect_BUFFER(tvb, offset, pinfo, tree, drep);
2947         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2948                                 hf_samr_rid, NULL);
2949         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2950                                 hf_samr_group, NULL);
2951         offset = dissect_ndr_nt_acct_ctrl(tvb, offset, pinfo, tree, drep);
2952         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2953                                 hf_samr_unknown_long, NULL);
2954         offset = dissect_ndr_nt_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2955         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2956                                 hf_samr_bad_pwd_count, NULL);
2957         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2958                                 hf_samr_logon_count, NULL);
2959         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2960                                 hf_samr_country, NULL);
2961         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2962                                 hf_samr_codepage, NULL);
2963         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2964                                 hf_samr_nt_pwd_set, NULL);
2965         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2966                                 hf_samr_lm_pwd_set, NULL);
2967         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2968                                 hf_samr_pwd_expired, NULL);
2969         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2970                                 hf_samr_unknown_char, NULL);
2971
2972         proto_item_set_len(item, offset-old_offset);
2973         return offset;
2974 }
2975
2976 static int
2977 samr_dissect_USER_INFO_22(tvbuff_t *tvb, int offset, 
2978                         packet_info *pinfo, proto_tree *parent_tree,
2979                         char *drep)
2980 {
2981         proto_item *item=NULL;
2982         proto_tree *tree=NULL;
2983         int old_offset=offset;
2984
2985         if(parent_tree){
2986                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
2987                         "USER_INFO_22:");
2988                 tree = proto_item_add_subtree(item, ett_samr_user_info_22);
2989         }
2990
2991         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
2992         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
2993                         hf_samr_revision, NULL);
2994
2995         proto_item_set_len(item, offset-old_offset);
2996         return offset;
2997 }
2998
2999 static int
3000 samr_dissect_USER_INFO_23(tvbuff_t *tvb, int offset, 
3001                         packet_info *pinfo, proto_tree *parent_tree,
3002                         char *drep)
3003 {
3004         proto_item *item=NULL;
3005         proto_tree *tree=NULL;
3006         int old_offset=offset;
3007
3008         if(parent_tree){
3009                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3010                         "USER_INFO_23:");
3011                 tree = proto_item_add_subtree(item, ett_samr_user_info_23);
3012         }
3013
3014         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
3015         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
3016
3017         proto_item_set_len(item, offset-old_offset);
3018         return offset;
3019 }
3020
3021 static int
3022 samr_dissect_USER_INFO_24(tvbuff_t *tvb, int offset, 
3023                         packet_info *pinfo, proto_tree *parent_tree,
3024                         char *drep)
3025 {
3026         proto_item *item=NULL;
3027         proto_tree *tree=NULL;
3028         int old_offset=offset;
3029
3030         if(parent_tree){
3031                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3032                         "USER_INFO_24:");
3033                 tree = proto_item_add_subtree(item, ett_samr_user_info_24);
3034         }
3035
3036         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
3037         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
3038                                 hf_samr_unknown_char, NULL);
3039
3040         proto_item_set_len(item, offset-old_offset);
3041         return offset;
3042 }
3043
3044 static int
3045 samr_dissect_USER_INFO (tvbuff_t *tvb, int offset, 
3046                              packet_info *pinfo, proto_tree *parent_tree,
3047                              char *drep)
3048 {
3049         proto_item *item=NULL;
3050         proto_tree *tree=NULL;
3051         int old_offset=offset;
3052         guint16 level;
3053
3054         if(parent_tree){
3055                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3056                         "USER_INFO:");
3057                 tree = proto_item_add_subtree(item, ett_samr_user_info);
3058         }
3059         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3060                                      hf_samr_level, &level);
3061
3062         switch(level){
3063         case 1: 
3064                 offset = samr_dissect_USER_INFO_1(
3065                                 tvb, offset, pinfo, tree, drep);
3066                 break;
3067         case 2: 
3068                 offset = samr_dissect_USER_INFO_2(
3069                                 tvb, offset, pinfo, tree, drep);
3070                 break;
3071         case 3: 
3072                 offset = samr_dissect_USER_INFO_3(
3073                                 tvb, offset, pinfo, tree, drep);
3074                 break;
3075         case 4: 
3076                 offset = dissect_ndr_nt_LOGON_HOURS(
3077                                 tvb, offset, pinfo, tree, drep);
3078                 break;
3079         case 5: 
3080                 offset = samr_dissect_USER_INFO_5(
3081                                 tvb, offset, pinfo, tree, drep);
3082                 break;
3083         case 6: 
3084                 offset = samr_dissect_USER_INFO_6(
3085                                 tvb, offset, pinfo, tree, drep);
3086                 break;
3087         case 7:
3088                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3089                                 hf_samr_full_name, 0);
3090                 break;
3091         case 8:
3092                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3093                                 hf_samr_acct_desc, 0);
3094                 break;
3095         case 9:
3096                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3097                                              hf_samr_unknown_long, NULL);
3098                 break;
3099         case 10:        
3100                 offset = samr_dissect_USER_INFO_6(
3101                                 tvb, offset, pinfo, tree, drep);
3102                 break;
3103         case 11:
3104                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3105                                 hf_samr_home, 0);
3106                 break;
3107         case 12:
3108                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3109                                 hf_samr_home_drive, 0);
3110                 break;
3111         case 13:
3112                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3113                                 hf_samr_script, 0);
3114                 break;
3115         case 14:
3116                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3117                                 hf_samr_workstations, 0);
3118                 break;
3119         case 16:
3120                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3121                                              hf_samr_unknown_long, NULL);
3122                 break;
3123         case 17:
3124                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
3125                                         hf_samr_unknown_time);
3126                 break;
3127         case 18:        
3128                 offset = samr_dissect_USER_INFO_18(
3129                                 tvb, offset, pinfo, tree, drep);
3130                 break;
3131         case 19:        
3132                 offset = samr_dissect_USER_INFO_19(
3133                                 tvb, offset, pinfo, tree, drep);
3134                 break;
3135         case 20:
3136                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3137                                 hf_samr_profile, 0);
3138                 break;
3139         case 21:        
3140                 offset = samr_dissect_USER_INFO_21(
3141                                 tvb, offset, pinfo, tree, drep);
3142                 break;
3143         case 22:        
3144                 offset = samr_dissect_USER_INFO_22(
3145                                 tvb, offset, pinfo, tree, drep);
3146                 break;
3147         case 23:        
3148                 offset = samr_dissect_USER_INFO_23(
3149                                 tvb, offset, pinfo, tree, drep);
3150                 break;
3151         case 24:        
3152                 offset = samr_dissect_USER_INFO_24(
3153                                 tvb, offset, pinfo, tree, drep);
3154                 break;
3155         }
3156
3157         proto_item_set_len(item, offset-old_offset);
3158         return offset;
3159 }
3160
3161 static int
3162 samr_dissect_USER_INFO_ptr(tvbuff_t *tvb, int offset, 
3163                         packet_info *pinfo, proto_tree *tree,
3164                         char *drep)
3165 {
3166         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3167                         samr_dissect_USER_INFO, NDR_POINTER_UNIQUE,
3168                         "USER_INFO pointer", -1, 0);
3169         return offset;
3170 }
3171
3172 static int
3173 samr_dissect_set_information_user2_rqst(tvbuff_t *tvb, int offset, 
3174                                         packet_info *pinfo, proto_tree *tree,
3175                                         char *drep)
3176 {
3177         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3178                                        hf_samr_hnd, NULL, FALSE, FALSE);
3179
3180         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3181                         hf_samr_level, NULL);
3182
3183         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3184                         samr_dissect_USER_INFO, NDR_POINTER_REF,
3185                         "", -1, 0);
3186
3187         return offset;
3188 }
3189
3190 static int
3191 samr_dissect_set_information_user2_reply(tvbuff_t *tvb, int offset, 
3192                                          packet_info *pinfo, proto_tree *tree, 
3193                                          char *drep)
3194 {
3195         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3196                                   hf_samr_rc, NULL);
3197
3198         return offset;
3199 }
3200
3201 static int
3202 samr_dissect_unknown_2f_rqst(tvbuff_t *tvb, int offset, 
3203                                  packet_info *pinfo, proto_tree *tree, 
3204                                  char *drep)
3205 {
3206         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3207                                        hf_samr_hnd, NULL, FALSE, FALSE);
3208
3209         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
3210                         hf_samr_level, NULL);
3211
3212         return offset;
3213 }
3214
3215 static int
3216 samr_dissect_unknown_2f_reply(tvbuff_t *tvb, int offset, 
3217                         packet_info *pinfo, proto_tree *tree,
3218                         char *drep)
3219 {
3220         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3221                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
3222                         "", -1, 0);
3223
3224         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3225                         hf_samr_rc, NULL);
3226
3227         return offset;
3228 }
3229
3230 static int
3231 samr_dissect_MEMBER_ARRAY_type(tvbuff_t *tvb, int offset, 
3232                         packet_info *pinfo, proto_tree *tree,
3233                         char *drep)
3234 {
3235         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3236                                 hf_samr_type, NULL);
3237
3238         return offset;
3239 }
3240
3241
3242 static int
3243 samr_dissect_MEMBER_ARRAY_types(tvbuff_t *tvb, int offset, 
3244                         packet_info *pinfo, proto_tree *parent_tree,
3245                         char *drep)
3246 {
3247         proto_item *item=NULL;
3248         proto_tree *tree=NULL;
3249         int old_offset=offset;
3250
3251         if(parent_tree){
3252                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3253                         "MEMBER_ARRAY_types:");
3254                 tree = proto_item_add_subtree(item, ett_samr_member_array_types);
3255         }
3256
3257         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3258                         samr_dissect_MEMBER_ARRAY_type);
3259
3260         proto_item_set_len(item, offset-old_offset);
3261         return offset;
3262
3263         return offset;
3264 }
3265
3266 static int
3267 samr_dissect_MEMBER_ARRAY_rid(tvbuff_t *tvb, int offset, 
3268                         packet_info *pinfo, proto_tree *tree,
3269                         char *drep)
3270 {
3271         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3272                                 hf_samr_rid, NULL);
3273
3274         return offset;
3275 }
3276
3277
3278 static int
3279 samr_dissect_MEMBER_ARRAY_rids(tvbuff_t *tvb, int offset, 
3280                         packet_info *pinfo, proto_tree *parent_tree,
3281                         char *drep)
3282 {
3283         proto_item *item=NULL;
3284         proto_tree *tree=NULL;
3285         int old_offset=offset;
3286
3287         if(parent_tree){
3288                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3289                         "MEMBER_ARRAY_rids:");
3290                 tree = proto_item_add_subtree(item, ett_samr_member_array_rids);
3291         }
3292
3293         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3294                         samr_dissect_MEMBER_ARRAY_rid);
3295
3296         proto_item_set_len(item, offset-old_offset);
3297         return offset;
3298
3299         return offset;
3300 }
3301
3302 static int
3303 samr_dissect_MEMBER_ARRAY(tvbuff_t *tvb, int offset, 
3304                         packet_info *pinfo, proto_tree *parent_tree,
3305                         char *drep)
3306 {
3307         guint32 count;
3308         proto_item *item=NULL;
3309         proto_tree *tree=NULL;
3310         int old_offset=offset;
3311
3312         if(parent_tree){
3313                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3314                         "MEMBER_ARRAY:");
3315                 tree = proto_item_add_subtree(item, ett_samr_member_array);
3316         }
3317
3318         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3319                         hf_samr_count, &count);
3320         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3321                         samr_dissect_MEMBER_ARRAY_rids, NDR_POINTER_UNIQUE,
3322                         "RIDs", -1, 0);
3323         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3324                         samr_dissect_MEMBER_ARRAY_types, NDR_POINTER_UNIQUE,
3325                         "Types", -1, 0);
3326
3327         proto_item_set_len(item, offset-old_offset);
3328         return offset;
3329 }
3330
3331 static int
3332 samr_dissect_MEMBER_ARRAY_ptr(tvbuff_t *tvb, int offset, 
3333                         packet_info *pinfo, proto_tree *tree,
3334                         char *drep)
3335 {
3336         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3337                         samr_dissect_MEMBER_ARRAY, NDR_POINTER_UNIQUE,
3338                         "MEMBER_ARRAY", -1, 0);
3339         return offset;
3340 }
3341
3342 static int
3343 samr_dissect_query_groupmem_rqst(tvbuff_t *tvb, int offset, 
3344                                  packet_info *pinfo, proto_tree *tree, 
3345                                  char *drep)
3346 {
3347         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3348                                       hf_samr_hnd, NULL);
3349         return offset;
3350 }
3351
3352 static int
3353 samr_dissect_query_groupmem_reply(tvbuff_t *tvb, int offset, 
3354                         packet_info *pinfo, proto_tree *tree,
3355                         char *drep)
3356 {
3357         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3358                         samr_dissect_MEMBER_ARRAY_ptr, NDR_POINTER_REF,
3359                         "", -1, 0);
3360
3361         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3362                                   hf_samr_rc, NULL);
3363
3364         return offset;
3365 }
3366
3367 static int
3368 samr_dissect_set_sec_object_rqst(tvbuff_t *tvb, int offset, 
3369                                  packet_info *pinfo, proto_tree *tree,
3370                                  char *drep)
3371 {
3372         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3373                                        hf_samr_hnd, NULL, FALSE, FALSE);
3374
3375         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3376                         hf_samr_info_type, NULL);
3377
3378         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3379                 lsa_dissect_LSA_SECURITY_DESCRIPTOR, NDR_POINTER_REF,
3380                 "LSA_SECURITY_DESCRIPTOR pointer: ", -1, 0);
3381
3382         return offset;
3383 }
3384
3385 static int
3386 samr_dissect_set_sec_object_reply(tvbuff_t *tvb, int offset, 
3387                                   packet_info *pinfo, proto_tree *tree, 
3388                                   char *drep)
3389 {
3390         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3391                                   hf_samr_rc, NULL);
3392
3393         return offset;
3394 }
3395
3396 static int
3397 samr_dissect_query_sec_object_rqst(tvbuff_t *tvb, int offset, 
3398                                    packet_info *pinfo, proto_tree *tree,
3399                                    char *drep)
3400 {
3401         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3402                                        hf_samr_hnd, NULL, FALSE, FALSE);
3403
3404         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3405                         hf_samr_info_type, NULL);
3406
3407         return offset;
3408 }
3409
3410 static int
3411 samr_dissect_query_sec_object_reply(tvbuff_t *tvb, int offset, 
3412                         packet_info *pinfo, proto_tree *tree,
3413                         char *drep)
3414 {
3415         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3416                 lsa_dissect_LSA_SECURITY_DESCRIPTOR, NDR_POINTER_UNIQUE,
3417                 "LSA_SECURITY_DESCRIPTOR pointer: ", -1, 0);
3418
3419         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3420                                   hf_samr_rc, NULL);
3421
3422         return offset;
3423 }
3424
3425 static int
3426 samr_dissect_LOOKUP_NAMES_name(tvbuff_t *tvb, int offset, 
3427                         packet_info *pinfo, proto_tree *tree,
3428                         char *drep)
3429 {
3430         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3431                                 hf_samr_acct_name, 1);
3432         return offset;
3433 }
3434
3435 static int
3436 samr_dissect_LOOKUP_NAMES(tvbuff_t *tvb, int offset, 
3437                         packet_info *pinfo, proto_tree *parent_tree,
3438                         char *drep)
3439 {
3440         proto_item *item=NULL;
3441         proto_tree *tree=NULL;
3442         int old_offset=offset;
3443
3444         if(parent_tree){
3445                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3446                         "NAMES:");
3447                 tree = proto_item_add_subtree(item, ett_samr_names);
3448         }
3449
3450         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3451                         samr_dissect_LOOKUP_NAMES_name);
3452
3453         proto_item_set_len(item, offset-old_offset);
3454         return offset;
3455 }
3456
3457
3458 static int
3459 samr_dissect_lookup_names_rqst(tvbuff_t *tvb, int offset, 
3460                                packet_info *pinfo, proto_tree *tree,
3461                                char *drep)
3462 {
3463         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3464                                        hf_samr_hnd, NULL, FALSE, FALSE);
3465
3466         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3467                         hf_samr_count, NULL);
3468
3469         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3470                         samr_dissect_LOOKUP_NAMES, NDR_POINTER_REF,
3471                         "", -1, 0);
3472
3473         return offset;
3474 }
3475
3476 static int
3477 samr_dissect_lookup_names_reply(tvbuff_t *tvb, int offset, 
3478                         packet_info *pinfo, proto_tree *tree,
3479                         char *drep)
3480 {
3481         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3482                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3483                         "", hf_samr_rid, 0);
3484         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3485                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3486                         "", hf_samr_type, 0);
3487
3488         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3489                                   hf_samr_rc, NULL);
3490
3491         return offset;
3492 }
3493
3494 static int
3495 samr_dissect_LOOKUP_RIDS_rid(tvbuff_t *tvb, int offset, 
3496                         packet_info *pinfo, proto_tree *tree,
3497                         char *drep)
3498 {
3499         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3500                                 hf_samr_rid, NULL);
3501
3502         return offset;
3503 }
3504
3505 static int
3506 samr_dissect_LOOKUP_RIDS(tvbuff_t *tvb, int offset, 
3507                         packet_info *pinfo, proto_tree *parent_tree,
3508                         char *drep)
3509 {
3510         proto_item *item=NULL;
3511         proto_tree *tree=NULL;
3512         int old_offset=offset;
3513
3514         if(parent_tree){
3515                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3516                         "RIDS:");
3517                 tree = proto_item_add_subtree(item, ett_samr_rids);
3518         }
3519
3520         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3521                         samr_dissect_LOOKUP_RIDS_rid);
3522
3523         proto_item_set_len(item, offset-old_offset);
3524         return offset;
3525 }
3526
3527
3528 static int
3529 samr_dissect_lookup_rids_rqst(tvbuff_t *tvb, int offset, 
3530                               packet_info *pinfo, proto_tree *tree,
3531                               char *drep)
3532 {
3533         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3534                                        hf_samr_hnd, NULL, FALSE, FALSE);
3535
3536         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3537                         hf_samr_count, NULL);
3538
3539         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3540                         samr_dissect_LOOKUP_RIDS, NDR_POINTER_REF,
3541                         "", -1, 0);
3542
3543         return offset;
3544 }
3545
3546 static int
3547 samr_dissect_UNICODE_STRING_ARRAY_name(tvbuff_t *tvb, int offset, 
3548                         packet_info *pinfo, proto_tree *tree,
3549                         char *drep)
3550 {
3551         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3552                                 hf_samr_acct_name, 0);
3553         return offset;
3554 }
3555
3556 static int
3557 samr_dissect_UNICODE_STRING_ARRAY_names(tvbuff_t *tvb, int offset, 
3558                         packet_info *pinfo, proto_tree *tree,
3559                         char *drep)
3560 {
3561         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3562                         samr_dissect_UNICODE_STRING_ARRAY_name);
3563         return offset;
3564 }
3565
3566 static int
3567 samr_dissect_UNICODE_STRING_ARRAY(tvbuff_t *tvb, int offset, 
3568                         packet_info *pinfo, proto_tree *parent_tree,
3569                         char *drep)
3570 {
3571         proto_item *item=NULL;
3572         proto_tree *tree=NULL;
3573         int old_offset=offset;
3574
3575         if(parent_tree){
3576                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
3577                         "NAMES:");
3578                 tree = proto_item_add_subtree(item, ett_samr_names);
3579         }
3580
3581         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3582                         hf_samr_count, NULL);
3583
3584         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3585                         samr_dissect_UNICODE_STRING_ARRAY_names, NDR_POINTER_UNIQUE,
3586                         "Strings", -1, 0);
3587
3588         proto_item_set_len(item, offset-old_offset);
3589         return offset;
3590
3591         return offset;
3592 }
3593
3594
3595 static int
3596 samr_dissect_lookup_rids_reply(tvbuff_t *tvb, int offset, 
3597                         packet_info *pinfo, proto_tree *tree,
3598                         char *drep)
3599 {
3600         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3601                         samr_dissect_UNICODE_STRING_ARRAY, NDR_POINTER_REF,
3602                         "", hf_samr_rid, 0);
3603         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3604                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3605                         "", hf_samr_type, 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_close_hnd_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, 
3615                             proto_tree *tree, char *drep)
3616 {
3617         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3618                                        hf_samr_hnd, NULL, FALSE, TRUE);
3619
3620         return offset;
3621 }
3622
3623 static int
3624 samr_dissect_close_hnd_reply(tvbuff_t *tvb, int offset, packet_info *pinfo, 
3625                              proto_tree *tree, char *drep)
3626 {
3627         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3628                                        hf_samr_hnd, NULL, FALSE, FALSE);
3629
3630         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3631                         hf_samr_rc, NULL);
3632
3633         return offset;
3634 }
3635
3636 static int
3637 samr_dissect_shutdown_sam_server_rqst(tvbuff_t *tvb, int offset, 
3638                                       packet_info *pinfo, proto_tree *tree, 
3639                                       char *drep)
3640 {
3641         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3642                                       hf_samr_hnd, NULL);
3643
3644         return offset;
3645 }
3646
3647 static int
3648 samr_dissect_shutdown_sam_server_reply(tvbuff_t *tvb, int offset, 
3649                                       packet_info *pinfo, proto_tree *tree, 
3650                                       char *drep)
3651 {
3652         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3653                                   hf_samr_rc, NULL);
3654
3655         return offset;
3656 }
3657
3658 static int
3659 samr_dissect_delete_dom_group_rqst(tvbuff_t *tvb, int offset, 
3660                                    packet_info *pinfo, proto_tree *tree, 
3661                                    char *drep)
3662 {
3663         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3664                                       hf_samr_hnd, NULL);
3665
3666         return offset;
3667 }
3668
3669 static int
3670 samr_dissect_delete_dom_group_reply(tvbuff_t *tvb, int offset, 
3671                                     packet_info *pinfo, proto_tree *tree, 
3672                                     char *drep)
3673 {
3674         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3675                                   hf_samr_rc, NULL);
3676
3677         return offset;
3678 }
3679
3680 static int
3681 samr_dissect_remove_member_from_group_rqst(tvbuff_t *tvb, int offset, 
3682                                            packet_info *pinfo, 
3683                                            proto_tree *tree, char *drep)
3684 {
3685         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3686                                        hf_samr_hnd, NULL, FALSE, FALSE);
3687
3688         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3689                                      hf_samr_group, NULL);
3690
3691         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3692                                      hf_samr_rid, NULL);
3693
3694         return offset;
3695 }
3696
3697 static int
3698 samr_dissect_remove_member_from_group_reply(tvbuff_t *tvb, int offset, 
3699                                             packet_info *pinfo, 
3700                                             proto_tree *tree, char *drep)
3701 {
3702         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3703                                   hf_samr_rc, NULL);
3704
3705         return offset;
3706 }
3707
3708 static int
3709 samr_dissect_delete_dom_alias_rqst(tvbuff_t *tvb, int offset, 
3710                                    packet_info *pinfo, proto_tree *tree, 
3711                                    char *drep)
3712 {
3713         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3714                                       hf_samr_hnd, NULL);
3715
3716         return offset;
3717 }
3718
3719 static int
3720 samr_dissect_delete_dom_alias_reply(tvbuff_t *tvb, int offset, 
3721                                     packet_info *pinfo, proto_tree *tree, 
3722                                     char *drep)
3723 {
3724         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3725                                   hf_samr_rc, NULL);
3726
3727         return offset;
3728 }
3729
3730 static int
3731 samr_dissect_add_alias_member_rqst(tvbuff_t *tvb, int offset, 
3732                                    packet_info *pinfo, proto_tree *tree, 
3733                                    char *drep)
3734 {
3735         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3736                                        hf_samr_hnd, NULL, FALSE, FALSE);
3737
3738         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3739                         dissect_ndr_nt_SID, NDR_POINTER_REF,
3740                         "SID", -1, 0);
3741         return offset;
3742 }
3743
3744 static int
3745 samr_dissect_add_alias_member_reply(tvbuff_t *tvb, int offset, 
3746                                     packet_info *pinfo, proto_tree *tree, 
3747                                     char *drep)
3748 {
3749         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3750                                   hf_samr_rc, NULL);
3751
3752         return offset;
3753 }
3754
3755 static int
3756 samr_dissect_remove_alias_member_rqst(tvbuff_t *tvb, int offset, 
3757                                       packet_info *pinfo, proto_tree *tree, 
3758                                       char *drep)
3759 {
3760         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3761                                        hf_samr_hnd, NULL, FALSE, FALSE);
3762
3763         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3764                         dissect_ndr_nt_SID, NDR_POINTER_REF,
3765                         "SID", -1, 0);
3766         return offset;
3767 }
3768
3769 static int
3770 samr_dissect_remove_alias_member_reply(tvbuff_t *tvb, int offset, 
3771                                        packet_info *pinfo, proto_tree *tree, 
3772                                        char *drep)
3773 {
3774         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3775                                   hf_samr_rc, NULL);
3776
3777         return offset;
3778 }
3779
3780 static int
3781 samr_dissect_delete_dom_user_rqst(tvbuff_t *tvb, int offset, 
3782                                   packet_info *pinfo, proto_tree *tree, 
3783                                   char *drep)
3784 {
3785         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3786                                        hf_samr_hnd, NULL, FALSE, FALSE);
3787
3788         return offset;
3789 }
3790
3791 static int
3792 samr_dissect_delete_dom_user_reply(tvbuff_t *tvb, int offset, 
3793                                    packet_info *pinfo, proto_tree *tree, 
3794                                    char *drep)
3795 {
3796         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3797                                   hf_samr_rc, NULL);
3798
3799         return offset;
3800 }
3801
3802 static int
3803 samr_dissect_test_private_fns_domain_rqst(tvbuff_t *tvb, int offset, 
3804                                           packet_info *pinfo, proto_tree *tree,
3805                                           char *drep)
3806 {
3807         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3808                                        hf_samr_hnd, NULL, FALSE, FALSE);
3809
3810         return offset;
3811 }
3812
3813 static int
3814 samr_dissect_test_private_fns_domain_reply(tvbuff_t *tvb, int offset, 
3815                                            packet_info *pinfo, 
3816                                            proto_tree *tree, char *drep)
3817 {
3818         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3819                                   hf_samr_rc, NULL);
3820
3821         return offset;
3822 }
3823
3824 static int
3825 samr_dissect_test_private_fns_user_rqst(tvbuff_t *tvb, int offset, 
3826                                         packet_info *pinfo, proto_tree *tree, 
3827                                         char *drep)
3828 {
3829         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3830                                        hf_samr_hnd, NULL, FALSE, FALSE);
3831
3832         return offset;
3833 }
3834
3835 static int
3836 samr_dissect_test_private_fns_user_reply(tvbuff_t *tvb, int offset, 
3837                                          packet_info *pinfo, 
3838                                          proto_tree *tree, char *drep)
3839 {
3840         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3841                                   hf_samr_rc, NULL);
3842
3843         return offset;
3844 }
3845
3846 static int
3847 samr_dissect_remove_member_from_foreign_domain_rqst(tvbuff_t *tvb, int offset, 
3848                                                     packet_info *pinfo, 
3849                                                     proto_tree *tree, 
3850                                                     char *drep)
3851 {
3852         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3853                                        hf_samr_hnd, NULL, FALSE, FALSE);
3854
3855         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3856                         dissect_ndr_nt_SID, NDR_POINTER_REF,
3857                         "SID", -1, 0);
3858         return offset;
3859 }
3860
3861 static int
3862 samr_dissect_remove_member_from_foreign_domain_reply(tvbuff_t *tvb, int offset,
3863                                                      packet_info *pinfo, 
3864                                                      proto_tree *tree, 
3865                                                      char *drep)
3866 {
3867         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3868                                   hf_samr_rc, NULL);
3869
3870         return offset;
3871 }
3872
3873 static int
3874 samr_dissect_remove_multiple_members_from_alias_rqst(tvbuff_t *tvb, 
3875                                                      int offset, 
3876                                                      packet_info *pinfo, 
3877                                                      proto_tree *tree, 
3878                                                      char *drep)
3879 {
3880         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3881                                        hf_samr_hnd, NULL, FALSE, FALSE);
3882
3883         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3884                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
3885                         "", -1, 0);
3886
3887         return offset;
3888 }
3889
3890 static int
3891 samr_dissect_remove_multiple_members_from_alias_reply(tvbuff_t *tvb, 
3892                                                       int offset, 
3893                                                       packet_info *pinfo, 
3894                                                       proto_tree *tree, 
3895                                                       char *drep)
3896 {
3897         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3898                                   hf_samr_rc, NULL);
3899
3900         return offset;
3901 }
3902
3903 static int
3904 samr_dissect_open_group_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, 
3905                             proto_tree *tree, char *drep)
3906 {
3907         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
3908         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3909         guint32 rid;
3910
3911         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3912                                        hf_samr_hnd, NULL, FALSE, FALSE);
3913
3914         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3915                         hf_samr_access, NULL);
3916
3917         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3918                         hf_samr_rid, &rid);
3919
3920         if (check_col(pinfo->cinfo, COL_INFO))
3921                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
3922
3923         dcv->private_data = (void *)rid;
3924
3925         return offset;
3926 }
3927
3928 static int
3929 samr_dissect_open_group_reply(tvbuff_t *tvb, int offset, 
3930                               packet_info *pinfo, proto_tree *tree, 
3931                               char *drep)
3932 {
3933         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3934                                        hf_samr_hnd, NULL, FALSE, FALSE);
3935
3936         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3937                         hf_samr_rc, NULL);
3938
3939         return offset;
3940 }
3941
3942 static int
3943 samr_dissect_open_alias_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, 
3944                              proto_tree *tree, char *drep)
3945 {
3946         dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
3947         dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3948         guint32 rid;
3949
3950         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3951                                        hf_samr_hnd, NULL, FALSE, FALSE);
3952
3953         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3954                         hf_samr_access, NULL);
3955
3956         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3957                         hf_samr_rid, &rid);
3958
3959         if (check_col(pinfo->cinfo, COL_INFO))
3960                 col_append_fstr(pinfo->cinfo, COL_INFO, ", rid 0x%x", rid);
3961
3962         dcv->private_data = (void *)rid;
3963
3964         return offset;
3965 }
3966
3967 static int
3968 samr_dissect_open_alias_reply(tvbuff_t *tvb, int offset, 
3969                               packet_info *pinfo, proto_tree *tree, 
3970                               char *drep)
3971 {
3972         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3973                                        hf_samr_hnd, NULL, FALSE, FALSE);
3974
3975         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
3976                         hf_samr_rc, NULL);
3977
3978         return offset;
3979 }
3980
3981 static int
3982 samr_dissect_add_multiple_members_to_alias_rqst(tvbuff_t *tvb, int offset, 
3983                                                 packet_info *pinfo, 
3984                                                 proto_tree *tree, char *drep)
3985 {
3986         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
3987                                        hf_samr_hnd, NULL, FALSE, FALSE);
3988
3989         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3990                         dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
3991                         "", -1, 0);
3992
3993         return offset;
3994 }
3995
3996 static int
3997 samr_dissect_add_multiple_members_to_alias_reply(tvbuff_t *tvb, int offset, 
3998                                                  packet_info *pinfo, 
3999                                                  proto_tree *tree, char *drep)
4000 {
4001         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4002                                   hf_samr_rc, NULL);
4003
4004         return offset;
4005 }
4006
4007 static int
4008 samr_dissect_create_group_in_domain_rqst(tvbuff_t *tvb, int offset, 
4009                                          packet_info *pinfo, proto_tree *tree, 
4010                                          char *drep)
4011 {
4012         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4013                                        hf_samr_hnd, NULL, FALSE, FALSE);
4014
4015         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4016                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
4017                         "Account Name", hf_samr_acct_name, 0);
4018
4019         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4020                                      hf_samr_access, NULL);
4021
4022         return offset;
4023 }
4024
4025 static int
4026 samr_dissect_create_group_in_domain_reply(tvbuff_t *tvb, int offset, 
4027                                           packet_info *pinfo, proto_tree *tree,
4028                                           char *drep)
4029 {
4030         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4031                                        hf_samr_hnd, NULL, FALSE, FALSE);
4032
4033         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4034                                      hf_samr_rid, NULL);
4035
4036         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4037                                   hf_samr_rc, NULL);
4038
4039         return offset;
4040 }
4041
4042 static int
4043 samr_dissect_query_information_domain_rqst(tvbuff_t *tvb, int offset, 
4044                                            packet_info *pinfo, 
4045                                            proto_tree *tree, char *drep)
4046 {
4047         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4048                                        hf_samr_hnd, NULL, FALSE, FALSE);
4049
4050         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
4051                         hf_samr_level, NULL);
4052
4053         return offset;
4054 }
4055
4056 static int
4057 samr_dissect_query_information_domain_reply(tvbuff_t *tvb, int offset, 
4058                         packet_info *pinfo, proto_tree *tree,
4059                         char *drep)
4060 {
4061         /*
4062          * Yes, in at least one capture with replies from a W2K server,
4063          * this was, indeed, a UNIQUE pointer, not a REF pointer.
4064          */
4065         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4066                         samr_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
4067                         "DOMAIN_INFO pointer", hf_samr_domain, 0);
4068
4069         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
4070                                      hf_samr_rc, NULL);
4071
4072         return offset;
4073 }
4074
4075 static int
4076 samr_dissect_query_information_user_rqst(tvbuff_t *tvb, int offset, 
4077                                           packet_info *pinfo, 
4078                                           proto_tree *tree, char *drep)
4079 {
4080         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
4081                                        hf_samr_hnd, NULL, FALSE, FALSE);
4082
4083         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
4084                         hf_samr_level, NULL);
4085
4086         return offset;
4087 }
4088
4089 static int
4090 samr_dissect_query_information_user_reply(tvbuff_t *tvb, int offset, 
4091                                            packet_info *pinfo, 
4092                                            proto_tree *tree, char *drep)
4093 {
4094         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
4095                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
4096                         "", -1, 0);
4097
4098         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
4099                                   hf_samr_rc, NULL);
4100
4101         return offset;
4102 }
4103
4104 static dcerpc_sub_dissector dcerpc_samr_dissectors[] = {
4105         { SAMR_CONNECT_ANON, "ConnectAnonymous",
4106                 samr_dissect_connect_anon_rqst,
4107                 samr_dissect_connect_anon_reply },
4108         { SAMR_CLOSE_HND, "Close",
4109                 samr_dissect_close_hnd_rqst,
4110                 samr_dissect_close_hnd_reply },
4111         { SAMR_SET_SEC_OBJECT, "SetSecObject",
4112                 samr_dissect_set_sec_object_rqst,
4113                 samr_dissect_set_sec_object_reply },
4114         { SAMR_QUERY_SEC_OBJECT, "QuerySecObject", 
4115                 samr_dissect_query_sec_object_rqst,
4116                 samr_dissect_query_sec_object_reply },
4117         { SAMR_SHUTDOWN_SAM_SERVER, "ShutdownSamServer",
4118                 samr_dissect_shutdown_sam_server_rqst,
4119                 samr_dissect_shutdown_sam_server_reply },
4120         { SAMR_LOOKUP_DOMAIN, "LookupDomain",
4121                 samr_dissect_lookup_domain_rqst,
4122                 samr_dissect_lookup_domain_reply },
4123         { SAMR_ENUM_DOMAINS, "EnumDomains",
4124                 samr_dissect_enum_domains_rqst,
4125                 samr_dissect_enum_domains_reply },
4126         { SAMR_OPEN_DOMAIN, "OpenDomain",
4127                 samr_dissect_open_domain_rqst,
4128                 samr_dissect_open_domain_reply },
4129         { SAMR_QUERY_DOMAIN_INFO, "QueryDomainInfo",
4130                 samr_dissect_query_information_alias_rqst,
4131                 samr_dissect_query_information_domain_reply },
4132         { SAMR_SET_DOMAIN_INFO, "SetDomainInfo",
4133                 samr_dissect_set_information_domain_rqst,
4134                 samr_dissect_set_information_domain_reply },
4135         { SAMR_CREATE_DOM_GROUP, "CreateGroup",
4136                 samr_dissect_create_alias_in_domain_rqst,
4137                 samr_dissect_create_alias_in_domain_reply },
4138         { SAMR_ENUM_DOM_GROUPS, "EnumDomainGroups",
4139                 samr_dissect_enum_dom_groups_rqst,
4140                 samr_dissect_enum_dom_groups_reply },
4141         { SAMR_CREATE_USER_IN_DOMAIN, "CreateUser",
4142                 samr_dissect_create_group_in_domain_rqst,
4143                 samr_dissect_create_group_in_domain_reply },
4144         { SAMR_ENUM_DOM_USERS, "EnumDomainUsers",
4145                 samr_dissect_enum_dom_groups_rqst,
4146                 samr_dissect_enum_dom_groups_reply },
4147         { SAMR_CREATE_DOM_ALIAS, "CreateAlias",
4148                 samr_dissect_create_alias_in_domain_rqst,
4149                 samr_dissect_create_alias_in_domain_reply },
4150         { SAMR_ENUM_DOM_ALIASES, "EnumAlises",
4151                 samr_dissect_enum_dom_aliases_rqst,
4152                 samr_dissect_enum_dom_aliases_reply },
4153         { SAMR_GET_ALIAS_MEMBERSHIP, "GetAliasMem",
4154                 samr_dissect_get_alias_membership_rqst,
4155                 samr_dissect_get_alias_membership_reply },
4156         { SAMR_LOOKUP_NAMES, "LookupNames", 
4157                 samr_dissect_lookup_names_rqst,
4158                 samr_dissect_lookup_names_reply },
4159         { SAMR_LOOKUP_RIDS, "LookupRIDs",
4160                 samr_dissect_lookup_rids_rqst,
4161                 samr_dissect_lookup_rids_reply },
4162         { SAMR_OPEN_GROUP, "OpenGroup",
4163                 samr_dissect_open_group_rqst,
4164                 samr_dissect_open_group_reply },
4165         { SAMR_QUERY_GROUPINFO, "QueryGroupInfo",
4166                 samr_dissect_query_information_group_rqst,
4167                 samr_dissect_query_information_group_reply },
4168         { SAMR_SET_GROUPINFO, "SetGroupInfo",
4169                 samr_dissect_set_information_group_rqst,
4170                 samr_dissect_set_information_group_reply },
4171         { SAMR_ADD_GROUPMEM, "AddGroupMem",
4172                 samr_dissect_add_member_to_group_rqst,
4173                 samr_dissect_add_member_to_group_reply },
4174         { SAMR_DELETE_DOM_GROUP, "DeleteDomainGroup",
4175                 samr_dissect_delete_dom_group_rqst,
4176                 samr_dissect_delete_dom_group_reply },
4177         { SAMR_DEL_GROUPMEM, "RemoveGroupMem",
4178                 samr_dissect_remove_member_from_group_rqst,
4179                 samr_dissect_remove_member_from_group_reply },
4180         { SAMR_QUERY_GROUPMEM, "QueryGroupMem",
4181                 samr_dissect_query_groupmem_rqst,
4182                 samr_dissect_query_groupmem_reply },
4183         { SAMR_SET_MEMBER_ATTRIBUTES_OF_GROUP, "SetMemberAttrGroup",
4184                 samr_dissect_set_member_attributes_of_group_rqst,
4185                 samr_dissect_set_member_attributes_of_group_reply },
4186         { SAMR_OPEN_ALIAS, "OpenAlias",
4187                 samr_dissect_open_alias_rqst,
4188                 samr_dissect_open_alias_reply },
4189         { SAMR_QUERY_ALIASINFO, "QueryAliasInfo",
4190                 samr_dissect_query_information_alias_rqst,
4191                 samr_dissect_query_information_alias_reply },
4192         { SAMR_SET_ALIASINFO, "SetAliasInfo",
4193                 samr_dissect_set_information_alias_rqst,
4194                 samr_dissect_set_information_alias_reply },
4195         { SAMR_DELETE_DOM_ALIAS, "DeleteAlias",
4196                 samr_dissect_delete_dom_alias_rqst,
4197                 samr_dissect_delete_dom_alias_reply },
4198         { SAMR_ADD_ALIASMEM, "AddAliasMem",
4199                 samr_dissect_add_alias_member_rqst,
4200                 samr_dissect_add_alias_member_reply },
4201         { SAMR_DEL_ALIASMEM, "RemoveAliasMem",
4202                 samr_dissect_remove_alias_member_rqst,
4203                 samr_dissect_remove_alias_member_reply },
4204         { SAMR_GET_MEMBERS_IN_ALIAS, "GetAliasMem",
4205                 samr_dissect_get_members_in_alias_rqst,
4206                 samr_dissect_get_members_in_alias_reply },
4207         { SAMR_OPEN_USER, "OpenUser", 
4208                 samr_dissect_open_user_rqst, 
4209                 samr_dissect_open_user_reply },
4210         { SAMR_DELETE_DOM_USER, "DeleteUser",
4211                 samr_dissect_delete_dom_user_rqst,
4212                 samr_dissect_delete_dom_user_reply },
4213         { SAMR_QUERY_USERINFO, "QueryUserInfo",
4214                 samr_dissect_query_information_user_rqst,
4215                 samr_dissect_query_information_user_reply },
4216         { SAMR_SET_USERINFO2, "SetUserInfo2",
4217                 samr_dissect_set_information_user2_rqst,
4218                 samr_dissect_set_information_user2_reply },
4219         { SAMR_CHANGE_PASSWORD_USER, "ChangePassword",
4220                 samr_dissect_change_password_user_rqst,
4221                 samr_dissect_change_password_user_reply },
4222         { SAMR_GET_GROUPS_FOR_USER, "GetGroups",
4223                 samr_dissect_get_groups_for_user_rqst,
4224                 samr_dissect_get_groups_for_user_reply },
4225         { SAMR_QUERY_DISPINFO, "QueryDispinfo", 
4226                 samr_dissect_query_dispinfo_rqst, 
4227                 samr_dissect_query_dispinfo_reply },
4228         { SAMR_GET_DISPLAY_ENUMERATION_INDEX, "GetDispEnumNDX", 
4229                 samr_dissect_get_display_enumeration_index_rqst, 
4230                 samr_dissect_get_display_enumeration_index_reply },
4231         { SAMR_TEST_PRIVATE_FUNCTIONS_DOMAIN, "TestPrivateFnsDomain",
4232                 samr_dissect_test_private_fns_domain_rqst,
4233                 samr_dissect_test_private_fns_domain_reply },
4234         { SAMR_TEST_PRIVATE_FUNCTIONS_USER, "TestPrivateFnsUser",
4235                 samr_dissect_test_private_fns_user_rqst,
4236                 samr_dissect_test_private_fns_user_reply },
4237         { SAMR_GET_USRDOM_PWINFO, "GetUserDomPwInfo",
4238                 samr_dissect_get_usrdom_pwinfo_rqst,
4239                 samr_dissect_get_usrdom_pwinfo_reply },
4240         { SAMR_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN, "RemoveMemberForeignDomain",
4241                 samr_dissect_remove_member_from_foreign_domain_rqst,
4242                 samr_dissect_remove_member_from_foreign_domain_reply },
4243         { SAMR_QUERY_INFORMATION_DOMAIN2, "QueryDomInfo2",
4244                 samr_dissect_query_information_domain_rqst,
4245                 samr_dissect_query_information_domain_reply },
4246         { SAMR_UNKNOWN_2f, "Unknown 0x2f",
4247                 samr_dissect_unknown_2f_rqst,
4248                 samr_dissect_unknown_2f_reply },
4249         { SAMR_QUERY_DISPINFO2, "QueryDispinfo2",
4250                 samr_dissect_query_dispinfo_rqst,
4251                 samr_dissect_query_dispinfo_reply },
4252         { SAMR_GET_DISPLAY_ENUMERATION_INDEX2, "GetDispEnumNDX2",
4253                 samr_dissect_get_display_enumeration_index2_rqst,
4254                 samr_dissect_get_display_enumeration_index2_reply },
4255         { SAMR_CREATE_USER2_IN_DOMAIN, "CreateUser2",
4256                 samr_dissect_create_user2_in_domain_rqst,
4257                 samr_dissect_create_user2_in_domain_reply },
4258         { SAMR_QUERY_DISPINFO3, "QueryDispinfo3",
4259                 samr_dissect_query_dispinfo_rqst,
4260                 samr_dissect_query_dispinfo_reply },
4261         { SAMR_ADD_MULTIPLE_MEMBERS_TO_ALIAS, "AddAliasMemMultiple",
4262                 samr_dissect_add_multiple_members_to_alias_rqst,
4263                 samr_dissect_add_multiple_members_to_alias_reply },
4264         { SAMR_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS, "RemoveAliasMemMultiple",
4265                 samr_dissect_remove_multiple_members_from_alias_rqst,
4266                 samr_dissect_remove_multiple_members_from_alias_reply },
4267         { SAMR_OEM_CHANGE_PASSWORD_USER2, "OEMChangePassword2",
4268                 samr_dissect_oem_change_password_user2_rqst,
4269                 samr_dissect_oem_change_password_user2_reply },
4270         { SAMR_UNICODE_CHANGE_PASSWORD_USER2, "UnicodeChangePassword2",
4271                 samr_dissect_unicode_change_password_user2_rqst,
4272                 samr_dissect_unicode_change_password_user2_reply },
4273         { SAMR_GET_DOM_PWINFO, "GetDomainPasswordInfo",
4274                 samr_dissect_get_domain_password_information_rqst,
4275                 samr_dissect_get_domain_password_information_reply },
4276         { SAMR_CONNECT2, "Connect2", 
4277                 samr_dissect_connect2_rqst,
4278                 samr_dissect_connect2_reply },
4279         { SAMR_SET_USERINFO, "SetUserInfo",
4280                 samr_dissect_set_information_user2_rqst,
4281                 samr_dissect_set_information_user2_reply },
4282         { SAMR_UNKNOWN_3B, "Unknown 0x3b",
4283                 samr_dissect_unknown_3b_rqst,
4284                 samr_dissect_unknown_3b_reply },
4285         { SAMR_UNKNOWN_3C, "Unknown 0x3c", 
4286                 samr_dissect_unknown_3c_rqst,
4287                 samr_dissect_unknown_3c_reply },
4288         {0, NULL, NULL,  NULL },
4289 };
4290
4291 void 
4292 proto_register_dcerpc_samr(void)
4293 {
4294         static hf_register_info hf[] = {
4295                 { &hf_samr_hnd,
4296                   { "Context Handle", "samr.hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
4297                 { &hf_samr_group,
4298                   { "Group", "samr.group", FT_UINT32, BASE_DEC, NULL, 0x0, "Group", HFILL }},
4299                 { &hf_samr_rid,
4300                   { "Rid", "samr.rid", FT_UINT32, BASE_DEC, NULL, 0x0, "RID", HFILL }},
4301                 { &hf_samr_type,
4302                   { "Type", "samr.type", FT_UINT32, BASE_HEX, NULL, 0x0, "Type", HFILL }},
4303                 { &hf_samr_alias,
4304                   { "Alias", "samr.alias", FT_UINT32, BASE_HEX, NULL, 0x0, "Alias", HFILL }},
4305                 { &hf_samr_rid_attrib,
4306                   { "Rid Attrib", "samr.rid.attrib", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
4307                 { &hf_samr_attrib,
4308                   { "Attributes", "samr.attr", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
4309                 { &hf_samr_rc,
4310                   { "Return code", "samr.rc", FT_UINT32, BASE_HEX, VALS (NT_errors), 0x0, "", HFILL }},
4311
4312         { &hf_samr_level,
4313                 { "Level", "samr.level", FT_UINT16, BASE_DEC, 
4314                 NULL, 0x0, "Level requested/returned for Information", HFILL }},
4315         { &hf_samr_start_idx,
4316                 { "Start Idx", "samr.start_idx", FT_UINT32, BASE_DEC, 
4317                 NULL, 0x0, "Start Index for returned Information", HFILL }},
4318
4319         { &hf_samr_entries,
4320                 { "Entries", "samr.entries", FT_UINT32, BASE_DEC, 
4321                 NULL, 0x0, "Number of entries to return", HFILL }},
4322
4323         { &hf_samr_max_entries,
4324                 { "Max Entries", "samr.max_entries", FT_UINT32, BASE_DEC, 
4325                 NULL, 0x0, "Maximum number of entries", HFILL }},
4326
4327         { &hf_samr_pref_maxsize,
4328                 { "Pref MaxSize", "samr.pref_maxsize", FT_UINT32, BASE_DEC, 
4329                 NULL, 0x0, "Maximum Size of data to return", HFILL }},
4330
4331         { &hf_samr_total_size,
4332                 { "Total Size", "samr.total_size", FT_UINT32, BASE_DEC, 
4333                 NULL, 0x0, "Total size of data", HFILL }},
4334
4335         { &hf_samr_bad_pwd_count,
4336                 { "Bad Pwd Count", "samr.bad_pwd_count", FT_UINT16, BASE_DEC, 
4337                 NULL, 0x0, "Number of bad pwd entries for this user", HFILL }},
4338
4339         { &hf_samr_logon_count,
4340                 { "Logon Count", "samr.logon_count", FT_UINT16, BASE_DEC, 
4341                 NULL, 0x0, "Number of logons for this user", HFILL }},
4342
4343         { &hf_samr_ret_size,
4344                 { "Returned Size", "samr.ret_size", FT_UINT32, BASE_DEC, 
4345                 NULL, 0x0, "Number of returned objects in this PDU", HFILL }},
4346
4347         { &hf_samr_index,
4348                 { "Index", "samr.index", FT_UINT32, BASE_DEC, 
4349                 NULL, 0x0, "Index", HFILL }},
4350
4351         { &hf_samr_count,
4352           { "Count", "samr.count", FT_UINT32, BASE_DEC, NULL, 0x0, "Number of elements in following array", HFILL }},
4353
4354         { &hf_samr_alias_name,
4355                 { "Alias Name", "samr.alias_name", FT_STRING, BASE_NONE,
4356                 NULL, 0, "Name of Alias", HFILL }},
4357
4358         { &hf_samr_group_name,
4359                 { "Group Name", "samr.group_name", FT_STRING, BASE_NONE,
4360                 NULL, 0, "Name of Group", HFILL }},
4361
4362         { &hf_samr_acct_name,
4363                 { "Account Name", "samr.acct_name", FT_STRING, BASE_NONE,
4364                 NULL, 0, "Name of Account", HFILL }},
4365
4366         { &hf_samr_server,
4367                 { "Server", "samr.server", FT_STRING, BASE_NONE,
4368                 NULL, 0, "Name of Server", HFILL }},
4369
4370         { &hf_samr_domain,
4371                 { "Domain", "samr.domain", FT_STRING, BASE_NONE,
4372                 NULL, 0, "Name of Domain", HFILL }},
4373
4374         { &hf_samr_controller,
4375                 { "DC", "samr.dc", FT_STRING, BASE_NONE,
4376                 NULL, 0, "Name of Domain Controller", HFILL }},
4377
4378         { &hf_samr_full_name,
4379                 { "Full Name", "samr.full_name", FT_STRING, BASE_NONE,
4380                 NULL, 0, "Full Name of Account", HFILL }},
4381
4382         { &hf_samr_home,
4383                 { "Home", "samr.home", FT_STRING, BASE_NONE,
4384                 NULL, 0, "Home directory for this user", HFILL }},
4385
4386         { &hf_samr_home_drive,
4387                 { "Home Drive", "samr.home_drive", FT_STRING, BASE_NONE,
4388                 NULL, 0, "Home drive for this user", HFILL }},
4389
4390         { &hf_samr_script,
4391                 { "Script", "samr.script", FT_STRING, BASE_NONE,
4392                 NULL, 0, "Login script for this user", HFILL }},
4393
4394         { &hf_samr_workstations,
4395                 { "Workstations", "samr.workstations", FT_STRING, BASE_NONE,
4396                 NULL, 0, "", HFILL }},
4397
4398         { &hf_samr_profile,
4399                 { "Profile", "samr.profile", FT_STRING, BASE_NONE,
4400                 NULL, 0, "Profile for this user", HFILL }},
4401
4402         { &hf_samr_acct_desc,
4403                 { "Account Desc", "samr.acct_desc", FT_STRING, BASE_NONE,
4404                 NULL, 0, "Account Description", HFILL }},
4405
4406         { &hf_samr_comment,
4407                 { "Comment", "samr.comment", FT_STRING, BASE_NONE,
4408                 NULL, 0, "Comment", HFILL }},
4409
4410         { &hf_samr_parameters,
4411                 { "Parameters", "samr.parameters", FT_STRING, BASE_NONE,
4412                 NULL, 0, "Parameters", HFILL }},
4413
4414         { &hf_samr_unknown_string,
4415                 { "Unknown string", "samr.unknown_string", FT_STRING, BASE_NONE,
4416                 NULL, 0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }},
4417
4418         { &hf_samr_unknown_hyper,
4419                 { "Unknown hyper", "samr.unknown.hyper", FT_UINT64, BASE_HEX, 
4420                 NULL, 0x0, "Unknown hyper. If you know what this is, contact ethereal developers.", HFILL }},
4421         { &hf_samr_unknown_long,
4422                 { "Unknown long", "samr.unknown.long", FT_UINT32, BASE_HEX, 
4423                 NULL, 0x0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
4424
4425         { &hf_samr_unknown_short,
4426                 { "Unknown short", "samr.unknown.short", FT_UINT16, BASE_HEX, 
4427                 NULL, 0x0, "Unknown short. If you know what this is, contact ethereal developers.", HFILL }},
4428
4429         { &hf_samr_unknown_char,
4430                 { "Unknown char", "samr.unknown.char", FT_UINT8, BASE_HEX, 
4431                 NULL, 0x0, "Unknown char. If you know what this is, contact ethereal developers.", HFILL }},
4432
4433         { &hf_samr_revision,
4434                 { "Revision", "samr.revision", FT_UINT64, BASE_HEX, 
4435                 NULL, 0x0, "Revision number for this structure", HFILL }},
4436  
4437         { &hf_samr_nt_pwd_set,
4438                 { "NT Pwd Set", "samr.nt_pwd_set", FT_UINT8, BASE_HEX, 
4439                 NULL, 0x0, "Flag indicating whether the NT password has been set", HFILL }},
4440  
4441         { &hf_samr_lm_pwd_set,
4442                 { "LM Pwd Set", "samr.lm_pwd_set", FT_UINT8, BASE_HEX, 
4443                 NULL, 0x0, "Flag indicating whether the LanManager password has been set", HFILL }},
4444  
4445         { &hf_samr_pwd_expired,
4446                 { "Expired flag", "samr.pwd_Expired", FT_UINT8, BASE_HEX, 
4447                 NULL, 0x0, "Flag indicating if the password for this account has expired or not", HFILL }},
4448
4449         /* XXX - is this a standard NT access mask? */
4450         { &hf_samr_access,
4451                 { "Access Mask", "samr.access", FT_UINT32, BASE_HEX, 
4452                 NULL, 0x0, "Access", HFILL }},
4453
4454         { &hf_samr_mask,
4455                 { "Mask", "samr.mask", FT_UINT32, BASE_HEX, 
4456                 NULL, 0x0, "Mask", HFILL }},
4457
4458         { &hf_samr_crypt_password, {
4459                 "Password", "samr.crypt_password", FT_BYTES, BASE_HEX,
4460                 NULL, 0, "Encrypted Password", HFILL }},
4461
4462         { &hf_samr_crypt_hash, {
4463                 "Hash", "samr.crypt_hash", FT_BYTES, BASE_HEX,
4464                 NULL, 0, "Encrypted Hash", HFILL }},
4465
4466         { &hf_samr_lm_change, {
4467                 "LM Change", "samr.lm_change", FT_UINT8, BASE_HEX,
4468                 NULL, 0, "LM Change value", HFILL }},
4469
4470         { &hf_samr_max_pwd_age,
4471                 { "Max Pwd Age", "samr.max_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
4472                 NULL, 0, "Maximum Password Age before it expires", HFILL }},
4473
4474         { &hf_samr_min_pwd_age,
4475                 { "Min Pwd Age", "samr.min_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
4476                 NULL, 0, "Minimum Password Age before it can be changed", HFILL }},
4477         { &hf_samr_unknown_time,
4478                 { "Unknown time", "samr.unknown_time", FT_ABSOLUTE_TIME, BASE_NONE,
4479                 NULL, 0, "Unknown NT TIME, contact ethereal developers if you know what this is", HFILL }},
4480         { &hf_samr_logon_time,
4481                 { "Logon Time", "samr.logon_time", FT_ABSOLUTE_TIME, BASE_NONE,
4482                 NULL, 0, "Time for last time this user logged on", HFILL }},
4483         { &hf_samr_kickoff_time,
4484                 { "Kickoff Time", "samr.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
4485                 NULL, 0, "Time when this user will be kicked off", HFILL }},
4486         { &hf_samr_logoff_time,
4487                 { "Logoff Time", "samr.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
4488                 NULL, 0, "Time for last time this user logged off", HFILL }},
4489         { &hf_samr_pwd_last_set_time,
4490                 { "PWD Last Set", "samr.pwd_last_set_time", FT_ABSOLUTE_TIME, BASE_NONE,
4491                 NULL, 0, "Last time this users password was changed", HFILL }},
4492         { &hf_samr_pwd_can_change_time,
4493                 { "PWD Can Change", "samr.pwd_can_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
4494                 NULL, 0, "When this users password may be changed", HFILL }},
4495         { &hf_samr_pwd_must_change_time,
4496                 { "PWD Must Change", "samr.pwd_must_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
4497                 NULL, 0, "When this users password must be changed", HFILL }},
4498         { &hf_samr_acct_expiry_time,
4499                 { "Acct Expiry", "samr.acct_expiry_time", FT_ABSOLUTE_TIME, BASE_NONE,
4500                 NULL, 0, "When this user account expires", HFILL }},
4501
4502         { &hf_samr_min_pwd_len, {
4503                 "Min Pwd Len", "samr.min_pwd_len", FT_UINT16, BASE_DEC,
4504                 NULL, 0, "Minimum Password Length", HFILL }},
4505         { &hf_samr_pwd_history_len, {
4506                 "Pwd History Len", "samr.pwd_history_len", FT_UINT16, BASE_DEC,
4507                 NULL, 0, "Password History Length", HFILL }},
4508         { &hf_samr_num_users, {
4509                 "Num Users", "samr.num_users", FT_UINT32, BASE_DEC,
4510                 NULL, 0, "Number of users in this domain", HFILL }},
4511         { &hf_samr_num_groups, {
4512                 "Num Groups", "samr.num_groups", FT_UINT32, BASE_DEC,
4513                 NULL, 0, "Number of groups in this domain", HFILL }},
4514         { &hf_samr_num_aliases, {
4515                 "Num Aliases", "samr.num_aliases", FT_UINT32, BASE_DEC,
4516                 NULL, 0, "Number of aliases in this domain", HFILL }},
4517         { &hf_samr_info_type, {
4518                 "Info Type", "samr.info_type", FT_UINT32, BASE_DEC,
4519                 NULL, 0, "Information Type", HFILL }},
4520         { &hf_samr_resume_hnd, {
4521                 "Resume Hnd", "samr.resume_hnd", FT_UINT32, BASE_DEC,
4522                 NULL, 0, "Resume handle", HFILL }},
4523         { &hf_samr_country, {
4524                 "Country", "samr.country", FT_UINT16, BASE_DEC,
4525                 VALS(ms_country_codes), 0, "Country setting for this user", HFILL }},
4526         { &hf_samr_codepage, {
4527                 "Codepage", "samr.codepage", FT_UINT16, BASE_DEC,
4528                 NULL, 0, "Codepage setting for this user", HFILL }},
4529         { &hf_samr_divisions, {
4530                 "Divisions", "samr.divisions", FT_UINT16, BASE_DEC,
4531                 NULL, 0, "Number of divisions for LOGON_HOURS", HFILL }},
4532
4533         /* these are used by packet-dcerpc-nt.c */
4534         { &hf_nt_string_length,
4535                 { "Length", "nt.string.length", FT_UINT16, BASE_DEC, 
4536                 NULL, 0x0, "Length of string in bytes", HFILL }},
4537
4538         { &hf_nt_string_size,
4539                 { "Size", "nt.string.size", FT_UINT16, BASE_DEC, 
4540                 NULL, 0x0, "Size of string in bytes", HFILL }},
4541
4542         { &hf_nt_str_len,
4543                 { "Length", "nt.str.len", FT_UINT32, BASE_DEC, 
4544                 NULL, 0x0, "Length of string in short integers", HFILL }},
4545
4546         { &hf_nt_str_off,
4547                 { "Offset", "nt.str.offset", FT_UINT32, BASE_DEC, 
4548                 NULL, 0x0, "Offset into string in short integers", HFILL }},
4549
4550         { &hf_nt_str_max_len,
4551                 { "Max Length", "nt.str.max_len", FT_UINT32, BASE_DEC, 
4552                 NULL, 0x0, "Max Length of string in short integers", HFILL }},
4553
4554         { &hf_nt_acct_ctrl,
4555                 { "Acct Ctrl", "nt.acct_ctrl", FT_UINT32, BASE_HEX, 
4556                 NULL, 0x0, "Acct CTRL", HFILL }},
4557
4558         { &hf_nt_acb_disabled, {
4559                 "", "nt.acb.disabled", FT_BOOLEAN, 32,
4560                 TFS(&tfs_nt_acb_disabled), 0x0001, "If this account is enabled or disabled", HFILL }},
4561
4562         { &hf_nt_acb_homedirreq, {
4563                 "", "nt.acb.homedirreq", FT_BOOLEAN, 32,
4564                 TFS(&tfs_nt_acb_homedirreq), 0x0002, "Is hom,edirs required for this account?", HFILL }},
4565
4566         { &hf_nt_acb_pwnotreq, {
4567                 "", "nt.acb.pwnotreq", FT_BOOLEAN, 32,
4568                 TFS(&tfs_nt_acb_pwnotreq), 0x0004, "If a password is required for this account?", HFILL }},
4569
4570         { &hf_nt_acb_tempdup, {
4571                 "", "nt.acb.tempdup", FT_BOOLEAN, 32,
4572                 TFS(&tfs_nt_acb_tempdup), 0x0008, "If this is a temporary duplicate account", HFILL }},
4573
4574         { &hf_nt_acb_normal, {
4575                 "", "nt.acb.normal", FT_BOOLEAN, 32,
4576                 TFS(&tfs_nt_acb_normal), 0x0010, "If this is a normal user account", HFILL }},
4577
4578         { &hf_nt_acb_mns, {
4579                 "", "nt.acb.mns", FT_BOOLEAN, 32,
4580                 TFS(&tfs_nt_acb_mns), 0x0020, "MNS logon user account", HFILL }},
4581
4582         { &hf_nt_acb_domtrust, {
4583                 "", "nt.acb.domtrust", FT_BOOLEAN, 32,
4584                 TFS(&tfs_nt_acb_domtrust), 0x0040, "Interdomain trust account", HFILL }},
4585
4586         { &hf_nt_acb_wstrust, {
4587                 "", "nt.acb.wstrust", FT_BOOLEAN, 32,
4588                 TFS(&tfs_nt_acb_wstrust), 0x0080, "Workstation trust account", HFILL }},
4589
4590         { &hf_nt_acb_svrtrust, {
4591                 "", "nt.acb.svrtrust", FT_BOOLEAN, 32,
4592                 TFS(&tfs_nt_acb_svrtrust), 0x0100, "Server trust account", HFILL }},
4593
4594         { &hf_nt_acb_pwnoexp, {
4595                 "", "nt.acb.pwnoexp", FT_BOOLEAN, 32,
4596                 TFS(&tfs_nt_acb_pwnoexp), 0x0200, "If this account expires or not", HFILL }},
4597
4598         { &hf_nt_acb_autolock, {
4599                 "", "nt.acb.autolock", FT_BOOLEAN, 32,
4600                 TFS(&tfs_nt_acb_autolock), 0x0400, "If this account has been autolocked", HFILL }},
4601         };
4602         static gint *ett[] = {
4603                 &ett_dcerpc_samr,
4604                 &ett_samr_user_dispinfo_1,
4605                 &ett_samr_user_dispinfo_1_array,
4606                 &ett_samr_user_dispinfo_2,
4607                 &ett_samr_user_dispinfo_2_array,
4608                 &ett_samr_group_dispinfo,
4609                 &ett_samr_group_dispinfo_array,
4610                 &ett_samr_ascii_dispinfo,
4611                 &ett_samr_ascii_dispinfo_array,
4612                 &ett_samr_display_info,
4613                 &ett_samr_password_info,
4614                 &ett_samr_server,
4615                 &ett_samr_user_group,
4616                 &ett_samr_user_group_array,
4617                 &ett_samr_alias_info,
4618                 &ett_samr_group_info,
4619                 &ett_samr_domain_info_1,
4620                 &ett_samr_domain_info_2,
4621                 &ett_samr_domain_info_8,
4622                 &ett_samr_replication_status,
4623                 &ett_samr_domain_info_11,
4624                 &ett_samr_domain_info_13,
4625                 &ett_samr_domain_info,
4626                 &ett_samr_sid_pointer,
4627                 &ett_samr_sid_array,
4628                 &ett_samr_index_array,
4629                 &ett_samr_idx_and_name,
4630                 &ett_samr_idx_and_name_array,
4631                 &ett_samr_logon_hours,
4632                 &ett_samr_logon_hours_hours,
4633                 &ett_samr_user_info_1,
4634                 &ett_samr_user_info_2,
4635                 &ett_samr_user_info_3,
4636                 &ett_samr_user_info_5,
4637                 &ett_samr_user_info_6,
4638                 &ett_samr_user_info_18,
4639                 &ett_samr_user_info_19,
4640                 &ett_samr_buffer_buffer,
4641                 &ett_samr_buffer,
4642                 &ett_samr_user_info_21,
4643                 &ett_samr_user_info_22,
4644                 &ett_samr_user_info_23,
4645                 &ett_samr_user_info_24,
4646                 &ett_samr_user_info,
4647                 &ett_samr_member_array_types,
4648                 &ett_samr_member_array_rids,
4649                 &ett_samr_member_array,
4650                 &ett_samr_names,
4651                 &ett_samr_rids,
4652                 &ett_samr_sid_and_attributes_array,
4653                 &ett_samr_sid_and_attributes,
4654                 &ett_nt_acct_ctrl,
4655         };
4656
4657         proto_dcerpc_samr = proto_register_protocol(
4658                 "Microsoft Security Account Manager", "SAMR", "samr");
4659
4660         proto_register_field_array (proto_dcerpc_samr, hf, array_length (hf));
4661         proto_register_subtree_array(ett, array_length(ett));
4662 }
4663
4664 void
4665 proto_reg_handoff_dcerpc_samr(void)
4666 {
4667         /* Register protocol as dcerpc */
4668
4669         dcerpc_init_uuid(proto_dcerpc_samr, ett_dcerpc_samr, &uuid_dcerpc_samr,
4670                          ver_dcerpc_samr, dcerpc_samr_dissectors);
4671 }