2003-05-12 05:20:17 +04: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 20:28:04 +04:00
extern struct current_user current_user ;
2003-05-12 05:20:17 +04:00
static FAKE_FILE fake_files [ ] = {
# ifdef WITH_QUOTAS
2004-09-17 19:09:20 +04:00
{ FAKE_FILE_NAME_QUOTA_UNIX , FAKE_FILE_TYPE_QUOTA , init_quota_handle , destroy_quota_handle } ,
2003-05-12 05:20:17 +04:00
# endif /* WITH_QUOTAS */
2004-09-17 19:09:20 +04:00
{ NULL , FAKE_FILE_TYPE_NONE , NULL , NULL }
2003-05-12 05:20:17 +04:00
} ;
2005-07-08 08:51:27 +04:00
/****************************************************************************
Create a fake file handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-05-12 05:20:17 +04:00
2005-07-08 08:51:27 +04:00
static struct _FAKE_FILE_HANDLE * init_fake_file_handle ( enum FAKE_FILE_TYPE type )
2003-05-12 05:20:17 +04:00
{
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 21:25:53 +03:00
if ( ( fh = TALLOC_ZERO_P ( mem_ctx , FAKE_FILE_HANDLE ) ) = = NULL ) {
2003-05-12 05:20:17 +04:00
DEBUG ( 0 , ( " talloc_zero() failed. \n " ) ) ;
talloc_destroy ( mem_ctx ) ;
return NULL ;
}
fh - > type = type ;
fh - > mem_ctx = mem_ctx ;
2005-07-08 08:51:27 +04:00
if ( fake_files [ i ] . init_pd ) {
2003-05-12 05:20:17 +04:00
fh - > pd = fake_files [ i ] . init_pd ( fh - > mem_ctx ) ;
2005-07-08 08:51:27 +04:00
}
2003-05-12 05:20:17 +04:00
fh - > free_pd = fake_files [ i ] . free_pd ;
return fh ;
}
}
return NULL ;
}
2005-07-08 08:51:27 +04:00
/****************************************************************************
Does this name match a fake filename ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
enum FAKE_FILE_TYPE is_fake_file ( const char * fname )
{
# ifdef HAVE_SYS_QUOTAS
int i ;
# endif
if ( ! fname ) {
return FAKE_FILE_TYPE_NONE ;
}
# ifdef HAVE_SYS_QUOTAS
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 ;
}
}
# endif
return FAKE_FILE_TYPE_NONE ;
}
/****************************************************************************
Open a fake quota file with a share mode .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-11 22:01:26 +04:00
NTSTATUS open_fake_file ( connection_struct * conn ,
2005-07-08 08:51:27 +04:00
enum FAKE_FILE_TYPE fake_file_type ,
const char * fname ,
2006-07-11 22:01:26 +04:00
uint32 access_mask ,
files_struct * * result )
2005-07-08 08:51:27 +04:00
{
files_struct * fsp = NULL ;
2006-07-11 22:01:26 +04:00
NTSTATUS status ;
2005-07-08 08:51:27 +04:00
/* access check */
2006-02-02 23:44:50 +03:00
if ( current_user . ut . uid ! = 0 ) {
2005-07-08 08:51:27 +04:00
DEBUG ( 1 , ( " open_fake_file_shared: access_denied to service[%s] file[%s] user[%s] \n " ,
lp_servicename ( SNUM ( conn ) ) , fname , conn - > user ) ) ;
2006-07-11 22:01:26 +04:00
return NT_STATUS_ACCESS_DENIED ;
2005-07-08 08:51:27 +04:00
}
2006-07-11 22:01:26 +04:00
status = file_new ( conn , & fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2005-07-08 08:51:27 +04:00
}
DEBUG ( 5 , ( " open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x \n " ,
fname , fsp - > fnum , ( unsigned int ) access_mask ) ) ;
fsp - > conn = conn ;
fsp - > fh - > fd = - 1 ;
fsp - > vuid = current_user . vuid ;
fsp - > fh - > pos = - 1 ;
2006-07-11 22:01:26 +04:00
fsp - > can_lock = False ; /* Should this be true ? - No, JRA */
2005-07-08 08:51:27 +04:00
fsp - > access_mask = access_mask ;
string_set ( & fsp - > fsp_name , fname ) ;
fsp - > fake_file_handle = init_fake_file_handle ( fake_file_type ) ;
if ( fsp - > fake_file_handle = = NULL ) {
file_free ( fsp ) ;
2006-07-11 22:01:26 +04:00
return NT_STATUS_NO_MEMORY ;
2005-07-08 08:51:27 +04:00
}
conn - > num_files_open + + ;
2006-07-11 22:01:26 +04:00
* result = fsp ;
return NT_STATUS_OK ;
2005-07-08 08:51:27 +04:00
}
2003-05-12 05:20:17 +04:00
void destroy_fake_file_handle ( FAKE_FILE_HANDLE * * fh )
{
2005-07-08 08:51:27 +04:00
if ( ! fh | | ! ( * fh ) ) {
2004-09-17 19:09:20 +04:00
return ;
2005-07-08 08:51:27 +04:00
}
2003-05-12 05:20:17 +04:00
2005-07-08 08:51:27 +04:00
if ( ( * fh ) - > free_pd ) {
2003-05-12 05:20:17 +04:00
( * fh ) - > free_pd ( & ( * fh ) - > pd ) ;
2005-07-08 08:51:27 +04:00
}
2003-05-12 05:20:17 +04:00
talloc_destroy ( ( * fh ) - > mem_ctx ) ;
( * fh ) = NULL ;
}
2006-05-17 19:01:57 +04:00
int close_fake_file ( files_struct * fsp )
{
file_free ( fsp ) ;
return 0 ;
}