2023-10-10 17:00:14 +03:00
/*
2003-05-12 05:20:17 +04:00
Unix SMB / CIFS implementation .
2023-07-18 12:30:18 +03:00
FAKE FILE support , for faking up special files windows want access to
2003-05-12 05:20:17 +04:00
Copyright ( C ) Stefan ( metze ) Metzmacher 2003
2023-10-10 17:00:14 +03:00
2003-05-12 05:20:17 +04:00
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 .
2023-10-10 17:00:14 +03:00
2003-05-12 05:20:17 +04:00
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 .
2023-10-10 17:00:14 +03:00
2003-05-12 05:20:17 +04:00
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
}
2021-06-04 17:31:20 +03:00
uint32_t dosmode_from_fake_filehandle ( const struct fake_file_handle * ffh )
{
if ( ffh - > type ! = FAKE_FILE_TYPE_QUOTA ) {
DBG_ERR ( " Unexpected fake_file_handle: %d \n " , ffh - > type ) ;
log_stack_trace ( ) ;
return FILE_ATTRIBUTE_NORMAL ;
}
/* This is what Windows 2016 returns */
return FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_ARCHIVE ;
}
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
{
2019-11-07 13:01:05 +03:00
const struct loadparm_substitution * lp_sub =
loadparm_s3_global_substitution ( ) ;
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 */
2010-02-02 02:57:16 +03:00
if ( geteuid ( ) ! = sec_initial_uid ( ) ) {
2022-08-12 13:49:07 +03:00
DBG_NOTICE ( " access_denied to service[%s] file[%s] user[%s] \n " ,
lp_servicename ( talloc_tos ( ) , lp_sub , SNUM ( conn ) ) ,
smb_fname_str_dbg ( smb_fname ) ,
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
}
2022-08-12 13:49:07 +03:00
DBG_INFO ( " fname = %s, %s, access_mask = 0x% " PRIx32 " \n " ,
smb_fname_str_dbg ( smb_fname ) ,
fsp_fnum_dbg ( fsp ) ,
access_mask ) ;
2005-07-08 08:51:27 +04:00
fsp - > conn = conn ;
2020-09-26 22:46:51 +03:00
fsp_set_fd ( fsp , - 1 ) ;
2008-06-15 15:37:53 +04:00
fsp - > vuid = current_vuid ;
2020-09-28 11:32:29 +03:00
fh_set_pos ( fsp - > fh , - 1 ) ;
2020-04-02 18:09:36 +03:00
fsp - > fsp_flags . 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 ) ;
2023-10-10 17:00:14 +03:00
2005-07-08 08:51:27 +04:00
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
}
2021-06-08 21:56:25 +03:00
status = smbd_calculate_access_mask_fsp ( conn - > cwd_fsp ,
fsp ,
2021-06-08 03:21:04 +03:00
false ,
access_mask ,
& access_mask ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2021-06-08 03:22:57 +03:00
DBG_DEBUG ( " smbd_calculate_access_mask_fsp "
2021-06-08 03:21:04 +03:00
" on service[%s] file[%s] returned %s \n " ,
lp_servicename ( talloc_tos ( ) , lp_sub , SNUM ( conn ) ) ,
smb_fname_str_dbg ( smb_fname ) ,
2021-06-08 03:22:57 +03:00
nt_errstr ( status ) ) ;
2021-06-08 03:21:04 +03:00
file_free ( req , fsp ) ;
return status ;
}
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
{
2022-02-01 19:19:54 +03:00
/*
* Nothing to do , fake files don ' t hold any resources
*/
2007-02-07 00:05:34 +03:00
return NT_STATUS_OK ;
2006-05-17 19:01:57 +04:00
}