2003-05-12 01:20:17 +00:00
/*
Unix SMB / CIFS implementation .
FAKE FILE suppport , for faking up special files windows want access to
Copyright ( C ) Stefan ( metze ) Metzmacher 2003
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"
2005-04-06 16:28:04 +00:00
extern struct current_user current_user ;
2003-05-12 01:20:17 +00:00
/****************************************************************************
Open a file with a share mode .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
files_struct * open_fake_file_shared1 ( enum FAKE_FILE_TYPE fake_file_type , connection_struct * conn , char * fname ,
SMB_STRUCT_STAT * psbuf ,
uint32 desired_access ,
2004-04-02 18:46:19 +00:00
int share_mode , int ofun , uint32 new_dos_attr , int oplock_request ,
2003-05-12 01:20:17 +00:00
int * Access , int * action )
{
int flags = 0 ;
files_struct * fsp = NULL ;
if ( fake_file_type = = 0 ) {
return open_file_shared1 ( conn , fname , psbuf , desired_access ,
2004-04-02 18:46:19 +00:00
share_mode , ofun , new_dos_attr ,
2003-05-12 01:20:17 +00:00
oplock_request , Access , action ) ;
}
/* access check */
2004-04-29 17:19:42 +00:00
if ( current_user . uid ! = 0 ) {
2003-05-12 01:20:17 +00:00
DEBUG ( 1 , ( " access_denied to service[%s] file[%s] user[%s] \n " ,
lp_servicename ( SNUM ( conn ) ) , fname , conn - > user ) ) ;
errno = EACCES ;
return NULL ;
}
fsp = file_new ( conn ) ;
if ( ! fsp )
return NULL ;
2004-04-02 18:46:19 +00:00
DEBUG ( 5 , ( " open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, oplock request = %d \n " ,
fname , fsp - > fnum , share_mode , ofun , oplock_request ) ) ;
2003-05-12 01:20:17 +00:00
if ( ! check_name ( fname , conn ) ) {
file_free ( fsp ) ;
return NULL ;
}
fsp - > fd = - 1 ;
fsp - > mode = psbuf - > st_mode ;
fsp - > inode = psbuf - > st_ino ;
fsp - > dev = psbuf - > st_dev ;
fsp - > vuid = current_user . vuid ;
fsp - > pos = - 1 ;
fsp - > can_lock = True ;
fsp - > can_read = ( ( flags & O_WRONLY ) = = 0 ) ;
fsp - > can_write = ( ( flags & ( O_WRONLY | O_RDWR ) ) ! = 0 ) ;
fsp - > share_mode = 0 ;
fsp - > desired_access = desired_access ;
fsp - > print_file = False ;
fsp - > modified = False ;
fsp - > oplock_type = NO_OPLOCK ;
fsp - > sent_oplock_break = NO_BREAK_SENT ;
fsp - > is_directory = False ;
fsp - > is_stat = False ;
fsp - > directory_delete_on_close = False ;
fsp - > conn = conn ;
string_set ( & fsp - > fsp_name , fname ) ;
fsp - > wcp = NULL ; /* Write cache pointer. */
fsp - > fake_file_handle = init_fake_file_handle ( fake_file_type ) ;
if ( fsp - > fake_file_handle = = NULL ) {
file_free ( fsp ) ;
return NULL ;
}
conn - > num_files_open + + ;
return fsp ;
}
static FAKE_FILE fake_files [ ] = {
# ifdef WITH_QUOTAS
2004-09-17 15:09:20 +00:00
{ FAKE_FILE_NAME_QUOTA_UNIX , FAKE_FILE_TYPE_QUOTA , init_quota_handle , destroy_quota_handle } ,
2003-05-12 01:20:17 +00:00
# endif /* WITH_QUOTAS */
2004-09-17 15:09:20 +00:00
{ NULL , FAKE_FILE_TYPE_NONE , NULL , NULL }
2003-05-12 01:20:17 +00:00
} ;
int is_fake_file ( char * fname )
{
int i ;
if ( ! fname )
return 0 ;
for ( i = 0 ; fake_files [ i ] . name ! = NULL ; i + + ) {
if ( strncmp ( fname , fake_files [ i ] . name , strlen ( fake_files [ i ] . name ) ) = = 0 ) {
DEBUG ( 5 , ( " is_fake_file: [%s] is a fake file \n " , fname ) ) ;
return fake_files [ i ] . type ;
}
}
return FAKE_FILE_TYPE_NONE ;
}
struct _FAKE_FILE_HANDLE * init_fake_file_handle ( enum FAKE_FILE_TYPE type )
{
TALLOC_CTX * mem_ctx = NULL ;
FAKE_FILE_HANDLE * fh = NULL ;
int i ;
for ( i = 0 ; fake_files [ i ] . name ! = NULL ; i + + ) {
if ( fake_files [ i ] . type = = type ) {
DEBUG ( 5 , ( " init_fake_file_handle: for [%s] \n " , fake_files [ i ] . name ) ) ;
if ( ( mem_ctx = talloc_init ( " fake_file_handle " ) ) = = NULL ) {
DEBUG ( 0 , ( " talloc_init(fake_file_handle) failed. \n " ) ) ;
return NULL ;
}
2004-12-07 18:25:53 +00:00
if ( ( fh = TALLOC_ZERO_P ( mem_ctx , FAKE_FILE_HANDLE ) ) = = NULL ) {
2003-05-12 01:20:17 +00:00
DEBUG ( 0 , ( " talloc_zero() failed. \n " ) ) ;
talloc_destroy ( mem_ctx ) ;
return NULL ;
}
fh - > type = type ;
fh - > mem_ctx = mem_ctx ;
if ( fake_files [ i ] . init_pd )
fh - > pd = fake_files [ i ] . init_pd ( fh - > mem_ctx ) ;
fh - > free_pd = fake_files [ i ] . free_pd ;
return fh ;
}
}
return NULL ;
}
void destroy_fake_file_handle ( FAKE_FILE_HANDLE * * fh )
{
if ( ! fh | | ! ( * fh ) )
2004-09-17 15:09:20 +00:00
return ;
2003-05-12 01:20:17 +00:00
if ( ( * fh ) - > free_pd )
( * fh ) - > free_pd ( & ( * fh ) - > pd ) ;
talloc_destroy ( ( * fh ) - > mem_ctx ) ;
( * fh ) = NULL ;
}