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