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