1997-12-13 17:16:07 +03:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
NBT netbios routines and daemon - version 2
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Luke Kenneth Casson Leighton 1994 - 1998
Copyright ( C ) Jeremy Allison 1994 - 1998
1997-12-13 17:16:07 +03: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 05:12:08 +04:00
extern pstring global_myname ;
extern fstring global_myworkgroup ;
1997-12-13 17:16:07 +03: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-29 01:43:48 +04:00
int code ;
1997-12-13 17:16:07 +03:00
uint16 token = 0 ;
uint32 ntversion ;
uint16 lmnttoken ;
uint16 lm20token ;
uint32 domainsidsize ;
char * getdc ;
char * uniuser ; /* Unicode user name. */
pstring ascuser ;
char * unicomp ; /* Unicode computer name. */
struct smb_passwd * smb_pass ; /* To check if machine account exists */
if ( ! lp_domain_logons ( ) )
{
1997-12-16 12:20:34 +03:00
DEBUG ( 3 , ( " process_logon_packet: Logon packet received from IP %s and domain \
1997-12-13 17:16:07 +03:00
logons are not enabled . \ n " , inet_ntoa(p->ip) ));
return ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( my_name , global_myname ) ;
1997-12-13 17:16:07 +03: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 04:55:32 +04:00
fstrcpy ( reply_name , my_name ) ;
1997-12-13 17:16:07 +03: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 ;
SSVAL ( q , 0 , 6 ) ; q + = 2 ;
1998-05-12 04:55:32 +04:00
fstrcpy ( reply_name , " \\ \\ " ) ;
fstrcat ( reply_name , my_name ) ;
fstrcpy ( q , reply_name ) ; q = skip_string ( q , 1 ) ; /* PDC name */
1997-12-13 17:16:07 +03:00
SSVAL ( q , 0 , token ) ; q + = 2 ;
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 21:04:24 +04:00
p - > ip , * iface_ip ( p - > ip ) , p - > port ) ;
1997-12-13 17:16:07 +03: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 ) ;
q = skip_unicode_string ( q , 1 ) ;
ntversion = IVAL ( q , 0 ) ; q + = 4 ;
lmnttoken = SVAL ( q , 0 ) ; q + = 2 ;
lm20token = SVAL ( q , 0 ) ; q + = 2 ;
/* Construct reply. */
q = outbuf ;
SSVAL ( q , 0 , QUERYFORPDC_R ) ; q + = 2 ;
1998-05-12 04:55:32 +04:00
fstrcpy ( reply_name , my_name ) ;
fstrcpy ( q , reply_name ) ; q = skip_string ( q , 1 ) ; /* PDC name */
1997-12-13 17:16:07 +03:00
if ( strcmp ( mailslot , NT_LOGON_MAILSLOT ) = = 0 ) {
q = align2 ( q , buf ) ;
PutUniCode ( q , my_name ) ; /* PDC name */
q = skip_unicode_string ( q , 1 ) ;
1998-04-25 05:12:08 +04:00
PutUniCode ( q , global_myworkgroup ) ; /* Domain name*/
1997-12-13 17:16:07 +03:00
q = skip_unicode_string ( q , 1 ) ;
SIVAL ( q , 0 , ntversion ) ; q + = 4 ;
SSVAL ( q , 0 , lmnttoken ) ; q + = 2 ;
SSVAL ( q , 0 , lm20token ) ; q + = 2 ;
}
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 ) ,
dgram - > dest_name . name ,
dgram - > dest_name . name_type ,
dgram - > source_name . name ,
dgram - > source_name . name_type ,
1998-08-30 21:04:24 +04:00
p - > ip , * iface_ip ( p - > ip ) , p - > port ) ;
1997-12-13 17:16:07 +03:00
return ;
}
case SAMLOGON :
{
char * q = buf + 2 ;
unicomp = q ;
uniuser = skip_unicode_string ( unicomp , 1 ) ;
getdc = skip_unicode_string ( uniuser , 1 ) ;
q = skip_string ( getdc , 1 ) ;
domainsidsize = IVAL ( q , 0 ) ; q + = 4 ;
q + = domainsidsize + 3 ;
ntversion = IVAL ( q , 0 ) ; q + = 4 ;
lmnttoken = SVAL ( q , 0 ) ; q + = 2 ;
lm20token = SVAL ( q , 0 ) ; q + = 2 ;
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON sidsize %d ntv %d \n " , domainsidsize , ntversion ) ) ;
/*
* If MACHINE $ is in our password database then respond , else ignore .
* Let ' s ignore the SID .
*/
1998-03-12 00:11:04 +03:00
pstrcpy ( ascuser , unistr ( uniuser ) ) ;
1997-12-13 17:16:07 +03:00
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON user %s \n " , ascuser ) ) ;
1998-05-12 04:55:32 +04:00
fstrcpy ( reply_name , " \\ \\ " ) ; /* Here it wants \\LOGONSERVER. */
fstrcpy ( reply_name + 2 , my_name ) ;
1997-12-13 17:16:07 +03:00
1998-05-19 01:30:57 +04:00
smb_pass = getsmbpwnam ( ascuser ) ;
1997-12-13 17:16:07 +03:00
1998-03-12 00:11:04 +03:00
if ( ! smb_pass )
1997-12-13 17:16:07 +03:00
{
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON request from %s(%s) for %s, not in password file \n " ,
unistr ( unicomp ) , inet_ntoa ( p - > ip ) , ascuser ) ) ;
return ;
}
1998-03-12 00:11:04 +03:00
else if ( smb_pass - > acct_ctrl & ACB_DISABLED )
{
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON request from %s(%s) for %s, accound disabled. \n " ,
unistr ( unicomp ) , inet_ntoa ( p - > ip ) , ascuser ) ) ;
return ;
}
1997-12-13 17:16:07 +03:00
else
{
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x \n " ,
1998-04-25 05:12:08 +04:00
unistr ( unicomp ) , inet_ntoa ( p - > ip ) , ascuser , reply_name , global_myworkgroup ,
1997-12-13 17:16:07 +03:00
SAMLOGON_R , lmnttoken ) ) ;
}
/* Construct reply. */
q = outbuf ;
SSVAL ( q , 0 , SAMLOGON_R ) ; q + = 2 ;
PutUniCode ( q , reply_name ) ; q = skip_unicode_string ( q , 1 ) ;
unistrcpy ( q , uniuser ) ; q = skip_unicode_string ( q , 1 ) ; /* User name (workstation trust account) */
PutUniCode ( q , lp_workgroup ( ) ) ; q = skip_unicode_string ( q , 1 ) ; /* Domain name. */
SIVAL ( q , 0 , ntversion ) ; q + = 4 ;
SSVAL ( q , 0 , lmnttoken ) ; q + = 2 ;
SSVAL ( q , 0 , lm20token ) ; q + = 2 ;
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 21:04:24 +04:00
p - > ip , * iface_ip ( p - > ip ) , p - > port ) ;
1997-12-13 17:16:07 +03:00
break ;
}
default :
{
DEBUG ( 3 , ( " process_logon_packet: Unknown domain request %d \n " , code ) ) ;
return ;
}
}
}