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.4 2002/01/25 08:35:59 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 static int proto_dcerpc_samr = -1;
38
39 static int hf_samr_hnd = -1;
40 static int hf_samr_perms = -1;
41 static int hf_samr_rid = -1;
42 static int hf_samr_rc = -1;
43 static int hf_samr_index = -1;
44 static int hf_samr_acct_ctrl = -1;
45 static int hf_samr_array_max_count = -1;
46
47 static int hf_samr_level = -1;
48 static int hf_samr_start_idx = -1;
49 static int hf_samr_max_entries = -1;
50 static int hf_samr_pref_maxsize = -1;
51 static int hf_samr_total_size = -1;
52 static int hf_samr_ret_size = -1;
53 static int hf_samr_acct_name = -1;
54 static int hf_samr_full_name = -1;
55 static int hf_samr_acct_desc = -1;
56
57 /* these are used by functions in packet-dcerpc-nt.c */
58 int hf_nt_str_len = -1;
59 int hf_nt_str_off = -1;
60 int hf_nt_str_max_len = -1;
61 int hf_nt_string_length = -1;
62 int hf_nt_string_size = -1;
63
64
65 static gint ett_dcerpc_samr = -1;
66 gint ett_nt_unicode_string = -1;        /* used by packet-dcerpc-nt.c*/
67 static gint ett_samr_user_dispinfo_1 = -1;
68
69 static e_uuid_t uuid_dcerpc_samr = {
70         0x12345778, 0x1234, 0xabcd, 
71         { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xac}
72 };
73
74 static guint16 ver_dcerpc_samr = 1;
75
76 static int
77 samr_dissect_gen_open_reply (tvbuff_t *tvb, int offset, 
78                              packet_info *pinfo, proto_tree *tree, 
79                              char *drep)
80 {
81         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
82                                       hf_samr_hnd, NULL);
83         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
84                                      hf_samr_rc, NULL);
85         return offset;
86 }
87
88 static int
89 samr_dissect_close_hnd_rqst (tvbuff_t *tvb, int offset, 
90                               packet_info *pinfo, proto_tree *tree, 
91                               char *drep)
92 {
93         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
94                                       hf_samr_hnd, NULL);
95         return offset;
96 }
97
98 static int
99 samr_dissect_open_user_rqst (tvbuff_t *tvb, int offset, 
100                              packet_info *pinfo, proto_tree *tree, 
101                              char *drep)
102 {
103         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
104                                       hf_samr_hnd, NULL);
105         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
106                                      hf_samr_perms, NULL);
107         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
108                                      hf_samr_rid, NULL);
109         return offset;
110 }
111
112
113 static int
114 samr_dissect_query_dispinfo_level (tvbuff_t *tvb, int offset, 
115                              packet_info *pinfo, proto_tree *tree, 
116                              char *drep)
117 {
118         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
119                                      hf_samr_level, NULL);
120
121         return offset;
122 }
123
124 static int
125 samr_dissect_query_dispinfo_rqst (tvbuff_t *tvb, int offset, 
126                              packet_info *pinfo, proto_tree *tree, 
127                              char *drep)
128 {
129         offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
130                                       hf_samr_hnd, NULL);
131         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
132                         samr_dissect_query_dispinfo_level, NDR_POINTER_REF,
133                         -1);
134         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
135                                      hf_samr_start_idx, NULL);
136         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
137                                      hf_samr_max_entries, NULL);
138         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
139                                      hf_samr_pref_maxsize, NULL);
140         return offset;
141 }
142
143 static int
144 samr_dissect_USER_DISPINFO_1 (tvbuff_t *tvb, int offset, 
145                              packet_info *pinfo, proto_tree *parent_tree, 
146                              char *drep)
147 {
148         proto_item *item=NULL;
149         proto_tree *tree=NULL;
150         int old_offset=offset;
151
152         if(parent_tree){
153                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
154                         "User_DispInfo_1");
155                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
156         }
157
158         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
159                                      hf_samr_index, NULL);
160         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
161                                      hf_samr_rid, NULL);
162         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
163                                      hf_samr_acct_ctrl, NULL);
164         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
165                         hf_samr_acct_name);
166         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
167                         hf_samr_full_name);
168         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
169                         hf_samr_acct_desc);
170
171         proto_item_set_len(item, offset-old_offset);
172         return offset;
173 }
174
175 static int
176 samr_dissect_USER_DISPINFO_1_ARRAY_users (tvbuff_t *tvb, int offset, 
177                              packet_info *pinfo, proto_tree *tree, 
178                              char *drep)
179 {
180         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
181                         samr_dissect_USER_DISPINFO_1);
182
183         return offset;
184 }
185
186 static int
187 samr_dissect_USER_DISPINFO_1_ARRAY (tvbuff_t *tvb, int offset, 
188                              packet_info *pinfo, proto_tree *parent_tree, 
189                              char *drep)
190 {
191         guint32 count;
192         proto_item *item=NULL;
193         proto_tree *tree=NULL;
194         int old_offset=offset;
195
196         if(parent_tree){
197                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
198                         "User_DispInfo_1 Array");
199                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
200         }
201
202
203         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
204                                      hf_samr_array_max_count, &count);
205         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
206                         samr_dissect_USER_DISPINFO_1_ARRAY_users, NDR_POINTER_PTR,
207                         -1);
208
209         proto_item_set_len(item, offset-old_offset);
210         return offset;
211 }
212
213
214
215 static int
216 samr_dissect_USER_DISPINFO_2 (tvbuff_t *tvb, int offset, 
217                              packet_info *pinfo, proto_tree *parent_tree, 
218                              char *drep)
219 {
220         proto_item *item=NULL;
221         proto_tree *tree=NULL;
222         int old_offset=offset;
223
224         if(parent_tree){
225                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
226                         "User_DispInfo_2");
227                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
228         }
229
230         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
231                                      hf_samr_index, NULL);
232         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
233                                      hf_samr_rid, NULL);
234         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
235                                      hf_samr_acct_ctrl, NULL);
236         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
237                         hf_samr_acct_name);
238         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
239                         hf_samr_acct_desc);
240
241         proto_item_set_len(item, offset-old_offset);
242         return offset;
243 }
244
245 static int
246 samr_dissect_USER_DISPINFO_2_ARRAY_users (tvbuff_t *tvb, int offset, 
247                              packet_info *pinfo, proto_tree *tree, 
248                              char *drep)
249 {
250         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
251                         samr_dissect_USER_DISPINFO_2);
252
253         return offset;
254 }
255
256 static int
257 samr_dissect_USER_DISPINFO_2_ARRAY (tvbuff_t *tvb, int offset, 
258                              packet_info *pinfo, proto_tree *parent_tree, 
259                              char *drep)
260 {
261         guint32 count;
262         proto_item *item=NULL;
263         proto_tree *tree=NULL;
264         int old_offset=offset;
265
266         if(parent_tree){
267                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
268                         "User_DispInfo_2 Array");
269                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
270         }
271
272
273         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
274                                      hf_samr_array_max_count, &count);
275         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
276                         samr_dissect_USER_DISPINFO_2_ARRAY_users, NDR_POINTER_PTR,
277                         -1);
278
279         proto_item_set_len(item, offset-old_offset);
280         return offset;
281 }
282
283
284
285
286
287 static int
288 samr_dissect_GROUP_DISPINFO (tvbuff_t *tvb, int offset, 
289                              packet_info *pinfo, proto_tree *parent_tree, 
290                              char *drep)
291 {
292         proto_item *item=NULL;
293         proto_tree *tree=NULL;
294         int old_offset=offset;
295
296         if(parent_tree){
297                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
298                         "Group_DispInfo");
299                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
300         }
301
302         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
303                                      hf_samr_index, NULL);
304         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
305                                      hf_samr_rid, NULL);
306         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
307                                      hf_samr_acct_ctrl, NULL);
308         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
309                         hf_samr_acct_name);
310         offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
311                         hf_samr_acct_desc);
312
313         proto_item_set_len(item, offset-old_offset);
314         return offset;
315 }
316
317 static int
318 samr_dissect_GROUP_DISPINFO_ARRAY_groups (tvbuff_t *tvb, int offset, 
319                              packet_info *pinfo, proto_tree *tree, 
320                              char *drep)
321 {
322         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
323                         samr_dissect_GROUP_DISPINFO);
324
325         return offset;
326 }
327
328 static int
329 samr_dissect_GROUP_DISPINFO_ARRAY (tvbuff_t *tvb, int offset, 
330                              packet_info *pinfo, proto_tree *parent_tree, 
331                              char *drep)
332 {
333         guint32 count;
334         proto_item *item=NULL;
335         proto_tree *tree=NULL;
336         int old_offset=offset;
337
338         if(parent_tree){
339                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
340                         "Group_DispInfo Array");
341                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
342         }
343
344         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
345                                      hf_samr_array_max_count, &count);
346         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
347                         samr_dissect_GROUP_DISPINFO_ARRAY_groups, NDR_POINTER_PTR,
348                         -1);
349
350         proto_item_set_len(item, offset-old_offset);
351         return offset;
352 }
353
354
355
356 static int
357 samr_dissect_ASCII_DISPINFO (tvbuff_t *tvb, int offset, 
358                              packet_info *pinfo, proto_tree *parent_tree, 
359                              char *drep)
360 {
361         proto_item *item=NULL;
362         proto_tree *tree=NULL;
363         int old_offset=offset;
364
365         if(parent_tree){
366                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
367                         "Ascii_DispInfo");
368                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
369         }
370
371         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
372                                      hf_samr_index, NULL);
373         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
374                                      hf_samr_rid, NULL);
375         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
376                                      hf_samr_acct_ctrl, NULL);
377         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
378                         hf_samr_acct_name);
379         offset = dissect_ndr_nt_STRING(tvb, offset, pinfo, tree, drep,
380                         hf_samr_acct_desc);
381
382         proto_item_set_len(item, offset-old_offset);
383         return offset;
384 }
385
386 static int
387 samr_dissect_ASCII_DISPINFO_ARRAY_users (tvbuff_t *tvb, int offset, 
388                              packet_info *pinfo, proto_tree *tree, 
389                              char *drep)
390 {
391         offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
392                         samr_dissect_ASCII_DISPINFO);
393
394         return offset;
395 }
396
397 static int
398 samr_dissect_ASCII_DISPINFO_ARRAY (tvbuff_t *tvb, int offset, 
399                              packet_info *pinfo, proto_tree *parent_tree,
400                              char *drep)
401 {
402         guint32 count;
403         proto_item *item=NULL;
404         proto_tree *tree=NULL;
405         int old_offset=offset;
406
407         if(parent_tree){
408                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
409                         "Ascii_DispInfo Array");
410                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
411         }
412
413         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
414                                      hf_samr_array_max_count, &count);
415         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
416                         samr_dissect_ASCII_DISPINFO_ARRAY_users, NDR_POINTER_PTR,
417                         -1);
418
419         proto_item_set_len(item, offset-old_offset);
420         return offset;
421 }
422
423
424 static int
425 samr_dissect_DISPLAY_INFO (tvbuff_t *tvb, int offset, 
426                              packet_info *pinfo, proto_tree *parent_tree,
427                              char *drep)
428 {
429         proto_item *item=NULL;
430         proto_tree *tree=NULL;
431         int old_offset=offset;
432         guint16 level;
433
434         if(parent_tree){
435                 item = proto_tree_add_text(parent_tree, tvb, offset, 0,
436                         "DispInfo");
437                 tree = proto_item_add_subtree(item, ett_samr_user_dispinfo_1);
438         }
439
440         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
441                                      hf_samr_level, &level);
442         switch(level){
443         case 1: 
444                 offset = samr_dissect_USER_DISPINFO_1_ARRAY(
445                                 tvb, offset, pinfo, tree, drep);
446                 break;
447         case 2: 
448                 offset = samr_dissect_USER_DISPINFO_2_ARRAY(
449                                 tvb, offset, pinfo, tree, drep);
450                 break;
451         case 3: 
452                 offset = samr_dissect_GROUP_DISPINFO_ARRAY(
453                                 tvb, offset, pinfo, tree, drep);
454                 break;
455         case 4: 
456                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
457                                 tvb, offset, pinfo, tree, drep);
458                 break;
459         case 5: 
460                 offset = samr_dissect_ASCII_DISPINFO_ARRAY(
461                                 tvb, offset, pinfo, tree, drep);
462                 break;
463         }
464
465         proto_item_set_len(item, offset-old_offset);
466         return offset;
467 }
468
469 static int
470 samr_dissect_query_dispinfo_total_size (tvbuff_t *tvb, int offset, 
471                              packet_info *pinfo, proto_tree *tree, 
472                              char *drep)
473 {
474         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
475                                      hf_samr_total_size, NULL);
476         return offset;
477 }
478 static int
479 samr_dissect_query_dispinfo_ret_size (tvbuff_t *tvb, int offset, 
480                              packet_info *pinfo, proto_tree *tree, 
481                              char *drep)
482 {
483         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
484                                      hf_samr_ret_size, NULL);
485         return offset;
486 }
487
488 static int
489 samr_dissect_query_dispinfo_reply (tvbuff_t *tvb, int offset, 
490                              packet_info *pinfo, proto_tree *tree, 
491                              char *drep)
492 {
493         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
494                         samr_dissect_query_dispinfo_total_size, NDR_POINTER_REF,
495                         -1);
496         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
497                         samr_dissect_query_dispinfo_ret_size, NDR_POINTER_REF,
498                         -1);
499         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
500                         samr_dissect_DISPLAY_INFO, NDR_POINTER_REF,
501                         -1);
502         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
503                                      hf_samr_rc, NULL);
504
505         return offset;
506 }
507
508
509 static dcerpc_sub_dissector dcerpc_samr_dissectors[] = {
510         { SAMR_CONNECT_ANON, "SAMR_CONNECT_ANON", NULL, samr_dissect_gen_open_reply },
511         { SAMR_CLOSE_HND, "SAMR_CLOSE_HND", samr_dissect_close_hnd_rqst, samr_dissect_gen_open_reply },
512         { SAMR_UNKNOWN_2, "SAMR_UNKNOWN_2", NULL, NULL },
513         { SAMR_QUERY_SEC_OBJECT, "SAMR_QUERY_SEC_OBJECT", NULL, NULL },
514         { SAMR_UNKNOWN_4, "SAMR_UNKNOWN_4", NULL, NULL },
515         { SAMR_LOOKUP_DOMAIN, "SAMR_LOOKUP_DOMAIN", NULL, NULL },
516         { SAMR_ENUM_DOMAINS, "SAMR_ENUM_DOMAINS", NULL, NULL },
517         { SAMR_OPEN_DOMAIN, "SAMR_OPEN_DOMAIN", NULL, samr_dissect_gen_open_reply },
518         { SAMR_QUERY_DOMAIN_INFO, "SAMR_QUERY_DOMAIN_INFO", NULL, NULL },
519         { SAMR_CREATE_DOM_GROUP, "SAMR_CREATE_DOM_GROUP", NULL, NULL },
520         { SAMR_ENUM_DOM_GROUPS, "SAMR_ENUM_DOM_GROUPS", NULL, NULL },
521         { SAMR_ENUM_DOM_USERS, "SAMR_ENUM_DOM_USERS", NULL, NULL },
522         { SAMR_CREATE_DOM_ALIAS, "SAMR_CREATE_DOM_ALIAS", NULL, NULL },
523         { SAMR_ENUM_DOM_ALIASES, "SAMR_ENUM_DOM_ALIASES", NULL, NULL },
524         { SAMR_QUERY_USERALIASES, "SAMR_QUERY_USERALIASES", NULL, NULL },
525         { SAMR_LOOKUP_NAMES, "SAMR_LOOKUP_NAMES", NULL, NULL },
526         { SAMR_LOOKUP_RIDS, "SAMR_LOOKUP_RIDS", NULL, NULL },
527         { SAMR_OPEN_GROUP, "SAMR_OPEN_GROUP", NULL, samr_dissect_gen_open_reply },
528         { SAMR_QUERY_GROUPINFO, "SAMR_QUERY_GROUPINFO", NULL, NULL },
529         { SAMR_SET_GROUPINFO, "SAMR_SET_GROUPINFO", NULL, NULL },
530         { SAMR_ADD_GROUPMEM, "SAMR_ADD_GROUPMEM", NULL, NULL },
531         { SAMR_DELETE_DOM_GROUP, "SAMR_DELETE_DOM_GROUP", NULL, NULL },
532         { SAMR_DEL_GROUPMEM, "SAMR_DEL_GROUPMEM", NULL, NULL },
533         { SAMR_QUERY_GROUPMEM, "SAMR_QUERY_GROUPMEM", NULL, NULL },
534         { SAMR_UNKNOWN_1A, "SAMR_UNKNOWN_1A", NULL, NULL },
535         { SAMR_OPEN_ALIAS, "SAMR_OPEN_ALIAS", NULL, samr_dissect_gen_open_reply },
536         { SAMR_QUERY_ALIASINFO, "SAMR_QUERY_ALIASINFO", NULL, NULL },
537         { SAMR_SET_ALIASINFO, "SAMR_SET_ALIASINFO", NULL, NULL },
538         { SAMR_DELETE_DOM_ALIAS, "SAMR_DELETE_DOM_ALIAS", NULL, NULL },
539         { SAMR_ADD_ALIASMEM, "SAMR_ADD_ALIASMEM", NULL, NULL },
540         { SAMR_DEL_ALIASMEM, "SAMR_DEL_ALIASMEM", NULL, NULL },
541         { SAMR_QUERY_ALIASMEM, "SAMR_QUERY_ALIASMEM", NULL, NULL },
542         { SAMR_OPEN_USER, "SAMR_OPEN_USER", samr_dissect_open_user_rqst, samr_dissect_gen_open_reply },
543         { SAMR_DELETE_DOM_USER, "SAMR_DELETE_DOM_USER", NULL, NULL },
544         { SAMR_QUERY_USERINFO, "SAMR_QUERY_USERINFO", NULL, NULL },
545         { SAMR_SET_USERINFO2, "SAMR_SET_USERINFO2", NULL, NULL },
546         { SAMR_QUERY_USERGROUPS, "SAMR_QUERY_USERGROUPS", NULL, NULL },
547         { SAMR_QUERY_DISPINFO, "SAMR_QUERY_DISPINFO", samr_dissect_query_dispinfo_rqst, samr_dissect_query_dispinfo_reply },
548         { SAMR_UNKNOWN_29, "SAMR_UNKNOWN_29", NULL, NULL },
549         { SAMR_UNKNOWN_2a, "SAMR_UNKNOWN_2a", NULL, NULL },
550         { SAMR_UNKNOWN_2b, "SAMR_UNKNOWN_2b", NULL, NULL },
551         { SAMR_GET_USRDOM_PWINFO, "SAMR_GET_USRDOM_PWINFO", NULL, NULL },
552         { SAMR_UNKNOWN_2D, "SAMR_UNKNOWN_2D", NULL, NULL },
553         { SAMR_UNKNOWN_2e, "SAMR_UNKNOWN_2e", NULL, NULL },
554         { SAMR_UNKNOWN_2f, "SAMR_UNKNOWN_2f", NULL, NULL },
555         { SAMR_QUERY_DISPINFO3, "SAMR_QUERY_DISPINFO3", NULL, NULL },
556         { SAMR_UNKNOWN_31, "SAMR_UNKNOWN_31", NULL, NULL },
557         { SAMR_CREATE_USER, "SAMR_CREATE_USER", NULL, NULL },
558         { SAMR_QUERY_DISPINFO4, "SAMR_QUERY_DISPINFO4", NULL, NULL },
559         { SAMR_ADDMULTI_ALIASMEM, "SAMR_ADDMULTI_ALIASMEM", NULL, NULL },
560         { SAMR_UNKNOWN_35, "SAMR_UNKNOWN_35", NULL, NULL },
561         { SAMR_UNKNOWN_36, "SAMR_UNKNOWN_36", NULL, NULL },
562         { SAMR_CHGPASSWD_USER, "SAMR_CHGPASSWD_USER", NULL, NULL },
563         { SAMR_GET_DOM_PWINFO, "SAMR_GET_DOM_PWINFO", NULL, NULL },
564         { SAMR_CONNECT, "SAMR_CONNECT", NULL, samr_dissect_gen_open_reply },
565         { SAMR_SET_USERINFO, "SAMR_SET_USERINFO", NULL, NULL },
566
567         {0, NULL, NULL,  NULL },
568 };
569
570 void 
571 proto_register_dcerpc_samr(void)
572 {
573         static hf_register_info hf[] = {
574                 { &hf_samr_hnd,
575                   { "Context Handle", "samr.hnd", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
576                 { &hf_samr_perms,
577                   { "Access Mask", "samr.perms", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
578                 { &hf_samr_rid,
579                   { "Rid", "samr.rid", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
580                 { &hf_samr_rc,
581                   { "Return code", "samr.rc", FT_UINT32, BASE_HEX, VALS (NT_errors), 0x0, "", HFILL }},
582
583         { &hf_samr_level,
584                 { "Level", "samr.level", FT_UINT16, BASE_DEC, 
585                 NULL, 0x0, "Level requested/returned for Information", HFILL }},
586         { &hf_samr_start_idx,
587                 { "Start Idx", "samr.start_idx", FT_UINT32, BASE_DEC, 
588                 NULL, 0x0, "Start Index for returned Information", HFILL }},
589
590         { &hf_samr_max_entries,
591                 { "Max Entries", "samr.max_entries", FT_UINT32, BASE_DEC, 
592                 NULL, 0x0, "Maximum number of entries to return", HFILL }},
593
594         { &hf_samr_pref_maxsize,
595                 { "Pref MaxSize", "samr.pref_maxsize", FT_UINT32, BASE_DEC, 
596                 NULL, 0x0, "Maximum Size of data to return", HFILL }},
597
598         { &hf_samr_total_size,
599                 { "Total Size", "samr.total_size", FT_UINT32, BASE_DEC, 
600                 NULL, 0x0, "Total size of data", HFILL }},
601
602         { &hf_samr_ret_size,
603                 { "Returned Size", "samr.ret_size", FT_UINT32, BASE_DEC, 
604                 NULL, 0x0, "Number of returned objects in this PDU", HFILL }},
605
606         { &hf_samr_index,
607                 { "Index", "samr.index", FT_UINT32, BASE_DEC, 
608                 NULL, 0x0, "Index", HFILL }},
609
610         { &hf_samr_acct_ctrl,
611                 { "Acct Ctrl", "samr.acct_ctrl", FT_UINT32, BASE_DEC, 
612                 NULL, 0x0, "Acct CTRL", HFILL }},
613
614         { &hf_samr_array_max_count,
615           { "Max Count", "samr.array.max_count", FT_UINT32, BASE_DEC, NULL, 0x0, "Maximum Count: Number of elements in the array", HFILL }},
616
617         { &hf_samr_acct_name,
618                 { "Account Name", "samr.acct_name", FT_STRING, BASE_NONE,
619                 NULL, 0, "Name of Account", HFILL }},
620
621         { &hf_samr_full_name,
622                 { "Full Name", "samr.full_name", FT_STRING, BASE_NONE,
623                 NULL, 0, "Full Name of Account", HFILL }},
624
625         { &hf_samr_acct_desc,
626                 { "Account Desc", "samr.acct_desc", FT_STRING, BASE_NONE,
627                 NULL, 0, "Account Description", HFILL }},
628
629
630
631         /* these are used by packet-dcerpc-nt.c */
632         { &hf_nt_string_length,
633                 { "Length", "nt.string.length", FT_UINT16, BASE_DEC, 
634                 NULL, 0x0, "Length of string in bytes", HFILL }},
635
636         { &hf_nt_string_size,
637                 { "Size", "nt.string.size", FT_UINT16, BASE_DEC, 
638                 NULL, 0x0, "Size of string in bytes", HFILL }},
639
640         { &hf_nt_str_len,
641                 { "Length", "nt.str.len", FT_UINT32, BASE_DEC, 
642                 NULL, 0x0, "Length of string in short integers", HFILL }},
643
644         { &hf_nt_str_off,
645                 { "Offset", "nt.str.offset", FT_UINT32, BASE_DEC, 
646                 NULL, 0x0, "Offset into string in short integers", HFILL }},
647
648         { &hf_nt_str_max_len,
649                 { "Max Length", "nt.str.max_len", FT_UINT32, BASE_DEC, 
650                 NULL, 0x0, "Max Length of string in short integers", HFILL }},
651         };
652         static gint *ett[] = {
653                 &ett_dcerpc_samr,
654                 &ett_nt_unicode_string,
655                 &ett_samr_user_dispinfo_1,
656         };
657
658         proto_dcerpc_samr = proto_register_protocol(
659                 "Microsoft Security Account Manager", "SAMR", "samr");
660
661         proto_register_field_array (proto_dcerpc_samr, hf, array_length (hf));
662         proto_register_subtree_array(ett, array_length(ett));
663 }
664
665 void
666 proto_reg_handoff_dcerpc_samr(void)
667 {
668         /* Register protocol as dcerpc */
669
670         dcerpc_init_uuid(proto_dcerpc_samr, ett_dcerpc_samr, &uuid_dcerpc_samr,
671                          ver_dcerpc_samr, dcerpc_samr_dissectors);
672 }