1997-12-13 14:16:07 +00:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
NBT netbios routines and daemon - version 2
1998-01-22 13:27:43 +00:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Luke Kenneth Casson Leighton 1994 - 1998
Copyright ( C ) Jeremy Allison 1994 - 1998
1997-12-13 14:16:07 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
Revision History :
*/
# include "includes.h"
extern int DEBUGLEVEL ;
1998-04-25 01:12:08 +00:00
extern pstring global_myname ;
extern fstring global_myworkgroup ;
1997-12-13 14:16:07 +00:00
/****************************************************************************
Process a domain logon packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void process_logon_packet ( struct packet_struct * p , char * buf , int len ,
char * mailslot )
{
struct dgram_packet * dgram = & p - > packet . dgram ;
pstring my_name ;
fstring reply_name ;
pstring outbuf ;
1998-09-28 21:43:48 +00:00
int code ;
1997-12-13 14:16:07 +00:00
uint16 token = 0 ;
uint32 ntversion ;
uint16 lmnttoken ;
uint16 lm20token ;
uint32 domainsidsize ;
char * getdc ;
char * uniuser ; /* Unicode user name. */
1999-12-13 13:27:58 +00:00
pstring ascuser ;
1997-12-13 14:16:07 +00:00
char * unicomp ; /* Unicode computer name. */
1998-10-21 01:35:01 +00:00
memset ( outbuf , 0 , sizeof ( outbuf ) ) ;
1997-12-13 14:16:07 +00:00
if ( ! lp_domain_logons ( ) )
{
1997-12-16 09:20:34 +00:00
DEBUG ( 3 , ( " process_logon_packet: Logon packet received from IP %s and domain \
1997-12-13 14:16:07 +00:00
logons are not enabled . \ n " , inet_ntoa(p->ip) ));
return ;
}
1998-05-12 00:55:32 +00:00
pstrcpy ( my_name , global_myname ) ;
1997-12-13 14:16:07 +00:00
strupper ( my_name ) ;
code = SVAL ( buf , 0 ) ;
DEBUG ( 1 , ( " process_logon_packet: Logon from %s: code = %x \n " , inet_ntoa ( p - > ip ) , code ) ) ;
switch ( code )
{
case 0 :
{
char * q = buf + 2 ;
char * machine = q ;
char * user = skip_string ( machine , 1 ) ;
getdc = skip_string ( user , 1 ) ;
q = skip_string ( getdc , 1 ) ;
token = SVAL ( q , 3 ) ;
1998-05-12 00:55:32 +00:00
fstrcpy ( reply_name , my_name ) ;
1997-12-13 14:16:07 +00:00
DEBUG ( 3 , ( " process_logon_packet: Domain login request from %s at IP %s user=%s token=%x \n " ,
machine , inet_ntoa ( p - > ip ) , user , token ) ) ;
q = outbuf ;
1998-09-29 17:16:15 +00:00
SSVAL ( q , 0 , 6 ) ;
q + = 2 ;
1997-12-13 14:16:07 +00:00
1998-05-12 00:55:32 +00:00
fstrcpy ( reply_name , " \\ \\ " ) ;
fstrcat ( reply_name , my_name ) ;
fstrcpy ( q , reply_name ) ; q = skip_string ( q , 1 ) ; /* PDC name */
1997-12-13 14:16:07 +00:00
1998-09-29 17:16:15 +00:00
SSVAL ( q , 0 , token ) ;
q + = 2 ;
1997-12-13 14:16:07 +00:00
dump_data ( 4 , outbuf , PTR_DIFF ( q , outbuf ) ) ;
send_mailslot ( True , getdc ,
outbuf , PTR_DIFF ( q , outbuf ) ,
dgram - > dest_name . name ,
dgram - > dest_name . name_type ,
dgram - > source_name . name ,
dgram - > source_name . name_type ,
1998-08-30 17:04:24 +00:00
p - > ip , * iface_ip ( p - > ip ) , p - > port ) ;
1997-12-13 14:16:07 +00:00
break ;
}
case QUERYFORPDC :
{
char * q = buf + 2 ;
char * machine = q ;
getdc = skip_string ( machine , 1 ) ;
unicomp = skip_string ( getdc , 1 ) ;
q = align2 ( unicomp , buf ) ;
1999-12-13 13:27:58 +00:00
q = skip_unicode_string ( q , 1 ) ;
1997-12-13 14:16:07 +00:00
1998-09-29 17:16:15 +00:00
ntversion = IVAL ( q , 0 ) ;
q + = 4 ;
lmnttoken = SVAL ( q , 0 ) ;
q + = 2 ;
lm20token = SVAL ( q , 0 ) ;
q + = 2 ;
1997-12-13 14:16:07 +00:00
/* Construct reply. */
q = outbuf ;
1998-09-29 17:16:15 +00:00
SSVAL ( q , 0 , QUERYFORPDC_R ) ;
q + = 2 ;
1997-12-13 14:16:07 +00:00
1998-05-12 00:55:32 +00:00
fstrcpy ( reply_name , my_name ) ;
1998-09-29 17:16:15 +00:00
fstrcpy ( q , reply_name ) ;
1999-12-13 13:27:58 +00:00
1998-09-29 17:16:15 +00:00
q = skip_string ( q , 1 ) ; /* PDC name */
1997-12-13 14:16:07 +00:00
1999-12-13 13:27:58 +00:00
if ( strcmp ( mailslot , NT_LOGON_MAILSLOT ) = = 0 ) {
1999-08-08 04:51:13 +00:00
q = align2 ( q , buf ) ;
1999-12-13 13:27:58 +00:00
dos_PutUniCode ( q , my_name , sizeof ( pstring ) ) ; /* PDC name */
q = skip_unicode_string ( q , 1 ) ;
1999-08-08 04:51:13 +00:00
1999-12-13 13:27:58 +00:00
dos_PutUniCode ( q , global_myworkgroup , sizeof ( pstring ) ) ; /* Domain name*/
q = skip_unicode_string ( q , 1 ) ;
1999-11-18 00:26:11 +00:00
1999-08-08 04:51:13 +00:00
SIVAL ( q , 0 , ntversion ) ;
q + = 4 ;
SSVAL ( q , 0 , lmnttoken ) ;
q + = 2 ;
SSVAL ( q , 0 , lm20token ) ;
q + = 2 ;
}
1997-12-13 14:16:07 +00:00
DEBUG ( 3 , ( " process_logon_packet: GETDC request from %s at IP %s, \
reporting % s domain % s 0 x % x ntversion = % x lm_nt token = % x lm_20 token = % x \ n " ,
machine , inet_ntoa ( p - > ip ) , reply_name , lp_workgroup ( ) ,
QUERYFORPDC_R , ( uint32 ) ntversion , ( uint32 ) lmnttoken ,
( uint32 ) lm20token ) ) ;
dump_data ( 4 , outbuf , PTR_DIFF ( q , outbuf ) ) ;
send_mailslot ( True , getdc ,
outbuf , PTR_DIFF ( q , outbuf ) ,
1999-12-13 13:27:58 +00:00
dgram - > dest_name . name ,
dgram - > dest_name . name_type ,
dgram - > source_name . name ,
dgram - > source_name . name_type ,
1998-08-30 17:04:24 +00:00
p - > ip , * iface_ip ( p - > ip ) , p - > port ) ;
1997-12-13 14:16:07 +00:00
return ;
}
case SAMLOGON :
{
char * q = buf + 2 ;
1998-09-29 17:17:48 +00:00
q + = 2 ;
1997-12-13 14:16:07 +00:00
unicomp = q ;
1999-12-13 13:27:58 +00:00
uniuser = skip_unicode_string ( unicomp , 1 ) ;
getdc = skip_unicode_string ( uniuser , 1 ) ;
1997-12-13 14:16:07 +00:00
q = skip_string ( getdc , 1 ) ;
1999-12-13 13:27:58 +00:00
q + = 4 ;
1998-09-29 17:16:15 +00:00
domainsidsize = IVAL ( q , 0 ) ;
q + = 4 ;
1999-12-13 13:27:58 +00:00
q + = domainsidsize + 3 ;
1998-09-29 17:16:15 +00:00
ntversion = IVAL ( q , 0 ) ;
q + = 4 ;
lmnttoken = SVAL ( q , 0 ) ;
q + = 2 ;
lm20token = SVAL ( q , 0 ) ;
q + = 2 ;
1997-12-13 14:16:07 +00:00
1999-12-13 13:27:58 +00:00
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON sidsize %d ntv %d \n " , domainsidsize , ntversion ) ) ;
1997-12-13 14:16:07 +00:00
/*
1998-12-09 06:35:37 +00:00
* we respond regadless of whether the machine is in our password
* database . If it isn ' t then we let smbd send an appropriate error .
1997-12-13 14:16:07 +00:00
* Let ' s ignore the SID .
*/
1999-12-13 13:27:58 +00:00
pstrcpy ( ascuser , dos_unistr ( uniuser ) ) ;
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON user %s \n " , ascuser ) ) ;
1998-05-12 00:55:32 +00:00
fstrcpy ( reply_name , " \\ \\ " ) ; /* Here it wants \\LOGONSERVER. */
fstrcpy ( reply_name + 2 , my_name ) ;
1997-12-13 14:16:07 +00:00
1999-12-13 13:27:58 +00:00
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x \n " ,
dos_unistr ( unicomp ) , inet_ntoa ( p - > ip ) , ascuser , reply_name , global_myworkgroup ,
SAMLOGON_R , lmnttoken ) ) ;
1997-12-13 14:16:07 +00:00
/* Construct reply. */
q = outbuf ;
1999-12-13 13:27:58 +00:00
SSVAL ( q , 0 , SAMLOGON_R ) ;
1998-09-29 17:16:15 +00:00
q + = 2 ;
1997-12-13 14:16:07 +00:00
1999-12-13 13:27:58 +00:00
dos_PutUniCode ( q , reply_name , sizeof ( pstring ) ) ;
q = skip_unicode_string ( q , 1 ) ;
unistrcpy ( q , uniuser ) ;
q = skip_unicode_string ( q , 1 ) ; /* User name (workstation trust account) */
dos_PutUniCode ( q , lp_workgroup ( ) , sizeof ( pstring ) ) ;
q = skip_unicode_string ( q , 1 ) ; /* Domain name. */
1998-09-29 17:16:15 +00:00
SIVAL ( q , 0 , ntversion ) ;
q + = 4 ;
SSVAL ( q , 0 , lmnttoken ) ;
q + = 2 ;
SSVAL ( q , 0 , lm20token ) ;
q + = 2 ;
1997-12-13 14:16:07 +00:00
dump_data ( 4 , outbuf , PTR_DIFF ( q , outbuf ) ) ;
send_mailslot ( True , getdc ,
outbuf , PTR_DIFF ( q , outbuf ) ,
1999-12-13 13:27:58 +00:00
dgram - > dest_name . name ,
dgram - > dest_name . name_type ,
dgram - > source_name . name ,
dgram - > source_name . name_type ,
1998-08-30 17:04:24 +00:00
p - > ip , * iface_ip ( p - > ip ) , p - > port ) ;
1997-12-13 14:16:07 +00:00
break ;
}
default :
{
DEBUG ( 3 , ( " process_logon_packet: Unknown domain request %d \n " , code ) ) ;
return ;
}
}
}