2010-10-04 17:56:49 +04:00
/*
Unix SMB / CIFS implementation .
Endpoint server for the epmapper pipe
2011-01-18 11:48:35 +03:00
Copyright ( C ) 2010 - 2011 Andreas Schneider < asn @ samba . org >
2010-10-04 17:56:49 +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
the Free Software Foundation ; either version 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2011-05-02 15:21:53 +04:00
# include "ntdomain.h"
2011-01-04 11:52:57 +03:00
# include "../libcli/security/security.h"
2011-06-16 18:22:49 +04:00
# include "../lib/tsocket/tsocket.h"
2011-03-14 16:49:51 +03:00
# include "srv_epmapper.h"
2011-03-24 14:08:15 +03:00
# include "auth.h"
2010-10-04 17:56:49 +04:00
2019-02-26 19:15:37 +03:00
# include "librpc/rpc/dcesrv_core.h"
2019-05-28 17:12:51 +03:00
# include "librpc/gen_ndr/ndr_epmapper.h"
2019-02-26 19:15:37 +03:00
# include "librpc/gen_ndr/ndr_epmapper_scompat.h"
2019-12-05 13:45:54 +03:00
# include "rpc_server/rpc_server.h"
2019-02-26 19:15:37 +03:00
2020-04-28 21:59:46 +03:00
/* handle types for this module */
enum handle_types { HTYPE_LOOKUP } ;
2010-10-04 17:56:49 +04:00
typedef uint32_t error_status_t ;
2010-10-04 19:58:33 +04:00
/* An endpoint combined with an interface description */
struct dcesrv_ep_iface {
const char * name ;
2010-10-05 13:56:47 +04:00
struct ndr_syntax_id syntax_id ;
2010-10-04 19:58:33 +04:00
struct epm_tower ep ;
} ;
2010-09-16 12:50:25 +04:00
/* A rpc service interface like samr, lsarpc or netlogon */
struct dcesrv_iface {
const char * name ;
struct ndr_syntax_id syntax_id ;
} ;
struct dcesrv_iface_list {
struct dcesrv_iface_list * next , * prev ;
struct dcesrv_iface * iface ;
} ;
2010-10-04 17:56:49 +04:00
/*
2010-09-16 12:50:25 +04:00
* An endpoint can serve multiple rpc services interfaces .
* For example \ \ pipe \ netlogon can be used by lsarpc and netlogon .
*/
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint {
struct dcesrv_epm_endpoint * next , * prev ;
2010-09-16 12:50:25 +04:00
/* The type and the location of the endpoint */
struct dcerpc_binding * ep_description ;
/* A list of rpc services able to connect to the endpoint */
struct dcesrv_iface_list * iface_list ;
} ;
2011-03-16 15:42:26 +03:00
struct dcesrv_ep_entry_list {
struct dcesrv_ep_entry_list * next , * prev ;
uint32_t num_ents ;
struct epm_entry_t * entries ;
} ;
2010-12-21 21:38:40 +03:00
struct rpc_eps {
struct dcesrv_ep_iface * e ;
uint32_t count ;
} ;
2019-01-31 23:57:04 +03:00
static struct dcesrv_epm_endpoint * endpoint_table = NULL ;
2010-09-16 12:50:25 +04:00
/*
* Check if the UUID and if_version match to an interface .
*/
static bool interface_match ( const struct dcesrv_iface * if1 ,
const struct dcesrv_iface * if2 )
{
return GUID_equal ( & if1 - > syntax_id . uuid , & if2 - > syntax_id . uuid ) ;
}
/*
* Find the interface operations on an endpoint .
*/
2019-01-31 23:57:04 +03:00
static const struct dcesrv_iface * find_interface ( const struct dcesrv_epm_endpoint * endpoint ,
2010-09-16 12:50:25 +04:00
const struct dcesrv_iface * iface )
{
struct dcesrv_iface_list * iflist ;
for ( iflist = endpoint - > iface_list ; iflist ; iflist = iflist - > next ) {
if ( interface_match ( iflist - > iface , iface ) ) {
return iflist - > iface ;
}
}
return NULL ;
}
2016-10-26 19:06:36 +03:00
#if 0
2010-10-11 19:22:22 +04:00
/*
* See if a uuid and if_version match to an interface
*/
static bool interface_match_by_uuid ( const struct dcesrv_iface * iface ,
const struct GUID * uuid )
{
return GUID_equal ( & iface - > syntax_id . uuid , uuid ) ;
}
2016-10-26 19:06:36 +03:00
# endif
2010-10-11 19:22:22 +04:00
2019-01-31 23:57:04 +03:00
static struct dcesrv_iface_list * find_interface_list ( const struct dcesrv_epm_endpoint * endpoint ,
2010-10-05 13:45:41 +04:00
const struct dcesrv_iface * iface )
{
struct dcesrv_iface_list * iflist ;
for ( iflist = endpoint - > iface_list ; iflist ; iflist = iflist - > next ) {
if ( interface_match ( iflist - > iface , iface ) ) {
return iflist ;
}
}
return NULL ;
}
2010-09-16 12:50:25 +04:00
/*
* Check if two endpoints match .
*/
2014-02-01 02:26:43 +04:00
static bool endpoints_match ( const struct dcerpc_binding * b1 ,
const struct dcerpc_binding * b2 )
2010-09-16 12:50:25 +04:00
{
2014-02-01 02:26:43 +04:00
enum dcerpc_transport_t t1 ;
const char * ep1 ;
const char * h1 ;
enum dcerpc_transport_t t2 ;
const char * ep2 ;
const char * h2 ;
t1 = dcerpc_binding_get_transport ( b1 ) ;
ep1 = dcerpc_binding_get_string_option ( b1 , " endpoint " ) ;
h1 = dcerpc_binding_get_string_option ( b1 , " host " ) ;
t2 = dcerpc_binding_get_transport ( b2 ) ;
ep2 = dcerpc_binding_get_string_option ( b2 , " endpoint " ) ;
h2 = dcerpc_binding_get_string_option ( b2 , " host " ) ;
if ( t1 ! = t2 ) {
2010-09-16 12:50:25 +04:00
return false ;
}
2014-02-01 02:26:43 +04:00
if ( ! ep1 & & ep2 ) {
2014-02-01 02:20:05 +04:00
return false ;
2010-09-16 12:50:25 +04:00
}
2014-02-01 02:26:43 +04:00
if ( ep1 & & ! ep2 ) {
2010-09-16 12:50:25 +04:00
return false ;
}
2014-02-01 02:26:43 +04:00
if ( ep1 & & ep2 ) {
if ( ! strequal ( ep1 , ep2 ) ) {
2014-02-01 02:20:05 +04:00
return false ;
}
}
2014-02-01 02:26:43 +04:00
if ( ! h1 & & h2 ) {
2014-02-01 02:20:05 +04:00
return false ;
2011-07-05 17:46:59 +04:00
}
2014-02-01 02:26:43 +04:00
if ( h1 & & ! h2 ) {
2011-07-05 17:46:59 +04:00
return false ;
}
2014-02-01 02:26:43 +04:00
if ( h1 & & h2 ) {
if ( ! strequal ( h1 , h2 ) ) {
2014-02-01 02:20:05 +04:00
return false ;
}
}
2010-09-16 12:50:25 +04:00
return true ;
}
2019-01-31 23:57:04 +03:00
static struct dcesrv_epm_endpoint * find_endpoint ( struct dcesrv_epm_endpoint * endpoint_list ,
2010-09-16 12:50:25 +04:00
struct dcerpc_binding * ep_description ) {
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint * ep = NULL ;
2010-09-16 12:50:25 +04:00
for ( ep = endpoint_list ; ep ! = NULL ; ep = ep - > next ) {
if ( endpoints_match ( ep - > ep_description , ep_description ) ) {
return ep ;
}
}
return NULL ;
}
/*
* Build a list of all interfaces handled by all endpoint servers .
*/
static uint32_t build_ep_list ( TALLOC_CTX * mem_ctx ,
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint * endpoint_list ,
2010-10-11 19:22:22 +04:00
const struct GUID * uuid ,
2011-02-22 18:48:43 +03:00
const char * srv_addr ,
2010-09-16 12:50:25 +04:00
struct dcesrv_ep_iface * * peps )
{
2010-10-04 19:58:33 +04:00
struct dcesrv_ep_iface * eps = NULL ;
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint * d = NULL ;
2010-09-16 12:50:25 +04:00
uint32_t total = 0 ;
NTSTATUS status ;
* peps = NULL ;
for ( d = endpoint_list ; d ! = NULL ; d = d - > next ) {
struct dcesrv_iface_list * iface ;
struct dcerpc_binding * description ;
for ( iface = d - > iface_list ; iface ! = NULL ; iface = iface - > next ) {
2014-02-01 00:10:41 +04:00
enum dcerpc_transport_t transport ;
const char * host = NULL ;
const char * host_addr = NULL ;
2016-10-26 19:06:36 +03:00
#if 0
/*
* Windows ignores the object uuid by default . There is
* one corner case . It is checked for the mgmt
* interface , which we do not implement here yet .
*/
2010-10-05 13:56:47 +04:00
if ( uuid & & ! interface_match_by_uuid ( iface - > iface , uuid ) ) {
2010-10-11 19:22:22 +04:00
continue ;
}
2016-10-26 19:06:36 +03:00
# endif
2010-10-11 19:22:22 +04:00
2010-09-16 12:50:25 +04:00
eps = talloc_realloc ( mem_ctx ,
eps ,
struct dcesrv_ep_iface ,
total + 1 ) ;
if ( eps = = NULL ) {
return 0 ;
}
2010-10-05 13:56:47 +04:00
eps [ total ] . name = talloc_strdup ( eps ,
iface - > iface - > name ) ;
2014-02-01 00:10:41 +04:00
if ( eps [ total ] . name = = NULL ) {
return 0 ;
}
2010-10-05 13:56:47 +04:00
eps [ total ] . syntax_id = iface - > iface - > syntax_id ;
2010-09-16 12:50:25 +04:00
2011-03-24 16:39:56 +03:00
description = dcerpc_binding_dup ( mem_ctx , d - > ep_description ) ;
if ( description = = NULL ) {
return 0 ;
}
2014-02-01 00:10:41 +04:00
status = dcerpc_binding_set_abstract_syntax ( description ,
& iface - > iface - > syntax_id ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 0 ;
}
transport = dcerpc_binding_get_transport ( description ) ;
host = dcerpc_binding_get_string_option ( description , " host " ) ;
if ( transport = = NCACN_IP_TCP ) {
if ( host = = NULL ) {
host_addr = srv_addr ;
} else if ( ! is_ipaddress_v4 ( host ) ) {
host_addr = srv_addr ;
} else if ( strcmp ( host , " 0.0.0.0 " ) = = 0 ) {
host_addr = srv_addr ;
}
}
if ( host_addr ! = NULL ) {
status = dcerpc_binding_set_string_option ( description ,
" host " ,
host_addr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 0 ;
}
2011-02-22 18:48:43 +03:00
}
2010-09-16 12:50:25 +04:00
status = dcerpc_binding_build_tower ( eps ,
description ,
& eps [ total ] . ep ) ;
2011-03-24 16:39:56 +03:00
TALLOC_FREE ( description ) ;
2010-09-16 12:50:25 +04:00
if ( NT_STATUS_IS_ERR ( status ) ) {
DEBUG ( 1 , ( " Unable to build tower for %s \n " ,
iface - > iface - > name ) ) ;
continue ;
}
total + + ;
}
}
* peps = eps ;
return total ;
}
2013-02-18 13:25:09 +04:00
static bool is_privileged_pipe ( struct auth_session_info * info ) {
2011-01-04 11:52:57 +03:00
/* If the user is not root, or has the system token, fail */
2011-07-15 08:59:14 +04:00
if ( ( info - > unix_token - > uid ! = sec_initial_uid ( ) ) & &
2011-02-09 08:52:35 +03:00
! security_token_is_system ( info - > security_token ) ) {
2011-01-04 11:52:57 +03:00
return false ;
}
return true ;
}
2019-12-05 13:45:54 +03:00
void srv_epmapper_delete_endpoints ( struct dcesrv_connection * conn ,
void * private_data )
2011-03-16 15:42:26 +03:00
{
2019-12-05 13:45:54 +03:00
struct pipes_struct * p = dcesrv_get_pipes_struct ( conn ) ;
struct dcesrv_auth * auth = NULL ;
2011-03-16 15:42:26 +03:00
struct epm_Delete r ;
2011-03-24 15:07:54 +03:00
struct dcesrv_ep_entry_list * el = p - > ep_entries ;
2011-03-16 15:42:26 +03:00
error_status_t result ;
2019-12-05 13:45:54 +03:00
/* We have to set p->session_info to check if the connection is
* privileged and delete the endpoints registered by this connection .
* Set the default session info created at connection time as a
* fallback .
*/
p - > session_info = conn - > default_auth_state - > session_info ;
/* Due to security context multiplexing we can have several states
* in the connection . Search the one of type NCALRPC_AS_SYSTEM to
* replace the default .
*/
for ( auth = conn - > auth_states ; auth ! = NULL ; auth = auth - > next ) {
if ( auth - > auth_type = = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM ) {
p - > session_info = auth - > session_info ;
}
}
2011-03-24 15:07:54 +03:00
while ( el ) {
struct dcesrv_ep_entry_list * next = el - > next ;
2011-03-16 15:42:26 +03:00
r . in . num_ents = el - > num_ents ;
r . in . entries = el - > entries ;
DEBUG ( 10 , ( " Delete_endpoints for: %s \n " ,
el - > entries [ 0 ] . annotation ) ) ;
result = _epm_Delete ( p , & r ) ;
if ( result ! = EPMAPPER_STATUS_OK ) {
2019-02-18 22:28:05 +03:00
DBG_ERR ( " Failed to delete endpoint maps \n " ) ;
return ;
2011-03-16 15:42:26 +03:00
}
DLIST_REMOVE ( p - > ep_entries , el ) ;
TALLOC_FREE ( el ) ;
2011-03-24 15:07:54 +03:00
el = next ;
2011-03-16 15:42:26 +03:00
}
}
2011-03-14 16:49:51 +03:00
void srv_epmapper_cleanup ( void )
{
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint * ep = endpoint_table ;
2011-03-24 15:07:54 +03:00
while ( ep ) {
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint * next = ep - > next ;
2011-03-14 16:49:51 +03:00
DLIST_REMOVE ( endpoint_table , ep ) ;
TALLOC_FREE ( ep ) ;
2011-03-24 15:07:54 +03:00
ep = next ;
2011-03-14 16:49:51 +03:00
}
}
2010-09-16 12:50:25 +04:00
/*
* epm_Insert
*
* Add the specified entries to an endpoint map .
*/
2010-10-04 17:56:49 +04:00
error_status_t _epm_Insert ( struct pipes_struct * p ,
struct epm_Insert * r )
{
2010-09-16 12:50:25 +04:00
TALLOC_CTX * tmp_ctx ;
error_status_t rc ;
NTSTATUS status ;
uint32_t i ;
2011-03-24 18:49:27 +03:00
struct dcerpc_binding * b ;
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint * ep = NULL ;
2011-03-24 18:49:27 +03:00
struct dcesrv_iface_list * iflist ;
struct dcesrv_iface * iface ;
bool add_ep ;
2010-10-04 17:56:49 +04:00
2013-02-18 13:25:09 +04:00
/* If this is not a privileged users, return */
2011-02-25 14:06:19 +03:00
if ( p - > transport ! = NCALRPC | |
2013-02-18 13:25:09 +04:00
! is_privileged_pipe ( p - > session_info ) ) {
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2011-01-04 11:52:57 +03:00
return EPMAPPER_STATUS_CANT_PERFORM_OP ;
}
2010-09-16 12:50:25 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return EPMAPPER_STATUS_NO_MEMORY ;
}
2010-10-04 17:56:49 +04:00
2019-09-28 03:20:26 +03:00
DBG_NOTICE ( " Trying to add % " PRIu32 " new entries. \n " ,
r - > in . num_ents ) ;
2010-10-04 17:56:49 +04:00
2010-09-16 12:50:25 +04:00
for ( i = 0 ; i < r - > in . num_ents ; i + + ) {
2014-02-01 00:10:41 +04:00
enum dcerpc_transport_t transport ;
2011-03-24 18:49:27 +03:00
add_ep = false ;
b = NULL ;
2010-09-16 12:50:25 +04:00
status = dcerpc_binding_from_tower ( tmp_ctx ,
& r - > in . entries [ i ] . tower - > tower ,
& b ) ;
2011-03-24 18:49:27 +03:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NO_MEMORY ) ) {
2010-09-16 12:50:25 +04:00
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
2011-03-24 18:49:27 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
rc = EPMAPPER_STATUS_CANT_PERFORM_OP ;
goto done ;
}
2010-09-16 12:50:25 +04:00
2014-02-01 00:10:41 +04:00
transport = dcerpc_binding_get_transport ( b ) ;
2010-09-16 12:50:25 +04:00
DEBUG ( 3 , ( " _epm_Insert: Adding transport %s for %s \n " ,
2014-02-01 00:10:41 +04:00
derpc_transport_string_by_transport ( transport ) ,
2010-09-16 12:50:25 +04:00
r - > in . entries [ i ] . annotation ) ) ;
/* Check if the entry already exits */
ep = find_endpoint ( endpoint_table , b ) ;
if ( ep = = NULL ) {
/* No entry found, create it */
2019-01-31 23:57:04 +03:00
ep = talloc_zero ( NULL , struct dcesrv_epm_endpoint ) ;
2010-09-16 12:50:25 +04:00
if ( ep = = NULL ) {
2011-03-24 18:49:27 +03:00
rc = EPMAPPER_STATUS_NO_MEMORY ;
2010-09-16 12:50:25 +04:00
goto done ;
}
add_ep = true ;
ep - > ep_description = talloc_steal ( ep , b ) ;
}
/* TODO Replace the entry if the replace flag is set */
/* Create an interface */
iface = talloc ( tmp_ctx , struct dcesrv_iface ) ;
if ( iface = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
iface - > name = talloc_strdup ( iface , r - > in . entries [ i ] . annotation ) ;
if ( iface - > name = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
2014-02-01 00:10:41 +04:00
iface - > syntax_id = dcerpc_binding_get_abstract_syntax ( b ) ;
2010-09-16 12:50:25 +04:00
/*
* Check if the rpc service is alrady registered on the
* endpoint .
*/
if ( find_interface ( ep , iface ) ! = NULL ) {
2013-04-02 15:09:13 +04:00
DEBUG ( 8 , ( " dcesrv_interface_register: interface '%s' "
2010-09-16 12:50:25 +04:00
" already registered on endpoint \n " ,
iface - > name ) ) ;
/* FIXME wrong error code? */
rc = EPMAPPER_STATUS_OK ;
goto done ;
}
/* Create an entry for the interface */
iflist = talloc ( ep , struct dcesrv_iface_list ) ;
if ( iflist = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
iflist - > iface = talloc_move ( iflist , & iface ) ;
/* Finally add the interface on the endpoint */
DLIST_ADD ( ep - > iface_list , iflist ) ;
/* If it's a new endpoint add it to the endpoint_table */
if ( add_ep ) {
DLIST_ADD ( endpoint_table , ep ) ;
}
}
2011-03-16 15:42:26 +03:00
if ( r - > in . num_ents > 0 ) {
struct dcesrv_ep_entry_list * el ;
2011-03-24 15:23:48 +03:00
el = talloc_zero ( p , struct dcesrv_ep_entry_list ) ;
2011-03-16 15:42:26 +03:00
if ( el = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
el - > num_ents = r - > in . num_ents ;
el - > entries = talloc_move ( el , & r - > in . entries ) ;
DLIST_ADD ( p - > ep_entries , el ) ;
}
2010-09-16 12:50:25 +04:00
rc = EPMAPPER_STATUS_OK ;
done :
talloc_free ( tmp_ctx ) ;
return rc ;
2010-10-04 17:56:49 +04:00
}
/*
2010-10-05 13:45:41 +04:00
* epm_Delete
*
* Delete the specified entries from an endpoint map .
*/
2010-10-04 17:56:49 +04:00
error_status_t _epm_Delete ( struct pipes_struct * p ,
2010-10-05 13:45:41 +04:00
struct epm_Delete * r )
2010-10-04 17:56:49 +04:00
{
2010-10-05 13:45:41 +04:00
TALLOC_CTX * tmp_ctx ;
error_status_t rc ;
NTSTATUS status ;
uint32_t i ;
2011-03-24 18:49:27 +03:00
struct dcerpc_binding * b ;
2019-01-31 23:57:04 +03:00
struct dcesrv_epm_endpoint * ep = NULL ;
2011-03-24 18:49:27 +03:00
struct dcesrv_iface iface ;
struct dcesrv_iface_list * iflist ;
2010-10-04 17:56:49 +04:00
2010-10-05 13:45:41 +04:00
DEBUG ( 3 , ( " _epm_Delete: Trying to delete %u entries. \n " ,
r - > in . num_ents ) ) ;
2010-10-04 17:56:49 +04:00
2013-02-18 13:25:09 +04:00
/* If this is not a privileged users, return */
2011-02-25 14:06:19 +03:00
if ( p - > transport ! = NCALRPC | |
2013-02-18 13:25:09 +04:00
! is_privileged_pipe ( p - > session_info ) ) {
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2011-01-04 11:52:57 +03:00
return EPMAPPER_STATUS_CANT_PERFORM_OP ;
}
2010-10-05 13:45:41 +04:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return EPMAPPER_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < r - > in . num_ents ; i + + ) {
2014-02-01 00:10:41 +04:00
enum dcerpc_transport_t transport ;
2011-03-24 18:49:27 +03:00
b = NULL ;
2010-10-05 13:45:41 +04:00
status = dcerpc_binding_from_tower ( tmp_ctx ,
& r - > in . entries [ i ] . tower - > tower ,
& b ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
2014-02-01 00:10:41 +04:00
transport = dcerpc_binding_get_transport ( b ) ;
2010-10-05 13:45:41 +04:00
DEBUG ( 3 , ( " _epm_Delete: Deleting transport '%s' for '%s' \n " ,
2014-02-01 00:10:41 +04:00
derpc_transport_string_by_transport ( transport ) ,
2010-10-05 13:45:41 +04:00
r - > in . entries [ i ] . annotation ) ) ;
ep = find_endpoint ( endpoint_table , b ) ;
if ( ep = = NULL ) {
rc = EPMAPPER_STATUS_OK ;
goto done ;
}
iface . name = r - > in . entries [ i ] . annotation ;
2014-02-04 05:32:29 +04:00
iface . syntax_id = dcerpc_binding_get_abstract_syntax ( b ) ;
2010-10-05 13:45:41 +04:00
iflist = find_interface_list ( ep , & iface ) ;
if ( iflist = = NULL ) {
DEBUG ( 0 , ( " _epm_Delete: No interfaces left, delete endpoint \n " ) ) ;
DLIST_REMOVE ( endpoint_table , ep ) ;
talloc_free ( ep ) ;
rc = EPMAPPER_STATUS_OK ;
goto done ;
}
DLIST_REMOVE ( ep - > iface_list , iflist ) ;
if ( ep - > iface_list = = NULL ) {
DEBUG ( 0 , ( " _epm_Delete: No interfaces left, delete endpoint \n " ) ) ;
DLIST_REMOVE ( endpoint_table , ep ) ;
talloc_free ( ep ) ;
rc = EPMAPPER_STATUS_OK ;
goto done ;
}
}
rc = EPMAPPER_STATUS_OK ;
done :
talloc_free ( tmp_ctx ) ;
return rc ;
2010-10-04 17:56:49 +04:00
}
/*
2010-10-05 13:56:47 +04:00
* epm_Lookup
*
* Lookup entries in an endpoint map .
*/
2010-10-04 17:56:49 +04:00
error_status_t _epm_Lookup ( struct pipes_struct * p ,
2010-10-05 13:56:47 +04:00
struct epm_Lookup * r )
2010-10-04 17:56:49 +04:00
{
2010-10-05 13:56:47 +04:00
struct policy_handle * entry_handle ;
2010-12-21 21:38:40 +03:00
struct rpc_eps * eps ;
2010-10-05 13:56:47 +04:00
TALLOC_CTX * tmp_ctx ;
error_status_t rc ;
uint32_t count = 0 ;
uint32_t num_ents = 0 ;
uint32_t i ;
bool match = false ;
bool ok ;
2020-05-18 13:04:33 +03:00
NTSTATUS status ;
2010-10-05 13:56:47 +04:00
* r - > out . num_ents = 0 ;
r - > out . entries = NULL ;
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return EPMAPPER_STATUS_NO_MEMORY ;
}
2011-03-24 12:44:14 +03:00
DEBUG ( 5 , ( " _epm_Lookup: Trying to lookup max. %u entries. \n " ,
2010-10-05 13:56:47 +04:00
r - > in . max_ents ) ) ;
if ( r - > in . entry_handle = = NULL | |
2012-03-18 20:44:24 +04:00
ndr_policy_handle_empty ( r - > in . entry_handle ) ) {
2011-06-16 18:22:49 +04:00
char * srv_addr = NULL ;
2010-10-05 13:56:47 +04:00
2011-03-24 12:44:14 +03:00
DEBUG ( 7 , ( " _epm_Lookup: No entry_handle found, creating it. \n " ) ) ;
2010-10-05 13:56:47 +04:00
eps = talloc_zero ( tmp_ctx , struct rpc_eps ) ;
if ( eps = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
2014-02-01 00:10:41 +04:00
if ( p - > local_address ! = NULL & &
tsocket_address_is_inet ( p - > local_address , " ipv4 " ) )
{
2011-06-16 18:22:49 +04:00
srv_addr = tsocket_address_inet_addr_string ( p - > local_address ,
tmp_ctx ) ;
}
2010-10-05 13:56:47 +04:00
switch ( r - > in . inquiry_type ) {
case RPC_C_EP_ALL_ELTS :
/*
* Return all elements from the endpoint map . The
* interface_id , vers_option , and object parameters MUST
* be ignored .
*/
eps - > count = build_ep_list ( eps ,
endpoint_table ,
NULL ,
2011-06-16 18:22:49 +04:00
srv_addr ,
2010-10-05 13:56:47 +04:00
& eps - > e ) ;
break ;
case RPC_C_EP_MATCH_BY_IF :
/*
* Return endpoint map elements that contain the
* interface identifier specified by the interface_id
* and vers_option values .
*
* RPC_C_EP_MATCH_BY_IF and RPC_C_EP_MATCH_BY_BOTH
* need both the same endpoint list . There is a second
* check for the inquiry_type below which differentiates
* between them .
*/
case RPC_C_EP_MATCH_BY_BOTH :
/*
* Return endpoint map elements that contain the
* interface identifier and object UUID specified by
* interface_id , vers_option , and object .
*/
eps - > count = build_ep_list ( eps ,
endpoint_table ,
& r - > in . interface_id - > uuid ,
2011-06-16 18:22:49 +04:00
srv_addr ,
2010-10-05 13:56:47 +04:00
& eps - > e ) ;
break ;
case RPC_C_EP_MATCH_BY_OBJ :
/*
* Return endpoint map elements that contain the object
* UUID specified by object .
*/
eps - > count = build_ep_list ( eps ,
endpoint_table ,
r - > in . object ,
2011-06-16 18:22:49 +04:00
srv_addr ,
2010-10-05 13:56:47 +04:00
& eps - > e ) ;
break ;
default :
rc = EPMAPPER_STATUS_CANT_PERFORM_OP ;
goto done ;
}
if ( eps - > count = = 0 ) {
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
2020-04-28 21:59:46 +03:00
ok = create_policy_hnd ( p , r - > out . entry_handle , HTYPE_LOOKUP , eps ) ;
2010-10-05 13:56:47 +04:00
if ( ! ok ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
2020-05-18 13:04:33 +03:00
eps = find_policy_by_hnd ( p ,
r - > out . entry_handle ,
HTYPE_LOOKUP ,
struct rpc_eps ,
& status ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-10-05 13:56:47 +04:00
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
entry_handle = r - > out . entry_handle ;
} else {
2011-03-24 12:44:14 +03:00
DEBUG ( 7 , ( " _epm_Lookup: Trying to find entry_handle. \n " ) ) ;
2010-10-05 13:56:47 +04:00
2020-05-18 13:04:33 +03:00
eps = find_policy_by_hnd ( p ,
r - > in . entry_handle ,
HTYPE_LOOKUP ,
struct rpc_eps ,
& status ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-10-05 13:56:47 +04:00
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
entry_handle = r - > in . entry_handle ;
}
if ( eps = = NULL | | eps - > e = = NULL ) {
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
/* return the next N elements */
count = r - > in . max_ents ;
if ( count > eps - > count ) {
count = eps - > count ;
}
2011-03-24 12:44:14 +03:00
DEBUG ( 5 , ( " _epm_Lookup: Find %u entries \n " , count ) ) ;
2010-10-05 13:56:47 +04:00
if ( count = = 0 ) {
close_policy_hnd ( p , entry_handle ) ;
ZERO_STRUCTP ( r - > out . entry_handle ) ;
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
r - > out . entries = talloc_array ( p - > mem_ctx , struct epm_entry_t , count ) ;
if ( r - > out . entries = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
for ( i = 0 ; i < count ; i + + ) {
match = false ;
switch ( r - > in . inquiry_type ) {
case RPC_C_EP_ALL_ELTS :
/*
* Return all elements from the endpoint map . The
* interface_id , vers_option , and object parameters MUST
* be ignored .
*/
match = true ;
break ;
case RPC_C_EP_MATCH_BY_IF :
/*
* Return endpoint map elements that contain the
* interface identifier specified by the interface_id
* and vers_option values .
*/
if ( GUID_equal ( & r - > in . interface_id - > uuid ,
& eps - > e [ i ] . syntax_id . uuid ) ) {
match = true ;
}
break ;
case RPC_C_EP_MATCH_BY_OBJ :
/*
* Return endpoint map elements that contain the object
* UUID specified by object .
*/
if ( GUID_equal ( r - > in . object ,
& eps - > e [ i ] . syntax_id . uuid ) ) {
match = true ;
}
break ;
case RPC_C_EP_MATCH_BY_BOTH :
/*
* Return endpoint map elements that contain the
* interface identifier and object UUID specified by
* interface_id , vers_option , and object .
*/
if ( GUID_equal ( & r - > in . interface_id - > uuid ,
& eps - > e [ i ] . syntax_id . uuid ) & &
GUID_equal ( r - > in . object , & eps - > e [ i ] . syntax_id . uuid ) ) {
match = true ;
}
break ;
default :
return EPMAPPER_STATUS_CANT_PERFORM_OP ;
}
if ( match ) {
if ( r - > in . inquiry_type = = RPC_C_EP_MATCH_BY_IF | |
r - > in . inquiry_type = = RPC_C_EP_MATCH_BY_OBJ ) {
2015-06-03 14:33:00 +03:00
/* Check interface version */
2010-10-05 13:56:47 +04:00
match = false ;
switch ( r - > in . vers_option ) {
case RPC_C_VERS_ALL :
/*
* Return endpoint map elements that
* contain the specified interface UUID ,
* regardless of the version numbers .
*/
match = true ;
break ;
case RPC_C_VERS_COMPATIBLE :
/*
* Return the endpoint map elements that
* contain the same major versions of
* the specified interface UUID and a
* minor version greater than or equal
* to the minor version of the specified
* UUID .
*/
if ( r - > in . interface_id - > vers_major = =
( eps - > e [ i ] . syntax_id . if_version > > 16 ) & &
r - > in . interface_id - > vers_minor < =
2012-03-04 00:40:27 +04:00
( eps - > e [ i ] . syntax_id . if_version & 0xFFFF ) ) {
2010-10-05 13:56:47 +04:00
match = true ;
}
break ;
case RPC_C_VERS_EXACT :
/*
* Return endpoint map elements that
* contain the specified version of the
* specified interface UUID .
*/
if ( r - > in . interface_id - > vers_major = =
( eps - > e [ i ] . syntax_id . if_version > > 16 ) & &
r - > in . interface_id - > vers_minor = =
2012-03-04 00:40:27 +04:00
( eps - > e [ i ] . syntax_id . if_version & 0xFFFF ) ) {
2010-10-05 13:56:47 +04:00
match = true ;
}
match = true ;
break ;
case RPC_C_VERS_MAJOR_ONLY :
/*
* Return endpoint map elements that
* contain the same version of the
* specified interface UUID and ignore
* the minor version .
*/
if ( r - > in . interface_id - > vers_major = =
( eps - > e [ i ] . syntax_id . if_version > > 16 ) ) {
match = true ;
}
match = true ;
break ;
case RPC_C_VERS_UPTO :
/*
* Return endpoint map elements that
* contain a version of the specified
* interface UUID less than or equal to
* the specified major and minor
* version .
*/
if ( r - > in . interface_id - > vers_major >
eps - > e [ i ] . syntax_id . if_version > > 16 ) {
match = true ;
} else {
if ( r - > in . interface_id - > vers_major = =
( eps - > e [ i ] . syntax_id . if_version > > 16 ) & &
r - > in . interface_id - > vers_minor > =
2012-03-04 00:40:27 +04:00
( eps - > e [ i ] . syntax_id . if_version & 0xFFFF ) ) {
2010-10-05 13:56:47 +04:00
match = true ;
}
}
break ;
default :
return EPMAPPER_STATUS_CANT_PERFORM_OP ;
}
}
}
if ( match ) {
ZERO_STRUCT ( r - > out . entries [ num_ents ] . object ) ;
DEBUG ( 10 , ( " _epm_Lookup: Adding tower for '%s' \n " ,
eps - > e [ i ] . name ) ) ;
r - > out . entries [ num_ents ] . annotation = talloc_strdup ( r - > out . entries ,
eps - > e [ i ] . name ) ;
r - > out . entries [ num_ents ] . tower = talloc ( r - > out . entries ,
struct epm_twr_t ) ;
if ( r - > out . entries [ num_ents ] . tower = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
r - > out . entries [ num_ents ] . tower - > tower . floors = talloc_move ( r - > out . entries [ num_ents ] . tower , & eps - > e [ i ] . ep . floors ) ;
r - > out . entries [ num_ents ] . tower - > tower . num_floors = eps - > e [ i ] . ep . num_floors ;
r - > out . entries [ num_ents ] . tower - > tower_length = 0 ;
num_ents + + ;
}
} /* end for loop */
* r - > out . num_ents = num_ents ;
eps - > count - = count ;
eps - > e + = count ;
if ( eps - > count = = 0 ) {
close_policy_hnd ( p , entry_handle ) ;
ZERO_STRUCTP ( r - > out . entry_handle ) ;
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
rc = EPMAPPER_STATUS_OK ;
done :
talloc_free ( tmp_ctx ) ;
return rc ;
2010-10-04 17:56:49 +04:00
}
/*
2010-10-04 19:58:33 +04:00
* epm_Map
*
2010-10-04 17:56:49 +04:00
* Apply some algorithm ( using the fields in the map_tower ) to an endpoint map
* to produce a list of protocol towers .
*/
error_status_t _epm_Map ( struct pipes_struct * p ,
struct epm_Map * r )
{
2010-12-21 21:38:40 +03:00
struct policy_handle * entry_handle ;
2010-10-04 19:58:33 +04:00
enum dcerpc_transport_t transport ;
2010-12-21 21:38:40 +03:00
struct ndr_syntax_id ifid ;
2010-10-04 19:58:33 +04:00
struct epm_floor * floors ;
2010-12-21 21:38:40 +03:00
struct rpc_eps * eps ;
TALLOC_CTX * tmp_ctx ;
error_status_t rc ;
uint32_t count = 0 ;
uint32_t num_towers = 0 ;
uint32_t i ;
bool ok ;
2020-05-18 13:04:33 +03:00
NTSTATUS status ;
2010-10-04 19:58:33 +04:00
2010-12-21 21:38:40 +03:00
* r - > out . num_towers = 0 ;
r - > out . towers = NULL ;
2010-10-04 19:58:33 +04:00
2010-12-21 21:38:40 +03:00
if ( r - > in . map_tower = = NULL | | r - > in . max_towers = = 0 | |
r - > in . map_tower - > tower . num_floors < 3 ) {
return EPMAPPER_STATUS_NO_MORE_ENTRIES ;
2010-10-04 19:58:33 +04:00
}
2010-12-21 21:38:40 +03:00
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
2010-10-04 19:58:33 +04:00
return EPMAPPER_STATUS_NO_MEMORY ;
}
2010-12-21 21:38:40 +03:00
ZERO_STRUCTP ( r - > out . entry_handle ) ;
2011-03-24 12:44:14 +03:00
DEBUG ( 5 , ( " _epm_Map: Trying to map max. %u towers. \n " ,
2010-12-21 21:38:40 +03:00
r - > in . max_towers ) ) ;
/*
* A tower has normally up to 6 floors
*
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Floor 1 | Provides the RPC interface identifier . ( e . g . UUID for |
* | | netlogon ) |
* + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Floor 2 | Transfer syntax ( NDR endcoded ) |
* + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Floor 3 | RPC protocol identifier ( ncacn_tcp_ip , ncacn_np , . . . ) |
* + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Floor 4 | Port address ( e . g . TCP Port : 49156 ) |
* + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Floor 5 | Transport ( e . g . IP : 192.168 .51 .10 ) |
* + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Floor 6 | Routing |
* + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2010-10-04 19:58:33 +04:00
floors = r - > in . map_tower - > tower . floors ;
2010-12-21 21:38:40 +03:00
/* We accept NDR as the transfer syntax */
dcerpc_floor_get_lhs_data ( & floors [ 1 ] , & ifid ) ;
2010-10-04 19:58:33 +04:00
if ( floors [ 1 ] . lhs . protocol ! = EPM_PROTOCOL_UUID | |
2012-03-18 19:46:57 +04:00
! GUID_equal ( & ifid . uuid , & ndr_transfer_syntax_ndr . uuid ) | |
ifid . if_version ! = ndr_transfer_syntax_ndr . if_version ) {
2010-12-21 21:38:40 +03:00
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
2010-10-04 19:58:33 +04:00
}
2010-12-21 21:38:40 +03:00
/* We only talk to sane transports */
2010-10-04 19:58:33 +04:00
transport = dcerpc_transport_by_tower ( & r - > in . map_tower - > tower ) ;
2010-12-21 21:38:40 +03:00
if ( transport = = NCA_UNKNOWN ) {
DEBUG ( 2 , ( " epm_Map: Client requested unknown transport with "
" levels: " ) ) ;
2010-10-04 19:58:33 +04:00
for ( i = 2 ; i < r - > in . map_tower - > tower . num_floors ; i + + ) {
DEBUG ( 2 , ( " %d, " , r - > in . map_tower - > tower . floors [ i ] . lhs . protocol ) ) ;
}
DEBUG ( 2 , ( " \n " ) ) ;
2010-12-21 21:38:40 +03:00
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
if ( r - > in . entry_handle = = NULL | |
2012-03-18 20:44:24 +04:00
ndr_policy_handle_empty ( r - > in . entry_handle ) ) {
2010-12-21 21:38:40 +03:00
struct GUID * obj ;
2011-06-16 18:22:49 +04:00
char * srv_addr = NULL ;
2010-12-21 21:38:40 +03:00
2011-03-24 12:44:14 +03:00
DEBUG ( 7 , ( " _epm_Map: No entry_handle found, creating it. \n " ) ) ;
2010-12-21 21:38:40 +03:00
eps = talloc_zero ( tmp_ctx , struct rpc_eps ) ;
if ( eps = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
/*
* * * * ATTENTION * * *
* CDE 1.1 states :
*
* ept_map ( )
* Apply some algorithm ( using the fields in the map_tower )
* to an endpoint map to produce a list of protocol towers .
*
* The following code is the mysterious " some algorithm " !
*/
/* Filter by object id if one was given. */
if ( r - > in . object = = NULL | | GUID_all_zero ( r - > in . object ) ) {
obj = NULL ;
} else {
obj = r - > in . object ;
}
2014-02-01 00:10:41 +04:00
if ( p - > local_address ! = NULL & &
tsocket_address_is_inet ( p - > local_address , " ipv4 " ) )
{
2011-06-16 18:22:49 +04:00
srv_addr = tsocket_address_inet_addr_string ( p - > local_address ,
tmp_ctx ) ;
}
2010-12-21 21:38:40 +03:00
eps - > count = build_ep_list ( eps ,
endpoint_table ,
obj ,
2011-06-16 18:22:49 +04:00
srv_addr ,
2010-12-21 21:38:40 +03:00
& eps - > e ) ;
if ( eps - > count = = 0 ) {
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
/* Filter out endpoints which match the interface. */
{
struct rpc_eps * teps ;
uint32_t total = 0 ;
teps = talloc_zero ( tmp_ctx , struct rpc_eps ) ;
if ( teps = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
for ( i = 0 ; i < eps - > count ; i + + ) {
if ( data_blob_cmp ( & r - > in . map_tower - > tower . floors [ 0 ] . lhs . lhs_data ,
& eps - > e [ i ] . ep . floors [ 0 ] . lhs . lhs_data ) ! = 0 | |
transport ! = dcerpc_transport_by_tower ( & eps - > e [ i ] . ep ) ) {
continue ;
}
teps - > e = talloc_realloc ( tmp_ctx ,
teps - > e ,
struct dcesrv_ep_iface ,
total + 1 ) ;
if ( teps - > e = = NULL ) {
return 0 ;
}
teps - > e [ total ] . ep . floors = talloc_move ( teps , & eps - > e [ i ] . ep . floors ) ;
teps - > e [ total ] . ep . num_floors = eps - > e [ i ] . ep . num_floors ;
teps - > e [ total ] . name = talloc_move ( teps , & eps - > e [ i ] . name ) ;
teps - > e [ total ] . syntax_id = eps - > e [ i ] . syntax_id ;
total + + ;
}
teps - > count = total ;
talloc_free ( eps ) ;
eps = teps ;
}
/* end of "some algorithm" */
2020-04-28 21:59:46 +03:00
ok = create_policy_hnd ( p , r - > out . entry_handle , HTYPE_LOOKUP , eps ) ;
2010-12-21 21:38:40 +03:00
if ( ! ok ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
2020-05-18 13:04:33 +03:00
eps = find_policy_by_hnd ( p ,
r - > out . entry_handle ,
HTYPE_LOOKUP ,
struct rpc_eps ,
& status ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-12-21 21:38:40 +03:00
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
entry_handle = r - > out . entry_handle ;
} else {
2011-03-24 12:44:14 +03:00
DEBUG ( 7 , ( " _epm_Map: Trying to find entry_handle. \n " ) ) ;
2010-12-21 21:38:40 +03:00
2020-05-18 13:04:33 +03:00
eps = find_policy_by_hnd ( p ,
r - > in . entry_handle ,
HTYPE_LOOKUP ,
struct rpc_eps ,
& status ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-12-21 21:38:40 +03:00
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
}
entry_handle = r - > in . entry_handle ;
}
if ( eps = = NULL | | eps - > e = = NULL ) {
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
/* return the next N elements */
count = r - > in . max_towers ;
if ( count > eps - > count ) {
count = eps - > count ;
}
if ( count = = 0 ) {
close_policy_hnd ( p , entry_handle ) ;
ZERO_STRUCTP ( r - > out . entry_handle ) ;
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES ;
goto done ;
}
r - > out . towers = talloc_array ( p - > mem_ctx , struct epm_twr_p_t , count ) ;
if ( r - > out . towers = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
2010-10-04 19:58:33 +04:00
}
for ( i = 0 ; i < count ; i + + ) {
2011-03-24 12:44:14 +03:00
DEBUG ( 7 , ( " _epm_Map: Map tower for '%s' \n " ,
2010-12-21 21:38:40 +03:00
eps - > e [ i ] . name ) ) ;
r - > out . towers [ num_towers ] . twr = talloc ( r - > out . towers ,
struct epm_twr_t ) ;
if ( r - > out . towers [ num_towers ] . twr = = NULL ) {
rc = EPMAPPER_STATUS_NO_MEMORY ;
goto done ;
2010-10-04 19:58:33 +04:00
}
2010-12-21 21:38:40 +03:00
r - > out . towers [ num_towers ] . twr - > tower . floors = talloc_move ( r - > out . towers [ num_towers ] . twr , & eps - > e [ i ] . ep . floors ) ;
r - > out . towers [ num_towers ] . twr - > tower . num_floors = eps - > e [ i ] . ep . num_floors ;
r - > out . towers [ num_towers ] . twr - > tower_length = 0 ;
2010-10-04 19:58:33 +04:00
2010-12-21 21:38:40 +03:00
num_towers + + ;
}
2010-10-04 19:58:33 +04:00
2010-12-21 21:38:40 +03:00
* r - > out . num_towers = num_towers ;
eps - > count - = count ;
eps - > e + = count ;
if ( eps - > count = = 0 ) {
close_policy_hnd ( p , entry_handle ) ;
ZERO_STRUCTP ( r - > out . entry_handle ) ;
2010-10-04 19:58:33 +04:00
}
2010-12-21 21:38:40 +03:00
rc = EPMAPPER_STATUS_OK ;
done :
talloc_free ( tmp_ctx ) ;
2010-10-04 19:58:33 +04:00
2010-12-21 21:38:40 +03:00
return rc ;
2010-10-04 17:56:49 +04:00
}
/*
2010-10-11 13:42:26 +04:00
* epm_LookupHandleFree
*/
2010-10-04 17:56:49 +04:00
error_status_t _epm_LookupHandleFree ( struct pipes_struct * p ,
2010-10-11 13:42:26 +04:00
struct epm_LookupHandleFree * r )
2010-10-04 17:56:49 +04:00
{
2010-10-11 13:42:26 +04:00
if ( r - > in . entry_handle = = NULL ) {
return EPMAPPER_STATUS_OK ;
}
if ( is_valid_policy_hnd ( r - > in . entry_handle ) ) {
close_policy_hnd ( p , r - > in . entry_handle ) ;
}
r - > out . entry_handle = r - > in . entry_handle ;
return EPMAPPER_STATUS_OK ;
2010-10-04 17:56:49 +04:00
}
/*
2011-01-18 11:48:35 +03:00
* epm_InqObject
*
* A client implementation SHOULD NOT call this method . These extensions do not
* provide an alternative method .
*/
2010-10-04 17:56:49 +04:00
error_status_t _epm_InqObject ( struct pipes_struct * p ,
struct epm_InqObject * r )
{
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2010-10-04 17:56:49 +04:00
return EPMAPPER_STATUS_CANT_PERFORM_OP ;
}
/*
2011-01-18 11:48:35 +03:00
* epm_MgmtDelete
*
* A client implementation SHOULD NOT call this method . These extensions do not
* provide an alternative method .
2010-10-04 17:56:49 +04:00
*/
error_status_t _epm_MgmtDelete ( struct pipes_struct * p ,
struct epm_MgmtDelete * r )
{
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2010-10-04 17:56:49 +04:00
return EPMAPPER_STATUS_CANT_PERFORM_OP ;
}
/*
epm_MapAuth
*/
error_status_t _epm_MapAuth ( struct pipes_struct * p ,
struct epm_MapAuth * r )
{
2012-06-27 17:21:11 +04:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2010-10-04 17:56:49 +04:00
return EPMAPPER_STATUS_CANT_PERFORM_OP ;
}
2019-02-26 19:15:37 +03:00
static NTSTATUS epmapper__op_shutdown_server ( struct dcesrv_context * dce_ctx ,
const struct dcesrv_endpoint_server * ep_server ) ;
# define DCESRV_INTERFACE_EPMAPPER_SHUTDOWN_SERVER \
epmapper_shutdown_server
static NTSTATUS epmapper_shutdown_server ( struct dcesrv_context * dce_ctx ,
const struct dcesrv_endpoint_server * ep_server )
{
srv_epmapper_cleanup ( ) ;
return epmapper__op_shutdown_server ( dce_ctx , ep_server ) ;
}
2019-02-22 20:30:45 +03:00
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_epmapper_scompat.c"
2010-10-04 17:56:49 +04:00
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */