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