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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-05-12 05:20:17 +04: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/>.
2003-05-12 05:20:17 +04:00
*/
# include "includes.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2011-07-10 15:59:40 +04:00
# include "smbd/globals.h"
2010-08-18 18:44:47 +04:00
# include "fake_file.h"
2011-03-24 15:46:20 +03:00
# include "auth.h"
2003-05-12 05:20:17 +04:00
2008-03-29 20:19:31 +03:00
struct fake_file_type {
const char * name ;
enum FAKE_FILE_TYPE type ;
void * ( * init_pd ) ( TALLOC_CTX * mem_ctx ) ;
} ;
2009-01-08 10:38:01 +03:00
static const struct fake_file_type fake_files [ ] = {
2003-05-12 05:20:17 +04:00
# ifdef WITH_QUOTAS
2008-03-29 20:19:31 +03:00
{ FAKE_FILE_NAME_QUOTA_UNIX , FAKE_FILE_TYPE_QUOTA , init_quota_handle } ,
2003-05-12 05:20:17 +04:00
# endif /* WITH_QUOTAS */
2008-03-29 20:19:31 +03:00
{ NULL , FAKE_FILE_TYPE_NONE , 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
2008-03-29 20:19:31 +03:00
static struct fake_file_handle * init_fake_file_handle ( enum FAKE_FILE_TYPE type )
2003-05-12 05:20:17 +04:00
{
2008-03-29 20:19:31 +03:00
struct fake_file_handle * fh = NULL ;
2003-05-12 05:20:17 +04:00
int i ;
2008-03-29 20:19:31 +03:00
for ( i = 0 ; fake_files [ i ] . name ! = NULL ; i + + ) {
2003-05-12 05:20:17 +04:00
if ( fake_files [ i ] . type = = type ) {
2008-03-29 20:19:31 +03:00
break ;
}
}
2003-05-12 05:20:17 +04:00
2008-03-29 20:19:31 +03:00
if ( fake_files [ i ] . name = = NULL ) {
return NULL ;
}
2003-05-12 05:20:17 +04:00
2008-03-29 20:19:31 +03:00
DEBUG ( 5 , ( " init_fake_file_handle: for [%s] \n " , fake_files [ i ] . name ) ) ;
2003-05-12 05:20:17 +04:00
2008-03-29 20:19:31 +03:00
fh = talloc ( NULL , struct fake_file_handle ) ;
if ( fh = = NULL ) {
DEBUG ( 0 , ( " TALLOC_ZERO() failed. \n " ) ) ;
return NULL ;
}
2003-05-12 05:20:17 +04:00
2008-03-29 20:19:31 +03:00
fh - > type = type ;
2003-05-12 05:20:17 +04:00
2008-03-29 20:19:31 +03:00
if ( fake_files [ i ] . init_pd ) {
fh - > private_data = fake_files [ i ] . init_pd ( fh ) ;
2003-05-12 05:20:17 +04:00
}
2008-03-29 20:19:31 +03:00
return fh ;
2003-05-12 05:20:17 +04:00
}
2005-07-08 08:51:27 +04:00
/****************************************************************************
Does this name match a fake filename ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-19 11:57:47 +04:00
enum FAKE_FILE_TYPE is_fake_file_path ( const char * path )
2005-07-08 08:51:27 +04:00
{
int i ;
2009-08-19 11:57:47 +04:00
if ( ! path ) {
return FAKE_FILE_TYPE_NONE ;
}
for ( i = 0 ; fake_files [ i ] . name ! = NULL ; i + + ) {
if ( strncmp ( path , fake_files [ i ] . name , strlen ( fake_files [ i ] . name ) ) = = 0 ) {
DEBUG ( 5 , ( " is_fake_file: [%s] is a fake file \n " , path ) ) ;
return fake_files [ i ] . type ;
}
}
return FAKE_FILE_TYPE_NONE ;
}
enum FAKE_FILE_TYPE is_fake_file ( const struct smb_filename * smb_fname )
{
2009-07-11 02:43:21 +04:00
char * fname = NULL ;
NTSTATUS status ;
2009-08-19 11:57:47 +04:00
enum FAKE_FILE_TYPE ret ;
2005-07-08 08:51:27 +04:00
2009-07-11 02:43:21 +04:00
if ( ! smb_fname ) {
2005-07-08 08:51:27 +04:00
return FAKE_FILE_TYPE_NONE ;
}
2009-07-11 02:43:21 +04:00
status = get_full_smb_filename ( talloc_tos ( ) , smb_fname , & fname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return FAKE_FILE_TYPE_NONE ;
}
2009-08-19 11:57:47 +04:00
ret = is_fake_file_path ( fname ) ;
2009-07-11 02:43:21 +04:00
TALLOC_FREE ( fname ) ;
2005-07-08 08:51:27 +04:00
2009-08-19 11:57:47 +04:00
return ret ;
2005-07-08 08:51:27 +04:00
}
/****************************************************************************
Open a fake quota file with a share mode .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-10-09 17:38:53 +04:00
NTSTATUS open_fake_file ( struct smb_request * req , connection_struct * conn ,
2012-06-05 17:39:44 +04:00
uint64_t current_vuid ,
2005-07-08 08:51:27 +04:00
enum FAKE_FILE_TYPE fake_file_type ,
2009-07-11 02:43:21 +04:00
const struct smb_filename * smb_fname ,
2015-05-01 05:22:21 +03:00
uint32_t access_mask ,
2006-07-11 22:01:26 +04:00
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
2012-09-14 04:12:24 +04:00
status = smbd_calculate_access_mask ( conn , smb_fname , false ,
2011-07-10 15:59:40 +04:00
access_mask , & access_mask ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " open_fake_file: smbd_calculate_access_mask "
" on service[%s] file[%s] returned %s \n " ,
2012-07-18 09:37:23 +04:00
lp_servicename ( talloc_tos ( ) , SNUM ( conn ) ) ,
2011-07-10 15:59:40 +04:00
smb_fname_str_dbg ( smb_fname ) ,
nt_errstr ( status ) ) ) ;
return status ;
}
2005-07-08 08:51:27 +04:00
/* access check */
2010-02-02 02:57:16 +03:00
if ( geteuid ( ) ! = sec_initial_uid ( ) ) {
2007-12-02 14:54:11 +03:00
DEBUG ( 3 , ( " open_fake_file_shared: access_denied to "
" service[%s] file[%s] user[%s] \n " ,
2012-07-18 09:37:23 +04:00
lp_servicename ( talloc_tos ( ) , SNUM ( conn ) ) ,
2009-07-11 02:43:21 +04:00
smb_fname_str_dbg ( smb_fname ) ,
2011-07-15 09:55:31 +04:00
conn - > session_info - > unix_info - > unix_name ) ) ;
2006-07-11 22:01:26 +04:00
return NT_STATUS_ACCESS_DENIED ;
2005-07-08 08:51:27 +04:00
}
2008-10-09 17:38:53 +04:00
status = file_new ( req , conn , & fsp ) ;
2006-07-11 22:01:26 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2005-07-08 08:51:27 +04:00
}
2012-06-14 14:48:59 +04:00
DEBUG ( 5 , ( " open_fake_file_shared: fname = %s, %s, access_mask = 0x%x \n " ,
smb_fname_str_dbg ( smb_fname ) , fsp_fnum_dbg ( fsp ) ,
2009-07-11 02:43:21 +04:00
( unsigned int ) access_mask ) ) ;
2005-07-08 08:51:27 +04:00
fsp - > conn = conn ;
fsp - > fh - > fd = - 1 ;
2008-06-15 15:37:53 +04:00
fsp - > vuid = current_vuid ;
2005-07-08 08:51:27 +04:00
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 ;
2009-07-11 02:43:21 +04:00
status = fsp_set_smb_fname ( fsp , smb_fname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
file_free ( req , fsp ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-07-08 08:51:27 +04:00
fsp - > fake_file_handle = init_fake_file_handle ( fake_file_type ) ;
if ( fsp - > fake_file_handle = = NULL ) {
2008-10-09 18:27:49 +04:00
file_free ( req , fsp ) ;
2006-07-11 22:01:26 +04:00
return NT_STATUS_NO_MEMORY ;
2005-07-08 08:51:27 +04:00
}
2006-07-11 22:01:26 +04:00
* result = fsp ;
return NT_STATUS_OK ;
2005-07-08 08:51:27 +04:00
}
2008-10-09 18:27:49 +04:00
NTSTATUS close_fake_file ( struct smb_request * req , files_struct * fsp )
2006-05-17 19:01:57 +04:00
{
2008-10-09 18:27:49 +04:00
file_free ( req , fsp ) ;
2007-02-07 00:05:34 +03:00
return NT_STATUS_OK ;
2006-05-17 19:01:57 +04:00
}