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