2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
NTVFS base code
This patch adds a better dcerpc server infastructure.
1.) We now register endpoint servers add startup via register_backend()
and later use the smb.conf 'dcerpc endpoint servers' parameter to setup the dcesrv_context
2.) each endpoint server can register at context creation time as much interfaces as it wants
(multiple interfaces on one endpoint are supported!)
(NOTE: there's a difference between 'endpoint server' and 'endpoint'!
for details look at rpc_server/dcesrv_server.h)
3.) one endpoint can have a security descriptor registered to it self
this will be checked in the future when a client wants to connect
to an smb pipe endpoint.
4.) we now have a 'remote' endpoint server, which works like the ntvfs_cifs module
it takes this options in the [globals] section:
dcerpc remote:interfaces = srvsvc, winreg, w32time, epmapper
dcerpc remote:binding = ...
dcerpc remote:user = ...
dcerpc remote:password = ...
5.) we currently have tree endpoint servers: epmapper, rpcecho and remote
the default for the 'dcerpc endpiont servers = epmapper, rpcecho'
for testing you can also do
dcerpc endpoint servers = rpcecho, remote, epmapper
dcerpc remote:interfaces = srvsvc, samr, netlogon
6,) please notice the the epmapper now only returns NO_ENTRIES
(but I think we'll find a solution for this too:-)
7.) also there're some other stuff left, but step by step :-)
This patch also includes updates for the
register_subsystem() , ntvfs_init(), and some other funtions
to check for duplicate subsystem registration
metze
(hmmm, my first large commit...I hope it works as supposed :-)
(This used to be commit 917e45dafd5be4c2cd90ff425b8d6f8403122349)
2004-01-09 01:55:27 +03:00
2003-08-13 05:53:07 +04:00
Copyright ( C ) Andrew Tridgell 2003
This patch adds a better dcerpc server infastructure.
1.) We now register endpoint servers add startup via register_backend()
and later use the smb.conf 'dcerpc endpoint servers' parameter to setup the dcesrv_context
2.) each endpoint server can register at context creation time as much interfaces as it wants
(multiple interfaces on one endpoint are supported!)
(NOTE: there's a difference between 'endpoint server' and 'endpoint'!
for details look at rpc_server/dcesrv_server.h)
3.) one endpoint can have a security descriptor registered to it self
this will be checked in the future when a client wants to connect
to an smb pipe endpoint.
4.) we now have a 'remote' endpoint server, which works like the ntvfs_cifs module
it takes this options in the [globals] section:
dcerpc remote:interfaces = srvsvc, winreg, w32time, epmapper
dcerpc remote:binding = ...
dcerpc remote:user = ...
dcerpc remote:password = ...
5.) we currently have tree endpoint servers: epmapper, rpcecho and remote
the default for the 'dcerpc endpiont servers = epmapper, rpcecho'
for testing you can also do
dcerpc endpoint servers = rpcecho, remote, epmapper
dcerpc remote:interfaces = srvsvc, samr, netlogon
6,) please notice the the epmapper now only returns NO_ENTRIES
(but I think we'll find a solution for this too:-)
7.) also there're some other stuff left, but step by step :-)
This patch also includes updates for the
register_subsystem() , ntvfs_init(), and some other funtions
to check for duplicate subsystem registration
metze
(hmmm, my first large commit...I hope it works as supposed :-)
(This used to be commit 917e45dafd5be4c2cd90ff425b8d6f8403122349)
2004-01-09 01:55:27 +03:00
Copyright ( C ) Stefan ( metze ) Metzmacher 2004
2003-08-13 05:53:07 +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-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 05:53:07 +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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 05:53:07 +04:00
*/
/*
this implements the core code for all NTVFS modules . Backends register themselves here .
*/
# include "includes.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/dlinklist.h"
2005-12-28 01:51:30 +03:00
# include "ntvfs/ntvfs.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2011-12-03 10:03:35 +04:00
# include "lib/util/samba_modules.h"
2003-08-13 05:53:07 +04:00
/* the list of currently registered NTVFS backends, note that there
* can be more than one backend with the same name , as long as they
* have different typesx */
2004-12-03 09:24:38 +03:00
static struct ntvfs_backend {
2004-02-03 14:10:56 +03:00
const struct ntvfs_ops * ops ;
2003-08-13 05:53:07 +04:00
} * backends = NULL ;
static int num_backends ;
/*
register a NTVFS backend .
The ' name ' can be later used by other backends to find the operations
structure for this backend .
The ' type ' is used to specify whether this is for a disk , printer or IPC $ share
*/
2008-04-02 06:53:27 +04:00
NTSTATUS ntvfs_register ( const struct ntvfs_ops * ops ,
2006-04-24 05:26:31 +04:00
const struct ntvfs_critical_sizes * const sizes )
2003-08-13 05:53:07 +04:00
{
2004-02-03 14:10:56 +03:00
struct ntvfs_ops * new_ops ;
2006-04-24 05:26:31 +04:00
if ( ntvfs_interface_differs ( sizes ) ) {
DEBUG ( 0 , ( " NTVFS backend '%s' for type %d "
" failed version check \n " ,
ops - > name , ( int ) ops - > type ) ) ;
return NT_STATUS_BAD_FUNCTION_TABLE ;
}
2003-11-25 06:15:26 +03:00
if ( ntvfs_backend_byname ( ops - > name , ops - > type ) ! = NULL ) {
2003-08-13 05:53:07 +04:00
/* its already registered! */
2004-02-02 16:28:29 +03:00
DEBUG ( 0 , ( " NTVFS backend '%s' for type %d already registered \n " ,
2003-11-25 06:15:26 +03:00
ops - > name , ( int ) ops - > type ) ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
2003-08-13 05:53:07 +04:00
}
2004-12-03 09:24:38 +03:00
backends = realloc_p ( backends , struct ntvfs_backend , num_backends + 1 ) ;
2003-08-13 05:53:07 +04:00
if ( ! backends ) {
smb_panic ( " out of memory in ntvfs_register " ) ;
}
2004-02-03 14:10:56 +03:00
new_ops = smb_xmemdup ( ops , sizeof ( * ops ) ) ;
new_ops - > name = smb_xstrdup ( ops - > name ) ;
backends [ num_backends ] . ops = new_ops ;
2003-08-13 05:53:07 +04:00
num_backends + + ;
2004-02-02 16:28:29 +03:00
DEBUG ( 3 , ( " NTVFS backend '%s' for type %d registered \n " ,
ops - > name , ops - > type ) ) ;
2003-11-25 06:15:26 +03:00
return NT_STATUS_OK ;
2003-08-13 05:53:07 +04:00
}
/*
return the operations structure for a named backend of the specified type
*/
2008-04-02 06:53:27 +04:00
const struct ntvfs_ops * ntvfs_backend_byname ( const char * name , enum ntvfs_type type )
2003-08-13 05:53:07 +04:00
{
int i ;
for ( i = 0 ; i < num_backends ; i + + ) {
2003-11-25 06:15:26 +03:00
if ( backends [ i ] . ops - > type = = type & &
strcmp ( backends [ i ] . ops - > name , name ) = = 0 ) {
2003-08-13 05:53:07 +04:00
return backends [ i ] . ops ;
}
}
return NULL ;
}
/*
return the NTVFS interface version , and the size of some critical types
This can be used by backends to either detect compilation errors , or provide
multiple implementations for different smbd compilation options in one module
*/
2006-04-24 05:26:31 +04:00
static const NTVFS_CURRENT_CRITICAL_SIZES ( critical_sizes ) ;
2006-03-10 17:31:17 +03:00
2008-04-02 06:53:27 +04:00
const struct ntvfs_critical_sizes * ntvfs_interface_version ( void )
2003-08-13 05:53:07 +04:00
{
2003-12-02 12:16:53 +03:00
return & critical_sizes ;
2003-08-13 05:53:07 +04:00
}
2008-04-02 06:53:27 +04:00
bool ntvfs_interface_differs ( const struct ntvfs_critical_sizes * const iface )
2006-04-24 05:26:31 +04:00
{
/* The comparison would be easier with memcmp, but compiler-interset
* alignment padding is not guaranteed to be zeroed .
*/
# define FIELD_DIFFERS(field) (iface->field != critical_sizes.field)
if ( FIELD_DIFFERS ( interface_version ) )
2007-10-07 02:28:14 +04:00
return true ;
2006-04-24 05:26:31 +04:00
if ( FIELD_DIFFERS ( sizeof_ntvfs_critical_sizes ) )
2007-10-07 02:28:14 +04:00
return true ;
2006-04-24 05:26:31 +04:00
if ( FIELD_DIFFERS ( sizeof_ntvfs_context ) )
2007-10-07 02:28:14 +04:00
return true ;
2006-04-24 05:26:31 +04:00
if ( FIELD_DIFFERS ( sizeof_ntvfs_module_context ) )
2007-10-07 02:28:14 +04:00
return true ;
2006-04-24 05:26:31 +04:00
if ( FIELD_DIFFERS ( sizeof_ntvfs_ops ) )
2007-10-07 02:28:14 +04:00
return true ;
2006-04-24 05:26:31 +04:00
if ( FIELD_DIFFERS ( sizeof_ntvfs_async_state ) )
2007-10-07 02:28:14 +04:00
return true ;
2006-04-24 05:26:31 +04:00
if ( FIELD_DIFFERS ( sizeof_ntvfs_request ) )
2007-10-07 02:28:14 +04:00
return true ;
2006-04-24 05:26:31 +04:00
/* Versions match. */
2007-10-07 02:28:14 +04:00
return false ;
2006-04-24 05:26:31 +04:00
# undef FIELD_DIFFERS
}
2003-08-13 05:53:07 +04:00
/*
initialise a connection structure to point at a NTVFS backend
*/
2006-07-23 22:43:07 +04:00
NTSTATUS ntvfs_init_connection ( TALLOC_CTX * mem_ctx , struct share_config * scfg , enum ntvfs_type type ,
2006-03-15 20:28:46 +03:00
enum protocol_types protocol ,
2008-03-06 17:14:08 +03:00
uint64_t ntvfs_client_caps ,
2011-05-03 04:40:33 +04:00
struct tevent_context * ev , struct imessaging_context * msg ,
2007-12-09 01:32:43 +03:00
struct loadparm_context * lp_ctx ,
2007-01-10 13:52:09 +03:00
struct server_id server_id , struct ntvfs_context * * _ctx )
2003-08-13 05:53:07 +04:00
{
2006-07-23 22:43:07 +04:00
const char * * handlers = share_string_list_option ( mem_ctx , scfg , SHARE_NTVFS_HANDLER ) ;
2004-09-29 17:17:09 +04:00
int i ;
struct ntvfs_context * ctx ;
2003-08-13 05:53:07 +04:00
2004-09-29 17:17:09 +04:00
if ( ! handlers ) {
2005-01-09 05:33:16 +03:00
return NT_STATUS_INTERNAL_ERROR ;
2004-09-29 17:17:09 +04:00
}
2003-08-13 05:53:07 +04:00
2006-03-15 20:28:46 +03:00
ctx = talloc_zero ( mem_ctx , struct ntvfs_context ) ;
2005-01-09 05:33:16 +03:00
NT_STATUS_HAVE_NO_MEMORY ( ctx ) ;
2006-03-15 20:28:46 +03:00
ctx - > protocol = protocol ;
2008-03-06 17:14:08 +03:00
ctx - > client_caps = ntvfs_client_caps ;
2006-03-15 20:28:46 +03:00
ctx - > type = type ;
2006-07-23 22:43:07 +04:00
ctx - > config = talloc_steal ( ctx , scfg ) ;
2006-03-15 20:28:46 +03:00
ctx - > event_ctx = ev ;
ctx - > msg_ctx = msg ;
ctx - > server_id = server_id ;
2007-12-09 01:32:43 +03:00
ctx - > lp_ctx = lp_ctx ;
2003-08-13 05:53:07 +04:00
2004-09-29 17:17:09 +04:00
for ( i = 0 ; handlers [ i ] ; i + + ) {
struct ntvfs_module_context * ntvfs ;
2004-09-23 11:44:42 +04:00
2006-03-15 20:28:46 +03:00
ntvfs = talloc_zero ( ctx , struct ntvfs_module_context ) ;
2005-01-09 05:33:16 +03:00
NT_STATUS_HAVE_NO_MEMORY ( ntvfs ) ;
2006-03-15 20:28:46 +03:00
ntvfs - > ctx = ctx ;
2004-09-29 17:17:09 +04:00
ntvfs - > ops = ntvfs_backend_byname ( handlers [ i ] , ctx - > type ) ;
if ( ! ntvfs - > ops ) {
DEBUG ( 1 , ( " ntvfs_init_connection: failed to find backend=%s, type=%d \n " ,
handlers [ i ] , ctx - > type ) ) ;
2005-01-09 05:33:16 +03:00
return NT_STATUS_INTERNAL_ERROR ;
2004-09-29 17:17:09 +04:00
}
ntvfs - > depth = i ;
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( ctx - > modules , ntvfs ) ;
2004-09-29 17:17:09 +04:00
}
if ( ! ctx - > modules ) {
2005-01-09 05:33:16 +03:00
return NT_STATUS_INTERNAL_ERROR ;
2004-09-29 17:17:09 +04:00
}
2006-03-15 20:28:46 +03:00
* _ctx = ctx ;
2004-09-29 17:17:09 +04:00
return NT_STATUS_OK ;
2004-09-23 11:44:42 +04:00
}
2005-12-26 19:46:55 +03:00
2010-11-11 02:35:38 +03:00
/*
adds the IPC $ share , needed for RPC calls
*/
static NTSTATUS ntvfs_add_ipc_share ( struct loadparm_context * lp_ctx )
{
struct loadparm_service * ipc ;
if ( lpcfg_service ( lp_ctx , " IPC$ " ) ) {
/* it has already been defined in smb.conf or elsewhere */
return NT_STATUS_OK ;
}
ipc = lpcfg_add_service ( lp_ctx , NULL , " IPC$ " ) ;
NT_STATUS_HAVE_NO_MEMORY ( ipc ) ;
lpcfg_do_service_parameter ( lp_ctx , ipc , " comment " , " IPC Service " ) ;
lpcfg_do_service_parameter ( lp_ctx , ipc , " path " , " /dev/null " ) ;
lpcfg_do_service_parameter ( lp_ctx , ipc , " ntvfs handler " , " default " ) ;
lpcfg_do_service_parameter ( lp_ctx , ipc , " browseable " , " No " ) ;
lpcfg_do_service_parameter ( lp_ctx , ipc , " fstype " , " IPC " ) ;
return NT_STATUS_OK ;
}
2007-12-10 06:33:16 +03:00
NTSTATUS ntvfs_init ( struct loadparm_context * lp_ctx )
2005-12-26 19:46:55 +03:00
{
2007-12-12 00:23:25 +03:00
static bool initialized = false ;
2010-11-01 07:38:37 +03:00
# define _MODULE_PROTO(init) extern NTSTATUS init(void);
STATIC_ntvfs_MODULES_PROTO ;
2011-12-03 10:03:35 +04:00
init_module_fn static_init [ ] = { STATIC_ntvfs_MODULES } ;
init_module_fn * shared_init ;
2007-12-12 00:23:25 +03:00
if ( initialized ) return NT_STATUS_OK ;
initialized = true ;
2011-12-03 10:03:35 +04:00
shared_init = load_samba_modules ( NULL , " ntvfs " ) ;
2005-12-26 19:46:55 +03:00
2011-12-03 10:03:35 +04:00
run_init_functions ( static_init ) ;
run_init_functions ( shared_init ) ;
2005-12-26 19:46:55 +03:00
talloc_free ( shared_init ) ;
2010-11-11 02:35:38 +03:00
ntvfs_add_ipc_share ( lp_ctx ) ;
2005-12-26 19:46:55 +03:00
return NT_STATUS_OK ;
}