Reduce the CinemaScope-like proportions of the preferences dialog by
[obnox/wireshark/wip.git] / packet-smb-logon.c
1 /* packet-smb-logon.c
2  * Routines for SMB net logon packet dissection
3  * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
4  *
5  * $Id: packet-smb-logon.c,v 1.19 2001/07/13 07:04:23 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-pop.c
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #include "packet-smb-common.h"
29 #include "packet-smb-logon.h"
30
31 static int proto_smb_logon = -1;
32 static int hf_command = -1;
33 static int hf_computer_name = -1;
34 static int hf_unicode_computer_name = -1;
35 static int hf_server_name = -1;
36 static int hf_user_name = -1;
37 static int hf_domain_name = -1;
38 static int hf_mailslot_name = -1;
39 static int hf_pdc_name = -1;
40 static int hf_unicode_pdc_name = -1;
41 static int hf_script_name = -1;
42 static int hf_nt_version = -1;
43 static int hf_lmnt_token = -1;
44 static int hf_lm_token = -1;
45 static int hf_major_version = -1;
46 static int hf_minor_version = -1;
47 static int hf_os_version = -1;
48 static int hf_date_time = -1;
49 static int hf_update_type = -1;
50 static int hf_request_count = -1;
51 static int hf_flags_autolock = -1;
52 static int hf_flags_expire = -1;
53 static int hf_flags_server_trust = -1;
54 static int hf_flags_workstation_trust = -1;
55 static int hf_flags_interdomain_trust = -1;
56 static int hf_flags_mns_user = -1;
57 static int hf_flags_normal_user = -1;
58 static int hf_flags_temp_dup_user = -1;
59 static int hf_flags_password_required = -1;
60 static int hf_flags_homedir_required = -1;
61 static int hf_flags_enabled = -1;
62 static int hf_domain_sid_size = -1;
63 static int hf_domain_sid = -1;
64 static int hf_low_serial = -1;
65 static int hf_pulse = -1;
66 static int hf_random = -1;
67 static int hf_db_count = -1;
68 static int hf_db_index = -1;
69 static int hf_large_serial = -1;
70 static int hf_nt_date_time = -1;
71
72 static int ett_smb_logon = -1;
73 static int ett_smb_account_flags = -1;
74 static int ett_smb_db_info = -1;
75
76 #define ACC_FLAG_AUTO_LOCKED                    0x0400
77 #define ACC_FLAG_EXPIRE                         0x0200
78 #define ACC_FLAG_SERVER_TRUST                   0x0100
79 #define ACC_FLAG_WORKSTATION_TRUST              0x0080
80 #define ACC_FLAG_INTERDOMAIN_TRUST              0x0040
81 #define ACC_FLAG_MNS_USER                       0x0020
82 #define ACC_FLAG_NORMAL_USER                    0x0010
83 #define ACC_FLAG_TEMP_DUP_USER                  0x0008
84 #define ACC_FLAG_PASSWORD_REQUIRED              0x0004
85 #define ACC_FLAG_HOMEDIR_REQUIRED               0x0002
86 #define ACC_FLAG_ENABLED                        0x0001
87
88 static const true_false_string tfs_flags_autolock = {
89         "User account auto-locked",
90         "User account NOT auto-locked"
91 };
92 static const true_false_string tfs_flags_expire = {
93         "User password will NOT expire",
94         "User password will expire"
95 };
96 static const true_false_string tfs_flags_server_trust = {
97         "Server Trust user account",
98         "NOT a Server Trust user account"
99 };
100 static const true_false_string tfs_flags_workstation_trust = {
101         "Workstation Trust user account",
102         "NOT a Workstation Trust user account"
103 };
104 static const true_false_string tfs_flags_interdomain_trust = {
105         "Inter-domain Trust user account",
106         "NOT a Inter-domain Trust user account"
107 };
108 static const true_false_string tfs_flags_mns_user = {
109         "MNS Logon user account",
110         "NOT a MNS Logon user account"
111 };
112 static const true_false_string tfs_flags_normal_user = {
113         "Normal user account",
114         "NOT a normal user account"
115 };
116 static const true_false_string tfs_flags_temp_dup_user = {
117         "Temp duplicate user account",
118         "NOT a temp duplicate user account"
119 };
120 static const true_false_string tfs_flags_password_required = {
121         "NO password required",
122         "Password required"
123 };
124 static const true_false_string tfs_flags_homedir_required = {
125         "NO homedir required",
126         "Homedir required"
127 };
128 static const true_false_string tfs_flags_enabled = {
129         "User account enabled",
130         "User account disabled"
131 };
132
133
134
135 static int
136 dissect_account_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
137 {
138         /* display the Allowable Account control bits */
139
140         proto_item *ti = NULL;
141         proto_tree *flags_tree = NULL;
142         guint32 flags;
143
144         flags = tvb_get_letohl(tvb, offset);
145
146         if (tree) {
147                 ti = proto_tree_add_text(tree, tvb, offset, 4,
148                         "Account control  = 0x%04x", flags);
149
150                 flags_tree = proto_item_add_subtree(ti, ett_smb_account_flags);
151         }
152
153         proto_tree_add_boolean(flags_tree, hf_flags_autolock, tvb, offset, 4, flags);
154         proto_tree_add_boolean(flags_tree, hf_flags_expire, tvb, offset, 4, flags);
155         proto_tree_add_boolean(flags_tree, hf_flags_server_trust, tvb, offset, 4, flags);
156         proto_tree_add_boolean(flags_tree, hf_flags_workstation_trust, tvb, offset, 4, flags);
157         proto_tree_add_boolean(flags_tree, hf_flags_interdomain_trust, tvb, offset, 4, flags);
158         proto_tree_add_boolean(flags_tree, hf_flags_mns_user, tvb, offset, 4, flags);
159         proto_tree_add_boolean(flags_tree, hf_flags_normal_user, tvb, offset, 4, flags);
160         proto_tree_add_boolean(flags_tree, hf_flags_temp_dup_user, tvb, offset, 4, flags);
161         proto_tree_add_boolean(flags_tree, hf_flags_password_required, tvb, offset, 4, flags);
162         proto_tree_add_boolean(flags_tree, hf_flags_homedir_required, tvb, offset, 4, flags);
163         proto_tree_add_boolean(flags_tree, hf_flags_enabled, tvb, offset, 4, flags);
164
165         offset += 4;
166
167         return offset;
168 }
169
170 static int
171 display_LM_token(tvbuff_t *tvb, int offset, packet_info *pinfo,
172     proto_tree *tree)
173 {
174         guint16 Token;
175
176         Token = tvb_get_letohs(tvb, offset);
177
178         if (Token & 0x01) {
179                 proto_tree_add_uint_format(tree, hf_lm_token, tvb, offset, 2, 
180                         Token,
181                         "LM20 Token: 0x%04x (LanMan 2.0 or higher)", Token);
182         } else {
183                 /*
184                  * XXX - are all values with the lower bit set LM 2.0,
185                  * and all values with it not set LM 1.0?
186                  * What do the other bits mean, if anything?
187                  */
188                 proto_tree_add_uint_format(tree, hf_lm_token, tvb, offset, 2, 
189                         Token,
190                         "LM10 Token: 0x%04x (WFW Networking)", Token);
191         }
192
193         offset += 2;
194
195         return offset;
196 }
197
198 static int
199 display_LMNT_token(tvbuff_t *tvb, int offset, packet_info *pinfo,
200     proto_tree *tree)
201 {
202         guint16 Token;
203
204         Token = tvb_get_letohs(tvb, offset);
205
206         if (Token == 0xffff) {
207                 proto_tree_add_uint_format(tree, hf_lmnt_token, tvb, offset, 2, 
208                         Token,
209                         "LMNT Token: 0x%04x (Windows NT Networking)", Token);
210         } else {
211                 /*
212                  * XXX - what is it if it's not 0xffff?
213                  */
214                 proto_tree_add_uint_format(tree, hf_lm_token, tvb, offset, 2, 
215                         Token,
216                         "LMNT Token: 0x%04x (Unknown)", Token);
217         }
218
219         offset += 2;
220
221         return offset;
222 }
223
224 static int
225 dissect_smb_logon_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
226 {
227         /*** 0x00 (LM1.0/LM2.0 LOGON Request) ***/
228  
229         /* computer name */
230         offset = display_ms_string(tvb, pinfo, tree, offset, hf_computer_name);
231
232         /* user name */
233         offset = display_ms_string(tvb, pinfo, tree, offset, hf_user_name);
234
235         /* mailslot name */
236         offset = display_ms_string(tvb, pinfo, tree, offset, hf_mailslot_name);
237
238         /*$$$$$ here add the Mailslot to the response list (if needed) */
239
240         /* Request count */
241         proto_tree_add_item(tree, hf_request_count, tvb, offset, 1, TRUE);
242         offset += 1;
243
244         /* NT version */
245         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 2, TRUE);
246         offset += 2;
247
248         /* LM token */
249         offset = display_LM_token(tvb, offset, pinfo, tree);
250
251         return offset;
252 }
253
254
255
256 static int
257 dissect_smb_logon_LM10_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
258 {
259         /*** 0x01 LanMan 1.0 Logon response ***/
260
261         /* user name */
262         offset = display_ms_string(tvb, pinfo, tree, offset, hf_user_name);
263
264         /* script name */
265         offset = display_ms_string(tvb, pinfo, tree, offset, hf_script_name);
266
267         return offset;
268 }
269
270
271 static int
272 dissect_smb_logon_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
273 {
274         /*** 0x02  LM1.0 Query - Centralized Initialization ***/
275         /*** 0x03  LM1.0 Query - Distributed Initialization ***/
276         /*** 0x04  LM1.0 Query - Centralized Query Response ***/
277         /*** 0x04  LM1.0 Query - Distributed Query Response ***/
278
279         /* computer name */
280         offset = display_ms_string(tvb, pinfo, tree, offset, hf_computer_name);
281
282         /* mailslot name */
283         offset = display_ms_string(tvb, pinfo, tree, offset, hf_mailslot_name);
284
285         /* NT version */
286         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 2, TRUE);
287         offset += 2;
288
289         /* LM token */
290         offset = display_LM_token(tvb, offset, pinfo, tree);
291
292         return offset;
293 }
294
295
296
297 static int
298 dissect_smb_logon_LM20_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
299 {
300         /*** 0x06 (LM2.0 LOGON Response)        ***/
301
302         /* server name */
303         offset = display_ms_string(tvb, pinfo, tree, offset, hf_server_name);
304
305         /* LM token */
306         offset = display_LM_token(tvb, offset, pinfo, tree);
307
308         return offset;
309 }
310
311
312
313 static int
314 dissect_smb_pdc_query(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
315 {
316         /*** 0x07 Query for Primary PDC  ***/
317  
318         /* computer name */
319         offset = display_ms_string(tvb, pinfo, tree, offset, hf_computer_name);
320
321         /* mailslot name */
322         offset = display_ms_string(tvb, pinfo, tree, offset, hf_mailslot_name);
323
324         if (tvb_reported_length_remaining(tvb, offset) > 2) {
325                 /*
326                  * NT-style Query for PDC?
327                  * If only 2 bytes remain, it's probably a Windows 95-style
328                  * query, which has only an LM token after the mailslot
329                  * name.
330                  *
331                  * XXX - base this on flags in the SMB header, e.g.
332                  * the ASCII/Unicode strings flag?
333                  */
334                 if (offset % 2) offset++;      /* word align ... */
335
336                 /* Unicode computer name */
337                 offset = display_unicode_string(tvb, pinfo, tree, offset, hf_unicode_computer_name);
338
339                 /* NT version */
340                 proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
341                 offset += 4;
342
343                 /* LMNT token */
344                 offset = display_LMNT_token(tvb, offset, pinfo, tree);
345         }
346
347         /* LM token */
348         offset = display_LM_token(tvb, offset, pinfo, tree);
349
350         return offset;
351 }
352
353
354
355 static int
356 dissect_smb_pdc_startup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
357 {
358         /*** 0x08  Announce startup of PDC ***/
359  
360         /* pdc name */
361         offset = display_ms_string(tvb, pinfo, tree, offset, hf_pdc_name);
362
363         /* A short Announce will not have the rest */
364
365         if (tvb_length_remaining(tvb, offset) != 0) { 
366
367           if (offset % 2) offset++;      /* word align ... */
368
369           /* pdc name */
370           offset = display_unicode_string(tvb, pinfo, tree, offset, hf_unicode_pdc_name);
371
372           if (offset % 2) offset++;
373
374           /* domain name */
375           offset = display_unicode_string(tvb, pinfo, tree, offset, hf_domain_name);
376
377           /* NT version */
378           proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
379           offset += 4;
380
381           /* LMNT token */
382           offset = display_LMNT_token(tvb, offset, pinfo, tree);
383
384           /* LM token */
385           offset = display_LM_token(tvb, offset, pinfo, tree);
386         }
387
388         return offset;
389 }
390
391
392
393 static int
394 dissect_smb_pdc_failure(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
395 {
396         /*** 0x09 Announce failure of the PDC ***/
397         /*** 0x0F LM2.0 Resp. during LOGON pause ***/
398         /*** 0x10 (LM 2.0 Unknown user response) ***/
399
400         /* NT version */
401         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
402         offset += 4;
403
404         /* LM token */
405         offset = display_LM_token(tvb, offset, pinfo, tree);
406
407         return offset;
408 }
409
410
411 static int
412 dissect_announce_change(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
413 {
414         /*** 0x0A ( Announce change to UAS or SAM ) ***/
415         guint32 info_count;
416         proto_item *ti = NULL;
417         proto_tree *info_tree = NULL;
418         guint32 db_index;
419         guint32 domain_sid_size;
420
421         /* low serial number */
422         proto_tree_add_item(tree, hf_low_serial, tvb, offset, 4, TRUE);
423         offset += 4;
424
425         /* date/time */
426         proto_tree_add_item(tree, hf_date_time, tvb, offset, 4, TRUE);
427         offset += 4;
428
429         /* pulse */
430         proto_tree_add_item(tree, hf_pulse, tvb, offset, 4, TRUE);
431         offset += 4;
432
433         /* random */
434         proto_tree_add_item(tree, hf_random, tvb, offset, 4, TRUE);
435         offset += 4;
436
437         /* pdc name */
438         offset = display_ms_string(tvb, pinfo, tree, offset, hf_pdc_name);
439
440         /* domain name */
441         offset = display_ms_string(tvb, pinfo, tree, offset, hf_domain_name);
442
443         if (offset % 2) offset++;      /* word align ... */
444
445         /* pdc name */
446         offset = display_unicode_string(tvb, pinfo, tree, offset, hf_unicode_pdc_name);
447
448         /* domain name */
449         offset = display_unicode_string(tvb, pinfo, tree, offset, hf_domain_name);
450
451         /* DB count */
452         info_count = tvb_get_letohl(tvb, offset);
453         proto_tree_add_uint(tree, hf_db_count, tvb, offset, 4, info_count);
454         offset += 4;
455
456         while (info_count != 0) {
457                 db_index = tvb_get_letohl(tvb, offset);
458                 if (tree) {
459                         ti = proto_tree_add_text(tree, tvb, offset, 20,
460                             "DBChange Info Structure: index %u", db_index);
461                         info_tree = proto_item_add_subtree(ti, ett_smb_db_info);
462                 }
463
464                 proto_tree_add_uint(info_tree, hf_db_index, tvb, offset, 4,
465                     db_index);
466                 offset += 4;
467
468                 proto_tree_add_item(info_tree, hf_large_serial, tvb, offset, 8,
469                     FALSE);
470                 offset += 8;
471
472                 proto_tree_add_item(info_tree, hf_nt_date_time, tvb, offset, 8,
473                     FALSE);
474                 offset += 8;
475
476                 info_count--;
477         }
478
479         /* Domain SID Size */
480         domain_sid_size = tvb_get_letohl(tvb, offset);
481         proto_tree_add_uint(tree, hf_domain_sid_size, tvb, offset, 4,
482             domain_sid_size);
483         offset += 4;
484
485         if (domain_sid_size != 0) {
486                 /* Domain SID */
487                 proto_tree_add_item(tree, hf_domain_sid, tvb, offset,
488                     domain_sid_size, TRUE);
489                 offset += domain_sid_size;
490         }
491
492         /* NT version */
493         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
494         offset += 4;
495
496         /* LMNT token */
497         offset = display_LMNT_token(tvb, offset, pinfo, tree);
498
499         /* LM token */
500         offset = display_LM_token(tvb, offset, pinfo, tree);
501
502         return offset;
503 }
504
505
506
507 static int
508 dissect_smb_sam_logon_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
509 {
510         /* Netlogon command 0x12 - decode the SAM logon request from client */
511
512         guint32 domain_sid_size;
513
514         /* Request count */
515         proto_tree_add_item(tree, hf_request_count, tvb, offset, 2, TRUE);
516         offset += 2;
517
518         /* computer name */
519         offset = display_unicode_string(tvb, pinfo, tree, offset, hf_unicode_computer_name);
520
521         /* user name */
522         offset = display_unicode_string(tvb, pinfo, tree, offset, hf_user_name);
523
524         /* mailslot name */
525         offset = display_ms_string(tvb, pinfo, tree, offset, hf_mailslot_name);
526
527         /* account control */
528         offset = dissect_account_control(tvb, pinfo, tree, offset);
529
530         /* Domain SID Size */
531         domain_sid_size = tvb_get_letohl(tvb, offset);
532         proto_tree_add_uint(tree, hf_domain_sid_size, tvb, offset, 4,
533             domain_sid_size);
534         offset += 4;
535
536         if (domain_sid_size != 0) {
537                 /* Domain SID */
538                 proto_tree_add_item(tree, hf_domain_sid, tvb, offset,
539                     domain_sid_size, TRUE);
540                 offset += domain_sid_size;
541
542                 /* XXX - at least one packet appears to put the NT version on
543                    a 4-byte boundary, with padding after the domain SID, at
544                    least according to Network Monitor.
545
546                    However, another frame, with a zero-length domain SID,
547                    doesn't do any padding, and other packets don't appear
548                    to put the NT version of a 4-byte boundary, so maybe
549                    the padding comes *before* the domain SID, and NetMon
550                    is just confused?  (NetMon has been known to misdissect
551                    SMB packets, even though, err, umm, NetMon comes from
552                    the people who are adding all this stuff to SMB....) */
553                 offset = ((offset + 3)/4)*4;
554         }
555         
556         /* NT version */
557         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
558         offset += 4;
559
560         /* LMNT token */
561         offset = display_LMNT_token(tvb, offset, pinfo, tree);
562
563         /* LM token */
564         offset = display_LM_token(tvb, offset, pinfo, tree);
565
566         return offset;
567 }
568
569
570
571 static int
572 dissect_smb_no_user(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
573 {
574         /* 0x0B (Announce no user on machine) */
575
576         /* computer name */
577         offset = display_ms_string(tvb, pinfo, tree, offset, hf_computer_name);
578
579         return offset;
580 }
581
582
583
584 static int
585 dissect_smb_relogon_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
586 {
587         /*** 0x0d LanMan Response to relogon request ***/
588
589         /* Major version */
590         proto_tree_add_item(tree, hf_major_version, tvb, offset, 1, TRUE);
591         offset += 1;
592
593         /* Minor version */
594         proto_tree_add_item(tree, hf_minor_version, tvb, offset, 1, TRUE);
595         offset += 1;
596
597         /* OS version */
598         proto_tree_add_item(tree, hf_os_version, tvb, offset, 1, TRUE);
599         offset += 1;
600
601         /* NT version */
602         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
603         offset += 4;
604
605         /* LM token */
606         offset = display_LM_token(tvb, offset, pinfo, tree);
607
608         return offset;
609 }
610
611
612
613 static int
614 dissect_smb_acc_update(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
615 {
616         /*** 0x11  LM2.1 Announce Acc updates  ***/
617
618         guint32 Temp1, Temp2;
619
620         Temp1 = tvb_get_letohl(tvb, offset);
621         Temp2 = tvb_get_letohl(tvb, offset + 4);
622
623         /* signature */
624         proto_tree_add_text(tree, tvb, offset, 8, "Signature: 0x%08x%08x",
625                 Temp1, Temp2);
626         offset += 8;
627
628         /* date/time */
629         proto_tree_add_item(tree, hf_date_time, tvb, offset, 4, TRUE);
630         offset += 4;
631
632         /* computer name */
633         offset = display_ms_string(tvb, pinfo, tree, offset, hf_computer_name);
634
635         /* user name */
636         offset = display_ms_string(tvb, pinfo, tree, offset, hf_user_name);
637
638         /* update type */
639         proto_tree_add_item(tree, hf_update_type, tvb, offset, 2, TRUE);
640         offset += 2;
641
642         /* NT version */
643         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
644         offset += 4;
645
646         /* LM token */
647         offset = display_LM_token(tvb, offset, pinfo, tree);
648
649         return offset;
650 }
651
652
653
654 static int
655 dissect_smb_inter_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
656 {
657         /* 0x0e LanMan Response to interrogate request */
658
659         /* Major version */
660         proto_tree_add_item(tree, hf_major_version, tvb, offset, 1, TRUE);
661         offset += 1;
662
663         /* Minor version */
664         proto_tree_add_item(tree, hf_minor_version, tvb, offset, 1, TRUE);
665         offset += 1;
666
667         /* OS version */
668         proto_tree_add_item(tree, hf_os_version, tvb, offset, 1, TRUE);
669         offset += 1;
670
671         /* NT version */
672         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
673         offset += 4;
674
675         /* LMNT token */
676         offset = display_LMNT_token(tvb, offset, pinfo, tree);
677
678         /* XXX - no LM token?  Every other packet has one after the LMNT
679            token. */
680
681         return offset;
682 }
683
684
685 static int
686 dissect_smb_sam_logon_resp(tvbuff_t *tvb, packet_info *pinfo,
687         proto_tree *tree, int offset)
688 {
689         /* Netlogon command 0x13 - decode the SAM logon response from server */
690
691         /* server name */
692         offset = display_unicode_string(tvb, pinfo, tree, offset, hf_server_name);
693
694         /* user name */
695         offset = display_unicode_string(tvb, pinfo, tree, offset, hf_user_name);
696
697         /* domain name */
698         offset = display_unicode_string(tvb, pinfo, tree, offset, hf_domain_name);
699
700         /* NT version */
701         proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
702         offset += 4;
703
704         /* LMNT token */
705         offset = display_LMNT_token(tvb, offset, pinfo, tree);
706
707         /* LM token */
708         offset = display_LM_token(tvb, offset, pinfo, tree);
709
710         return offset;
711 }
712
713
714 #define LOGON_LM10_LOGON_REQUEST                0x00
715 #define LOGON_LM10_LOGON_RESPONSE               0x01
716 #define LOGON_LM10_QUERY_CI                     0x02
717 #define LOGON_LM10_QUERY_DI                     0x03
718 #define LOGON_LM10_RESPONSE_CI                  0x04
719 #define LOGON_LM10_RESPONSE_DI                  0x05
720 #define LOGON_LM20_LOGON_RESPONSE               0x06
721 #define LOGON_PDC_QUERY                         0x07
722 #define LOGON_PDC_STARTUP                       0x08
723 #define LOGON_PDC_FAILED                        0x09
724 #define LOGON_UAS_SAM                           0x0a
725 #define LOGON_NO_USER                           0x0b
726 #define LOGON_PDC_RESPONSE                      0x0c
727 #define LOGON_RELOGON_RESPONSE                  0x0d
728 #define LOGON_INTERROGATE_RESPONSE              0x0e
729 #define LOGON_LM20_RESPONSE_DURING_LOGON        0x0f
730 #define LOGON_LM20_USER_UNKNOWN                 0x10
731 #define LOGON_LM20_ACCOUNT_UPDATE               0x11
732 #define LOGON_SAM_LOGON_REQUEST                 0x12
733 #define LOGON_SAM_LOGON_RESPONSE                0x13
734 #define LOGON_SAM_RESPONSE_DURING_LOGON         0x14
735 #define LOGON_SAM_USER_UNKNOWN                  0x15
736 #define LOGON_SAM_INTERROGATE_RESPONSE          0x16
737 #define LOGON_LAST_CMD                          0x17
738
739 static const value_string commands[] = {
740         {LOGON_LM10_LOGON_REQUEST,      "LM1.0/LM2.0 LOGON Request"},
741         {LOGON_LM10_LOGON_RESPONSE,     "LM1.0 LOGON Response"},
742         {LOGON_LM10_QUERY_CI,           "LM1.0 Query - Centralized Initialization"},
743         {LOGON_LM10_QUERY_DI,           "LM1.0 Query - Distributed Initialization"},
744         {LOGON_LM10_RESPONSE_CI,        "LM1.0 Response - Centralized Query"},
745         {LOGON_LM10_RESPONSE_DI,        "LM1.0 Response - Distributed Initialization"},
746         {LOGON_LM20_LOGON_RESPONSE,     "LM2.0 Response to LOGON Request"},
747         {LOGON_PDC_QUERY,               "Query for PDC"},
748         {LOGON_PDC_STARTUP,             "Announce Startup of PDC"},
749         {LOGON_PDC_FAILED,              "Announce Failed PDC"},
750         {LOGON_UAS_SAM,                 "Announce Change to UAS or SAM"},
751         {LOGON_NO_USER,                 "Announce no user on machine"},
752         {LOGON_PDC_RESPONSE,            "Response from PDC"},
753         {LOGON_RELOGON_RESPONSE,        "LM1.0/LM2.0 Response to re-LOGON Request"},
754         {LOGON_INTERROGATE_RESPONSE,    "LM1.0/LM2.0 Response to Interrogate Request"},
755         {LOGON_LM20_RESPONSE_DURING_LOGON,"LM2.0 Response during LOGON pause"},
756         {LOGON_LM20_USER_UNKNOWN,       "LM2.0 Response - user unknown"},
757         {LOGON_LM20_ACCOUNT_UPDATE,     "LM2.0 Announce account updates"},
758         {LOGON_SAM_LOGON_REQUEST,       "SAM LOGON request from client"},
759         {LOGON_SAM_LOGON_RESPONSE,      "Response to SAM LOGON request"},
760         {LOGON_SAM_RESPONSE_DURING_LOGON,"SAM Response during LOGON pause"},
761         {LOGON_SAM_USER_UNKNOWN,        "SAM Response - user unknown"},
762         {LOGON_SAM_INTERROGATE_RESPONSE,"SAM Response to Interrogate Request"},
763         {0,     NULL}
764 };
765
766
767 static int (*dissect_smb_logon_cmds[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) = {
768         dissect_smb_logon_request,  /* 0x00 (LM1.0/LM2.0 LOGON Request) */
769         dissect_smb_logon_LM10_resp,/* 0x01 (LM1.0 LOGON Response)      */
770         dissect_smb_logon_2,        /* 0x02 (LM1.0 Query Centralized Init.)*/
771         dissect_smb_logon_2,        /* 0x03 (LM1.0 Query Distributed Init.)*/
772         dissect_smb_logon_2,        /* 0x04 (LM1.0 Centralized Query Resp.)*/
773         dissect_smb_logon_2,        /* 0x05 (LM1.0 Distributed Query Resp.) */
774         dissect_smb_logon_LM20_resp,/* 0x06 (LM2.0 LOGON Response)      */
775         dissect_smb_pdc_query,      /* 0x07 (Query for PDC)             */
776         dissect_smb_pdc_startup,    /* 0x08 (Announce PDC startup)      */
777         dissect_smb_pdc_failure,    /* 0x09 (Announce Failed PDC)       */
778         dissect_announce_change,    /* 0x0A (Announce Change to UAS or SAM)*/
779         dissect_smb_no_user,        /* 0x0B (Announce no user on machine)*/
780         dissect_smb_pdc_startup,    /* 0x0C (Response from PDC)         */
781         dissect_smb_relogon_resp,   /* 0x0D (Relogon response)          */
782         dissect_smb_inter_resp,     /* 0x0E (Interrogate response)      */
783         dissect_smb_pdc_failure,    /* 0x0F (LM2.0 Resp. during LOGON pause*/
784         dissect_smb_pdc_failure,    /* 0x10 (LM 2.0 Unknown user response)*/
785         dissect_smb_acc_update,     /* 0x11 (LM2.1 Announce Acc updates)*/
786         dissect_smb_sam_logon_req,  /* 0x12 (SAM LOGON request )        */
787         dissect_smb_sam_logon_resp, /* 0x13 (SAM LOGON response)        */
788         dissect_smb_unknown,        /* 0x14 (SAM Response during LOGON Pause) */
789         dissect_smb_unknown,        /* 0x15 (SAM Response User Unknown)      */
790         dissect_smb_unknown,        /* 0x16 (SAM Response to Interrogate)   */
791 };
792
793
794 gboolean
795 dissect_smb_logon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
796 {
797         int        offset = 0;
798         guint8     cmd;
799         proto_tree *smb_logon_tree = NULL;
800         proto_item *item = NULL;
801
802         if (!proto_is_protocol_enabled(proto_smb_logon))
803                 return FALSE;
804
805         pinfo->current_proto = "NETLOGON";
806
807         if (check_col(pinfo->fd, COL_PROTOCOL))
808                 col_set_str(pinfo->fd, COL_PROTOCOL, "NETLOGON");
809         if (check_col(pinfo->fd, COL_INFO))
810                 col_clear(pinfo->fd, COL_INFO);
811
812         /* get the Command field */
813         cmd = tvb_get_guint8(tvb, offset);
814
815         if (check_col(pinfo->fd, COL_INFO))
816                 col_add_str(pinfo->fd, COL_INFO, val_to_str(cmd, commands, "Unknown Command:%02x") );
817
818         if (tree) {
819                 item = proto_tree_add_item(tree, proto_smb_logon, tvb,
820                         offset, tvb_length_remaining(tvb, offset), FALSE);
821
822                 smb_logon_tree = proto_item_add_subtree(item, ett_smb_logon);
823         }
824
825         /* command */
826         proto_tree_add_uint(smb_logon_tree, hf_command, tvb, offset, 1, cmd);
827         offset += 1;
828
829         /* skip next byte */
830         offset += 1;
831
832         if (cmd<LOGON_LAST_CMD) {
833                 offset = (dissect_smb_logon_cmds[cmd])(tvb, pinfo,
834                     smb_logon_tree, offset);
835         } else {
836                 /* unknown command */
837                 offset = dissect_smb_unknown(tvb, pinfo, smb_logon_tree,
838                     offset);
839         }
840
841         return TRUE;
842 }
843
844
845
846 void
847 register_proto_smb_logon( void){
848
849         static hf_register_info hf[] = {
850                 { &hf_command,
851                         { "Command", "netlogon.command", FT_UINT8, BASE_HEX,
852                           VALS(commands), 0, "NETLOGON Command", HFILL }},
853
854                 { &hf_computer_name,
855                         { "Computer Name", "netlogon.computer_name", FT_STRING, BASE_NONE,
856                           NULL, 0, "NETLOGON Computer Name", HFILL }},
857
858                 { &hf_unicode_computer_name,
859                         { "Unicode Computer Name", "netlogon.unicode_computer_name", FT_STRING, BASE_NONE,
860                           NULL, 0, "NETLOGON Unicode Computer Name", HFILL }},
861
862                 { &hf_server_name,
863                         { "Server Name", "netlogon.server_name", FT_STRING, BASE_NONE,
864                           NULL, 0, "NETLOGON Server Name", HFILL }},
865
866                 { &hf_user_name,
867                         { "User Name", "netlogon.user_name", FT_STRING, BASE_NONE,
868                           NULL, 0, "NETLOGON User Name", HFILL }},
869
870                 { &hf_domain_name,
871                         { "Domain Name", "netlogon.domain_name", FT_STRING, BASE_NONE,
872                           NULL, 0, "NETLOGON Domain Name", HFILL }},
873
874                 { &hf_mailslot_name,
875                         { "Mailslot Name", "netlogon.mailslot_name", FT_STRING, BASE_NONE,
876                           NULL, 0, "NETLOGON Mailslot Name", HFILL }},
877
878                 { &hf_pdc_name,
879                         { "PDC Name", "netlogon.pdc_name", FT_STRING, BASE_NONE,
880                           NULL, 0, "NETLOGON PDC Name", HFILL }},
881
882                 { &hf_unicode_pdc_name,
883                         { "Unicode PDC Name", "netlogon.unicode_pdc_name", FT_STRING, BASE_NONE,
884                           NULL, 0, "NETLOGON Unicode PDC Name", HFILL }},
885
886                 { &hf_script_name,
887                         { "Script Name", "netlogon.script_name", FT_STRING, BASE_NONE,
888                           NULL, 0, "NETLOGON Script Name", HFILL }},
889
890                 { &hf_nt_version,
891                         { "NT Version", "netlogon.nt_version", FT_UINT32, BASE_DEC,
892                           NULL, 0, "NETLOGON NT Version", HFILL }},
893
894                 /* An LMNT Token, if 0xffff, is "WindowsNT Networking"; 
895                    what is it otherwise? */
896                 { &hf_lmnt_token,
897                         { "LMNT Token", "netlogon.lmnt_token", FT_UINT16, BASE_HEX,
898                           NULL, 0, "NETLOGON LMNT Token", HFILL }},
899
900                 { &hf_lm_token,
901                         { "LM Token", "netlogon.lm_token", FT_UINT16, BASE_HEX,
902                           NULL, 0, "NETLOGON LM Token", HFILL }},
903
904                 { &hf_major_version,
905                         { "Workstation Major Version", "netlogon.major_version", FT_UINT8, BASE_DEC,
906                           NULL, 0, "NETLOGON Workstation Major Version", HFILL }},
907
908                 { &hf_minor_version,
909                         { "Workstation Minor Version", "netlogon.minor_version", FT_UINT8, BASE_DEC,
910                           NULL, 0, "NETLOGON Workstation Minor Version", HFILL }},
911
912                 { &hf_os_version,
913                         { "Workstation OS Version", "netlogon.os_version", FT_UINT8, BASE_DEC,
914                           NULL, 0, "NETLOGON Workstation OS Version", HFILL }},
915
916                 { &hf_date_time,
917                         { "Date/Time", "netlogon.date_time", FT_UINT32, BASE_DEC,
918                           NULL, 0, "NETLOGON Date/Time", HFILL }},
919
920                 { &hf_update_type,
921                         { "Update Type", "netlogon.update", FT_UINT16, BASE_DEC,
922                           NULL, 0, "NETLOGON Update Type", HFILL }},
923
924                 { &hf_request_count,
925                         { "Request Count", "netlogon.request_count", FT_UINT16, BASE_DEC,
926                           NULL, 0, "NETLOGON Request Count", HFILL }},
927
928                 { &hf_flags_autolock,
929                         { "Autolock", "netlogon.flags.autolock", FT_BOOLEAN, 32,
930                         TFS(&tfs_flags_autolock), ACC_FLAG_AUTO_LOCKED, "NETLOGON Account Autolock", HFILL}},
931
932                 { &hf_flags_expire,
933                         { "Expire", "netlogon.flags.expire", FT_BOOLEAN, 32,
934                         TFS(&tfs_flags_expire), ACC_FLAG_EXPIRE, "NETLOGON Will Account Expire", HFILL}},
935
936                 { &hf_flags_server_trust,
937                         { "Server Trust", "netlogon.flags.server", FT_BOOLEAN, 32,
938                         TFS(&tfs_flags_server_trust), ACC_FLAG_SERVER_TRUST, "NETLOGON Server Trust Account", HFILL}},
939
940                 { &hf_flags_workstation_trust,
941                         { "Workstation Trust", "netlogon.flags.workstation", FT_BOOLEAN, 32,
942                         TFS(&tfs_flags_workstation_trust), ACC_FLAG_WORKSTATION_TRUST, "NETLOGON Workstation Trust Account", HFILL}},
943
944                 { &hf_flags_interdomain_trust,
945                         { "Interdomain Trust", "netlogon.flags.interdomain", FT_BOOLEAN, 32,
946                         TFS(&tfs_flags_interdomain_trust), ACC_FLAG_INTERDOMAIN_TRUST, "NETLOGON Inter-domain Trust Account", HFILL}},
947
948                 { &hf_flags_mns_user,
949                         { "MNS User", "netlogon.flags.mns", FT_BOOLEAN, 32,
950                         TFS(&tfs_flags_mns_user), ACC_FLAG_MNS_USER, "NETLOGON MNS User Account", HFILL}},
951
952                 { &hf_flags_normal_user,
953                         { "Normal User", "netlogon.flags.normal", FT_BOOLEAN, 32,
954                         TFS(&tfs_flags_normal_user), ACC_FLAG_NORMAL_USER, "NETLOGON Normal User Account", HFILL}},
955
956                 { &hf_flags_temp_dup_user,
957                         { "Temp Duplicate User", "netlogon.flags.temp_dup", FT_BOOLEAN, 32,
958                         TFS(&tfs_flags_temp_dup_user), ACC_FLAG_TEMP_DUP_USER, "NETLOGON Temp Duplicate User Account", HFILL}},
959
960                 { &hf_flags_password_required,
961                         { "Password", "netlogon.flags.password", FT_BOOLEAN, 32,
962                         TFS(&tfs_flags_password_required), ACC_FLAG_PASSWORD_REQUIRED, "NETLOGON Password Required", HFILL}},
963
964                 { &hf_flags_homedir_required,
965                         { "Homedir", "netlogon.flags.homedir", FT_BOOLEAN, 32,
966                         TFS(&tfs_flags_homedir_required), ACC_FLAG_HOMEDIR_REQUIRED, "NETLOGON Homedir Required", HFILL}},
967
968                 { &hf_flags_enabled,
969                         { "Enabled", "netlogon.flags.enabled", FT_BOOLEAN, 32,
970                         TFS(&tfs_flags_enabled), ACC_FLAG_ENABLED, "NETLOGON Is This Account Enabled", HFILL}},
971
972                 { &hf_domain_sid_size,
973                         { "Domain SID Size", "netlogon.domain_sid_size", FT_UINT32, BASE_DEC,
974                           NULL, 0, "NETLOGON Domain SID Size", HFILL }},
975
976                 { &hf_domain_sid,
977                         { "Domain SID", "netlogon.domain_sid", FT_BYTES, BASE_NONE,
978                           NULL, 0, "NETLOGON Domain SID", HFILL }},
979
980                 { &hf_low_serial,
981                         { "Low Serial Number", "netlogon.low_serial", FT_UINT32, BASE_DEC,
982                           NULL, 0, "NETLOGON Low Serial Number", HFILL }},
983
984                 { &hf_pulse,
985                         { "Pulse", "netlogon.pulse", FT_UINT32, BASE_DEC,
986                           NULL, 0, "NETLOGON Pulse", HFILL }},
987
988                 { &hf_random,
989                         { "Random", "netlogon.random", FT_UINT32, BASE_DEC,
990                           NULL, 0, "NETLOGON Random", HFILL }},
991
992                 { &hf_db_count,
993                         { "DB Count", "netlogon.db_count", FT_UINT32, BASE_DEC,
994                           NULL, 0, "NETLOGON DB Count", HFILL }},
995
996                 { &hf_db_index,
997                         { "Database Index", "netlogon.db_index", FT_UINT32, BASE_DEC,
998                           NULL, 0, "NETLOGON Database Index", HFILL }},
999
1000                 /* XXX - 64-bit integer? */
1001                 { &hf_large_serial,
1002                         { "Large Serial Number", "netlogon.large_serial", FT_BYTES, BASE_NONE,
1003                           NULL, 0, "NETLOGON Large Serial Number", HFILL }},
1004
1005                 /* XXX - 64-bit FILETIME */
1006                 { &hf_nt_date_time,
1007                         { "NT Date/Time", "netlogon.nt_date_time", FT_BYTES, BASE_NONE,
1008                           NULL, 0, "NETLOGON NT Date/Time", HFILL }},
1009         };
1010
1011         static gint *ett[] = {
1012                 &ett_smb_logon,
1013                 &ett_smb_account_flags,
1014                 &ett_smb_db_info
1015         };
1016
1017         proto_smb_logon = proto_register_protocol(
1018                 "Microsoft Windows Logon Protocol", "NETLOGON", "netlogon");
1019
1020         proto_register_field_array(proto_smb_logon, hf, array_length(hf));
1021         proto_register_subtree_array(ett, array_length(ett));          
1022 }