2003-08-13 01:53:07 +00:00
/*
Unix SMB / CIFS implementation .
2004-09-08 05:39:06 +00:00
2003-08-13 01:53:07 +00:00
POSIX NTVFS backend
2004-09-08 05:39:06 +00:00
Copyright ( C ) Andrew Tridgell 2004
2003-08-13 01:53:07 +00: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
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 .
*/
/*
this implements most of the POSIX NTVFS backend
This is the default backend
*/
2003-11-25 03:15:26 +00:00
# include "include/includes.h"
2004-09-08 05:39:06 +00:00
# include "vfs_posix.h"
2003-08-13 01:53:07 +00:00
2004-09-20 07:28:43 +00:00
/*
setup config options for a posix share
*/
static void pvfs_setup_options ( struct pvfs_state * pvfs )
{
int snum = pvfs - > tcon - > service ;
2004-10-17 02:55:47 +00:00
if ( lp_map_hidden ( snum ) ) pvfs - > flags | = PVFS_FLAG_MAP_HIDDEN ;
if ( lp_map_archive ( snum ) ) pvfs - > flags | = PVFS_FLAG_MAP_ARCHIVE ;
if ( lp_map_system ( snum ) ) pvfs - > flags | = PVFS_FLAG_MAP_SYSTEM ;
if ( lp_readonly ( snum ) ) pvfs - > flags | = PVFS_FLAG_READONLY ;
if ( lp_strict_sync ( snum ) ) pvfs - > flags | = PVFS_FLAG_STRICT_SYNC ;
if ( lp_strict_locking ( snum ) ) pvfs - > flags | = PVFS_FLAG_STRICT_LOCKING ;
2004-09-20 07:28:43 +00:00
pvfs - > share_name = talloc_strdup ( pvfs , lp_servicename ( snum ) ) ;
}
2003-08-13 01:53:07 +00:00
/*
connect to a share - used when a tree_connect operation comes
in . For a disk based backend we needs to ensure that the base
directory exists ( tho it doesn ' t need to be accessible by the user ,
that comes later )
*/
2004-09-29 13:17:09 +00:00
static NTSTATUS pvfs_connect ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , const char * sharename )
2003-08-13 01:53:07 +00:00
{
2004-09-08 05:39:06 +00:00
struct smbsrv_tcon * tcon = req - > tcon ;
struct pvfs_state * pvfs ;
struct stat st ;
2004-09-18 08:16:14 +00:00
char * base_directory ;
2004-10-12 05:10:43 +00:00
NTSTATUS status ;
2004-09-08 05:39:06 +00:00
2004-10-19 06:39:51 +00:00
pvfs = talloc_zero_p ( tcon , struct pvfs_state ) ;
2004-09-08 05:39:06 +00:00
if ( pvfs = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-09-18 08:16:14 +00:00
/* for simplicity of path construction, remove any trailing slash now */
base_directory = talloc_strdup ( pvfs , lp_pathname ( tcon - > service ) ) ;
trim_string ( base_directory , NULL , " / " ) ;
2004-09-20 07:28:43 +00:00
pvfs - > tcon = tcon ;
2004-09-18 08:16:14 +00:00
pvfs - > base_directory = base_directory ;
2004-09-08 05:39:06 +00:00
/* the directory must exist. Note that we deliberately don't
check that it is readable */
if ( stat ( pvfs - > base_directory , & st ) ! = 0 | | ! S_ISDIR ( st . st_mode ) ) {
DEBUG ( 0 , ( " pvfs_connect: '%s' is not a directory, when connecting to [%s] \n " ,
pvfs - > base_directory , sharename ) ) ;
return NT_STATUS_BAD_NETWORK_NAME ;
}
tcon - > fs_type = talloc_strdup ( tcon , " NTFS " ) ;
tcon - > dev_type = talloc_strdup ( tcon , " A: " ) ;
2004-09-23 07:44:42 +00:00
2004-09-29 13:17:09 +00:00
ntvfs - > private_data = pvfs ;
2004-09-08 05:39:06 +00:00
2004-10-17 02:55:47 +00:00
pvfs - > brl_context = brl_init ( pvfs ,
pvfs - > tcon - > smb_conn - > connection - > server_id ,
2004-10-18 07:40:17 +00:00
pvfs - > tcon - > service ,
pvfs - > tcon - > smb_conn - > connection - > messaging_ctx ) ;
2004-10-17 02:55:47 +00:00
if ( pvfs - > brl_context = = NULL ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-10-22 01:19:07 +00:00
pvfs - > odb_context = odb_init ( pvfs ,
pvfs - > tcon - > smb_conn - > connection - > server_id ,
pvfs - > tcon - > service ,
pvfs - > tcon - > smb_conn - > connection - > messaging_ctx ) ;
if ( pvfs - > odb_context = = NULL ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-10-19 06:39:51 +00:00
/* allocate the fnum id -> ptr tree */
pvfs - > idtree_fnum = idr_init ( pvfs ) ;
if ( pvfs - > idtree_fnum = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
/* allocate the search handle -> ptr tree */
pvfs - > idtree_search = idr_init ( pvfs ) ;
if ( pvfs - > idtree_search = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-10-12 05:10:43 +00:00
status = pvfs_mangle_init ( pvfs ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2004-09-20 07:28:43 +00:00
pvfs_setup_options ( pvfs ) ;
2004-09-08 05:39:06 +00:00
return NT_STATUS_OK ;
2003-08-13 01:53:07 +00:00
}
/*
disconnect from a share
*/
2004-09-29 13:17:09 +00:00
static NTSTATUS pvfs_disconnect ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_tcon * tcon )
2003-08-13 01:53:07 +00:00
{
return NT_STATUS_OK ;
}
2004-09-08 07:59:52 +00:00
/*
ioctl interface - we don ' t do any
*/
2004-09-29 13:17:09 +00:00
static NTSTATUS pvfs_ioctl ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , union smb_ioctl * io )
2004-09-08 07:59:52 +00:00
{
return NT_STATUS_INVALID_PARAMETER ;
}
/*
check if a directory exists
*/
2004-09-29 13:17:09 +00:00
static NTSTATUS pvfs_chkpath ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , struct smb_chkpath * cp )
2004-09-08 07:59:52 +00:00
{
2004-09-29 13:17:09 +00:00
struct pvfs_state * pvfs = ntvfs - > private_data ;
2004-09-18 08:16:14 +00:00
struct pvfs_filename * name ;
NTSTATUS status ;
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name ( pvfs , req , cp - > in . path , 0 , & name ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( ! name - > exists ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
if ( ! S_ISDIR ( name - > st . st_mode ) ) {
return NT_STATUS_NOT_A_DIRECTORY ;
}
return NT_STATUS_OK ;
2004-09-08 07:59:52 +00:00
}
/*
copy a set of files
*/
2004-09-29 13:17:09 +00:00
static NTSTATUS pvfs_copy ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , struct smb_copy * cp )
2004-09-08 07:59:52 +00:00
{
2004-09-18 08:16:14 +00:00
DEBUG ( 0 , ( " pvfs_copy not implemented \n " ) ) ;
2004-09-08 07:59:52 +00:00
return NT_STATUS_NOT_SUPPORTED ;
}
/*
return print queue info
*/
2004-09-29 13:17:09 +00:00
static NTSTATUS pvfs_lpq ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , union smb_lpq * lpq )
2004-09-08 07:59:52 +00:00
{
return NT_STATUS_NOT_SUPPORTED ;
}
/* SMBtrans - not used on file shares */
2004-09-29 13:17:09 +00:00
static NTSTATUS pvfs_trans ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , struct smb_trans2 * trans2 )
2004-09-08 07:59:52 +00:00
{
return NT_STATUS_ACCESS_DENIED ;
}
2003-08-13 01:53:07 +00:00
/*
initialialise the POSIX disk backend , registering ourselves with the ntvfs subsystem
*/
2003-11-25 03:15:26 +00:00
NTSTATUS ntvfs_posix_init ( void )
2003-08-13 01:53:07 +00:00
{
2003-11-25 03:15:26 +00:00
NTSTATUS ret ;
2003-08-13 01:53:07 +00:00
struct ntvfs_ops ops ;
ZERO_STRUCT ( ops ) ;
2003-11-25 03:15:26 +00:00
ops . type = NTVFS_DISK ;
2003-08-13 01:53:07 +00:00
/* fill in all the operations */
ops . connect = pvfs_connect ;
ops . disconnect = pvfs_disconnect ;
2004-09-08 07:59:52 +00:00
ops . unlink = pvfs_unlink ;
ops . chkpath = pvfs_chkpath ;
ops . qpathinfo = pvfs_qpathinfo ;
ops . setpathinfo = pvfs_setpathinfo ;
ops . open = pvfs_open ;
ops . mkdir = pvfs_mkdir ;
ops . rmdir = pvfs_rmdir ;
ops . rename = pvfs_rename ;
ops . copy = pvfs_copy ;
ops . ioctl = pvfs_ioctl ;
ops . read = pvfs_read ;
ops . write = pvfs_write ;
ops . seek = pvfs_seek ;
ops . flush = pvfs_flush ;
ops . close = pvfs_close ;
ops . exit = pvfs_exit ;
ops . lock = pvfs_lock ;
ops . setfileinfo = pvfs_setfileinfo ;
ops . qfileinfo = pvfs_qfileinfo ;
ops . fsinfo = pvfs_fsinfo ;
ops . lpq = pvfs_lpq ;
ops . search_first = pvfs_search_first ;
ops . search_next = pvfs_search_next ;
ops . search_close = pvfs_search_close ;
ops . trans = pvfs_trans ;
2004-09-26 11:30:20 +00:00
ops . logoff = pvfs_logoff ;
2004-10-18 13:27:22 +00:00
ops . async_setup = pvfs_async_setup ;
2004-09-08 07:59:52 +00:00
/* register ourselves with the NTVFS subsystem. We register
under the name ' default ' as we wish to be the default
backend , and also register as ' posix ' */
2004-09-08 11:01:18 +00:00
ops . name = " default " ;
2004-09-08 07:59:52 +00:00
ret = register_backend ( " ntvfs " , & ops ) ;
2003-08-13 01:53:07 +00:00
2004-09-08 11:01:18 +00:00
ops . name = " posix " ;
2003-11-25 03:15:26 +00:00
ret = register_backend ( " ntvfs " , & ops ) ;
2003-08-13 01:53:07 +00:00
2003-11-25 03:15:26 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-08-13 01:53:07 +00:00
DEBUG ( 0 , ( " Failed to register POSIX backend! \n " ) ) ;
}
2003-11-25 03:15:26 +00:00
return ret ;
2003-08-13 01:53:07 +00:00
}