2009-09-15 18:42:54 +04:00
/*
Unix SMB / CIFS implementation .
manipulate nbt name structures
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Jeremy Allison 2007
Copyright ( C ) Andrew Bartlett 2009.
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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2009-09-15 21:11:45 +04:00
# include "lib/util/util_net.h"
2009-09-15 18:42:54 +04:00
# include "system/filesys.h"
# include "system/network.h"
2010-05-28 05:04:45 +04:00
# include "../libcli/nbt/libnbt.h"
2009-09-15 18:42:54 +04:00
/********************************************************
Start parsing the lmhosts file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-23 10:55:16 +03:00
FILE * startlmhosts ( const char * fname )
2009-09-15 18:42:54 +04:00
{
2016-11-23 10:55:16 +03:00
FILE * fp = fopen ( fname , " r " ) ;
2009-09-15 18:42:54 +04:00
if ( ! fp ) {
DEBUG ( 4 , ( " startlmhosts: Can't open lmhosts file %s. "
" Error was %s \n " ,
fname , strerror ( errno ) ) ) ;
return NULL ;
}
return fp ;
}
/********************************************************
Parse the next line in the lmhosts file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-23 10:55:16 +03:00
bool getlmhostsent ( TALLOC_CTX * ctx , FILE * fp , char * * pp_name , int * name_type ,
struct sockaddr_storage * pss )
2009-09-15 18:42:54 +04:00
{
char line [ 1024 ] ;
* pp_name = NULL ;
2016-11-23 10:55:16 +03:00
while ( ! feof ( fp ) & & ! ferror ( fp ) ) {
2009-09-15 18:42:54 +04:00
char * ip = NULL ;
char * flags = NULL ;
char * extra = NULL ;
char * name = NULL ;
const char * ptr ;
char * ptr1 = NULL ;
int count = 0 ;
* name_type = - 1 ;
2016-11-23 10:55:16 +03:00
if ( ! fgets_slash ( NULL , line , sizeof ( line ) , fp ) ) {
2009-09-15 18:42:54 +04:00
continue ;
}
if ( * line = = ' # ' ) {
continue ;
}
ptr = line ;
if ( next_token_talloc ( ctx , & ptr , & ip , NULL ) )
+ + count ;
if ( next_token_talloc ( ctx , & ptr , & name , NULL ) )
+ + count ;
if ( next_token_talloc ( ctx , & ptr , & flags , NULL ) )
+ + count ;
if ( next_token_talloc ( ctx , & ptr , & extra , NULL ) )
+ + count ;
if ( count < = 0 )
continue ;
if ( count > 0 & & count < 2 ) {
DEBUG ( 0 , ( " getlmhostsent: Ill formed hosts line [%s] \n " ,
line ) ) ;
continue ;
}
if ( count > = 4 ) {
DEBUG ( 0 , ( " getlmhostsent: too many columns "
" in lmhosts file (obsolete syntax) \n " ) ) ;
continue ;
}
if ( ! flags ) {
flags = talloc_strdup ( ctx , " " ) ;
if ( ! flags ) {
continue ;
}
}
DEBUG ( 4 , ( " getlmhostsent: lmhost entry: %s %s %s \n " ,
ip , name , flags ) ) ;
if ( strchr_m ( flags , ' G ' ) | | strchr_m ( flags , ' S ' ) ) {
DEBUG ( 0 , ( " getlmhostsent: group flag "
" in lmhosts ignored (obsolete) \n " ) ) ;
continue ;
}
if ( ! interpret_string_addr ( pss , ip , AI_NUMERICHOST ) ) {
DEBUG ( 0 , ( " getlmhostsent: invalid address "
" %s. \n " , ip ) ) ;
}
/* Extra feature. If the name ends in '#XX',
* where XX is a hex number , then only add that name type . */
if ( ( ptr1 = strchr_m ( name , ' # ' ) ) ! = NULL ) {
char * endptr ;
ptr1 + + ;
* name_type = ( int ) strtol ( ptr1 , & endptr , 16 ) ;
if ( ! * ptr1 | | ( endptr = = ptr1 ) ) {
DEBUG ( 0 , ( " getlmhostsent: invalid name "
" %s containing '#'. \n " , name ) ) ;
continue ;
}
* ( - - ptr1 ) = ' \0 ' ; /* Truncate at the '#' */
}
* pp_name = talloc_strdup ( ctx , name ) ;
if ( ! * pp_name ) {
return false ;
}
return true ;
}
return false ;
}
/********************************************************
Finish parsing the lmhosts file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-23 10:55:16 +03:00
void endlmhosts ( FILE * fp )
2009-09-15 18:42:54 +04:00
{
2016-11-23 10:55:16 +03:00
fclose ( fp ) ;
2009-09-15 18:42:54 +04:00
}
2009-11-03 06:15:07 +03:00
/********************************************************
Resolve via " lmhosts " method .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS resolve_lmhosts_file_as_sockaddr ( const char * lmhosts_file ,
const char * name , int name_type ,
TALLOC_CTX * mem_ctx ,
struct sockaddr_storage * * return_iplist ,
int * return_count )
{
/*
* " lmhosts " means parse the local lmhosts file .
*/
2016-11-23 10:55:16 +03:00
FILE * fp ;
2009-11-03 06:15:07 +03:00
char * lmhost_name = NULL ;
int name_type2 ;
struct sockaddr_storage return_ss ;
NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND ;
TALLOC_CTX * ctx = NULL ;
* return_iplist = NULL ;
* return_count = 0 ;
DEBUG ( 3 , ( " resolve_lmhosts: "
" Attempting lmhosts lookup for name %s<0x%x> \n " ,
name , name_type ) ) ;
fp = startlmhosts ( lmhosts_file ) ;
if ( fp = = NULL )
return NT_STATUS_NO_SUCH_FILE ;
ctx = talloc_new ( mem_ctx ) ;
if ( ! ctx ) {
endlmhosts ( fp ) ;
return NT_STATUS_NO_MEMORY ;
}
while ( getlmhostsent ( ctx , fp , & lmhost_name , & name_type2 , & return_ss ) ) {
if ( ! strequal ( name , lmhost_name ) ) {
TALLOC_FREE ( lmhost_name ) ;
continue ;
}
if ( ( name_type2 ! = - 1 ) & & ( name_type ! = name_type2 ) ) {
TALLOC_FREE ( lmhost_name ) ;
continue ;
}
* return_iplist = talloc_realloc ( ctx , ( * return_iplist ) ,
struct sockaddr_storage ,
( * return_count ) + 1 ) ;
if ( ( * return_iplist ) = = NULL ) {
TALLOC_FREE ( ctx ) ;
endlmhosts ( fp ) ;
DEBUG ( 3 , ( " resolve_lmhosts: talloc_realloc fail ! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
( * return_iplist ) [ * return_count ] = return_ss ;
* return_count + = 1 ;
/* we found something */
status = NT_STATUS_OK ;
/* Multiple names only for DC lookup */
if ( name_type ! = 0x1c )
break ;
}
talloc_steal ( mem_ctx , * return_iplist ) ;
TALLOC_FREE ( ctx ) ;
endlmhosts ( fp ) ;
return status ;
}