1997-12-13 17:16:07 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1997-12-13 17:16:07 +03:00
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
2003-08-27 05:25:01 +04:00
Copyright ( C ) Jeremy Allison 1994 - 2003
2003-08-01 19:30:44 +04:00
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2002
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1997-12-13 17:16:07 +03:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1997-12-13 17:16:07 +03:00
Revision History :
*/
# include "includes.h"
2001-08-24 23:28:08 +04:00
struct sam_database_info {
uint32 index ;
uint32 serial_lo , serial_hi ;
uint32 date_lo , date_hi ;
} ;
1997-12-13 17:16:07 +03:00
/****************************************************************************
Process a domain logon packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-01-03 11:28:12 +03:00
void process_logon_packet ( struct packet_struct * p , char * buf , int len ,
const char * mailslot )
1997-12-13 17:16:07 +03:00
{
2003-08-27 05:25:01 +04:00
struct dgram_packet * dgram = & p - > packet . dgram ;
2007-11-20 02:15:09 +03:00
fstring my_name ;
2003-08-27 05:25:01 +04:00
fstring reply_name ;
2007-11-20 02:15:09 +03:00
char outbuf [ 1024 ] ;
2003-08-27 05:25:01 +04:00
int code ;
uint16 token = 0 ;
uint32 ntversion = 0 ;
uint16 lmnttoken = 0 ;
uint16 lm20token = 0 ;
uint32 domainsidsize ;
2007-10-19 04:40:25 +04:00
bool short_request = False ;
2003-08-27 05:25:01 +04:00
char * getdc ;
char * uniuser ; /* Unicode user name. */
2007-11-20 02:15:09 +03:00
fstring ascuser ;
2003-08-27 05:25:01 +04:00
char * unicomp ; /* Unicode computer name. */
2007-09-19 21:52:06 +04:00
size_t size ;
2007-10-11 05:25:16 +04:00
struct sockaddr_storage ss ;
const struct sockaddr_storage * pss ;
struct in_addr ip ;
in_addr_to_sockaddr_storage ( & ss , p - > ip ) ;
pss = iface_ip ( & ss ) ;
if ( ! pss ) {
DEBUG ( 5 , ( " process_logon_packet:can't find outgoing interface "
" for packet from IP %s \n " ,
inet_ntoa ( p - > ip ) ) ) ;
return ;
}
ip = ( ( struct sockaddr_in * ) pss ) - > sin_addr ;
2003-08-27 05:25:01 +04:00
memset ( outbuf , 0 , sizeof ( outbuf ) ) ;
if ( ! lp_domain_logons ( ) ) {
2004-01-24 13:46:55 +03:00
DEBUG ( 5 , ( " 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) ));
2003-08-27 05:25:01 +04:00
return ;
}
2007-11-20 02:15:09 +03:00
fstrcpy ( my_name , global_myname ( ) ) ;
2003-08-27 05:25:01 +04:00
r22042: Try and clean up my own mess using the API Volker
suggested. I now use :
BOOL is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
Volker, please criticize and comment. Thanks,
Jeremy.
(This used to be commit d47af7c9263f519e7307859b6a696d854c5dfca3)
2007-04-02 23:04:57 +04:00
code = get_safe_SVAL ( buf , len , buf , 0 , - 1 ) ;
2004-01-24 13:46:55 +03:00
DEBUG ( 4 , ( " process_logon_packet: Logon from %s: code = 0x%x \n " , inet_ntoa ( p - > ip ) , code ) ) ;
2003-08-27 05:25:01 +04:00
switch ( code ) {
2007-09-14 02:08:59 +04:00
case 0 :
2003-08-27 05:25:01 +04:00
{
fstring mach_str , user_str , getdc_str ;
char * q = buf + 2 ;
char * machine = q ;
2007-04-03 00:10:21 +04:00
char * user = skip_string ( buf , len , machine ) ;
2003-08-27 05:25:01 +04:00
2007-03-31 02:25:08 +04:00
if ( ! user | | PTR_DIFF ( user , buf ) > = len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2007-04-03 00:10:21 +04:00
getdc = skip_string ( buf , len , user ) ;
2004-09-04 05:57:16 +04:00
2007-03-31 02:25:08 +04:00
if ( ! getdc | | PTR_DIFF ( getdc , buf ) > = len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2007-04-03 00:10:21 +04:00
q = skip_string ( buf , len , getdc ) ;
2004-09-04 05:57:16 +04:00
2007-03-31 02:25:08 +04:00
if ( ! q | | PTR_DIFF ( q + 5 , buf ) > len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
token = SVAL ( q , 3 ) ;
2007-11-20 02:15:09 +03:00
fstrcpy ( reply_name , my_name ) ;
2003-08-27 05:25:01 +04:00
pull_ascii_fstring ( mach_str , machine ) ;
pull_ascii_fstring ( user_str , user ) ;
pull_ascii_fstring ( getdc_str , getdc ) ;
2004-01-24 13:46:55 +03:00
DEBUG ( 5 , ( " process_logon_packet: Domain login request from %s at IP %s user=%s token=%x \n " ,
2003-08-27 05:25:01 +04:00
mach_str , inet_ntoa ( p - > ip ) , user_str , token ) ) ;
q = outbuf ;
SSVAL ( q , 0 , 6 ) ;
q + = 2 ;
fstrcpy ( reply_name , " \\ \\ " ) ;
fstrcat ( reply_name , my_name ) ;
2007-09-19 21:52:06 +04:00
size = push_ascii ( q , reply_name ,
2007-09-14 02:08:59 +04:00
sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) ,
STR_TERMINATE ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 ) {
return ;
}
2007-04-03 00:10:21 +04:00
q = skip_string ( outbuf , sizeof ( outbuf ) , q ) ; /* PDC name */
2003-08-27 05:25:01 +04:00
SSVAL ( q , 0 , token ) ;
q + = 2 ;
2007-03-28 17:34:59 +04:00
dump_data ( 4 , ( uint8 * ) outbuf , PTR_DIFF ( q , outbuf ) ) ;
2003-08-27 05:25:01 +04:00
2007-09-14 02:08:59 +04:00
send_mailslot ( True , getdc_str ,
2003-08-27 05:25:01 +04:00
outbuf , PTR_DIFF ( q , outbuf ) ,
global_myname ( ) , 0x0 ,
mach_str ,
dgram - > source_name . name_type ,
2007-10-11 05:25:16 +04:00
p - > ip , ip , p - > port ) ;
2003-08-27 05:25:01 +04:00
break ;
}
case QUERYFORPDC :
{
fstring mach_str , getdc_str ;
2004-03-13 05:16:21 +03:00
fstring source_name ;
2003-08-27 05:25:01 +04:00
char * q = buf + 2 ;
char * machine = q ;
2007-09-14 02:08:59 +04:00
if ( ! lp_domain_master ( ) ) {
2003-08-27 05:25:01 +04:00
/* We're not Primary Domain Controller -- ignore this */
return ;
}
2007-04-03 00:10:21 +04:00
getdc = skip_string ( buf , len , machine ) ;
2004-09-04 05:57:16 +04:00
2007-03-31 02:25:08 +04:00
if ( ! getdc | | PTR_DIFF ( getdc , buf ) > = len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2007-04-03 00:10:21 +04:00
q = skip_string ( buf , len , getdc ) ;
2004-09-04 05:57:16 +04:00
2007-03-31 02:25:08 +04:00
if ( ! q | | PTR_DIFF ( q , buf ) > = len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
q = ALIGN2 ( q , buf ) ;
/* At this point we can work out if this is a W9X or NT style
request . Experiments show that the difference is wether the
packet ends here . For a W9X request we now end with a pair of
bytes ( usually 0xFE 0xFF ) whereas with NT we have two further
strings - the following is a simple way of detecting this */
if ( len - PTR_DIFF ( q , buf ) < = 3 ) {
short_request = True ;
} else {
unicomp = q ;
2004-09-04 05:57:16 +04:00
if ( PTR_DIFF ( q , buf ) > = len ) {
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
/* A full length (NT style) request */
q = skip_unibuf ( unicomp , PTR_DIFF ( buf + len , unicomp ) ) ;
2004-09-04 05:57:16 +04:00
if ( PTR_DIFF ( q , buf ) > = len ) {
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
if ( len - PTR_DIFF ( q , buf ) > 8 ) {
/* with NT5 clients we can sometimes
get additional data - a length specificed string
containing the domain name , then 16 bytes of
data ( no idea what it is ) */
int dom_len = CVAL ( q , 0 ) ;
q + + ;
if ( dom_len ! = 0 ) {
q + = dom_len + 1 ;
}
q + = 16 ;
}
2004-09-04 05:57:16 +04:00
2004-09-09 05:46:20 +04:00
if ( PTR_DIFF ( q + 8 , buf ) > len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
ntversion = IVAL ( q , 0 ) ;
lmnttoken = SVAL ( q , 4 ) ;
lm20token = SVAL ( q , 6 ) ;
}
/* Construct reply. */
q = outbuf ;
SSVAL ( q , 0 , QUERYFORPDC_R ) ;
q + = 2 ;
fstrcpy ( reply_name , my_name ) ;
2007-09-19 21:52:06 +04:00
size = push_ascii ( q , reply_name ,
2007-09-14 02:08:59 +04:00
sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) ,
STR_TERMINATE ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 ) {
return ;
}
2007-04-03 00:10:21 +04:00
q = skip_string ( outbuf , sizeof ( outbuf ) , q ) ; /* PDC name */
2003-08-27 05:25:01 +04:00
/* PDC and domain name */
if ( ! short_request ) {
/* Make a full reply */
q = ALIGN2 ( q , outbuf ) ;
2007-09-14 02:08:59 +04:00
q + = dos_PutUniCode ( q , my_name ,
2007-11-20 02:15:09 +03:00
sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) ,
2007-09-14 02:08:59 +04:00
True ) ; /* PDC name */
q + = dos_PutUniCode ( q , lp_workgroup ( ) ,
2007-11-20 02:15:09 +03:00
sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) ,
2007-09-14 02:08:59 +04:00
True ) ; /* Domain name*/
2007-11-20 02:15:09 +03:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 8 ) {
2007-09-14 02:08:59 +04:00
return ;
}
2003-08-27 05:25:01 +04:00
SIVAL ( q , 0 , 1 ) ; /* our nt version */
SSVAL ( q , 4 , 0xffff ) ; /* our lmnttoken */
SSVAL ( q , 6 , 0xffff ) ; /* our lm20token */
q + = 8 ;
}
/* RJS, 21-Feb-2000, we send a short reply if the request was short */
pull_ascii_fstring ( mach_str , machine ) ;
2004-01-24 13:46:55 +03:00
DEBUG ( 5 , ( " process_logon_packet: GETDC request from %s at IP %s, \
2003-08-27 05:25:01 +04:00
reporting % s domain % s 0 x % x ntversion = % x lm_nt token = % x lm_20 token = % x \ n " ,
mach_str , inet_ntoa ( p - > ip ) , reply_name , lp_workgroup ( ) ,
QUERYFORPDC_R , ( uint32 ) ntversion , ( uint32 ) lmnttoken ,
( uint32 ) lm20token ) ) ;
2007-03-28 17:34:59 +04:00
dump_data ( 4 , ( uint8 * ) outbuf , PTR_DIFF ( q , outbuf ) ) ;
2003-08-27 05:25:01 +04:00
pull_ascii_fstring ( getdc_str , getdc ) ;
2004-03-13 05:16:21 +03:00
pull_ascii_nstring ( source_name , sizeof ( source_name ) , dgram - > source_name . name ) ;
2003-08-27 05:25:01 +04:00
send_mailslot ( True , getdc_str ,
outbuf , PTR_DIFF ( q , outbuf ) ,
global_myname ( ) , 0x0 ,
source_name ,
dgram - > source_name . name_type ,
2007-10-11 05:25:16 +04:00
p - > ip , ip , p - > port ) ;
2003-08-27 05:25:01 +04:00
return ;
}
case SAMLOGON :
{
fstring getdc_str ;
2004-03-16 00:45:45 +03:00
fstring source_name ;
2003-08-27 05:25:01 +04:00
char * q = buf + 2 ;
fstring asccomp ;
q + = 2 ;
2004-09-04 05:57:16 +04:00
if ( PTR_DIFF ( q , buf ) > = len ) {
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
unicomp = q ;
uniuser = skip_unibuf ( unicomp , PTR_DIFF ( buf + len , unicomp ) ) ;
2004-09-04 05:57:16 +04:00
if ( PTR_DIFF ( uniuser , buf ) > = len ) {
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
getdc = skip_unibuf ( uniuser , PTR_DIFF ( buf + len , uniuser ) ) ;
2004-09-04 05:57:16 +04:00
if ( PTR_DIFF ( getdc , buf ) > = len ) {
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2007-04-03 00:10:21 +04:00
q = skip_string ( buf , len , getdc ) ;
2004-09-04 05:57:16 +04:00
2007-03-31 02:25:08 +04:00
if ( ! q | | PTR_DIFF ( q + 8 , buf ) > = len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
q + = 4 ; /* Account Control Bits - indicating username type */
domainsidsize = IVAL ( q , 0 ) ;
q + = 4 ;
2004-01-24 13:46:55 +03:00
DEBUG ( 5 , ( " process_logon_packet: SAMLOGON sidsize %d, len = %d \n " , domainsidsize , len ) ) ;
2003-08-27 05:25:01 +04:00
if ( domainsidsize < ( len - PTR_DIFF ( q , buf ) ) & & ( domainsidsize ! = 0 ) ) {
q + = domainsidsize ;
q = ALIGN4 ( q , buf ) ;
}
2004-01-24 13:46:55 +03:00
DEBUG ( 5 , ( " process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld \n " , len , ( unsigned long ) PTR_DIFF ( q , buf ) ) ) ;
2003-08-27 05:25:01 +04:00
if ( len - PTR_DIFF ( q , buf ) > 8 ) {
2000-03-27 16:19:58 +04:00
/* with NT5 clients we can sometimes
2003-08-27 05:25:01 +04:00
get additional data - a length specificed string
containing the domain name , then 16 bytes of
data ( no idea what it is ) */
2000-03-27 16:19:58 +04:00
int dom_len = CVAL ( q , 0 ) ;
q + + ;
2003-08-27 05:25:01 +04:00
if ( dom_len < ( len - PTR_DIFF ( q , buf ) ) & & ( dom_len ! = 0 ) ) {
2000-03-27 16:19:58 +04:00
q + = dom_len + 1 ;
}
q + = 16 ;
2003-08-27 05:25:01 +04:00
}
2004-09-09 05:46:20 +04:00
if ( PTR_DIFF ( q + 8 , buf ) > len ) {
2004-09-04 05:57:16 +04:00
DEBUG ( 0 , ( " process_logon_packet: bad packet \n " ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
ntversion = IVAL ( q , 0 ) ;
lmnttoken = SVAL ( q , 4 ) ;
lm20token = SVAL ( q , 6 ) ;
q + = 8 ;
DEBUG ( 3 , ( " process_logon_packet: SAMLOGON sidsize %d ntv %d \n " , domainsidsize , ntversion ) ) ;
/*
* we respond regadless of whether the machine is in our password
* database . If it isn ' t then we let smbd send an appropriate error .
* Let ' s ignore the SID .
*/
2007-11-20 02:15:09 +03:00
pull_ucs2_fstring ( ascuser , uniuser ) ;
2003-08-27 05:25:01 +04:00
pull_ucs2_fstring ( asccomp , unicomp ) ;
2004-01-24 13:46:55 +03:00
DEBUG ( 5 , ( " process_logon_packet: SAMLOGON user %s \n " , ascuser ) ) ;
2003-08-27 05:25:01 +04:00
fstrcpy ( reply_name , " \\ \\ " ) ; /* Here it wants \\LOGONSERVER. */
fstrcat ( reply_name , my_name ) ;
2004-01-24 13:46:55 +03:00
DEBUG ( 5 , ( " process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x \n " ,
2003-08-27 05:25:01 +04:00
asccomp , inet_ntoa ( p - > ip ) , ascuser , reply_name , lp_workgroup ( ) ,
SAMLOGON_R , lmnttoken ) ) ;
/* Construct reply. */
q = outbuf ;
/* we want the simple version unless we are an ADS PDC..which means */
/* never, at least for now */
if ( ( ntversion < 11 ) | | ( SEC_ADS ! = lp_security ( ) ) | | ( ROLE_DOMAIN_PDC ! = lp_server_role ( ) ) ) {
if ( SVAL ( uniuser , 0 ) = = 0 ) {
SSVAL ( q , 0 , SAMLOGON_UNK_R ) ; /* user unknown */
} else {
SSVAL ( q , 0 , SAMLOGON_R ) ;
}
2002-08-17 21:00:51 +04:00
2003-08-27 05:25:01 +04:00
q + = 2 ;
2002-08-17 21:00:51 +04:00
2007-09-14 02:08:59 +04:00
q + = dos_PutUniCode ( q , reply_name ,
2007-11-20 02:15:09 +03:00
sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) ,
2007-09-14 02:08:59 +04:00
True ) ;
q + = dos_PutUniCode ( q , ascuser ,
2007-11-20 02:15:09 +03:00
sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) ,
2007-09-14 02:08:59 +04:00
True ) ;
q + = dos_PutUniCode ( q , lp_workgroup ( ) ,
2007-11-20 02:15:09 +03:00
sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) ,
2007-09-14 02:08:59 +04:00
True ) ;
2003-08-27 05:25:01 +04:00
}
2002-08-17 21:00:51 +04:00
# ifdef HAVE_ADS
2003-08-27 05:25:01 +04:00
else {
2006-09-19 04:39:21 +04:00
struct GUID domain_guid ;
2004-04-13 18:39:48 +04:00
UUID_FLAT flat_guid ;
2007-11-09 04:25:45 +03:00
char * domain ;
2007-11-09 05:50:07 +03:00
char * hostname ;
2003-08-27 05:25:01 +04:00
char * component , * dc , * q1 ;
char * q_orig = q ;
int str_offset ;
2007-11-09 04:25:45 +03:00
domain = get_mydnsdomname ( talloc_tos ( ) ) ;
if ( ! domain ) {
DEBUG ( 2 ,
( " get_mydnsdomname failed. \n " ) ) ;
return ;
}
2007-11-09 05:50:07 +03:00
hostname = get_myname ( talloc_tos ( ) ) ;
if ( ! hostname ) {
DEBUG ( 2 ,
( " get_myname failed. \n " ) ) ;
return ;
}
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 8 ) {
return ;
}
2003-08-27 05:25:01 +04:00
if ( SVAL ( uniuser , 0 ) = = 0 ) {
SIVAL ( q , 0 , SAMLOGON_AD_UNK_R ) ; /* user unknown */
} else {
SIVAL ( q , 0 , SAMLOGON_AD_R ) ;
}
q + = 4 ;
2002-08-17 21:00:51 +04:00
2003-08-27 05:25:01 +04:00
SIVAL ( q , 0 , ADS_PDC | ADS_GC | ADS_LDAP | ADS_DS |
ADS_KDC | ADS_TIMESERV | ADS_CLOSEST | ADS_WRITABLE ) ;
q + = 4 ;
2002-08-17 21:00:51 +04:00
2003-08-27 05:25:01 +04:00
/* Push Domain GUID */
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < UUID_FLAT_SIZE ) {
return ;
}
2003-08-27 05:25:01 +04:00
if ( False = = secrets_fetch_domain_guid ( domain , & domain_guid ) ) {
DEBUG ( 2 , ( " Could not fetch DomainGUID for %s \n " , domain ) ) ;
return ;
}
2004-04-13 18:39:48 +04:00
smb_uuid_pack ( domain_guid , & flat_guid ) ;
memcpy ( q , & flat_guid . info , UUID_FLAT_SIZE ) ;
q + = UUID_FLAT_SIZE ;
2003-08-27 05:25:01 +04:00
/* Forest */
str_offset = q - q_orig ;
dc = domain ;
q1 = q ;
while ( ( component = strtok ( dc , " . " ) ) ) {
dc = NULL ;
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 1 ) {
return ;
}
size = push_ascii ( & q [ 1 ] , component ,
sizeof ( outbuf ) - PTR_DIFF ( q + 1 , outbuf ) ,
0 ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 | | size > 0xff ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , size ) ;
q + = ( size + 1 ) ;
}
2003-05-20 17:49:53 +04:00
2003-08-27 05:25:01 +04:00
/* Unk0 */
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 4 ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , 0 ) ;
q + + ;
2002-08-17 21:00:51 +04:00
2003-08-27 05:25:01 +04:00
/* Domain */
SCVAL ( q , 0 , 0xc0 | ( ( str_offset > > 8 ) & 0x3F ) ) ;
SCVAL ( q , 1 , str_offset & 0xFF ) ;
q + = 2 ;
/* Hostname */
2007-09-14 02:08:59 +04:00
size = push_ascii ( & q [ 1 ] , hostname ,
sizeof ( outbuf ) - PTR_DIFF ( q + 1 , outbuf ) ,
0 ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 | | size > 0xff ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , size ) ;
q + = ( size + 1 ) ;
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 3 ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , 0xc0 | ( ( str_offset > > 8 ) & 0x3F ) ) ;
SCVAL ( q , 1 , str_offset & 0xFF ) ;
q + = 2 ;
/* NETBIOS of domain */
2007-09-14 02:08:59 +04:00
size = push_ascii ( & q [ 1 ] , lp_workgroup ( ) ,
sizeof ( outbuf ) - PTR_DIFF ( q + 1 , outbuf ) ,
STR_UPPER ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 | | size > 0xff ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , size ) ;
q + = ( size + 1 ) ;
/* Unk1 */
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 2 ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , 0 ) ;
q + + ;
/* NETBIOS of hostname */
2007-09-14 02:08:59 +04:00
size = push_ascii ( & q [ 1 ] , my_name ,
sizeof ( outbuf ) - PTR_DIFF ( q + 1 , outbuf ) ,
0 ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 | | size > 0xff ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , size ) ;
q + = ( size + 1 ) ;
/* Unk2 */
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 4 ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , 0 ) ;
q + + ;
/* User name */
if ( SVAL ( uniuser , 0 ) ! = 0 ) {
2007-09-14 02:08:59 +04:00
size = push_ascii ( & q [ 1 ] , ascuser ,
sizeof ( outbuf ) - PTR_DIFF ( q + 1 , outbuf ) ,
0 ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 | | size > 0xff ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , size ) ;
q + = ( size + 1 ) ;
}
q_orig = q ;
/* Site name */
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 1 ) {
return ;
}
size = push_ascii ( & q [ 1 ] , " Default-First-Site-Name " ,
sizeof ( outbuf ) - PTR_DIFF ( q + 1 , outbuf ) ,
0 ) ;
2007-09-19 21:52:06 +04:00
if ( size = = ( size_t ) - 1 | | size > 0xff ) {
return ;
}
2003-08-27 05:25:01 +04:00
SCVAL ( q , 0 , size ) ;
q + = ( size + 1 ) ;
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 18 ) {
return ;
}
2003-08-27 05:25:01 +04:00
/* Site name (2) */
str_offset = q - q_orig ;
SCVAL ( q , 0 , 0xc0 | ( ( str_offset > > 8 ) & 0x3F ) ) ;
SCVAL ( q , 1 , str_offset & 0xFF ) ;
q + = 2 ;
SCVAL ( q , 0 , PTR_DIFF ( q , q1 ) ) ;
SCVAL ( q , 1 , 0x10 ) ; /* unknown */
SIVAL ( q , 0 , 0x00000002 ) ;
q + = 4 ; /* unknown */
2007-10-11 05:25:16 +04:00
SIVAL ( q , 0 , ntohl ( ip . s_addr ) ) ;
2003-08-27 05:25:01 +04:00
q + = 4 ;
SIVAL ( q , 0 , 0x00000000 ) ;
q + = 4 ; /* unknown */
SIVAL ( q , 0 , 0x00000000 ) ;
q + = 4 ; /* unknown */
2007-09-15 02:03:41 +04:00
}
2002-08-17 21:00:51 +04:00
# endif
1998-09-29 21:16:15 +04:00
2007-09-14 02:08:59 +04:00
if ( sizeof ( outbuf ) - PTR_DIFF ( q , outbuf ) < 8 ) {
return ;
}
2003-08-27 05:25:01 +04:00
/* tell the client what version we are */
SIVAL ( q , 0 , ( ( ntversion < 11 ) | | ( SEC_ADS ! = lp_security ( ) ) ) ? 1 : 13 ) ;
/* our ntversion */
2007-09-15 02:03:41 +04:00
SSVAL ( q , 4 , 0xffff ) ; /* our lmnttoken */
2003-08-27 05:25:01 +04:00
SSVAL ( q , 6 , 0xffff ) ; /* our lm20token */
q + = 8 ;
2007-03-28 17:34:59 +04:00
dump_data ( 4 , ( uint8 * ) outbuf , PTR_DIFF ( q , outbuf ) ) ;
2003-08-27 05:25:01 +04:00
pull_ascii_fstring ( getdc_str , getdc ) ;
2004-03-13 05:16:21 +03:00
pull_ascii_nstring ( source_name , sizeof ( source_name ) , dgram - > source_name . name ) ;
2003-08-27 05:25:01 +04:00
send_mailslot ( True , getdc ,
outbuf , PTR_DIFF ( q , outbuf ) ,
global_myname ( ) , 0x0 ,
2004-03-16 00:45:45 +03:00
source_name ,
2003-08-27 05:25:01 +04:00
dgram - > source_name . name_type ,
2007-10-11 05:25:16 +04:00
p - > ip , ip , p - > port ) ;
2003-08-27 05:25:01 +04:00
break ;
}
/* Announce change to UAS or SAM. Send by the domain controller when a
replication event is required . */
case SAM_UAS_CHANGE :
2007-07-10 04:47:40 +04:00
DEBUG ( 5 , ( " Got SAM_UAS_CHANGE \n " ) ) ;
break ;
2001-08-24 23:28:08 +04:00
2003-08-27 05:25:01 +04:00
default :
DEBUG ( 3 , ( " process_logon_packet: Unknown domain request %d \n " , code ) ) ;
return ;
}
1997-12-13 17:16:07 +03:00
}