Fixes from Ronnie Sahlberg.
[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  *
5  * $Id: packet-dcerpc-samr.c,v 1.8 2002/02/08 11:02:03 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include "packet-dcerpc.h"
33 #include "packet-dcerpc-nt.h"
34 #include "packet-dcerpc-samr.h"
35 #include "smb.h"        /* for "NT_errors[]" */
36
37 int dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name);
38
39 static int proto_dcerpc_samr = -1;
40
41 static int hf_samr_hnd = -1;
42 static int hf_samr_group = -1;
43 static int hf_samr_rid = -1;
44 static int hf_samr_type = -1;
45 static int hf_samr_alias = -1;
46 static int hf_samr_rid_attrib = -1;
47 static int hf_samr_rc = -1;
48 static int hf_samr_index = -1;
49 static int hf_samr_acct_ctrl = -1;
50 static int hf_samr_count = -1;
51
52 static int hf_samr_level = -1;
53 static int hf_samr_start_idx = -1;
54 static int hf_samr_max_entries = -1;
55 static int hf_samr_entries = -1;
56 static int hf_samr_pref_maxsize = -1;
57 static int hf_samr_total_size = -1;
58 static int hf_samr_ret_size = -1;
59 static int hf_samr_acct_name = -1;
60 static int hf_samr_full_name = -1;
61 static int hf_samr_acct_desc = -1;
62 static int hf_samr_home = -1;
63 static int hf_samr_home_drive = -1;
64 static int hf_samr_script = -1;
65 static int hf_samr_workstations = -1;
66 static int hf_samr_profile = -1;
67 static int hf_samr_server = -1;
68 static int hf_samr_domain = -1;
69 static int hf_samr_controller = -1;
70 static int hf_samr_access = -1;
71 static int hf_samr_mask = -1;
72 static int hf_samr_crypt_password = -1;
73 static int hf_samr_crypt_hash = -1;
74 static int hf_samr_lm_change = -1;
75 static int hf_samr_attrib = -1;
76 static int hf_samr_max_pwd_age = -1;
77 static int hf_samr_min_pwd_age = -1;
78 static int hf_samr_min_pwd_len = -1;
79 static int hf_samr_pwd_history_len = -1;
80 static int hf_samr_num_users = -1;
81 static int hf_samr_num_groups = -1;
82 static int hf_samr_num_aliases = -1;
83 static int hf_samr_resume_hnd = -1;
84 static int hf_samr_bad_pwd_count = -1;
85 static int hf_samr_logon_count = -1;
86 static int hf_samr_logon_time = -1;
87 static int hf_samr_logoff_time = -1;
88 static int hf_samr_kickoff_time = -1;
89 static int hf_samr_pwd_last_set_time = -1;
90 static int hf_samr_pwd_can_change_time = -1;
91 static int hf_samr_pwd_must_change_time = -1;
92 static int hf_samr_acct_expiry_time = -1;
93 static int hf_samr_country = -1;
94 static int hf_samr_codepage = -1;
95 static int hf_samr_comment = -1;
96 static int hf_samr_parameters = -1;
97 static int hf_samr_nt_pwd_set = -1;
98 static int hf_samr_lm_pwd_set = -1;
99 static int hf_samr_pwd_expired = -1;
100 static int hf_samr_revision = -1;
101 static int hf_samr_divisions = -1;
102 static int hf_samr_info_type = -1;
103
104 static int hf_samr_unknown_hyper = -1;
105 static int hf_samr_unknown_long = -1;
106 static int hf_samr_unknown_short = -1;
107 static int hf_samr_unknown_char = -1;
108 static int hf_samr_unknown_string = -1;
109 static int hf_samr_unknown_time = -1;
110
111 /* these are used by functions in packet-dcerpc-nt.c */
112 int hf_nt_str_len = -1;
113 int hf_nt_str_off = -1;
114 int hf_nt_str_max_len = -1;
115 int hf_nt_string_length = -1;
116 int hf_nt_string_size = -1;
117
118
119 static gint ett_dcerpc_samr = -1;
120 gint ett_nt_unicode_string = -1;        /* used by packet-dcerpc-nt.c*/
121 static gint ett_samr_user_dispinfo_1 = -1;
122
123 static e_uuid_t uuid_dcerpc_samr = {
124         0x12345778, 0x1234, 0xabcd, 
125         { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xac}
126 };
127
128 static guint16 ver_dcerpc_samr = 1;
129
130
131 /* functions to dissect a UNICODE_STRING structure, common to many 
132    NT services
133    struct {
134      short len;
135      short size;
136      [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
137    } UNICODE_STRING;
138
139    these variables can be found in packet-dcerpc-samr.c 
140 */
141 extern int hf_nt_str_len;
142 extern int hf_nt_str_off;
143 extern int hf_nt_str_max_len;
144 extern int hf_nt_string_length;
145 extern int hf_nt_string_size;
146 extern gint ett_nt_unicode_string;
147
148 int
149 dissect_ndr_nt_UNICODE_STRING_string (tvbuff_t *tvb, int offset, 
150                              packet_info *pinfo, proto_tree *tree, 
151                              char *drep)
152 {
153         guint32 len, off, max_len;
154         guint16 *data16;
155         char *text;
156         int old_offset;
157         header_field_info *hfi;
158         dcerpc_info *di;
159
160         di=pinfo->private_data;
161         if(di->conformant_run){
162                 /*just a run to handle conformant arrays, nothing to dissect */
163                 return offset;
164         }
165
166         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
167                                      hf_nt_str_len, &len);
168         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
169                                      hf_nt_str_off, &off);
170         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
171                                      hf_nt_str_max_len, &max_len);
172
173         old_offset=offset;
174         offset = prs_uint16s(tvb, offset, pinfo, tree, max_len, &data16, NULL);
175         text = fake_unicode(data16, max_len);
176
177         hfi = proto_registrar_get_nth(di->hf_index);
178         proto_tree_add_string_format(tree, di->hf_index, 
179                 tvb, old_offset, offset-old_offset,
180                 text, "%s: %s", hfi->name, text);
181
182         if(tree){
183                 proto_item_set_text(tree, "%s: %s", hfi->name, text);
184                 proto_item_set_text(tree->parent, "%s: %s", hfi->name, text);
185         }
186         return offset;
187 }
188
189 int
190 dissect_ndr_nt_UNICODE_STRING (tvbuff_t *tvb, int offset, 
191                              packet_info *pinfo, proto_tree *parent_tree, 
192                              char *drep, int hf_index)
193 {
194         proto_item *item=NULL;
195         proto_tree *tree=NULL;
196         int old_offset=offset;
197         dcerpc_info *di;
198
199         di=pinfo->private_data;
200         if(di->conformant_run){
201                 /*just a run to handle conformant arrays, nothing to dissect */
202                 return offset;
203         }
204
205         if(parent_tree){
206                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
207                         "Unicode String");
208                 tree = proto_item_add_subtree(item, ett_nt_unicode_string);
209         }
210
211         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
212                                      hf_nt_string_length, NULL);
213         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
214                                      hf_nt_string_size, NULL);
215         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
216                         dissect_ndr_nt_UNICODE_STRING_string, NDR_POINTER_PTR,
217                         hf_index);
218
219         proto_item_set_len(item, offset-old_offset);
220         return offset;
221 }
222
223 /* functions to dissect a STRING structure, common to many 
224    NT services
225    struct {
226      short len;
227      short size;
228      [size_is(size), length_is(len), ptr] char *string;
229    } STRING;
230 */
231
232 static int
233 dissect_ndr_nt_STRING_string (tvbuff_t *tvb, int offset, 
234                              packet_info *pinfo, proto_tree *tree, 
235                              char *drep)
236 {
237         guint32 len, off, max_len;
238         guint8 *text;
239         int old_offset;
240         header_field_info *hfi;
241         dcerpc_info *di;
242
243         di=pinfo->private_data;
244         if(di->conformant_run){
245                 /*just a run to handle conformant arrays, nothing to dissect */
246                 return offset;
247         }
248
249         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
250                                      hf_nt_str_len, &len);
251         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
252                                      hf_nt_str_off, &off);
253         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
254                                      hf_nt_str_max_len, &max_len);
255
256         old_offset=offset;
257         offset = prs_uint8s(tvb, offset, pinfo, tree, max_len, &text, NULL);
258
259         hfi = proto_registrar_get_nth(di->hf_index);
260         proto_tree_add_string_format(tree, di->hf_index, 
261                 tvb, old_offset, offset-old_offset,
262                 text, "%s: %s", hfi->name, text);
263
264         if(tree){
265                 proto_item_set_text(tree, "%s: %s", hfi->name, text);
266                 proto_item_set_text(tree->parent, "%s: %s", hfi->name, text);
267         }
268         return offset;
269 }
270
271 int
272 dissect_ndr_nt_STRING (tvbuff_t *tvb, int offset, 
273                              packet_info *pinfo, proto_tree *parent_tree, 
274                              char *drep, int hf_index)
275 {
276         proto_item *item=NULL;
277         proto_tree *tree=NULL;
278         int old_offset=offset;
279         dcerpc_info *di;
280
281         di=pinfo->private_data;
282         if(di->conformant_run){
283                 /*just a run to handle conformant arrays, nothing to dissect */
284                 return offset;
285         }
286
287         if(parent_tree){
288                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
289                         "Unicode String");
290                 tree = proto_item_add_subtree(item, ett_nt_unicode_string);
291         }
292
293         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
294                                      hf_nt_string_length, NULL);
295         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
296                                      hf_nt_string_size, NULL);
297         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
298                         dissect_ndr_nt_STRING_string, NDR_POINTER_PTR,
299                         hf_index);
300
301         proto_item_set_len(item, offset-old_offset);
302         return offset;
303 }
304
305 /* This should get fixed both here and in dissect_smb_64bit_time so
306    one can handle both BIG and LITTLE endian encodings 
307  */
308 int dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int hf_date);
309 int
310 dissect_ndr_nt_NTTIME (tvbuff_t *tvb, int offset, 
311                         packet_info *pinfo, proto_tree *tree, 
312                         char *drep, int hf_index)
313 {
314         dcerpc_info *di;
315
316         di=pinfo->private_data;
317         if(di->conformant_run){
318                 /*just a run to handle conformant arrays, nothing to dissect */
319                 return offset;
320         }
321
322         /* align to 4 byte boundary */
323         if(offset&0x03){
324                 offset = (offset&0xfffffffc)+4;
325         }
326
327         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
328                  hf_index);
329         return offset;
330 }
331
332 static int
333 samr_dissect_SID(tvbuff_t *tvb, int offset, 
334                         packet_info *pinfo, proto_tree *tree, 
335                         char *drep)
336 {
337         dcerpc_info *di;
338
339         di=pinfo->private_data;
340         if(di->conformant_run){
341                 /* just a run to handle conformant arrays, no scalars to dissect */
342                 return offset;
343         }
344
345         /* the SID contains a conformant array, first we must eat
346            the 4-byte max_count before we can hand it off */
347         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
348                         hf_samr_count, NULL);
349
350         offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Domain");
351         return offset;
352 }
353
354 static int
355 samr_dissect_SID_ptr(tvbuff_t *tvb, int offset, 
356                         packet_info *pinfo, proto_tree *tree, 
357                         char *drep)
358 {
359         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
360                         samr_dissect_SID, NDR_POINTER_UNIQUE,
361                         -1);
362         return offset;
363 }
364
365
366
367 /* above this line, just some general support routines which should be placed
368    in some more generic file common to all NT services dissectors
369 */
370
371
372
373
374
375
376 static int
377 samr_dissect_context_handle_reply(tvbuff_t *tvb, int offset, 
378                         packet_info *pinfo, proto_tree *tree, 
379                         char *drep)
380 {
381         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
382                         hf_samr_hnd, NULL);
383         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
384                         hf_samr_rc, NULL);
385
386         return offset;
387 }
388
389
390 static int
391 samr_dissect_open_user_rqst(tvbuff_t *tvb, int offset, 
392                         packet_info *pinfo, proto_tree *tree, 
393                         char *drep)
394 {
395         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
396                         hf_samr_hnd, NULL);
397         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
398                         hf_samr_access, NULL);
399         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
400                         hf_samr_rid, NULL);
401
402         return offset;
403 }
404
405 static int
406 samr_dissect_pointer_long(tvbuff_t *tvb, int offset, 
407                              packet_info *pinfo, proto_tree *tree, 
408                              char *drep)
409 {
410         dcerpc_info *di;
411
412         di=pinfo->private_data;
413         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
414                                      di->hf_index, NULL);
415         return offset;
416 }
417
418 static int
419 samr_dissect_pointer_STRING(tvbuff_t *tvb, int offset, 
420                              packet_info *pinfo, proto_tree *tree, 
421                              char *drep)
422 {
423         dcerpc_info *di;
424
425         di=pinfo->private_data;
426         if(di->conformant_run){
427                 /*just a run to handle conformant arrays, nothing to dissect */
428                 return offset;
429         }
430
431         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
432                         di->hf_index);
433         return offset;
434 }
435
436 static int
437 samr_dissect_pointer_UNICODE_STRING(tvbuff_t *tvb, int offset, 
438                              packet_info *pinfo, proto_tree *tree, 
439                              char *drep)
440 {
441         dcerpc_info *di;
442
443         di=pinfo->private_data;
444         if(di->conformant_run){
445                 /*just a run to handle conformant arrays, nothing to dissect */
446                 return offset;
447         }
448
449         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
450                         di->hf_index);
451         return offset;
452 }
453
454 static int
455 samr_dissect_pointer_short(tvbuff_t *tvb, int offset, 
456                              packet_info *pinfo, proto_tree *tree, 
457                              char *drep)
458 {
459         dcerpc_info *di;
460
461         di=pinfo->private_data;
462         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
463                                      di->hf_index, NULL);
464         return offset;
465 }
466
467
468 static int
469 samr_dissect_query_dispinfo_rqst (tvbuff_t *tvb, int offset, 
470                              packet_info *pinfo, proto_tree *tree, 
471                              char *drep)
472 {
473         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
474                                       hf_samr_hnd, NULL);
475         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
476                                      hf_samr_level, NULL);
477         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
478                                      hf_samr_start_idx, NULL);
479         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
480                                      hf_samr_max_entries, NULL);
481         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
482                                      hf_samr_pref_maxsize, NULL);
483         return offset;
484 }
485
486 static int
487 samr_dissect_USER_DISPINFO_1(tvbuff_t *tvb, int offset, 
488                         packet_info *pinfo, proto_tree *parent_tree, 
489                         char *drep)
490 {
491         proto_item *item=NULL;
492         proto_tree *tree=NULL;
493         int old_offset=offset;
494
495         if(parent_tree){
496                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
497                         "User_DispInfo_1");
498                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
499         }
500
501         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
502                                 hf_samr_index, NULL);
503         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
504                                 hf_samr_rid, NULL);
505         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
506                                 hf_samr_acct_ctrl, NULL);
507         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
508                                 hf_samr_acct_name);
509         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
510                                 hf_samr_full_name);
511         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
512                                 hf_samr_acct_desc);
513
514         proto_item_set_len(item, offset-old_offset);
515         return offset;
516 }
517
518 static int
519 samr_dissect_USER_DISPINFO_1_ARRAY_users(tvbuff_t *tvb, int offset, 
520                         packet_info *pinfo, proto_tree *tree, 
521                         char *drep)
522 {
523         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
524                         samr_dissect_USER_DISPINFO_1);
525
526         return offset;
527 }
528
529 static int
530 samr_dissect_USER_DISPINFO_1_ARRAY (tvbuff_t *tvb, int offset, 
531                              packet_info *pinfo, proto_tree *parent_tree, 
532                              char *drep)
533 {
534         guint32 count;
535         proto_item *item=NULL;
536         proto_tree *tree=NULL;
537         int old_offset=offset;
538
539         if(parent_tree){
540                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
541                         "User_DispInfo_1 Array");
542                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
543         }
544
545
546         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
547                                      hf_samr_count, &count);
548         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
549                         samr_dissect_USER_DISPINFO_1_ARRAY_users, NDR_POINTER_PTR,
550                         -1);
551
552         proto_item_set_len(item, offset-old_offset);
553         return offset;
554 }
555
556
557
558 static int
559 samr_dissect_USER_DISPINFO_2(tvbuff_t *tvb, int offset, 
560                         packet_info *pinfo, proto_tree *parent_tree, 
561                         char *drep)
562 {
563         proto_item *item=NULL;
564         proto_tree *tree=NULL;
565         int old_offset=offset;
566
567         if(parent_tree){
568                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
569                         "User_DispInfo_2");
570                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
571         }
572
573         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
574                         hf_samr_index, NULL);
575         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
576                         hf_samr_rid, NULL);
577         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
578                         hf_samr_acct_ctrl, NULL);
579         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
580                         hf_samr_acct_name);
581         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
582                         hf_samr_acct_desc);
583
584         proto_item_set_len(item, offset-old_offset);
585         return offset;
586 }
587
588 static int
589 samr_dissect_USER_DISPINFO_2_ARRAY_users (tvbuff_t *tvb, int offset, 
590                              packet_info *pinfo, proto_tree *tree, 
591                              char *drep)
592 {
593         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
594                         samr_dissect_USER_DISPINFO_2);
595
596         return offset;
597 }
598
599 static int
600 samr_dissect_USER_DISPINFO_2_ARRAY (tvbuff_t *tvb, int offset, 
601                              packet_info *pinfo, proto_tree *parent_tree, 
602                              char *drep)
603 {
604         guint32 count;
605         proto_item *item=NULL;
606         proto_tree *tree=NULL;
607         int old_offset=offset;
608
609         if(parent_tree){
610                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
611                         "User_DispInfo_2 Array");
612                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
613         }
614
615
616         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
617                                      hf_samr_count, &count);
618         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
619                         samr_dissect_USER_DISPINFO_2_ARRAY_users, NDR_POINTER_PTR,
620                         -1);
621
622         proto_item_set_len(item, offset-old_offset);
623         return offset;
624 }
625
626
627
628
629
630 static int
631 samr_dissect_GROUP_DISPINFO(tvbuff_t *tvb, int offset, 
632                         packet_info *pinfo, proto_tree *parent_tree, 
633                         char *drep)
634 {
635         proto_item *item=NULL;
636         proto_tree *tree=NULL;
637         int old_offset=offset;
638
639         if(parent_tree){
640                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
641                         "Group_DispInfo");
642                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
643         }
644
645         
646         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
647                         hf_samr_index, NULL);
648         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
649                         hf_samr_rid, NULL);
650         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
651                         hf_samr_acct_ctrl, NULL);
652         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
653                         hf_samr_acct_name);
654         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
655                         hf_samr_acct_desc);
656
657         proto_item_set_len(item, offset-old_offset);
658         return offset;
659 }
660
661 static int
662 samr_dissect_GROUP_DISPINFO_ARRAY_groups(tvbuff_t *tvb, int offset, 
663                         packet_info *pinfo, proto_tree *tree, 
664                         char *drep)
665 {
666         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
667                         samr_dissect_GROUP_DISPINFO);
668
669         return offset;
670 }
671
672 static int
673 samr_dissect_GROUP_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
674                         packet_info *pinfo, proto_tree *parent_tree, 
675                         char *drep)
676 {
677         guint32 count;
678         proto_item *item=NULL;
679         proto_tree *tree=NULL;
680         int old_offset=offset;
681
682         if(parent_tree){
683                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
684                         "Group_DispInfo Array");
685                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
686         }
687
688         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
689                                      hf_samr_count, &count);
690         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
691                         samr_dissect_GROUP_DISPINFO_ARRAY_groups, NDR_POINTER_PTR,
692                         -1);
693
694         proto_item_set_len(item, offset-old_offset);
695         return offset;
696 }
697
698
699
700 static int
701 samr_dissect_ASCII_DISPINFO(tvbuff_t *tvb, int offset, 
702                         packet_info *pinfo, proto_tree *parent_tree, 
703                         char *drep)
704 {
705         proto_item *item=NULL;
706         proto_tree *tree=NULL;
707         int old_offset=offset;
708
709         if(parent_tree){
710                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
711                         "Ascii_DispInfo");
712                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
713         }
714
715         
716         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
717                         hf_samr_index, NULL);
718         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
719                         hf_samr_rid, NULL);
720         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
721                         hf_samr_acct_ctrl, NULL);
722         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
723                         hf_samr_acct_name);
724         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
725                         hf_samr_acct_desc);
726
727         proto_item_set_len(item, offset-old_offset);
728         return offset;
729 }
730
731 static int
732 samr_dissect_ASCII_DISPINFO_ARRAY_users(tvbuff_t *tvb, int offset, 
733                         packet_info *pinfo, proto_tree *tree, 
734                         char *drep)
735 {
736         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
737                         samr_dissect_ASCII_DISPINFO);
738
739         return offset;
740 }
741
742 static int
743 samr_dissect_ASCII_DISPINFO_ARRAY(tvbuff_t *tvb, int offset, 
744                         packet_info *pinfo, proto_tree *parent_tree,
745                         char *drep)
746 {
747         guint32 count;
748         proto_item *item=NULL;
749         proto_tree *tree=NULL;
750         int old_offset=offset;
751
752         if(parent_tree){
753                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
754                         "Ascii_DispInfo Array");
755                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
756         }
757
758         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
759                                      hf_samr_count, &count);
760         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
761                         samr_dissect_ASCII_DISPINFO_ARRAY_users, NDR_POINTER_PTR,
762                         -1);
763
764         proto_item_set_len(item, offset-old_offset);
765         return offset;
766 }
767
768
769 static int
770 samr_dissect_DISPLAY_INFO (tvbuff_t *tvb, int offset, 
771                              packet_info *pinfo, proto_tree *parent_tree,
772                              char *drep)
773 {
774         proto_item *item=NULL;
775         proto_tree *tree=NULL;
776         int old_offset=offset;
777         guint16 level;
778
779         if(parent_tree){
780                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
781                         "DispInfo");
782                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
783         }
784
785         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
786                                      hf_samr_level, &level);
787         switch(level){
788         case 1: 
789                 offset = samr_dissect_USER_DISPINFO_1_ARRAY(
790                                 tvb, offset, pinfo, tree, drep);
791                 break;
792         case 2: 
793                 offset = samr_dissect_USER_DISPINFO_2_ARRAY(
794                                 tvb, offset, pinfo, tree, drep);
795                 break;
796         case 3: 
797                 offset = samr_dissect_GROUP_DISPINFO_ARRAY(
798                                 tvb, offset, pinfo, tree, drep);
799                 break;
800         case 4: 
801                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
802                                 tvb, offset, pinfo, tree, drep);
803                 break;
804         case 5: 
805                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
806                                 tvb, offset, pinfo, tree, drep);
807                 break;
808         }
809
810         proto_item_set_len(item, offset-old_offset);
811         return offset;
812 }
813
814 static int
815 samr_dissect_query_dispinfo_reply (tvbuff_t *tvb, int offset, 
816                              packet_info *pinfo, proto_tree *tree, 
817                              char *drep)
818 {
819         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
820                         samr_dissect_pointer_long, NDR_POINTER_REF,
821                         hf_samr_total_size);
822         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
823                         samr_dissect_pointer_long, NDR_POINTER_REF,
824                         hf_samr_ret_size);
825         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
826                         samr_dissect_DISPLAY_INFO, NDR_POINTER_REF,
827                         -1);
828         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
829                                      hf_samr_rc, NULL);
830
831         return offset;
832 }
833
834
835 static int
836 samr_dissect_get_display_enumeration_index_rqst(tvbuff_t *tvb, int offset, 
837                              packet_info *pinfo, proto_tree *tree, 
838                              char *drep)
839 {
840         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
841                                       hf_samr_hnd, NULL);
842         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
843                                      hf_samr_level, NULL);
844         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
845                         hf_samr_acct_name);
846         return offset;
847 }
848
849
850 static int
851 samr_dissect_get_display_enumeration_index_reply(tvbuff_t *tvb, int offset, 
852                              packet_info *pinfo, proto_tree *tree, 
853                              char *drep)
854 {
855         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
856                         samr_dissect_pointer_long, NDR_POINTER_REF,
857                         hf_samr_index);
858         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
859                                      hf_samr_rc, NULL);
860
861         return offset;
862 }
863
864
865
866
867 static int
868 samr_dissect_PASSWORD_INFO(tvbuff_t *tvb, int offset, 
869                         packet_info *pinfo, proto_tree *parent_tree,
870                         char *drep)
871 {
872         guint32 count;
873         proto_item *item=NULL;
874         proto_tree *tree=NULL;
875         int old_offset=offset;
876
877         if(parent_tree){
878                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
879                         "Password Info");
880                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
881         }
882
883         
884         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
885                         hf_samr_unknown_short, NULL);
886         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
887                         hf_samr_unknown_long, NULL);
888
889         proto_item_set_len(item, offset-old_offset);
890         return offset;
891 }
892
893 static int
894 samr_dissect_get_usrdom_pwinfo_reply(tvbuff_t *tvb, int offset, 
895                              packet_info *pinfo, proto_tree *tree, 
896                              char *drep)
897 {
898         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
899                         samr_dissect_PASSWORD_INFO, NDR_POINTER_REF,
900                         -1);
901         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
902                                      hf_samr_rc, NULL);
903         return offset;
904 }
905
906
907
908 static int
909 samr_dissect_connect2_server(tvbuff_t *tvb, int offset, 
910                              packet_info *pinfo, proto_tree *parent_tree, 
911                              char *drep)
912 {
913         proto_item *item=NULL;
914         proto_tree *tree=NULL;
915         int old_offset=offset;
916
917         if(parent_tree){
918                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
919                         "Server");
920                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
921         }
922
923         offset = dissect_ndr_nt_UNICODE_STRING_string(tvb, offset, pinfo, 
924                         tree, drep);
925
926         proto_item_set_len(item, offset-old_offset);
927         return offset;
928 }
929
930 static int
931 samr_dissect_connect2_rqst(tvbuff_t *tvb, int offset, 
932                              packet_info *pinfo, proto_tree *tree, 
933                              char *drep)
934 {
935         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
936                         samr_dissect_connect2_server, NDR_POINTER_UNIQUE,
937                         hf_samr_server);
938
939         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
940                                      hf_samr_access, NULL);
941         return offset;
942 }
943
944 static int
945 samr_dissect_connect2_reply(tvbuff_t *tvb, int offset, 
946                              packet_info *pinfo, proto_tree *tree, 
947                              char *drep)
948 {
949         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
950                                       hf_samr_hnd, NULL);
951         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
952                                      hf_samr_rc, NULL);
953         return offset;
954 }
955
956
957
958
959 static int
960 samr_dissect_USER_GROUP(tvbuff_t *tvb, int offset, 
961                              packet_info *pinfo, proto_tree *parent_tree,
962                              char *drep)
963 {
964         proto_item *item=NULL;
965         proto_tree *tree=NULL;
966         int old_offset=offset;
967
968         if(parent_tree){
969                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
970                         "User Group");
971                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
972         }
973
974         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
975                                      hf_samr_rid, NULL);
976         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
977                                      hf_samr_rid_attrib, NULL);
978
979         proto_item_set_len(item, offset-old_offset);
980         return offset;
981 }
982
983 static int
984 samr_dissect_USER_GROUP_ARRAY_groups (tvbuff_t *tvb, int offset, 
985                              packet_info *pinfo, proto_tree *tree,
986                              char *drep)
987 {
988         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
989                         samr_dissect_USER_GROUP);
990
991         return offset;
992 }
993
994 static int
995 samr_dissect_USER_GROUP_ARRAY(tvbuff_t *tvb, int offset, 
996                         packet_info *pinfo, proto_tree *parent_tree,
997                         char *drep)
998 {
999         guint32 count;
1000         proto_item *item=NULL;
1001         proto_tree *tree=NULL;
1002         int old_offset=offset;
1003
1004         if(parent_tree){
1005                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1006                         "User_Group Array");
1007                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1008         }
1009
1010         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1011                         hf_samr_count, &count);
1012         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1013                         samr_dissect_USER_GROUP_ARRAY_groups, NDR_POINTER_UNIQUE,
1014                         -1);
1015
1016         proto_item_set_len(item, offset-old_offset);
1017         return offset;
1018 }
1019
1020 static int
1021 samr_dissect_USER_GROUP_ARRAY_ptr(tvbuff_t *tvb, int offset, 
1022                         packet_info *pinfo, proto_tree *tree,
1023                         char *drep)
1024 {
1025         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1026                         samr_dissect_USER_GROUP_ARRAY, NDR_POINTER_UNIQUE,
1027                         -1);
1028         return offset;
1029 }
1030
1031 static int
1032 samr_dissect_get_groups_for_user_reply(tvbuff_t *tvb, int offset, 
1033                              packet_info *pinfo, proto_tree *tree, 
1034                              char *drep)
1035 {
1036         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1037                         samr_dissect_USER_GROUP_ARRAY_ptr, NDR_POINTER_REF,
1038                         -1);
1039         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1040                                      hf_samr_rc, NULL);
1041         return offset;
1042 }
1043
1044
1045
1046 static int
1047 samr_dissect_open_domain_rqst(tvbuff_t *tvb, int offset, 
1048                              packet_info *pinfo, proto_tree *tree, 
1049                              char *drep)
1050 {
1051         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1052                                       hf_samr_hnd, NULL);
1053         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1054                                      hf_samr_access, NULL);
1055         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1056                         samr_dissect_SID, NDR_POINTER_REF,
1057                         -1);
1058         return offset;
1059 }
1060
1061 static int
1062 samr_dissect_open_domain_reply(tvbuff_t *tvb, int offset, 
1063                              packet_info *pinfo, proto_tree *tree, 
1064                              char *drep)
1065 {
1066         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1067                                       hf_samr_hnd, NULL);
1068         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1069                                      hf_samr_rc, NULL);
1070         return offset;
1071 }
1072
1073
1074
1075 static int
1076 samr_dissect_context_handle_SID(tvbuff_t *tvb, int offset, 
1077                              packet_info *pinfo, proto_tree *tree, 
1078                              char *drep)
1079 {
1080         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1081                                       hf_samr_hnd, NULL);
1082         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1083                         samr_dissect_SID, NDR_POINTER_REF,
1084                         -1);
1085         return offset;
1086 }
1087
1088 static int
1089 samr_dissect_context_handle(tvbuff_t *tvb, int offset, 
1090                              packet_info *pinfo, proto_tree *tree, 
1091                              char *drep)
1092 {
1093         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1094                                       hf_samr_hnd, NULL);
1095         return offset;
1096 }
1097
1098
1099 static int
1100 samr_dissect_rc(tvbuff_t *tvb, int offset, 
1101                              packet_info *pinfo, proto_tree *tree, 
1102                              char *drep)
1103 {
1104         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1105                                      hf_samr_rc, NULL);
1106         return offset;
1107 }
1108
1109 static int
1110 samr_dissect_add_member_to_group_rqst(tvbuff_t *tvb, int offset, 
1111                              packet_info *pinfo, proto_tree *tree, 
1112                              char *drep)
1113 {
1114         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1115                                       hf_samr_hnd, NULL);
1116         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1117                                      hf_samr_group, NULL);
1118         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1119                                      hf_samr_rid, NULL);
1120         return offset;
1121 }
1122
1123 static int
1124 samr_dissect_unknown_3c_reply(tvbuff_t *tvb, int offset, 
1125                              packet_info *pinfo, proto_tree *tree, 
1126                              char *drep)
1127 {
1128         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1129                         samr_dissect_pointer_short, NDR_POINTER_REF,
1130                         hf_samr_unknown_short);
1131         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1132                                      hf_samr_rc, NULL);
1133         return offset;
1134 }
1135
1136
1137
1138 static int
1139 samr_dissect_create_alias_in_domain_rqst(tvbuff_t *tvb, int offset, 
1140                              packet_info *pinfo, proto_tree *tree, 
1141                              char *drep)
1142 {
1143         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1144                                       hf_samr_hnd, NULL);
1145         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1146                         hf_samr_acct_name);
1147         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1148                                      hf_samr_access, NULL);
1149         return offset;
1150 }
1151
1152 static int
1153 samr_dissect_create_alias_in_domain_reply(tvbuff_t *tvb, int offset, 
1154                              packet_info *pinfo, proto_tree *tree, 
1155                              char *drep)
1156 {
1157         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1158                                       hf_samr_hnd, NULL);
1159         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1160                                      hf_samr_rid, NULL);
1161         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1162                                      hf_samr_rc, NULL);
1163
1164         return offset;
1165 }
1166
1167
1168 static int
1169 samr_dissect_query_information_alias_rqst(tvbuff_t *tvb, int offset, 
1170                         packet_info *pinfo, proto_tree *tree, 
1171                         char *drep)
1172 {
1173         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1174                         hf_samr_hnd, NULL);
1175         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1176                         hf_samr_level, NULL);
1177
1178         return offset;
1179 }
1180
1181
1182 static int
1183 samr_dissect_ALIAS_INFO_1 (tvbuff_t *tvb, int offset, 
1184                              packet_info *pinfo, proto_tree *tree,
1185                              char *drep)
1186 {
1187         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1188                 tree, drep,
1189                 hf_samr_acct_name);
1190         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1191                                      hf_samr_rid, NULL);
1192         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1193                 tree, drep,
1194                 hf_samr_acct_desc);
1195         return offset;
1196 }
1197
1198 static int
1199 samr_dissect_ALIAS_INFO(tvbuff_t *tvb, int offset, 
1200                         packet_info *pinfo, proto_tree *parent_tree,
1201                         char *drep)
1202 {
1203         proto_item *item=NULL;
1204         proto_tree *tree=NULL;
1205         int old_offset=offset;
1206         guint16 level;
1207
1208         if(parent_tree){
1209                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1210                         "AliasInfo");
1211                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1212         }
1213
1214         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1215                                      hf_samr_level, &level);
1216         switch(level){
1217         case 1: 
1218                 offset = samr_dissect_ALIAS_INFO_1(
1219                                 tvb, offset, pinfo, tree, drep);
1220                 break;
1221         case 2: 
1222                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1223                         tree, drep,
1224                         hf_samr_acct_name);
1225                 break;
1226         case 3: 
1227                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1228                         tree, drep,
1229                         hf_samr_acct_desc);
1230                 break;
1231         }
1232
1233         proto_item_set_len(item, offset-old_offset);
1234         return offset;
1235 }
1236
1237 static int
1238 samr_dissect_ALIAS_INFO_ptr(tvbuff_t *tvb, int offset, 
1239                         packet_info *pinfo, proto_tree *tree,
1240                         char *drep)
1241 {
1242         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1243                         samr_dissect_ALIAS_INFO, NDR_POINTER_UNIQUE,
1244                         -1);
1245         return offset;
1246 }
1247
1248 static int
1249 samr_dissect_query_information_alias_reply(tvbuff_t *tvb, int offset, 
1250                         packet_info *pinfo, proto_tree *tree, 
1251                         char *drep)
1252 {
1253         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1254                         samr_dissect_ALIAS_INFO_ptr, NDR_POINTER_REF,
1255                         -1);
1256         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1257                         hf_samr_rc, NULL);
1258         return offset;
1259 }
1260
1261 static int
1262 samr_dissect_set_information_alias_rqst(tvbuff_t *tvb, int offset, 
1263                              packet_info *pinfo, proto_tree *tree, 
1264                              char *drep)
1265 {
1266         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1267                                       hf_samr_hnd, NULL);
1268         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1269                                      hf_samr_level, NULL);
1270         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1271                         samr_dissect_ALIAS_INFO, NDR_POINTER_REF,
1272                         -1);
1273         return offset;
1274 }
1275
1276
1277 static int
1278 samr_dissect_CRYPT_PASSWORD(tvbuff_t *tvb, int offset, 
1279                         packet_info *pinfo, proto_tree *tree, 
1280                         char *drep)
1281 {
1282         proto_tree_add_item(tree, hf_samr_crypt_password, tvb, offset, 516,
1283                 FALSE);
1284         offset += 516;
1285         return offset;
1286 }
1287
1288 static int
1289 samr_dissect_CRYPT_HASH(tvbuff_t *tvb, int offset, 
1290                         packet_info *pinfo, proto_tree *tree, 
1291                         char *drep)
1292 {
1293         proto_tree_add_item(tree, hf_samr_crypt_hash, tvb, offset, 16,
1294                 FALSE);
1295         offset += 16;
1296         return offset;
1297 }
1298
1299
1300 static int
1301 samr_dissect_oem_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1302                              packet_info *pinfo, proto_tree *tree, 
1303                              char *drep)
1304 {
1305         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1306                                       hf_samr_hnd, NULL);
1307         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1308                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1309                         hf_samr_server);
1310         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1311                         samr_dissect_pointer_STRING, NDR_POINTER_REF,
1312                         hf_samr_acct_name);
1313         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1314                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1315                         -1);
1316         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1317                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1318                         -1);
1319         return offset;
1320 }
1321
1322 static int
1323 samr_dissect_unicode_change_password_user2_rqst(tvbuff_t *tvb, int offset, 
1324                              packet_info *pinfo, proto_tree *tree, 
1325                              char *drep)
1326 {
1327         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1328                                       hf_samr_hnd, NULL);
1329         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1330                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1331                         hf_samr_server);
1332         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1333                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_REF,
1334                         hf_samr_acct_name);
1335         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1336                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1337                         -1);
1338         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1339                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1340                         -1);
1341         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1342                                      hf_samr_lm_change, NULL);
1343         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1344                         samr_dissect_CRYPT_PASSWORD, NDR_POINTER_UNIQUE,
1345                         -1);
1346         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1347                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1348                         -1);
1349         return offset;
1350 }
1351
1352 static int
1353 samr_dissect_unknown_3b_rqst(tvbuff_t *tvb, int offset, 
1354                              packet_info *pinfo, proto_tree *tree, 
1355                              char *drep)
1356 {
1357         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1358                                       hf_samr_hnd, NULL);
1359         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1360                                      hf_samr_unknown_short, NULL);
1361         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1362                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1363                         hf_samr_unknown_string);
1364         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1365                         samr_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
1366                         hf_samr_unknown_string);
1367         return offset;
1368 }
1369
1370
1371 static int
1372 samr_dissect_create_user2_in_domain_rqst(tvbuff_t *tvb, int offset, 
1373                         packet_info *pinfo, proto_tree *tree, 
1374                         char *drep)
1375 {
1376         
1377         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1378                         hf_samr_hnd, NULL);
1379         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1380                         hf_samr_acct_name);
1381         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1382                         hf_samr_acct_ctrl, NULL);
1383         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1384                         hf_samr_access, NULL);
1385
1386         return offset;
1387 }
1388
1389 static int
1390 samr_dissect_create_user2_in_domain_reply(tvbuff_t *tvb, int offset, 
1391                              packet_info *pinfo, proto_tree *tree, 
1392                              char *drep)
1393 {
1394         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1395                                       hf_samr_hnd, NULL);
1396         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1397                                      hf_samr_unknown_long, NULL);
1398         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1399                                      hf_samr_rid, NULL);
1400         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1401                                      hf_samr_rc, NULL);
1402         return offset;
1403 }
1404
1405 static int
1406 samr_dissect_get_display_enumeration_index2_rqst(tvbuff_t *tvb, int offset, 
1407                              packet_info *pinfo, proto_tree *tree, 
1408                              char *drep)
1409 {
1410         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1411                                       hf_samr_hnd, NULL);
1412         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1413                                      hf_samr_level, NULL);
1414         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1415                         hf_samr_acct_name);
1416         return offset;
1417 }
1418
1419 static int
1420 samr_dissect_get_display_enumeration_index2_reply(tvbuff_t *tvb, int offset, 
1421                              packet_info *pinfo, proto_tree *tree, 
1422                              char *drep)
1423 {
1424         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1425                                      hf_samr_index, NULL);
1426         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1427                                      hf_samr_rc, NULL);
1428         return offset;
1429 }
1430
1431 static int
1432 samr_dissect_change_password_user_rqst(tvbuff_t *tvb, int offset, 
1433                         packet_info *pinfo, proto_tree *tree, 
1434                         char *drep)
1435 {
1436         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1437                         hf_samr_hnd, NULL);
1438         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1439                         hf_samr_unknown_char, NULL);
1440         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1441                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1442                         -1);
1443         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1444                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1445                         -1);
1446         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1447                         hf_samr_unknown_char, NULL);
1448         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1449                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1450                         -1);
1451         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1452                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1453                         -1);
1454         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1455                         hf_samr_unknown_char, NULL);
1456         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1457                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1458                         -1);
1459         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1460                         hf_samr_unknown_char, NULL);
1461         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1462                         samr_dissect_CRYPT_HASH, NDR_POINTER_UNIQUE,
1463                         -1);
1464
1465         return offset;
1466 }
1467
1468 static int
1469 samr_dissect_set_member_attributes_of_group_rqst(tvbuff_t *tvb, int offset, 
1470                              packet_info *pinfo, proto_tree *tree, 
1471                              char *drep)
1472 {
1473         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1474                                       hf_samr_hnd, NULL);
1475         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1476                                      hf_samr_attrib, NULL);
1477         return offset;
1478 }
1479
1480
1481 static int
1482 samr_dissect_GROUP_INFO_1 (tvbuff_t *tvb, int offset, 
1483                              packet_info *pinfo, proto_tree *tree,
1484                              char *drep)
1485 {
1486         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1487                 tree, drep,
1488                 hf_samr_acct_name);
1489         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1490                                      hf_samr_rid, NULL);
1491         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1492                                         hf_samr_attrib, NULL);
1493         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1494                 tree, drep,
1495                 hf_samr_acct_desc);
1496         return offset;
1497 }
1498
1499 static int
1500 samr_dissect_GROUP_INFO(tvbuff_t *tvb, int offset, 
1501                         packet_info *pinfo, proto_tree *parent_tree,
1502                         char *drep)
1503 {
1504         proto_item *item=NULL;
1505         proto_tree *tree=NULL;
1506         int old_offset=offset;
1507         guint16 level;
1508
1509         if(parent_tree){
1510                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1511                         "GroupInfo");
1512                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1513         }
1514
1515         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1516                                      hf_samr_level, &level);
1517         switch(level){
1518         case 1: 
1519                 offset = samr_dissect_GROUP_INFO_1(
1520                                 tvb, offset, pinfo, tree, drep);
1521                 break;
1522         case 2: 
1523                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1524                         tree, drep,
1525                         hf_samr_acct_name);
1526                 break;
1527         case 3:
1528                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1529                         hf_samr_attrib, NULL);
1530                 break;
1531         case 4: 
1532                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1533                         tree, drep,
1534                         hf_samr_acct_desc);
1535                 break;
1536         }
1537
1538         proto_item_set_len(item, offset-old_offset);
1539         return offset;
1540 }
1541
1542 static int
1543 samr_dissect_GROUP_INFO_ptr(tvbuff_t *tvb, int offset, 
1544                         packet_info *pinfo, proto_tree *tree,
1545                         char *drep)
1546 {
1547         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1548                         samr_dissect_GROUP_INFO, NDR_POINTER_UNIQUE,
1549                         -1);
1550         return offset;
1551 }
1552
1553 static int
1554 samr_dissect_query_information_group_rqst (tvbuff_t *tvb, int offset, 
1555                              packet_info *pinfo, proto_tree *tree,
1556                              char *drep)
1557 {
1558         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1559                                       hf_samr_hnd, NULL);
1560         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1561                                      hf_samr_level, NULL);
1562         return offset;
1563 }
1564
1565 static int
1566 samr_dissect_query_information_group_reply(tvbuff_t *tvb, int offset, 
1567                         packet_info *pinfo, proto_tree *tree,
1568                         char *drep)
1569 {
1570         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1571                         samr_dissect_GROUP_INFO_ptr, NDR_POINTER_REF,
1572                         -1);
1573         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1574                         hf_samr_rc, NULL);
1575         return offset;
1576 }
1577
1578 static int
1579 samr_dissect_set_information_group_rqst (tvbuff_t *tvb, int offset, 
1580                              packet_info *pinfo, proto_tree *tree,
1581                              char *drep)
1582 {
1583         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1584                                       hf_samr_hnd, NULL);
1585         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1586                                      hf_samr_level, NULL);
1587         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1588                         samr_dissect_GROUP_INFO, NDR_POINTER_REF,
1589                         -1);
1590         return offset;
1591 }
1592
1593
1594
1595 static int
1596 samr_dissect_get_domain_password_information_rqst (tvbuff_t *tvb, int offset, 
1597                              packet_info *pinfo, proto_tree *tree,
1598                              char *drep)
1599 {
1600         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1601                                       hf_samr_hnd, NULL);
1602
1603         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1604                         samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
1605                         hf_samr_domain);
1606         return offset;
1607 }
1608
1609
1610 static int
1611 samr_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset, 
1612                              packet_info *pinfo, proto_tree *parent_tree,
1613                              char *drep)
1614 {
1615         proto_item *item=NULL;
1616         proto_tree *tree=NULL;
1617         int old_offset=offset;
1618
1619         if(parent_tree){
1620                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1621                         "DomainInfo_1");
1622                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1623         }
1624
1625         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1626                                         hf_samr_min_pwd_len, NULL);
1627         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
1628                                         hf_samr_pwd_history_len, NULL);
1629         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1630                                         hf_samr_unknown_long, NULL);
1631         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1632                                         hf_samr_max_pwd_age);
1633         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1634                                         hf_samr_min_pwd_age);
1635         proto_item_set_len(item, offset-old_offset);
1636         return offset;
1637 }
1638
1639 static int
1640 samr_dissect_DOMAIN_INFO_2(tvbuff_t *tvb, int offset, 
1641                         packet_info *pinfo, proto_tree *parent_tree,
1642                         char *drep)
1643 {
1644         proto_item *item=NULL;
1645         proto_tree *tree=NULL;
1646         int old_offset=offset;
1647
1648         if(parent_tree){
1649                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1650                         "DomainInfo_2");
1651                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1652         }
1653
1654         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1655                         hf_samr_unknown_time);
1656         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1657                         hf_samr_unknown_string);
1658         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1659                         hf_samr_domain);
1660         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
1661                         hf_samr_controller);
1662         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1663                         hf_samr_unknown_time);
1664         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1665                         hf_samr_unknown_long, NULL);
1666         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1667                         hf_samr_unknown_long, NULL);
1668         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
1669                         hf_samr_unknown_char, NULL);
1670         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1671                         hf_samr_num_users, NULL);
1672         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1673                         hf_samr_num_groups, NULL);
1674         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1675                         hf_samr_num_aliases, NULL);
1676
1677         proto_item_set_len(item, offset-old_offset);
1678         return offset;
1679 }
1680
1681 static int
1682 samr_dissect_DOMAIN_INFO_8(tvbuff_t *tvb, int offset, 
1683                              packet_info *pinfo, proto_tree *parent_tree,
1684                              char *drep)
1685 {
1686         proto_item *item=NULL;
1687         proto_tree *tree=NULL;
1688         int old_offset=offset;
1689
1690         if(parent_tree){
1691                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1692                         "DomainInfo_8");
1693                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1694         }
1695
1696         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1697                                         hf_samr_max_pwd_age);
1698         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1699                                         hf_samr_min_pwd_age);
1700
1701         proto_item_set_len(item, offset-old_offset);
1702         return offset;
1703 }
1704
1705 static int
1706 samr_dissect_REPLICATION_STATUS(tvbuff_t *tvb, int offset, 
1707                         packet_info *pinfo, proto_tree *parent_tree,
1708                         char *drep)
1709 {
1710         proto_item *item=NULL;
1711         proto_tree *tree=NULL;
1712         int old_offset=offset;
1713
1714         if(parent_tree){
1715                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1716                         "Replication Status");
1717                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1718         }
1719
1720         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1721                         hf_samr_unknown_hyper, NULL);
1722         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
1723                         hf_samr_unknown_hyper, NULL);
1724         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1725                         hf_samr_unknown_short, NULL);
1726
1727         proto_item_set_len(item, offset-old_offset);
1728         return offset;
1729 }
1730
1731 static int
1732 samr_dissect_DOMAIN_INFO_11(tvbuff_t *tvb, int offset, 
1733                              packet_info *pinfo, proto_tree *parent_tree,
1734                              char *drep)
1735 {
1736         proto_item *item=NULL;
1737         proto_tree *tree=NULL;
1738         int old_offset=offset;
1739
1740         if(parent_tree){
1741                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1742                         "DomainInfo_11");
1743                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1744         }
1745
1746         offset = samr_dissect_DOMAIN_INFO_2(
1747                         tvb, offset, pinfo, tree, drep);
1748         offset = samr_dissect_REPLICATION_STATUS(
1749                         tvb, offset, pinfo, tree, drep);
1750
1751         proto_item_set_len(item, offset-old_offset);
1752         return offset;
1753 }
1754
1755 static int
1756 samr_dissect_DOMAIN_INFO_13(tvbuff_t *tvb, int offset, 
1757                              packet_info *pinfo, proto_tree *parent_tree,
1758                              char *drep)
1759 {
1760         proto_item *item=NULL;
1761         proto_tree *tree=NULL;
1762         int old_offset=offset;
1763
1764         if(parent_tree){
1765                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1766                         "DomainInfo_13");
1767                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1768         }
1769
1770         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1771                                         hf_samr_unknown_time);
1772         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1773                                         hf_samr_unknown_time);
1774         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1775                                         hf_samr_unknown_time);
1776
1777         proto_item_set_len(item, offset-old_offset);
1778         return offset;
1779 }
1780
1781
1782 static int
1783 samr_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset, 
1784                         packet_info *pinfo, proto_tree *parent_tree,
1785                         char *drep)
1786 {
1787         proto_item *item=NULL;
1788         proto_tree *tree=NULL;
1789         int old_offset=offset;
1790         guint16 level;
1791
1792         if(parent_tree){
1793                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1794                         "DomainInfo");
1795                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1796         }
1797
1798         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1799                                      hf_samr_level, &level);
1800         switch(level){
1801         case 1: 
1802                 offset = samr_dissect_DOMAIN_INFO_1(
1803                                 tvb, offset, pinfo, tree, drep);
1804                 break;
1805         case 2: 
1806                 offset = samr_dissect_DOMAIN_INFO_2(
1807                                 tvb, offset, pinfo, tree, drep);
1808                 break;
1809
1810         case 3:
1811                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
1812                                 hf_samr_unknown_time);
1813                 break;
1814         case 4:
1815                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1816                         tree, drep, hf_samr_unknown_string);
1817                 break;
1818
1819         case 5:
1820                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1821                         tree, drep, hf_samr_domain);
1822                 break;
1823
1824         case 6:
1825                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
1826                         tree, drep, hf_samr_controller);
1827                 break;
1828
1829         case 7:
1830                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1831                         hf_samr_unknown_short, NULL);
1832                 break;
1833         case 8: 
1834                 offset = samr_dissect_DOMAIN_INFO_8(
1835                                 tvb, offset, pinfo, tree, drep);
1836                 break;
1837         case 9:
1838                 offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1839                         hf_samr_unknown_short, NULL);
1840                 break;
1841         case 11:        
1842                 offset = samr_dissect_DOMAIN_INFO_11(
1843                                 tvb, offset, pinfo, tree, drep);
1844                 break;
1845         case 12:
1846                 offset = samr_dissect_REPLICATION_STATUS(
1847                                 tvb, offset, pinfo, tree, drep);
1848                 break;
1849         case 13:        
1850                 offset = samr_dissect_DOMAIN_INFO_13(
1851                                 tvb, offset, pinfo, tree, drep);
1852                 break;
1853         }
1854
1855         proto_item_set_len(item, offset-old_offset);
1856         return offset;
1857 }
1858
1859 static int
1860 samr_dissect_DOMAIN_INFO_ptr(tvbuff_t *tvb, int offset, 
1861                         packet_info *pinfo, proto_tree *tree,
1862                         char *drep)
1863 {
1864         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1865                         samr_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
1866                         hf_samr_domain);
1867         return offset;
1868 }
1869
1870 static int
1871 samr_dissect_query_information_domain_reply(tvbuff_t *tvb, int offset, 
1872                         packet_info *pinfo, proto_tree *tree,
1873                         char *drep)
1874 {
1875         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1876                         samr_dissect_DOMAIN_INFO_ptr, NDR_POINTER_REF,
1877                         hf_samr_domain);
1878         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1879                                      hf_samr_rc, NULL);
1880         return offset;
1881 }
1882
1883
1884 static int
1885 samr_dissect_set_information_domain_rqst(tvbuff_t *tvb, int offset, 
1886                              packet_info *pinfo, proto_tree *tree,
1887                              char *drep)
1888 {
1889         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
1890                                       hf_samr_hnd, NULL);
1891         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
1892                                      hf_samr_level, NULL);
1893         offset = samr_dissect_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
1894         return offset;
1895 }
1896
1897
1898
1899 static int
1900 samr_dissect_lookup_domain_reply(tvbuff_t *tvb, int offset, 
1901                              packet_info *pinfo, proto_tree *tree,
1902                              char *drep)
1903 {
1904         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1905                         samr_dissect_SID_ptr, NDR_POINTER_REF,
1906                         -1);
1907         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1908                                      hf_samr_rc, NULL);
1909         return offset;
1910 }
1911
1912 static int
1913 samr_dissect_PSID(tvbuff_t *tvb, int offset, 
1914                              packet_info *pinfo, proto_tree *parent_tree,
1915                              char *drep)
1916 {
1917         proto_item *item=NULL;
1918         proto_tree *tree=NULL;
1919         int old_offset=offset;
1920
1921         if(parent_tree){
1922                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1923                         "SID");
1924                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1925         }
1926
1927         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1928                         samr_dissect_SID, NDR_POINTER_UNIQUE,
1929                         -1);
1930
1931         proto_item_set_len(item, offset-old_offset);
1932         return offset;
1933 }
1934
1935
1936 static int
1937 samr_dissect_PSID_ARRAY_sids (tvbuff_t *tvb, int offset, 
1938                              packet_info *pinfo, proto_tree *tree,
1939                              char *drep)
1940 {
1941         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
1942                         samr_dissect_PSID);
1943
1944         return offset;
1945 }
1946
1947
1948 static int
1949 samr_dissect_PSID_ARRAY(tvbuff_t *tvb, int offset, 
1950                         packet_info *pinfo, proto_tree *parent_tree,
1951                         char *drep)
1952 {
1953         guint32 count;
1954         proto_item *item=NULL;
1955         proto_tree *tree=NULL;
1956         int old_offset=offset;
1957
1958         if(parent_tree){
1959                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1960                         "SID Array");
1961                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1962         }
1963
1964         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
1965                         hf_samr_count, &count);
1966         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1967                         samr_dissect_PSID_ARRAY_sids, NDR_POINTER_UNIQUE,
1968                         -1);
1969
1970         proto_item_set_len(item, offset-old_offset);
1971         return offset;
1972 }
1973
1974 static int
1975 samr_dissect_pindex(tvbuff_t *tvb, int offset, 
1976                              packet_info *pinfo, proto_tree *parent_tree,
1977                              char *drep)
1978 {
1979         proto_item *item=NULL;
1980         proto_tree *tree=NULL;
1981         int old_offset=offset;
1982         dcerpc_info *di;
1983
1984         di=pinfo->private_data;
1985
1986         if(parent_tree){
1987                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
1988                         "SID");
1989                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
1990         }
1991
1992         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
1993                         samr_dissect_pointer_long, NDR_POINTER_UNIQUE,
1994                         di->hf_index);
1995
1996         proto_item_set_len(item, offset-old_offset);
1997         return offset;
1998 }
1999
2000
2001 static int
2002 samr_dissect_INDEX_ARRAY_value (tvbuff_t *tvb, int offset, 
2003                              packet_info *pinfo, proto_tree *tree,
2004                              char *drep)
2005 {
2006         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2007                         samr_dissect_pindex);
2008
2009         return offset;
2010 }
2011
2012
2013 static int
2014 samr_dissect_INDEX_ARRAY(tvbuff_t *tvb, int offset, 
2015                         packet_info *pinfo, proto_tree *parent_tree,
2016                         char *drep)
2017 {
2018         guint32 count;
2019         proto_item *item=NULL;
2020         proto_tree *tree=NULL;
2021         int old_offset=offset;
2022         dcerpc_info *di;
2023
2024         di=pinfo->private_data;
2025
2026         if(parent_tree){
2027                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2028                         "Index Array");
2029                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2030         }
2031
2032         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2033                         hf_samr_count, &count);
2034         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2035                         samr_dissect_INDEX_ARRAY_value, NDR_POINTER_UNIQUE,
2036                         di->hf_index);
2037
2038         proto_item_set_len(item, offset-old_offset);
2039         return offset;
2040 }
2041
2042
2043 static int
2044 samr_dissect_get_alias_membership_rqst(tvbuff_t *tvb, int offset, 
2045                              packet_info *pinfo, proto_tree *tree,
2046                              char *drep)
2047 {
2048         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2049                                       hf_samr_hnd, NULL);
2050         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2051                         samr_dissect_PSID_ARRAY, NDR_POINTER_REF,
2052                         -1);
2053         return offset;
2054 }
2055
2056 static int
2057 samr_dissect_get_alias_membership_reply(tvbuff_t *tvb, int offset, 
2058                              packet_info *pinfo, proto_tree *tree,
2059                              char *drep)
2060 {
2061         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2062                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
2063                         hf_samr_alias);
2064         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2065                         hf_samr_rc, NULL);
2066         return offset;
2067 }
2068
2069
2070 static int
2071 samr_dissect_IDX_AND_NAME(tvbuff_t *tvb, int offset, 
2072                              packet_info *pinfo, proto_tree *parent_tree,
2073                              char *drep)
2074 {
2075         proto_item *item=NULL;
2076         proto_tree *tree=NULL;
2077         int old_offset=offset;
2078         dcerpc_info *di;
2079
2080         di=pinfo->private_data;
2081
2082         if(parent_tree){
2083                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2084                         "IDX_AND_NAME");
2085                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2086         }
2087
2088         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2089                         hf_samr_index, NULL);
2090         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, 
2091                         tree, drep, di->hf_index);
2092
2093         proto_item_set_len(item, offset-old_offset);
2094         return offset;
2095 }
2096
2097 static int
2098 samr_dissect_IDX_AND_NAME_entry (tvbuff_t *tvb, int offset, 
2099                              packet_info *pinfo, proto_tree *tree,
2100                              char *drep)
2101 {
2102         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2103                         samr_dissect_IDX_AND_NAME);
2104
2105         return offset;
2106 }
2107
2108
2109 static int
2110 samr_dissect_IDX_AND_NAME_ARRAY(tvbuff_t *tvb, int offset, 
2111                         packet_info *pinfo, proto_tree *parent_tree,
2112                         char *drep)
2113 {
2114         guint32 count;
2115         proto_item *item=NULL;
2116         proto_tree *tree=NULL;
2117         int old_offset=offset;
2118         dcerpc_info *di;
2119
2120         di=pinfo->private_data;
2121
2122         if(parent_tree){
2123                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2124                         "IDX_AND_NAME Array");
2125                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2126         }
2127
2128         
2129         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2130                         hf_samr_count, &count);
2131         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2132                         samr_dissect_IDX_AND_NAME_entry, NDR_POINTER_UNIQUE,
2133                         di->hf_index);
2134
2135         proto_item_set_len(item, offset-old_offset);
2136         return offset;
2137 }
2138
2139 static int
2140 samr_dissect_IDX_AND_NAME_ARRAY_ptr(tvbuff_t *tvb, int offset, 
2141                         packet_info *pinfo, proto_tree *tree,
2142                         char *drep)
2143 {
2144         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2145                         samr_dissect_IDX_AND_NAME_ARRAY, NDR_POINTER_UNIQUE,
2146                         hf_samr_domain);
2147         return offset;
2148 }
2149
2150 static int
2151 samr_dissect_enum_domains_rqst(tvbuff_t *tvb, int offset, 
2152                              packet_info *pinfo, proto_tree *tree,
2153                              char *drep)
2154 {
2155         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2156                         hf_samr_hnd, NULL);
2157         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2158                         samr_dissect_pointer_long, NDR_POINTER_REF,
2159                         hf_samr_resume_hnd);
2160         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2161                         hf_samr_pref_maxsize, NULL);
2162         return offset;
2163 }
2164
2165 static int
2166 samr_dissect_enum_domains_reply(tvbuff_t *tvb, int offset, 
2167                              packet_info *pinfo, proto_tree *tree,
2168                              char *drep)
2169 {
2170         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2171                         samr_dissect_pointer_long, NDR_POINTER_REF,
2172                         hf_samr_resume_hnd);
2173         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2174                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2175                         hf_samr_domain);
2176         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2177                         samr_dissect_pointer_long, NDR_POINTER_REF,
2178                         hf_samr_entries);
2179         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2180                                      hf_samr_rc, NULL);
2181         return offset;
2182 }
2183
2184 static int
2185 samr_dissect_enum_dom_groups_rqst(tvbuff_t *tvb, int offset, 
2186                              packet_info *pinfo, proto_tree *tree,
2187                              char *drep)
2188 {
2189         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2190                         hf_samr_hnd, NULL);
2191         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2192                         samr_dissect_pointer_long, NDR_POINTER_REF,
2193                         hf_samr_resume_hnd);
2194         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2195                         hf_samr_mask, NULL);
2196         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2197                         hf_samr_pref_maxsize, NULL);
2198         return offset;
2199 }
2200
2201 static int
2202 samr_dissect_enum_dom_groups_reply(tvbuff_t *tvb, int offset, 
2203                              packet_info *pinfo, proto_tree *tree,
2204                              char *drep)
2205 {
2206         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2207                         samr_dissect_pointer_long, NDR_POINTER_REF,
2208                         hf_samr_resume_hnd);
2209         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2210                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2211                         hf_samr_group);
2212         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2213                         samr_dissect_pointer_long, NDR_POINTER_REF,
2214                         hf_samr_entries);
2215         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2216                         hf_samr_rc, NULL);
2217         return offset;
2218 }
2219
2220 static int
2221 samr_dissect_enum_dom_alias_reply(tvbuff_t *tvb, int offset, 
2222                              packet_info *pinfo, proto_tree *tree,
2223                              char *drep)
2224 {
2225         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2226                         samr_dissect_pointer_long, NDR_POINTER_REF,
2227                         hf_samr_resume_hnd);
2228         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2229                         samr_dissect_IDX_AND_NAME_ARRAY_ptr, NDR_POINTER_REF,
2230                         hf_samr_alias);
2231         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2232                         samr_dissect_pointer_long, NDR_POINTER_REF,
2233                         hf_samr_entries);
2234         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2235                         hf_samr_rc, NULL);
2236         return offset;
2237 }
2238
2239 static int
2240 samr_dissect_get_members_in_alias_reply(tvbuff_t *tvb, int offset, 
2241                         packet_info *pinfo, proto_tree *tree,
2242                         char *drep)
2243 {
2244         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2245                         samr_dissect_PSID_ARRAY, NDR_POINTER_REF,
2246                         -1);
2247         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2248                         hf_samr_rc, NULL);
2249
2250         return offset;
2251 }
2252
2253 static int
2254 samr_dissect_LOGON_HOURS_entry(tvbuff_t *tvb, int offset, 
2255                              packet_info *pinfo, proto_tree *tree,
2256                              char *drep)
2257 {
2258         offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
2259                         hf_samr_unknown_char, NULL);
2260         return offset;
2261 }
2262
2263 static int
2264 samr_dissect_LOGON_HOURS_hours(tvbuff_t *tvb, int offset, 
2265                              packet_info *pinfo, proto_tree *parent_tree,
2266                              char *drep)
2267 {
2268         proto_item *item=NULL;
2269         proto_tree *tree=NULL;
2270         int old_offset=offset;
2271
2272         if(parent_tree){
2273                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2274                         "LOGON_HOURS");
2275                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2276         }
2277
2278         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
2279                         samr_dissect_LOGON_HOURS_entry);
2280
2281         proto_item_set_len(item, offset-old_offset);
2282         return offset;
2283
2284         return offset;
2285 }
2286
2287 static int
2288 samr_dissect_LOGON_HOURS(tvbuff_t *tvb, int offset, 
2289                         packet_info *pinfo, proto_tree *parent_tree,
2290                         char *drep)
2291 {
2292         proto_item *item=NULL;
2293         proto_tree *tree=NULL;
2294         int old_offset=offset;
2295
2296         if(parent_tree){
2297                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2298                         "LOGON_HOURS");
2299                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2300         }
2301
2302         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2303                                 hf_samr_divisions, NULL);
2304         /* XXX - is this a bitmask like the "logon hours" field in the
2305            Remote API call "NetUserGetInfo()" with an information level
2306            of 11? */
2307         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2308                         samr_dissect_LOGON_HOURS_hours, NDR_POINTER_UNIQUE,
2309                         -1);
2310
2311         proto_item_set_len(item, offset-old_offset);
2312         return offset;
2313 }
2314
2315
2316 static int
2317 samr_dissect_USER_INFO_1(tvbuff_t *tvb, int offset, 
2318                         packet_info *pinfo, proto_tree *parent_tree,
2319                         char *drep)
2320 {
2321         proto_item *item=NULL;
2322         proto_tree *tree=NULL;
2323         int old_offset=offset;
2324
2325         if(parent_tree){
2326                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2327                         "UserInfo_1");
2328                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2329         }
2330
2331         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2332                                 hf_samr_acct_name);
2333         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2334                                 hf_samr_full_name);
2335         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2336                                 hf_samr_acct_ctrl, NULL);
2337         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2338                                 hf_samr_home);
2339         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2340                                 hf_samr_script);
2341
2342         proto_item_set_len(item, offset-old_offset);
2343         return offset;
2344 }
2345
2346 static int
2347 samr_dissect_USER_INFO_2(tvbuff_t *tvb, int offset, 
2348                         packet_info *pinfo, proto_tree *parent_tree,
2349                         char *drep)
2350 {
2351         proto_item *item=NULL;
2352         proto_tree *tree=NULL;
2353         int old_offset=offset;
2354
2355         if(parent_tree){
2356                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2357                         "UserInfo_2");
2358                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2359         }
2360
2361         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2362                                 hf_samr_acct_name);
2363         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2364                                 hf_samr_full_name);
2365         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2366                                 hf_samr_bad_pwd_count, NULL);
2367         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2368                                 hf_samr_logon_count, NULL);
2369
2370         proto_item_set_len(item, offset-old_offset);
2371         return offset;
2372 }
2373
2374 static int
2375 samr_dissect_USER_INFO_3(tvbuff_t *tvb, int offset, 
2376                         packet_info *pinfo, proto_tree *parent_tree,
2377                         char *drep)
2378 {
2379         proto_item *item=NULL;
2380         proto_tree *tree=NULL;
2381         int old_offset=offset;
2382
2383         if(parent_tree){
2384                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2385                         "UserInfo_3");
2386                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2387         }
2388
2389         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2390                                 hf_samr_acct_name);
2391         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2392                                 hf_samr_full_name);
2393         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2394                                 hf_samr_rid, NULL);
2395         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2396                                 hf_samr_group, NULL);
2397         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2398                                 hf_samr_home);
2399         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2400                                 hf_samr_home_drive);
2401         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2402                                 hf_samr_script);
2403         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2404                                 hf_samr_acct_desc);
2405         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2406                                 hf_samr_workstations);
2407         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2408                                 hf_samr_logon_time);
2409         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2410                                 hf_samr_logoff_time);
2411         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2412                                 hf_samr_pwd_last_set_time);
2413         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2414                                 hf_samr_pwd_can_change_time);
2415         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2416                                 hf_samr_pwd_must_change_time);
2417         offset = samr_dissect_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2418         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2419                                 hf_samr_logon_count, NULL);
2420         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2421                                 hf_samr_bad_pwd_count, NULL);
2422         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2423                                 hf_samr_acct_ctrl, NULL);
2424
2425         proto_item_set_len(item, offset-old_offset);
2426         return offset;
2427 }
2428
2429 static int
2430 samr_dissect_USER_INFO_5(tvbuff_t *tvb, int offset, 
2431                         packet_info *pinfo, proto_tree *parent_tree,
2432                         char *drep)
2433 {
2434         proto_item *item=NULL;
2435         proto_tree *tree=NULL;
2436         int old_offset=offset;
2437
2438         if(parent_tree){
2439                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2440                         "UserInfo_5");
2441                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2442         }
2443
2444         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2445                                 hf_samr_acct_name);
2446         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2447                                 hf_samr_full_name);
2448         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2449                                 hf_samr_rid, NULL);
2450         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2451                                 hf_samr_group, NULL);
2452         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2453                                 hf_samr_country, NULL);
2454         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2455                                 hf_samr_codepage, NULL);
2456         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2457                                 hf_samr_home);
2458         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2459                                 hf_samr_home_drive);
2460         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2461                                 hf_samr_script);
2462         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2463                                 hf_samr_acct_desc);
2464         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2465                                 hf_samr_workstations);
2466         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2467                                 hf_samr_logon_time);
2468         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2469                                 hf_samr_logoff_time);
2470         offset = samr_dissect_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2471         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2472                                 hf_samr_bad_pwd_count, NULL);
2473         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2474                                 hf_samr_logon_count, NULL);
2475         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2476                                 hf_samr_pwd_last_set_time);
2477         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2478                                 hf_samr_acct_expiry_time);
2479         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2480                                 hf_samr_acct_ctrl, NULL);
2481
2482         proto_item_set_len(item, offset-old_offset);
2483         return offset;
2484 }
2485
2486 static int
2487 samr_dissect_USER_INFO_6(tvbuff_t *tvb, int offset, 
2488                         packet_info *pinfo, proto_tree *parent_tree,
2489                         char *drep)
2490 {
2491         proto_item *item=NULL;
2492         proto_tree *tree=NULL;
2493         int old_offset=offset;
2494
2495         if(parent_tree){
2496                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2497                         "UserInfo_6");
2498                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2499         }
2500
2501         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2502                                 hf_samr_acct_name);
2503         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2504                                 hf_samr_full_name);
2505
2506         proto_item_set_len(item, offset-old_offset);
2507         return offset;
2508 }
2509
2510 static int
2511 samr_dissect_USER_INFO_18(tvbuff_t *tvb, int offset, 
2512                         packet_info *pinfo, proto_tree *parent_tree,
2513                         char *drep)
2514 {
2515         proto_item *item=NULL;
2516         proto_tree *tree=NULL;
2517         int old_offset=offset;
2518
2519         if(parent_tree){
2520                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2521                         "UserInfo_18");
2522                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2523         }
2524
2525         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2526         offset = samr_dissect_CRYPT_HASH(tvb, offset, pinfo, tree, drep);
2527         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2528                         hf_samr_unknown_char, NULL);
2529         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2530                         hf_samr_unknown_char, NULL);
2531         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2532                         hf_samr_unknown_char, NULL);
2533
2534         proto_item_set_len(item, offset-old_offset);
2535         return offset;
2536 }
2537
2538 static int
2539 samr_dissect_USER_INFO_19(tvbuff_t *tvb, int offset, 
2540                         packet_info *pinfo, proto_tree *parent_tree,
2541                         char *drep)
2542 {
2543         proto_item *item=NULL;
2544         proto_tree *tree=NULL;
2545         int old_offset=offset;
2546
2547         if(parent_tree){
2548                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2549                         "UserInfo_19");
2550                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2551         }
2552
2553         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2554                                 hf_samr_acct_ctrl, NULL);
2555         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2556                                 hf_samr_logon_time);
2557         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2558                                 hf_samr_logoff_time);
2559         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2560                                 hf_samr_bad_pwd_count, NULL);
2561         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2562                                 hf_samr_logon_count, NULL);
2563
2564         proto_item_set_len(item, offset-old_offset);
2565         return offset;
2566 }
2567
2568 static int
2569 samr_dissect_BUFFER_entry(tvbuff_t *tvb, int offset, 
2570                              packet_info *pinfo, proto_tree *tree,
2571                              char *drep)
2572 {
2573         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2574                         hf_samr_unknown_char, NULL);
2575         return offset;
2576 }
2577
2578
2579 static int
2580 samr_dissect_BUFFER_buffer(tvbuff_t *tvb, int offset, 
2581                              packet_info *pinfo, proto_tree *parent_tree,
2582                              char *drep)
2583 {
2584         proto_item *item=NULL;
2585         proto_tree *tree=NULL;
2586         int old_offset=offset;
2587
2588         if(parent_tree){
2589                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2590                         "BUFFER");
2591                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2592         }
2593
2594         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2595                         samr_dissect_BUFFER_entry);
2596
2597         proto_item_set_len(item, offset-old_offset);
2598         return offset;
2599
2600         return offset;
2601 }
2602
2603 static int
2604 samr_dissect_BUFFER(tvbuff_t *tvb, int offset, 
2605                         packet_info *pinfo, proto_tree *parent_tree,
2606                         char *drep)
2607 {
2608         proto_item *item=NULL;
2609         proto_tree *tree=NULL;
2610         int old_offset=offset;
2611
2612         if(parent_tree){
2613                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2614                         "BUFFER");
2615                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2616         }
2617         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2618                                 hf_samr_count, NULL);
2619         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2620                         samr_dissect_BUFFER_buffer, NDR_POINTER_UNIQUE,
2621                         -1);
2622
2623         proto_item_set_len(item, offset-old_offset);
2624         return offset;
2625 }
2626
2627 static int
2628 samr_dissect_BUFFER_ptr(tvbuff_t *tvb, int offset, 
2629                         packet_info *pinfo, proto_tree *tree,
2630                         char *drep)
2631 {
2632         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2633                         samr_dissect_BUFFER, NDR_POINTER_UNIQUE,
2634                         -1);
2635         return offset;
2636 }
2637
2638 static int
2639 samr_dissect_USER_INFO_21(tvbuff_t *tvb, int offset, 
2640                         packet_info *pinfo, proto_tree *parent_tree,
2641                         char *drep)
2642 {
2643         proto_item *item=NULL;
2644         proto_tree *tree=NULL;
2645         int old_offset=offset;
2646
2647         if(parent_tree){
2648                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2649                         "UserInfo_21");
2650                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2651         }
2652
2653         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2654                                 hf_samr_logon_time);
2655         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2656                                 hf_samr_logoff_time);
2657         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2658                                 hf_samr_kickoff_time);
2659         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2660                                 hf_samr_pwd_last_set_time);
2661         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2662                                 hf_samr_pwd_can_change_time);
2663         offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2664                                 hf_samr_pwd_must_change_time);
2665         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2666                                 hf_samr_acct_name);
2667         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2668                                 hf_samr_full_name);
2669         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2670                                 hf_samr_home);
2671         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2672                                 hf_samr_home_drive);
2673         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2674                                 hf_samr_script);
2675         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2676                                 hf_samr_profile);
2677         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2678                                 hf_samr_acct_desc);
2679         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2680                                 hf_samr_workstations);
2681         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2682                                 hf_samr_comment);
2683         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2684                                 hf_samr_parameters);
2685         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2686                                 hf_samr_unknown_string);
2687         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2688                                 hf_samr_unknown_string);
2689         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2690                                 hf_samr_unknown_string);
2691         offset = samr_dissect_BUFFER(tvb, offset, pinfo, tree, drep);
2692         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2693                                 hf_samr_rid, NULL);
2694         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2695                                 hf_samr_group, NULL);
2696         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2697                                 hf_samr_acct_ctrl, NULL);
2698         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2699                                 hf_samr_unknown_long, NULL);
2700         offset = samr_dissect_LOGON_HOURS(tvb, offset, pinfo, tree, drep);
2701         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2702                                 hf_samr_bad_pwd_count, NULL);
2703         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2704                                 hf_samr_logon_count, NULL);
2705         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2706                                 hf_samr_country, NULL);
2707         offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
2708                                 hf_samr_codepage, NULL);
2709         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2710                                 hf_samr_nt_pwd_set, NULL);
2711         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2712                                 hf_samr_lm_pwd_set, NULL);
2713         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2714                                 hf_samr_pwd_expired, NULL);
2715         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2716                                 hf_samr_unknown_char, NULL);
2717
2718         proto_item_set_len(item, offset-old_offset);
2719         return offset;
2720 }
2721
2722 static int
2723 samr_dissect_USER_INFO_22(tvbuff_t *tvb, int offset, 
2724                         packet_info *pinfo, proto_tree *parent_tree,
2725                         char *drep)
2726 {
2727         proto_item *item=NULL;
2728         proto_tree *tree=NULL;
2729         int old_offset=offset;
2730
2731         if(parent_tree){
2732                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2733                         "UserInfo_22");
2734                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2735         }
2736
2737         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
2738         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
2739                         hf_samr_revision, NULL);
2740
2741         proto_item_set_len(item, offset-old_offset);
2742         return offset;
2743 }
2744
2745 static int
2746 samr_dissect_USER_INFO_23(tvbuff_t *tvb, int offset, 
2747                         packet_info *pinfo, proto_tree *parent_tree,
2748                         char *drep)
2749 {
2750         proto_item *item=NULL;
2751         proto_tree *tree=NULL;
2752         int old_offset=offset;
2753
2754         if(parent_tree){
2755                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2756                         "UserInfo_23");
2757                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2758         }
2759
2760         offset = samr_dissect_USER_INFO_21(tvb, offset, pinfo, tree, drep);
2761         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
2762
2763         proto_item_set_len(item, offset-old_offset);
2764         return offset;
2765 }
2766
2767 static int
2768 samr_dissect_USER_INFO_24(tvbuff_t *tvb, int offset, 
2769                         packet_info *pinfo, proto_tree *parent_tree,
2770                         char *drep)
2771 {
2772         proto_item *item=NULL;
2773         proto_tree *tree=NULL;
2774         int old_offset=offset;
2775
2776         if(parent_tree){
2777                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2778                         "UserInfo_24");
2779                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2780         }
2781
2782         offset = samr_dissect_CRYPT_PASSWORD(tvb, offset, pinfo, tree, drep);
2783         offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
2784                                 hf_samr_unknown_char, NULL);
2785
2786         proto_item_set_len(item, offset-old_offset);
2787         return offset;
2788 }
2789
2790 static int
2791 samr_dissect_USER_INFO (tvbuff_t *tvb, int offset, 
2792                              packet_info *pinfo, proto_tree *parent_tree,
2793                              char *drep)
2794 {
2795         proto_item *item=NULL;
2796         proto_tree *tree=NULL;
2797         int old_offset=offset;
2798         guint16 level;
2799
2800         if(parent_tree){
2801                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2802                         "UserInfo");
2803                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2804         }
2805         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2806                                      hf_samr_level, &level);
2807
2808         switch(level){
2809         case 1: 
2810                 offset = samr_dissect_USER_INFO_1(
2811                                 tvb, offset, pinfo, tree, drep);
2812                 break;
2813         case 2: 
2814                 offset = samr_dissect_USER_INFO_2(
2815                                 tvb, offset, pinfo, tree, drep);
2816                 break;
2817         case 3: 
2818                 offset = samr_dissect_USER_INFO_3(
2819                                 tvb, offset, pinfo, tree, drep);
2820                 break;
2821         case 4: 
2822                 offset = samr_dissect_LOGON_HOURS(
2823                                 tvb, offset, pinfo, tree, drep);
2824                 break;
2825         case 5: 
2826                 offset = samr_dissect_USER_INFO_5(
2827                                 tvb, offset, pinfo, tree, drep);
2828                 break;
2829         case 6: 
2830                 offset = samr_dissect_USER_INFO_6(
2831                                 tvb, offset, pinfo, tree, drep);
2832                 break;
2833         case 7:
2834                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2835                                 hf_samr_full_name);
2836                 break;
2837         case 8:
2838                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2839                                 hf_samr_acct_desc);
2840                 break;
2841         case 9:
2842                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2843                                              hf_samr_unknown_long, NULL);
2844                 break;
2845         case 10:        
2846                 offset = samr_dissect_USER_INFO_6(
2847                                 tvb, offset, pinfo, tree, drep);
2848                 break;
2849         case 11:
2850                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2851                                 hf_samr_home);
2852                 break;
2853         case 12:
2854                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2855                                 hf_samr_home_drive);
2856                 break;
2857         case 13:
2858                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2859                                 hf_samr_script);
2860                 break;
2861         case 14:
2862                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2863                                 hf_samr_workstations);
2864                 break;
2865         case 16:
2866                 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
2867                                              hf_samr_unknown_long, NULL);
2868                 break;
2869         case 17:
2870                 offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
2871                                         hf_samr_unknown_time);
2872                 break;
2873         case 18:        
2874                 offset = samr_dissect_USER_INFO_18(
2875                                 tvb, offset, pinfo, tree, drep);
2876                 break;
2877         case 19:        
2878                 offset = samr_dissect_USER_INFO_19(
2879                                 tvb, offset, pinfo, tree, drep);
2880                 break;
2881         case 20:
2882                 offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
2883                                 hf_samr_profile);
2884                 break;
2885         case 21:        
2886                 offset = samr_dissect_USER_INFO_21(
2887                                 tvb, offset, pinfo, tree, drep);
2888                 break;
2889         case 22:        
2890                 offset = samr_dissect_USER_INFO_22(
2891                                 tvb, offset, pinfo, tree, drep);
2892                 break;
2893         case 23:        
2894                 offset = samr_dissect_USER_INFO_23(
2895                                 tvb, offset, pinfo, tree, drep);
2896                 break;
2897         case 24:        
2898                 offset = samr_dissect_USER_INFO_24(
2899                                 tvb, offset, pinfo, tree, drep);
2900                 break;
2901         }
2902
2903         proto_item_set_len(item, offset-old_offset);
2904         return offset;
2905 }
2906
2907 static int
2908 samr_dissect_USER_INFO_ptr(tvbuff_t *tvb, int offset, 
2909                         packet_info *pinfo, proto_tree *tree,
2910                         char *drep)
2911 {
2912         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2913                         samr_dissect_USER_INFO, NDR_POINTER_UNIQUE,
2914                         -1);
2915         return offset;
2916 }
2917
2918 static int
2919 samr_dissect_set_information_user2_rqst(tvbuff_t *tvb, int offset, 
2920                         packet_info *pinfo, proto_tree *tree,
2921                         char *drep)
2922 {
2923         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
2924                         hf_samr_hnd, NULL);
2925         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
2926                         hf_samr_level, NULL);
2927         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2928                         samr_dissect_USER_INFO, NDR_POINTER_REF,
2929                         -1);
2930
2931         return offset;
2932 }
2933
2934 static int
2935 samr_dissect_query_userinfo_reply(tvbuff_t *tvb, int offset, 
2936                         packet_info *pinfo, proto_tree *tree,
2937                         char *drep)
2938 {
2939         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
2940                         samr_dissect_USER_INFO_ptr, NDR_POINTER_REF,
2941                         -1);
2942         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2943                         hf_samr_rc, NULL);
2944
2945         return offset;
2946 }
2947
2948 static int
2949 samr_dissect_MEMBER_ARRAY_type(tvbuff_t *tvb, int offset, 
2950                         packet_info *pinfo, proto_tree *tree,
2951                         char *drep)
2952 {
2953         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2954                                 hf_samr_type, NULL);
2955
2956         return offset;
2957 }
2958
2959
2960 static int
2961 samr_dissect_MEMBER_ARRAY_types(tvbuff_t *tvb, int offset, 
2962                         packet_info *pinfo, proto_tree *parent_tree,
2963                         char *drep)
2964 {
2965         proto_item *item=NULL;
2966         proto_tree *tree=NULL;
2967         int old_offset=offset;
2968
2969         if(parent_tree){
2970                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
2971                         "Types");
2972                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
2973         }
2974
2975         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
2976                         samr_dissect_MEMBER_ARRAY_type);
2977
2978         proto_item_set_len(item, offset-old_offset);
2979         return offset;
2980
2981         return offset;
2982 }
2983
2984 static int
2985 samr_dissect_MEMBER_ARRAY_rid(tvbuff_t *tvb, int offset, 
2986                         packet_info *pinfo, proto_tree *tree,
2987                         char *drep)
2988 {
2989         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
2990                                 hf_samr_rid, NULL);
2991
2992         return offset;
2993 }
2994
2995
2996 static int
2997 samr_dissect_MEMBER_ARRAY_rids(tvbuff_t *tvb, int offset, 
2998                         packet_info *pinfo, proto_tree *parent_tree,
2999                         char *drep)
3000 {
3001         proto_item *item=NULL;
3002         proto_tree *tree=NULL;
3003         int old_offset=offset;
3004
3005         if(parent_tree){
3006                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
3007                         "RIDs");
3008                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
3009         }
3010
3011         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3012                         samr_dissect_MEMBER_ARRAY_rid);
3013
3014         proto_item_set_len(item, offset-old_offset);
3015         return offset;
3016
3017         return offset;
3018 }
3019
3020 static int
3021 samr_dissect_MEMBER_ARRAY(tvbuff_t *tvb, int offset, 
3022                         packet_info *pinfo, proto_tree *parent_tree,
3023                         char *drep)
3024 {
3025         guint32 count;
3026         proto_item *item=NULL;
3027         proto_tree *tree=NULL;
3028         int old_offset=offset;
3029
3030         if(parent_tree){
3031                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
3032                         "Member Array");
3033                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
3034         }
3035
3036         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3037                         hf_samr_count, &count);
3038         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3039                         samr_dissect_MEMBER_ARRAY_rids, NDR_POINTER_UNIQUE,
3040                         -1);
3041         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3042                         samr_dissect_MEMBER_ARRAY_types, NDR_POINTER_UNIQUE,
3043                         -1);
3044
3045         proto_item_set_len(item, offset-old_offset);
3046         return offset;
3047 }
3048
3049 static int
3050 samr_dissect_MEMBER_ARRAY_ptr(tvbuff_t *tvb, int offset, 
3051                         packet_info *pinfo, proto_tree *tree,
3052                         char *drep)
3053 {
3054         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3055                         samr_dissect_MEMBER_ARRAY, NDR_POINTER_UNIQUE,
3056                         -1);
3057         return offset;
3058 }
3059
3060 static int
3061 samr_dissect_query_groupmem_reply(tvbuff_t *tvb, int offset, 
3062                         packet_info *pinfo, proto_tree *tree,
3063                         char *drep)
3064 {
3065         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3066                         samr_dissect_MEMBER_ARRAY_ptr, NDR_POINTER_REF,
3067                         -1);
3068         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3069                         hf_samr_rc, NULL);
3070
3071         return offset;
3072 }
3073
3074 static int
3075 samr_dissect_set_sec_object_rqst(tvbuff_t *tvb, int offset, 
3076                         packet_info *pinfo, proto_tree *tree,
3077                         char *drep)
3078 {
3079         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3080                         hf_samr_hnd, NULL);
3081         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3082                         hf_samr_info_type, NULL);
3083         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3084                         samr_dissect_BUFFER, NDR_POINTER_REF,
3085                         -1);
3086
3087         return offset;
3088 }
3089
3090 static int
3091 samr_dissect_query_sec_object_rqst(tvbuff_t *tvb, int offset, 
3092                         packet_info *pinfo, proto_tree *tree,
3093                         char *drep)
3094 {
3095         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3096                         hf_samr_hnd, NULL);
3097         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
3098                         hf_samr_info_type, NULL);
3099
3100         return offset;
3101 }
3102
3103 static int
3104 samr_dissect_query_sec_object_reply(tvbuff_t *tvb, int offset, 
3105                         packet_info *pinfo, proto_tree *tree,
3106                         char *drep)
3107 {
3108         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3109                         samr_dissect_BUFFER_ptr, NDR_POINTER_REF,
3110                         -1);
3111         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3112                         hf_samr_rc, NULL);
3113
3114
3115         return offset;
3116 }
3117
3118 static int
3119 samr_dissect_LOOKUP_NAMES_name(tvbuff_t *tvb, int offset, 
3120                         packet_info *pinfo, proto_tree *tree,
3121                         char *drep)
3122 {
3123         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3124                                 hf_samr_acct_name);
3125         return offset;
3126 }
3127
3128 static int
3129 samr_dissect_LOOKUP_NAMES(tvbuff_t *tvb, int offset, 
3130                         packet_info *pinfo, proto_tree *parent_tree,
3131                         char *drep)
3132 {
3133         proto_item *item=NULL;
3134         proto_tree *tree=NULL;
3135         int old_offset=offset;
3136
3137         if(parent_tree){
3138                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
3139                         "Names");
3140                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
3141         }
3142
3143         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3144                         samr_dissect_LOOKUP_NAMES_name);
3145
3146         proto_item_set_len(item, offset-old_offset);
3147         return offset;
3148 }
3149
3150
3151 static int
3152 samr_dissect_lookup_names_rqst(tvbuff_t *tvb, int offset, 
3153                         packet_info *pinfo, proto_tree *tree,
3154                         char *drep)
3155 {
3156         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3157                         hf_samr_hnd, NULL);
3158         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3159                         hf_samr_count, NULL);
3160         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3161                         samr_dissect_LOOKUP_NAMES, NDR_POINTER_REF,
3162                         -1);
3163
3164         return offset;
3165 }
3166
3167 static int
3168 samr_dissect_lookup_names_reply(tvbuff_t *tvb, int offset, 
3169                         packet_info *pinfo, proto_tree *tree,
3170                         char *drep)
3171 {
3172         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3173                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3174                         hf_samr_rid);
3175         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3176                         samr_dissect_INDEX_ARRAY, NDR_POINTER_REF,
3177                         hf_samr_type);
3178         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3179                         hf_samr_rc, NULL);
3180
3181         return offset;
3182 }
3183
3184 static int
3185 samr_dissect_LOOKUP_RIDS_rid(tvbuff_t *tvb, int offset, 
3186                         packet_info *pinfo, proto_tree *tree,
3187                         char *drep)
3188 {
3189         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3190                                 hf_samr_rid, NULL);
3191
3192         return offset;
3193 }
3194
3195 static int
3196 samr_dissect_LOOKUP_RIDS(tvbuff_t *tvb, int offset, 
3197                         packet_info *pinfo, proto_tree *parent_tree,
3198                         char *drep)
3199 {
3200         proto_item *item=NULL;
3201         proto_tree *tree=NULL;
3202         int old_offset=offset;
3203
3204         if(parent_tree){
3205                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
3206                         "RIDs");
3207                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
3208         }
3209
3210         offset = dissect_ndr_ucvarray(tvb, offset, pinfo, tree, drep,
3211                         samr_dissect_LOOKUP_RIDS_rid);
3212
3213         proto_item_set_len(item, offset-old_offset);
3214         return offset;
3215 }
3216
3217
3218 static int
3219 samr_dissect_lookup_rids_rqst(tvbuff_t *tvb, int offset, 
3220                         packet_info *pinfo, proto_tree *tree,
3221                         char *drep)
3222 {
3223         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
3224                         hf_samr_hnd, NULL);
3225         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3226                         hf_samr_count, NULL);
3227         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3228                         samr_dissect_LOOKUP_RIDS, NDR_POINTER_REF,
3229                         -1);
3230
3231         return offset;
3232 }
3233
3234 static int
3235 samr_dissect_UNICODE_STRING_ARRAY_name(tvbuff_t *tvb, int offset, 
3236                         packet_info *pinfo, proto_tree *tree,
3237                         char *drep)
3238 {
3239         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
3240                                 hf_samr_acct_name);
3241         return offset;
3242 }
3243
3244 static int
3245 samr_dissect_UNICODE_STRING_ARRAY(tvbuff_t *tvb, int offset, 
3246                         packet_info *pinfo, proto_tree *parent_tree,
3247                         char *drep)
3248 {
3249         proto_item *item=NULL;
3250         proto_tree *tree=NULL;
3251         int old_offset=offset;
3252
3253         if(parent_tree){
3254                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
3255                         "Names");
3256                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
3257         }
3258
3259         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3260                         hf_samr_count, NULL);
3261
3262         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
3263                         samr_dissect_UNICODE_STRING_ARRAY_name);
3264
3265         proto_item_set_len(item, offset-old_offset);
3266         return offset;
3267
3268         return offset;
3269 }
3270
3271
3272 static int
3273 samr_dissect_lookup_rids_reply(tvbuff_t *tvb, int offset, 
3274                         packet_info *pinfo, proto_tree *tree,
3275                         char *drep)
3276 {
3277         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3278                         samr_dissect_UNICODE_STRING_ARRAY, NDR_POINTER_REF,
3279                         hf_samr_rid);
3280         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
3281                         samr_dissect_MEMBER_ARRAY_types, NDR_POINTER_REF,
3282                         -1);
3283         offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
3284                         hf_samr_rc, NULL);
3285
3286         return offset;
3287 }
3288
3289
3290
3291 static dcerpc_sub_dissector dcerpc_samr_dissectors[] = {
3292         { SAMR_CONNECT_ANON, "CONNECT_ANON",
3293                 samr_dissect_connect2_rqst,
3294                 samr_dissect_context_handle_reply },
3295         { SAMR_CLOSE_HND, "CLOSE_HND",
3296                 samr_dissect_context_handle,
3297                 samr_dissect_context_handle_reply },
3298         { SAMR_SET_SEC_OBJECT, "SET_SEC_OBJECT",
3299                 samr_dissect_set_sec_object_rqst,
3300                 samr_dissect_rc },
3301         { SAMR_QUERY_SEC_OBJECT, "QUERY_SEC_OBJECT", 
3302                 samr_dissect_query_sec_object_rqst,
3303                 samr_dissect_query_sec_object_reply },
3304         { SAMR_SHUTDOWN_SAM_SERVER, "SHUTDOWN_SAM_SERVER",
3305                 samr_dissect_context_handle,
3306                 samr_dissect_rc },
3307         { SAMR_LOOKUP_DOMAIN, "LOOKUP_DOMAIN",
3308                 samr_dissect_get_domain_password_information_rqst,
3309                 samr_dissect_lookup_domain_reply },
3310         { SAMR_ENUM_DOMAINS, "ENUM_DOMAINS",
3311                 samr_dissect_enum_domains_rqst,
3312                 samr_dissect_enum_domains_reply },
3313         { SAMR_OPEN_DOMAIN, "OPEN_DOMAIN",
3314                 samr_dissect_open_domain_rqst,
3315                 samr_dissect_open_domain_reply },
3316         { SAMR_QUERY_DOMAIN_INFO, "QUERY_INFORMATION_DOMAIN",
3317                 samr_dissect_query_information_alias_rqst,
3318                 samr_dissect_query_information_domain_reply },
3319         { SAMR_SET_DOMAIN_INFO, "SET_INFORMATION_DOMAIN",
3320                 samr_dissect_set_information_domain_rqst,
3321                 samr_dissect_rc },
3322         { SAMR_CREATE_DOM_GROUP, "CREATE_GROUP_IN_DOMAIN",
3323                 samr_dissect_create_alias_in_domain_rqst,
3324                 samr_dissect_create_alias_in_domain_reply },
3325         { SAMR_ENUM_DOM_GROUPS, "ENUM_DOM_GROUPS",
3326                 samr_dissect_enum_dom_groups_rqst,
3327                 samr_dissect_enum_dom_groups_reply },
3328         { SAMR_CREATE_USER_IN_DOMAIN, "CREATE_USER_IN_DOMAIN",
3329                 samr_dissect_create_alias_in_domain_rqst,
3330                 samr_dissect_create_alias_in_domain_reply },
3331         { SAMR_ENUM_DOM_USERS, "ENUM_DOM_USERS",
3332                 samr_dissect_enum_dom_groups_rqst,
3333                 samr_dissect_enum_dom_groups_reply },
3334         { SAMR_CREATE_DOM_ALIAS, "CREATE_ALIAS_IN_DOMAIN",
3335                 samr_dissect_create_alias_in_domain_rqst,
3336                 samr_dissect_create_alias_in_domain_reply },
3337         { SAMR_ENUM_DOM_ALIASES, "ENUM_DOM_ALIASES",
3338                 samr_dissect_enum_dom_groups_rqst,
3339                 samr_dissect_enum_dom_alias_reply },
3340         { SAMR_GET_ALIAS_MEMBERSHIP, "GET_ALIAS_MEMBERSHIP",
3341                 samr_dissect_get_alias_membership_rqst,
3342                 samr_dissect_get_alias_membership_reply },
3343         { SAMR_LOOKUP_NAMES, "LOOKUP_NAMES", 
3344                 samr_dissect_lookup_names_rqst,
3345                 samr_dissect_lookup_names_reply },
3346         { SAMR_LOOKUP_RIDS, "LOOKUP_RIDS",
3347                 samr_dissect_lookup_rids_rqst,
3348                 samr_dissect_lookup_rids_reply },
3349         { SAMR_OPEN_GROUP, "OPEN_GROUP",
3350                 samr_dissect_open_user_rqst,
3351                 samr_dissect_context_handle_reply },
3352         { SAMR_QUERY_GROUPINFO, "QUERY_INFORMATION_GROUP",
3353                 samr_dissect_query_information_group_rqst,
3354                 samr_dissect_query_information_group_reply },
3355         { SAMR_SET_GROUPINFO, "SET_INFORMATION_GROUP",
3356                 samr_dissect_set_information_group_rqst,
3357                 samr_dissect_rc },
3358         { SAMR_ADD_GROUPMEM, "ADD_MEMBER_TO_GROUP",
3359                 samr_dissect_add_member_to_group_rqst,
3360                 samr_dissect_rc },
3361         { SAMR_DELETE_DOM_GROUP, "DELETE_DOM_GROUP",
3362                 samr_dissect_context_handle,
3363                 samr_dissect_rc },
3364         { SAMR_DEL_GROUPMEM, "REMOVE_MEMBER_FROM_GROUP",
3365                 samr_dissect_add_member_to_group_rqst,
3366                 samr_dissect_rc },
3367         { SAMR_QUERY_GROUPMEM, "QUERY_GROUPMEM",
3368                 samr_dissect_context_handle,
3369                 samr_dissect_query_groupmem_reply },
3370         { SAMR_SET_MEMBER_ATTRIBUTES_OF_GROUP, "SET_MEMBER_ATTRIBUTES_OF_GROUP",
3371                 samr_dissect_set_member_attributes_of_group_rqst,
3372                 samr_dissect_rc },
3373         { SAMR_OPEN_ALIAS, "OPEN_ALIAS",
3374                 samr_dissect_open_user_rqst,
3375                 samr_dissect_context_handle_reply },
3376         { SAMR_QUERY_ALIASINFO, "QUERY_INFORMATION_ALIAS",
3377                 samr_dissect_query_information_alias_rqst,
3378                 samr_dissect_query_information_alias_reply },
3379         { SAMR_SET_ALIASINFO, "SET_INFORMATION_ALIAS",
3380                 samr_dissect_set_information_alias_rqst,
3381                 samr_dissect_rc },
3382         { SAMR_DELETE_DOM_ALIAS, "DELETE_DOM_ALIAS",
3383                 samr_dissect_context_handle,
3384                 samr_dissect_rc },
3385         { SAMR_ADD_ALIASMEM, "ADD_MEMBER_TO_ALIAS",
3386                 samr_dissect_context_handle_SID,
3387                 samr_dissect_rc },
3388         { SAMR_DEL_ALIASMEM, "REMOVE_MEMBER_FROM_ALIAS",
3389                 samr_dissect_context_handle_SID,
3390                 samr_dissect_rc },
3391         { SAMR_GET_MEMBERS_IN_ALIAS, "GET_MEMBERS_IN_ALIAS",
3392                 samr_dissect_context_handle,
3393                 samr_dissect_get_members_in_alias_reply },
3394         { SAMR_OPEN_USER, "OPEN_USER", 
3395                 samr_dissect_open_user_rqst, 
3396                 samr_dissect_context_handle_reply },
3397         { SAMR_DELETE_DOM_USER, "DELETE_DOM_USER",
3398                 samr_dissect_context_handle,
3399                 samr_dissect_rc },
3400         { SAMR_QUERY_USERINFO, "QUERY_USERINFO",
3401                 samr_dissect_query_information_alias_rqst,
3402                 samr_dissect_query_userinfo_reply },
3403         { SAMR_SET_USERINFO2, "SET_USERINFO2",
3404                 samr_dissect_set_information_user2_rqst,
3405                 samr_dissect_rc },
3406         { SAMR_CHANGE_PASSWORD_USER, "CHANGE_PASSWORD_USER",
3407                 samr_dissect_change_password_user_rqst,
3408                 samr_dissect_rc },
3409         { SAMR_GET_GROUPS_FOR_USER, "GET_GROUPS_FOR_USER",
3410                 samr_dissect_context_handle,
3411                 samr_dissect_get_groups_for_user_reply },
3412         { SAMR_QUERY_DISPINFO, "QUERY_DISPINFO", 
3413                 samr_dissect_query_dispinfo_rqst, 
3414                 samr_dissect_query_dispinfo_reply },
3415         { SAMR_GET_DISPLAY_ENUMERATION_INDEX, "GET_DISPLAY_ENUMERATION_INDEX", 
3416                 samr_dissect_get_display_enumeration_index_rqst, 
3417                 samr_dissect_get_display_enumeration_index_reply },
3418         { SAMR_TEST_PRIVATE_FUNCTIONS_DOMAIN, "TEST_PRIVATE_FUNCTIONS_DOMAIN",
3419                 samr_dissect_context_handle,
3420                 samr_dissect_rc },
3421         { SAMR_TEST_PRIVATE_FUNCTIONS_USER, "TEST_PRIVATE_FUNCTIONS_USER",
3422                 samr_dissect_context_handle,
3423                 samr_dissect_rc },
3424         { SAMR_GET_USRDOM_PWINFO, "GET_USRDOM_PWINFO",
3425                 samr_dissect_context_handle,
3426                 samr_dissect_get_usrdom_pwinfo_reply },
3427         { SAMR_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN, "REMOVE_MEMBER_FROM_FOREIGN_DOMAIN",
3428                 samr_dissect_context_handle_SID,
3429                 samr_dissect_rc },
3430         { SAMR_QUERY_INFORMATION_DOMAIN2, "QUERY_INFORMATION_DOMAIN2",
3431                 samr_dissect_query_information_alias_rqst,
3432                 samr_dissect_query_information_domain_reply },
3433         { SAMR_UNKNOWN_2f, "UNKNOWN_2f",
3434                 samr_dissect_query_information_alias_rqst,
3435                 samr_dissect_query_userinfo_reply },
3436         { SAMR_QUERY_DISPINFO2, "QUERY_INFORMATION_DISPLAY2",
3437                 samr_dissect_query_dispinfo_rqst,
3438                 samr_dissect_query_dispinfo_reply },
3439         { SAMR_GET_DISPLAY_ENUMERATION_INDEX2, "GET_DISPLAY_ENUMERATION_INDEX2",
3440                 samr_dissect_get_display_enumeration_index2_rqst,
3441                 samr_dissect_get_display_enumeration_index2_reply },
3442         { SAMR_CREATE_USER2_IN_DOMAIN, "CREATE_USER2_IN_DOMAIN",
3443                 samr_dissect_create_user2_in_domain_rqst,
3444                 samr_dissect_create_user2_in_domain_reply },
3445         { SAMR_QUERY_DISPINFO3, "QUERY_INFORMATION_DISPLAY3",
3446                 samr_dissect_query_dispinfo_rqst,
3447                 samr_dissect_query_dispinfo_reply },
3448         { SAMR_ADD_MULTIPLE_MEMBERS_TO_ALIAS, "ADD_MULTIPLE_MEMBERS_TO_ALIAS",
3449                 samr_dissect_get_alias_membership_rqst,
3450                 samr_dissect_rc },
3451         { SAMR_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS, "REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS",
3452                 samr_dissect_get_alias_membership_rqst,
3453                 samr_dissect_rc },
3454         { SAMR_OEM_CHANGE_PASSWORD_USER2, "OEM_CHANGE_PASSWORD_USER2",
3455                 samr_dissect_oem_change_password_user2_rqst,
3456                 samr_dissect_rc },
3457         { SAMR_UNICODE_CHANGE_PASSWORD_USER2, "UNICODE_CHANGE_PASSWORD_USER2",
3458                 samr_dissect_unicode_change_password_user2_rqst,
3459                 samr_dissect_rc },
3460         { SAMR_GET_DOM_PWINFO, "GET_DOMAIN_PASSWORD_INFORMATION",
3461                 samr_dissect_get_domain_password_information_rqst,
3462                 samr_dissect_get_usrdom_pwinfo_reply },
3463        { SAMR_CONNECT2, "CONNECT2", 
3464                 samr_dissect_connect2_rqst,
3465                 samr_dissect_connect2_reply },
3466         { SAMR_SET_USERINFO, "SET_USERINFO",
3467                 samr_dissect_set_information_user2_rqst,
3468                 samr_dissect_rc },
3469         { SAMR_UNKNOWN_3B, "UNKNOWN_3B",
3470                 samr_dissect_unknown_3b_rqst,
3471                 samr_dissect_rc },
3472         { SAMR_UNKNOWN_3C, "SAMR_UNKNOWN_3C", 
3473                 samr_dissect_context_handle,
3474                 samr_dissect_unknown_3c_reply },
3475         {0, NULL, NULL,  NULL },
3476 };
3477
3478 void 
3479 proto_register_dcerpc_samr(void)
3480 {
3481         static hf_register_info hf[] = {
3482                 { &hf_samr_hnd,
3483                   { "Context Handle", "samr.hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
3484                 { &hf_samr_group,
3485                   { "Group", "samr.group", FT_UINT32, BASE_DEC, NULL, 0x0, "Group", HFILL }},
3486                 { &hf_samr_rid,
3487                   { "Rid", "samr.rid", FT_UINT32, BASE_DEC, NULL, 0x0, "RID", HFILL }},
3488                 { &hf_samr_type,
3489                   { "Type", "samr.type", FT_UINT32, BASE_HEX, NULL, 0x0, "Type", HFILL }},
3490                 { &hf_samr_alias,
3491                   { "Alias", "samr.alias", FT_UINT32, BASE_HEX, NULL, 0x0, "Alias", HFILL }},
3492                 { &hf_samr_rid_attrib,
3493                   { "Rid Attrib", "samr.rid.attrib", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
3494                 { &hf_samr_attrib,
3495                   { "Attributes", "samr.attr", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
3496                 { &hf_samr_rc,
3497                   { "Return code", "samr.rc", FT_UINT32, BASE_HEX, VALS (NT_errors), 0x0, "", HFILL }},
3498
3499         { &hf_samr_level,
3500                 { "Level", "samr.level", FT_UINT16, BASE_DEC, 
3501                 NULL, 0x0, "Level requested/returned for Information", HFILL }},
3502         { &hf_samr_start_idx,
3503                 { "Start Idx", "samr.start_idx", FT_UINT32, BASE_DEC, 
3504                 NULL, 0x0, "Start Index for returned Information", HFILL }},
3505
3506         { &hf_samr_entries,
3507                 { "Entries", "samr.entries", FT_UINT32, BASE_DEC, 
3508                 NULL, 0x0, "Number of entries to return", HFILL }},
3509
3510         { &hf_samr_max_entries,
3511                 { "Max Entries", "samr.max_entries", FT_UINT32, BASE_DEC, 
3512                 NULL, 0x0, "Maximum number of entries", HFILL }},
3513
3514         { &hf_samr_pref_maxsize,
3515                 { "Pref MaxSize", "samr.pref_maxsize", FT_UINT32, BASE_DEC, 
3516                 NULL, 0x0, "Maximum Size of data to return", HFILL }},
3517
3518         { &hf_samr_total_size,
3519                 { "Total Size", "samr.total_size", FT_UINT32, BASE_DEC, 
3520                 NULL, 0x0, "Total size of data", HFILL }},
3521
3522         { &hf_samr_bad_pwd_count,
3523                 { "Bad Pwd Count", "samr.bad_pwd_count", FT_UINT16, BASE_DEC, 
3524                 NULL, 0x0, "Number of bad pwd entries for this user", HFILL }},
3525
3526         { &hf_samr_logon_count,
3527                 { "Logon Count", "samr.logon_count", FT_UINT16, BASE_DEC, 
3528                 NULL, 0x0, "Number of logons for this user", HFILL }},
3529
3530         { &hf_samr_ret_size,
3531                 { "Returned Size", "samr.ret_size", FT_UINT32, BASE_DEC, 
3532                 NULL, 0x0, "Number of returned objects in this PDU", HFILL }},
3533
3534         { &hf_samr_index,
3535                 { "Index", "samr.index", FT_UINT32, BASE_DEC, 
3536                 NULL, 0x0, "Index", HFILL }},
3537
3538         { &hf_samr_acct_ctrl,
3539                 { "Acct Ctrl", "samr.acct_ctrl", FT_UINT32, BASE_DEC, 
3540                 NULL, 0x0, "Acct CTRL", HFILL }},
3541
3542         { &hf_samr_count,
3543           { "Count", "samr.count", FT_UINT32, BASE_DEC, NULL, 0x0, "Number of elements in following array", HFILL }},
3544
3545         { &hf_samr_acct_name,
3546                 { "Account Name", "samr.acct_name", FT_STRING, BASE_NONE,
3547                 NULL, 0, "Name of Account", HFILL }},
3548
3549         { &hf_samr_server,
3550                 { "Server", "samr.server", FT_STRING, BASE_NONE,
3551                 NULL, 0, "Name of Server", HFILL }},
3552
3553         { &hf_samr_domain,
3554                 { "Domain", "samr.domain", FT_STRING, BASE_NONE,
3555                 NULL, 0, "Name of Domain", HFILL }},
3556
3557         { &hf_samr_controller,
3558                 { "DC", "samr.dc", FT_STRING, BASE_NONE,
3559                 NULL, 0, "Name of Domain Controller", HFILL }},
3560
3561         { &hf_samr_full_name,
3562                 { "Full Name", "samr.full_name", FT_STRING, BASE_NONE,
3563                 NULL, 0, "Full Name of Account", HFILL }},
3564
3565         { &hf_samr_home,
3566                 { "Home", "samr.home", FT_STRING, BASE_NONE,
3567                 NULL, 0, "Home directory for this user", HFILL }},
3568
3569         { &hf_samr_home_drive,
3570                 { "Home Drive", "samr.home_drive", FT_STRING, BASE_NONE,
3571                 NULL, 0, "Home drive for this user", HFILL }},
3572
3573         { &hf_samr_script,
3574                 { "Script", "samr.script", FT_STRING, BASE_NONE,
3575                 NULL, 0, "Login script for this user", HFILL }},
3576
3577         { &hf_samr_workstations,
3578                 { "Workstations", "samr.workstations", FT_STRING, BASE_NONE,
3579                 NULL, 0, "", HFILL }},
3580
3581         { &hf_samr_profile,
3582                 { "Profile", "samr.profile", FT_STRING, BASE_NONE,
3583                 NULL, 0, "Profile for this user", HFILL }},
3584
3585         { &hf_samr_acct_desc,
3586                 { "Account Desc", "samr.acct_desc", FT_STRING, BASE_NONE,
3587                 NULL, 0, "Account Description", HFILL }},
3588
3589         { &hf_samr_comment,
3590                 { "Comment", "samr.comment", FT_STRING, BASE_NONE,
3591                 NULL, 0, "Comment", HFILL }},
3592
3593         { &hf_samr_parameters,
3594                 { "Parameters", "samr.parameters", FT_STRING, BASE_NONE,
3595                 NULL, 0, "Parameters", HFILL }},
3596
3597         { &hf_samr_unknown_string,
3598                 { "Unknwon string", "samr.unknown_string", FT_STRING, BASE_NONE,
3599                 NULL, 0, "Unknown string. If you know what this is, contact ethereal developers.", HFILL }},
3600
3601         { &hf_samr_unknown_hyper,
3602                 { "Unknown hyper", "samr.unknown.hyper", FT_UINT64, BASE_HEX, 
3603                 NULL, 0x0, "Unknown hyper. If you know what this is, contact ethereal developers.", HFILL }},
3604         { &hf_samr_unknown_long,
3605                 { "Unknown long", "samr.unknown.long", FT_UINT32, BASE_HEX, 
3606                 NULL, 0x0, "Unknown long. If you know what this is, contact ethereal developers.", HFILL }},
3607
3608         { &hf_samr_unknown_short,
3609                 { "Unknown short", "samr.unknown.short", FT_UINT16, BASE_HEX, 
3610                 NULL, 0x0, "Unknown short. If you know what this is, contact ethereal developers.", HFILL }},
3611
3612         { &hf_samr_unknown_char,
3613                 { "Unknown char", "samr.unknown.char", FT_UINT8, BASE_HEX, 
3614                 NULL, 0x0, "Unknown char. If you know what this is, contact ethereal developers.", HFILL }},
3615
3616         { &hf_samr_revision,
3617                 { "Revision", "samr.revision", FT_UINT64, BASE_HEX, 
3618                 NULL, 0x0, "Revision number for this structure", HFILL }},
3619  
3620         { &hf_samr_nt_pwd_set,
3621                 { "NT Pwd Set", "samr.nt_pwd_set", FT_UINT8, BASE_HEX, 
3622                 NULL, 0x0, "Flag indicating whether the NT password has been set", HFILL }},
3623  
3624         { &hf_samr_lm_pwd_set,
3625                 { "LM Pwd Set", "samr.lm_pwd_set", FT_UINT8, BASE_HEX, 
3626                 NULL, 0x0, "Flag indicating whether the LanManager password has been set", HFILL }},
3627  
3628         { &hf_samr_pwd_expired,
3629                 { "Expired flag", "samr.pwd_Expired", FT_UINT8, BASE_HEX, 
3630                 NULL, 0x0, "Flag indicating if the password for this account has expired or not", HFILL }},
3631
3632         /* XXX - is this a standard NT access mask? */
3633         { &hf_samr_access,
3634                 { "Access Mask", "samr.access", FT_UINT32, BASE_HEX, 
3635                 NULL, 0x0, "Access", HFILL }},
3636
3637         { &hf_samr_mask,
3638                 { "Mask", "samr.mask", FT_UINT32, BASE_HEX, 
3639                 NULL, 0x0, "Mask", HFILL }},
3640
3641         { &hf_samr_crypt_password, {
3642                 "Password", "samr.crypt_password", FT_BYTES, BASE_HEX,
3643                 NULL, 0, "Encrypted Password", HFILL }},
3644
3645         { &hf_samr_crypt_hash, {
3646                 "Hash", "samr.crypt_hash", FT_BYTES, BASE_HEX,
3647                 NULL, 0, "Encrypted Hash", HFILL }},
3648
3649         { &hf_samr_lm_change, {
3650                 "LM Change", "samr.lm_change", FT_UINT8, BASE_HEX,
3651                 NULL, 0, "LM Change value", HFILL }},
3652
3653         { &hf_samr_max_pwd_age,
3654                 { "Max Pwd Age", "samr.max_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
3655                 NULL, 0, "Maximum Password Age before it expires", HFILL }},
3656
3657         { &hf_samr_min_pwd_age,
3658                 { "Min Pwd Age", "samr.min_pwd_age", FT_RELATIVE_TIME, BASE_NONE,
3659                 NULL, 0, "Minimum Password Age before it can be changed", HFILL }},
3660         { &hf_samr_unknown_time,
3661                 { "Unknown time", "samr.unknown_time", FT_ABSOLUTE_TIME, BASE_NONE,
3662                 NULL, 0, "Unknown NT TIME, contact ethereal developers if you know what this is", HFILL }},
3663         { &hf_samr_logon_time,
3664                 { "Logon Time", "samr.logon_time", FT_ABSOLUTE_TIME, BASE_NONE,
3665                 NULL, 0, "Time for last time this user logged on", HFILL }},
3666         { &hf_samr_kickoff_time,
3667                 { "Kickoff Time", "samr.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3668                 NULL, 0, "Time when this user will be kicked off", HFILL }},
3669         { &hf_samr_logoff_time,
3670                 { "Logoff Time", "samr.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3671                 NULL, 0, "Time for last time this user logged off", HFILL }},
3672         { &hf_samr_pwd_last_set_time,
3673                 { "PWD Last Set", "samr.pwd_last_set_time", FT_ABSOLUTE_TIME, BASE_NONE,
3674                 NULL, 0, "Last time this users password was changed", HFILL }},
3675         { &hf_samr_pwd_can_change_time,
3676                 { "PWD Can Change", "samr.pwd_can_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
3677                 NULL, 0, "When this users password may be changed", HFILL }},
3678         { &hf_samr_pwd_must_change_time,
3679                 { "PWD Must Change", "samr.pwd_must_change_time", FT_ABSOLUTE_TIME, BASE_NONE,
3680                 NULL, 0, "When this users password must be changed", HFILL }},
3681         { &hf_samr_acct_expiry_time,
3682                 { "Acct Expiry", "samr.acct_expiry_time", FT_ABSOLUTE_TIME, BASE_NONE,
3683                 NULL, 0, "When this user account expires", HFILL }},
3684
3685         { &hf_samr_min_pwd_len, {
3686                 "Min Pwd Len", "samr.min_pwd_len", FT_UINT16, BASE_DEC,
3687                 NULL, 0, "Minimum Password Length", HFILL }},
3688         { &hf_samr_pwd_history_len, {
3689                 "Pwd History Len", "samr.pwd_history_len", FT_UINT16, BASE_DEC,
3690                 NULL, 0, "Password History Length", HFILL }},
3691         { &hf_samr_num_users, {
3692                 "Num Users", "samr.num_users", FT_UINT32, BASE_DEC,
3693                 NULL, 0, "Number of users in this domain", HFILL }},
3694         { &hf_samr_num_groups, {
3695                 "Num Groups", "samr.num_groups", FT_UINT32, BASE_DEC,
3696                 NULL, 0, "Number of groups in this domain", HFILL }},
3697         { &hf_samr_num_aliases, {
3698                 "Num Aliases", "samr.num_aliases", FT_UINT32, BASE_DEC,
3699                 NULL, 0, "Number of aliases in this domain", HFILL }},
3700         { &hf_samr_info_type, {
3701                 "Info Type", "samr.info_type", FT_UINT32, BASE_DEC,
3702                 NULL, 0, "Information Type", HFILL }},
3703         { &hf_samr_resume_hnd, {
3704                 "Resume Hnd", "samr.resume_hnd", FT_UINT32, BASE_DEC,
3705                 NULL, 0, "Resume handle", HFILL }},
3706         { &hf_samr_country, {
3707                 "Country", "samr.country", FT_UINT16, BASE_DEC,
3708                 NULL, 0, "Country setting for this user", HFILL }},
3709         { &hf_samr_codepage, {
3710                 "Codepage", "samr.codepage", FT_UINT16, BASE_DEC,
3711                 NULL, 0, "Codepage setting for this user", HFILL }},
3712         { &hf_samr_divisions, {
3713                 "Divisions", "samr.divisions", FT_UINT16, BASE_DEC,
3714                 NULL, 0, "Number of divisions for LOGON_HOURS", HFILL }},
3715
3716
3717         /* these are used by packet-dcerpc-nt.c */
3718         { &hf_nt_string_length,
3719                 { "Length", "nt.string.length", FT_UINT16, BASE_DEC, 
3720                 NULL, 0x0, "Length of string in bytes", HFILL }},
3721
3722         { &hf_nt_string_size,
3723                 { "Size", "nt.string.size", FT_UINT16, BASE_DEC, 
3724                 NULL, 0x0, "Size of string in bytes", HFILL }},
3725
3726         { &hf_nt_str_len,
3727                 { "Length", "nt.str.len", FT_UINT32, BASE_DEC, 
3728                 NULL, 0x0, "Length of string in short integers", HFILL }},
3729
3730         { &hf_nt_str_off,
3731                 { "Offset", "nt.str.offset", FT_UINT32, BASE_DEC, 
3732                 NULL, 0x0, "Offset into string in short integers", HFILL }},
3733
3734         { &hf_nt_str_max_len,
3735                 { "Max Length", "nt.str.max_len", FT_UINT32, BASE_DEC, 
3736                 NULL, 0x0, "Max Length of string in short integers", HFILL }},
3737         };
3738         static gint *ett[] = {
3739                 &ett_dcerpc_samr,
3740                 &ett_nt_unicode_string,
3741                 &ett_samr_user_dispinfo_1,
3742         };
3743
3744         proto_dcerpc_samr = proto_register_protocol(
3745                 "Microsoft Security Account Manager", "SAMR", "samr");
3746
3747         proto_register_field_array (proto_dcerpc_samr, hf, array_length (hf));
3748         proto_register_subtree_array(ett, array_length(ett));
3749 }
3750
3751 void
3752 proto_reg_handoff_dcerpc_samr(void)
3753 {
3754         /* Register protocol as dcerpc */
3755
3756         dcerpc_init_uuid(proto_dcerpc_samr, ett_dcerpc_samr, &uuid_dcerpc_samr,
3757                          ver_dcerpc_samr, dcerpc_samr_dissectors);
3758 }