2004-03-27 01:26:33 +03:00
/*
* Expand msdfs targets based on client IP
*
* Copyright ( C ) Volker Lendecke , 2004
*
* 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 .
*/
# include "includes.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_VFS
2006-12-12 20:38:42 +03:00
extern userdom_struct current_user_info ;
2004-03-27 01:26:33 +03:00
/**********************************************************
Under mapfile we expect a table of the following format :
IP - Prefix whitespace expansion
For example :
192.168 .234 local . samba . org
192.168 remote . samba . org
default . samba . org
This is to redirect a DFS client to a host close to it .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL read_target_host ( const char * mapfile , pstring targethost )
{
XFILE * f ;
pstring buf ;
2005-01-20 04:19:57 +03:00
char * space = buf ;
2004-03-27 01:26:33 +03:00
BOOL found = False ;
f = x_fopen ( mapfile , O_RDONLY , 0 ) ;
if ( f = = NULL ) {
DEBUG ( 0 , ( " can't open IP map %s. Error %s \n " ,
mapfile , strerror ( errno ) ) ) ;
return False ;
}
DEBUG ( 10 , ( " Scanning mapfile [%s] \n " , mapfile ) ) ;
2005-01-20 04:19:57 +03:00
while ( x_fgets ( buf , sizeof ( buf ) , f ) ! = NULL ) {
2004-03-29 15:40:43 +04:00
2004-03-29 15:54:34 +04:00
if ( ( strlen ( buf ) > 0 ) & & ( buf [ strlen ( buf ) - 1 ] = = ' \n ' ) )
2004-03-29 15:40:43 +04:00
buf [ strlen ( buf ) - 1 ] = ' \0 ' ;
DEBUG ( 10 , ( " Scanning line [%s] \n " , buf ) ) ;
2004-03-27 01:26:33 +03:00
space = strchr_m ( buf , ' ' ) ;
if ( space = = NULL ) {
DEBUG ( 0 , ( " Ignoring invalid line %s \n " , buf ) ) ;
continue ;
}
* space = ' \0 ' ;
if ( strncmp ( client_addr ( ) , buf , strlen ( buf ) ) = = 0 ) {
found = True ;
break ;
}
}
x_fclose ( f ) ;
if ( ! found )
return False ;
space + = 1 ;
while ( isspace ( * space ) )
space + = 1 ;
pstrcpy ( targethost , space ) ;
return True ;
}
/**********************************************************
Expand the msdfs target host using read_target_host
explained above . The syntax used in the msdfs link is
msdfs : @ table - filename @ / share
Everything between and including the two @ - signs is
replaced by the substitution string found in the table
described above .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL expand_msdfs_target ( connection_struct * conn , pstring target )
{
pstring mapfilename ;
char * filename_start = strchr_m ( target , ' @ ' ) ;
char * filename_end ;
int filename_len ;
pstring targethost ;
pstring new_target ;
if ( filename_start = = NULL ) {
DEBUG ( 10 , ( " No filename start in %s \n " , target ) ) ;
return False ;
}
filename_end = strchr_m ( filename_start + 1 , ' @ ' ) ;
if ( filename_end = = NULL ) {
DEBUG ( 10 , ( " No filename end in %s \n " , target ) ) ;
return False ;
}
filename_len = PTR_DIFF ( filename_end , filename_start + 1 ) ;
pstrcpy ( mapfilename , filename_start + 1 ) ;
mapfilename [ filename_len ] = ' \0 ' ;
DEBUG ( 10 , ( " Expanding from table [%s] \n " , mapfilename ) ) ;
if ( ! read_target_host ( mapfilename , targethost ) ) {
DEBUG ( 1 , ( " Could not expand target host from file %s \n " ,
mapfilename ) ) ;
return False ;
}
2006-07-11 22:01:26 +04:00
standard_sub_advanced ( lp_servicename ( SNUM ( conn ) ) , conn - > user ,
conn - > connectpath , conn - > gid ,
get_current_username ( ) ,
current_user_info . domain ,
mapfilename , sizeof ( mapfilename ) ) ;
2004-03-27 01:26:33 +03:00
DEBUG ( 10 , ( " Expanded targethost to %s \n " , targethost ) ) ;
* filename_start = ' \0 ' ;
pstrcpy ( new_target , target ) ;
pstrcat ( new_target , targethost ) ;
pstrcat ( new_target , filename_end + 1 ) ;
DEBUG ( 10 , ( " New DFS target: %s \n " , new_target ) ) ;
pstrcpy ( target , new_target ) ;
return True ;
}
static int expand_msdfs_readlink ( struct vfs_handle_struct * handle ,
const char * path , char * buf , size_t bufsiz )
{
pstring target ;
int result ;
2006-07-11 22:01:26 +04:00
result = SMB_VFS_NEXT_READLINK ( handle , path , target ,
2004-03-27 01:26:33 +03:00
sizeof ( target ) ) ;
if ( result < 0 )
return result ;
target [ result ] = ' \0 ' ;
2004-03-29 15:40:43 +04:00
if ( ( strncmp ( target , " msdfs: " , strlen ( " msdfs: " ) ) = = 0 ) & &
( strchr_m ( target , ' @ ' ) ! = NULL ) ) {
2006-07-11 22:01:26 +04:00
if ( ! expand_msdfs_target ( handle - > conn , target ) ) {
2004-03-27 01:26:33 +03:00
errno = ENOENT ;
return - 1 ;
}
}
safe_strcpy ( buf , target , bufsiz - 1 ) ;
return strlen ( buf ) ;
}
/* VFS operations structure */
static vfs_op_tuple expand_msdfs_ops [ ] = {
{ SMB_VFS_OP ( expand_msdfs_readlink ) , SMB_VFS_OP_READLINK ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( NULL ) , SMB_VFS_OP_NOOP , SMB_VFS_LAYER_NOOP }
} ;
2006-12-19 23:16:52 +03:00
NTSTATUS vfs_expand_msdfs_init ( void ) ;
2004-03-27 01:26:33 +03:00
NTSTATUS vfs_expand_msdfs_init ( void )
{
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " expand_msdfs " ,
expand_msdfs_ops ) ;
}