2003-12-13 05:20:40 +03:00
/*
Unix SMB / CIFS implementation .
endpoint server for the epmapper pipe
Copyright ( C ) Andrew Tridgell 2003
2004-10-24 17:30:50 +04:00
Copyright ( C ) Jelmer Vernooij 2004
2003-12-13 05:20:40 +03: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-12-13 05:20:40 +03: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-12-13 05:20:40 +03:00
*/
# include "includes.h"
2004-11-01 13:30:34 +03:00
# include "librpc/gen_ndr/ndr_epmapper.h"
2004-11-02 10:42:47 +03:00
# include "rpc_server/dcerpc_server.h"
2003-12-13 05:20:40 +03:00
2018-11-21 22:06:21 +03:00
# define DCESRV_INTERFACE_EPMAPPER_BIND(context, iface) \
dcesrv_interface_epmapper_bind ( context , iface )
static NTSTATUS dcesrv_interface_epmapper_bind ( struct dcesrv_connection_context * context ,
2016-03-26 21:17:40 +03:00
const struct dcesrv_interface * iface )
{
2018-11-21 22:06:21 +03:00
return dcesrv_interface_bind_allow_connect ( context , iface ) ;
2016-03-26 21:17:40 +03:00
}
2004-08-14 09:53:53 +04:00
typedef uint32_t error_status_t ;
2003-12-13 05:20:40 +03:00
/* handle types for this module */
enum handle_types { HTYPE_LOOKUP } ;
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
/* a endpoint combined with an interface description */
struct dcesrv_ep_iface {
const char * name ;
2004-12-29 18:36:45 +03:00
struct epm_tower ep ;
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-12-13 06:23:41 +03:00
/*
build a list of all interfaces handled by all endpoint servers
*/
2004-05-25 20:24:13 +04:00
static uint32_t build_ep_list ( TALLOC_CTX * mem_ctx ,
2004-09-26 16:50:36 +04:00
struct dcesrv_endpoint * endpoint_list ,
struct dcesrv_ep_iface * * eps )
2003-12-13 06:23:41 +03:00
{
2004-01-09 05:43:23 +03:00
struct dcesrv_endpoint * d ;
2004-05-25 20:24:13 +04:00
uint32_t total = 0 ;
2004-12-29 18:36:45 +03:00
NTSTATUS status ;
2003-12-13 06:23:41 +03:00
2004-09-27 05:36:19 +04:00
* eps = NULL ;
2004-01-09 05:43:23 +03:00
for ( d = endpoint_list ; d ; d = d - > next ) {
struct dcesrv_if_list * iface ;
for ( iface = d - > interface_list ; iface ; iface = iface - > next ) {
2014-02-04 05:33:03 +04:00
struct dcerpc_binding * description ;
2005-01-27 10:08:20 +03:00
( * eps ) = talloc_realloc ( mem_ctx ,
2004-09-27 05:36:19 +04:00
* eps ,
2004-01-09 05:43:23 +03:00
struct dcesrv_ep_iface ,
total + 1 ) ;
if ( ! * eps ) {
return 0 ;
}
2019-10-01 17:48:01 +03:00
( * eps ) [ total ] . name = iface - > iface - > name ;
2004-12-29 18:36:45 +03:00
2014-02-04 05:33:03 +04:00
description = dcerpc_binding_dup ( * eps , d - > ep_description ) ;
if ( description = = NULL ) {
return 0 ;
}
2014-02-04 05:33:03 +04:00
status = dcerpc_binding_set_abstract_syntax ( description ,
2019-10-01 17:48:01 +03:00
& iface - > iface - > syntax_id ) ;
2014-02-04 05:33:03 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 0 ;
}
2004-12-29 18:36:45 +03:00
2009-10-21 08:15:48 +04:00
status = dcerpc_binding_build_tower ( * eps , description , & ( * eps ) [ total ] . ep ) ;
2014-02-04 05:33:03 +04:00
TALLOC_FREE ( description ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2019-10-01 17:48:01 +03:00
DBG_ERR ( " Unable to build tower for %s - %s \n " ,
iface - > iface - > name ,
nt_errstr ( status ) ) ;
2004-12-29 18:36:45 +03:00
continue ;
}
2004-01-09 05:43:23 +03:00
total + + ;
}
}
2003-12-13 06:23:41 +03:00
return total ;
}
2007-04-04 18:24:44 +04:00
static error_status_t dcesrv_epm_Insert ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx , struct epm_Insert * r )
2003-12-13 05:20:40 +03:00
{
2004-08-14 09:29:16 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2003-12-13 05:20:40 +03:00
}
2007-01-17 17:49:36 +03:00
static error_status_t dcesrv_epm_Delete ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 09:53:53 +04:00
struct epm_Delete * r )
2003-12-13 05:20:40 +03:00
{
2004-08-14 09:29:16 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2003-12-13 05:20:40 +03:00
}
/*
implement epm_Lookup . This call is used to enumerate the interfaces
available on a rpc server
*/
2007-01-17 17:49:36 +03:00
static error_status_t dcesrv_epm_Lookup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 09:53:53 +04:00
struct epm_Lookup * r )
2003-12-13 05:20:40 +03:00
{
struct dcesrv_handle * h ;
struct rpc_eps {
2004-05-25 20:24:13 +04:00
uint32_t count ;
2003-12-13 05:20:40 +03:00
struct dcesrv_ep_iface * e ;
} * eps ;
2004-05-25 20:24:13 +04:00
uint32_t num_ents ;
2009-11-21 20:59:30 +03:00
unsigned int i ;
2003-12-13 05:20:40 +03:00
2005-01-10 15:15:26 +03:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . entry_handle , HTYPE_LOOKUP ) ;
2003-12-13 05:20:40 +03:00
eps = h - > data ;
if ( ! eps ) {
/* this is the first call - fill the list. Subsequent calls
will feed from this list , stored in the handle */
2005-01-27 10:08:20 +03:00
eps = talloc ( h , struct rpc_eps ) ;
2003-12-13 05:20:40 +03:00
if ( ! eps ) {
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_NO_MEMORY ;
2003-12-13 05:20:40 +03:00
}
h - > data = eps ;
2003-12-13 06:23:41 +03:00
2004-09-25 15:24:10 +04:00
eps - > count = build_ep_list ( h , dce_call - > conn - > dce_ctx - > endpoint_list , & eps - > e ) ;
2003-12-13 05:20:40 +03:00
}
/* return the next N elements */
num_ents = r - > in . max_ents ;
if ( num_ents > eps - > count ) {
num_ents = eps - > count ;
}
* r - > out . entry_handle = h - > wire_handle ;
2006-11-22 19:55:21 +03:00
r - > out . num_ents = talloc ( mem_ctx , uint32_t ) ;
* r - > out . num_ents = num_ents ;
2003-12-13 05:20:40 +03:00
if ( num_ents = = 0 ) {
r - > out . entries = NULL ;
2003-12-13 07:46:50 +03:00
ZERO_STRUCTP ( r - > out . entry_handle ) ;
2005-01-10 15:15:26 +03:00
talloc_free ( h ) ;
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_NO_MORE_ENTRIES ;
2003-12-13 05:20:40 +03:00
}
2005-01-27 10:08:20 +03:00
r - > out . entries = talloc_array ( mem_ctx , struct epm_entry_t , num_ents ) ;
2003-12-13 05:20:40 +03:00
if ( ! r - > out . entries ) {
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_NO_MEMORY ;
2003-12-13 05:20:40 +03:00
}
for ( i = 0 ; i < num_ents ; i + + ) {
ZERO_STRUCT ( r - > out . entries [ i ] . object ) ;
2003-12-13 07:46:50 +03:00
r - > out . entries [ i ] . annotation = eps - > e [ i ] . name ;
2005-01-27 10:08:20 +03:00
r - > out . entries [ i ] . tower = talloc ( mem_ctx , struct epm_twr_t ) ;
2003-12-13 06:23:41 +03:00
if ( ! r - > out . entries [ i ] . tower ) {
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_NO_MEMORY ;
2003-12-13 05:20:40 +03:00
}
2004-12-29 18:36:45 +03:00
r - > out . entries [ i ] . tower - > tower = eps - > e [ i ] . ep ;
2003-12-13 05:20:40 +03:00
}
eps - > count - = num_ents ;
eps - > e + = num_ents ;
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_OK ;
2003-12-13 05:20:40 +03:00
}
/*
implement epm_Map . This is used to find the specific endpoint to talk to given
a generic protocol tower
*/
2007-01-17 17:49:36 +03:00
static error_status_t dcesrv_epm_Map ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 09:53:53 +04:00
struct epm_Map * r )
2003-12-13 05:20:40 +03:00
{
2004-05-25 20:24:13 +04:00
uint32_t count ;
2009-11-21 20:59:30 +03:00
unsigned int i ;
2003-12-13 06:23:41 +03:00
struct dcesrv_ep_iface * eps ;
struct epm_floor * floors ;
2004-10-24 17:30:50 +04:00
enum dcerpc_transport_t transport ;
2023-10-13 10:18:25 +03:00
struct ndr_syntax_id abstract_syntax ;
2007-08-18 10:57:49 +04:00
struct ndr_syntax_id ndr_syntax ;
2023-10-13 10:11:51 +03:00
NTSTATUS status ;
2003-12-13 06:23:41 +03:00
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
count = build_ep_list ( mem_ctx , dce_call - > conn - > dce_ctx - > endpoint_list , & eps ) ;
2003-12-13 06:23:41 +03:00
2004-06-04 03:15:16 +04:00
ZERO_STRUCT ( * r - > out . entry_handle ) ;
2006-11-22 19:55:21 +03:00
r - > out . num_towers = talloc ( mem_ctx , uint32_t ) ;
2009-01-07 01:25:41 +03:00
if ( ! r - > out . num_towers ) {
return EPMAPPER_STATUS_NO_MEMORY ;
}
2006-11-22 19:55:21 +03:00
* r - > out . num_towers = 1 ;
2005-01-27 10:08:20 +03:00
r - > out . towers = talloc ( mem_ctx , struct epm_twr_p_t ) ;
2003-12-13 06:23:41 +03:00
if ( ! r - > out . towers ) {
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_NO_MEMORY ;
2003-12-13 06:23:41 +03:00
}
2005-01-27 10:08:20 +03:00
r - > out . towers - > twr = talloc ( mem_ctx , struct epm_twr_t ) ;
2003-12-13 06:23:41 +03:00
if ( ! r - > out . towers - > twr ) {
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_NO_MEMORY ;
2003-12-13 06:23:41 +03:00
}
2004-10-24 17:30:50 +04:00
if ( ! r - > in . map_tower | | r - > in . max_towers = = 0 | |
r - > in . map_tower - > tower . num_floors < 3 ) {
2003-12-13 06:23:41 +03:00
goto failed ;
}
2004-10-21 14:52:03 +04:00
floors = r - > in . map_tower - > tower . floors ;
2003-12-13 06:23:41 +03:00
2023-10-13 10:18:25 +03:00
status = dcerpc_floor_get_uuid_full ( & floors [ 0 ] , & abstract_syntax ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto failed ;
}
2023-10-13 10:11:51 +03:00
status = dcerpc_floor_get_uuid_full ( & floors [ 1 ] , & ndr_syntax ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto failed ;
}
2005-02-04 04:32:19 +03:00
2023-10-13 10:11:51 +03:00
if ( ! ndr_syntax_id_equal ( & ndr_syntax , & ndr_transfer_syntax_ndr ) ) {
2004-10-24 17:30:50 +04:00
goto failed ;
}
transport = dcerpc_transport_by_tower ( & r - > in . map_tower - > tower ) ;
if ( transport = = - 1 ) {
2005-01-30 03:54:57 +03:00
DEBUG ( 2 , ( " Client requested unknown transport with levels: " ) ) ;
2004-10-24 17:30:50 +04:00
for ( i = 2 ; i < r - > in . map_tower - > tower . num_floors ; i + + ) {
2005-01-30 03:54:57 +03:00
DEBUG ( 2 , ( " %d, " , r - > in . map_tower - > tower . floors [ i ] . lhs . protocol ) ) ;
2004-10-24 17:30:50 +04:00
}
2005-01-30 03:54:57 +03:00
DEBUG ( 2 , ( " \n " ) ) ;
2003-12-13 06:23:41 +03:00
goto failed ;
}
2004-10-24 17:30:50 +04:00
2004-12-29 18:36:45 +03:00
for ( i = 0 ; i < count ; i + + ) {
2023-10-13 10:18:25 +03:00
struct ndr_syntax_id ep_abstract_syntax ;
int match ;
2023-10-12 18:19:21 +03:00
if ( transport ! = dcerpc_transport_by_tower ( & eps [ i ] . ep ) ) {
2004-10-24 17:30:50 +04:00
continue ;
}
2023-10-12 18:19:21 +03:00
2023-10-13 10:18:25 +03:00
status = dcerpc_floor_get_uuid_full ( & eps [ i ] . ep . floors [ 0 ] ,
& ep_abstract_syntax ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
continue ;
}
match = ndr_syntax_id_equal ( & ep_abstract_syntax ,
& abstract_syntax ) ;
if ( ! match ) {
2023-10-12 18:19:21 +03:00
continue ;
}
2004-12-29 18:36:45 +03:00
r - > out . towers - > twr - > tower = eps [ i ] . ep ;
2004-06-06 14:49:26 +04:00
r - > out . towers - > twr - > tower_length = 0 ;
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_OK ;
2003-12-13 06:23:41 +03:00
}
failed :
2006-11-22 19:55:21 +03:00
* r - > out . num_towers = 0 ;
2003-12-13 06:23:41 +03:00
r - > out . towers - > twr = NULL ;
2004-08-14 09:53:53 +04:00
return EPMAPPER_STATUS_NO_MORE_ENTRIES ;
2003-12-13 05:20:40 +03:00
}
2007-01-17 17:49:36 +03:00
static error_status_t dcesrv_epm_LookupHandleFree ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 09:53:53 +04:00
struct epm_LookupHandleFree * r )
2003-12-13 05:20:40 +03:00
{
2020-06-29 13:49:33 +03:00
struct dcesrv_handle * h = NULL ;
r - > out . entry_handle = r - > in . entry_handle ;
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . entry_handle , HTYPE_LOOKUP ) ;
TALLOC_FREE ( h ) ;
ZERO_STRUCTP ( r - > out . entry_handle ) ;
return EPMAPPER_STATUS_OK ;
2003-12-13 05:20:40 +03:00
}
2007-01-17 17:49:36 +03:00
static error_status_t dcesrv_epm_InqObject ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 09:53:53 +04:00
struct epm_InqObject * r )
2003-12-13 05:20:40 +03:00
{
2004-08-14 09:29:16 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2003-12-13 05:20:40 +03:00
}
2007-01-17 17:49:36 +03:00
static error_status_t dcesrv_epm_MgmtDelete ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2003-12-13 06:23:41 +03:00
struct epm_MgmtDelete * r )
2003-12-13 05:20:40 +03:00
{
2004-08-14 09:29:16 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2003-12-13 05:20:40 +03:00
}
2007-01-17 17:49:36 +03:00
static error_status_t dcesrv_epm_MapAuth ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 05:11:34 +04:00
struct epm_MapAuth * r )
{
2004-08-14 09:53:53 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-08-14 05:11:34 +04:00
}
2003-12-13 05:20:40 +03:00
2003-12-14 16:22:12 +03:00
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_epmapper_s.c"