1998-03-11 21:11:04 +00:00
/*
2002-01-30 06:08:46 +00:00
* Unix SMB / CIFS implementation .
1998-03-11 21:11:04 +00:00
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 1997 ,
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997 ,
2001-03-11 00:32:10 +00:00
* Copyright ( C ) Jeremy Allison 2001.
1998-03-11 21:11:04 +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
2007-07-09 19:25:36 +00:00
* the Free Software Foundation ; either version 3 of the License , or
1998-03-11 21:11:04 +00: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 05:23:25 +00:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
1998-03-11 21:11:04 +00:00
*/
# include "includes.h"
2011-10-27 12:00:53 +02:00
# include "system/passwd.h" /* uid_wrapper */
2010-05-05 01:39:16 +02:00
# include "../librpc/gen_ndr/ndr_lsa.h"
2010-05-28 02:18:21 +02:00
# include "../librpc/gen_ndr/ndr_samr.h"
2011-03-24 12:08:15 +01:00
# include "auth.h"
2011-07-21 09:53:10 -04:00
# include "rpc_server/rpc_pipes.h"
2011-07-19 11:57:05 +10:00
# include "../libcli/security/security.h"
2011-07-21 11:02:59 -04:00
# include "lib/tsocket/tsocket.h"
2013-09-18 10:58:16 +02:00
# include "librpc/ndr/ndr_table.h"
2020-05-06 13:56:46 +02:00
# include "librpc/rpc/dcesrv_core.h"
1998-03-11 21:11:04 +00:00
2002-07-15 10:35:28 +00:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2019-11-04 18:38:14 +01:00
static size_t num_handles = 0 ;
2011-07-21 09:53:10 -04:00
/* TODO
* the following prototypes are declared here to avoid
* code being moved about too much for a patch to be
* disrupted / less obvious .
*
* these functions , and associated functions that they
* call , should be moved behind a . so module - loading
* system _anyway_ . so that ' s the next step . . .
*/
2011-07-21 11:02:59 -04:00
int make_base_pipes_struct ( TALLOC_CTX * mem_ctx ,
struct messaging_context * msg_ctx ,
const char * pipe_name ,
enum dcerpc_transport_t transport ,
const struct tsocket_address * remote_address ,
const struct tsocket_address * local_address ,
struct pipes_struct * * _p )
{
struct pipes_struct * p ;
p = talloc_zero ( mem_ctx , struct pipes_struct ) ;
if ( ! p ) {
return ENOMEM ;
}
p - > mem_ctx = talloc_named ( p , 0 , " pipe %s %p " , pipe_name , p ) ;
if ( ! p - > mem_ctx ) {
talloc_free ( p ) ;
return ENOMEM ;
}
p - > msg_ctx = msg_ctx ;
p - > transport = transport ;
p - > remote_address = tsocket_address_copy ( remote_address , p ) ;
if ( p - > remote_address = = NULL ) {
talloc_free ( p ) ;
return ENOMEM ;
}
if ( local_address ) {
2011-07-26 11:04:48 +02:00
p - > local_address = tsocket_address_copy ( local_address , p ) ;
2011-07-21 11:02:59 -04:00
if ( p - > local_address = = NULL ) {
talloc_free ( p ) ;
return ENOMEM ;
}
}
* _p = p ;
return 0 ;
}
2011-07-21 09:53:10 -04:00
bool check_open_pipes ( void )
{
2019-11-04 18:38:14 +01:00
if ( num_handles > 0 ) {
return true ;
2011-07-21 09:53:10 -04:00
}
2019-11-04 18:38:14 +01:00
return false ;
2002-03-30 00:45:26 +00:00
}
2019-11-04 18:38:14 +01:00
size_t num_pipe_handles ( void )
2009-04-18 16:10:57 +02:00
{
2019-11-04 18:38:14 +01:00
return num_handles ;
1998-03-11 21:11:04 +00:00
}
/****************************************************************************
find first available policy slot . creates a policy handle for you .
2009-01-07 18:44:52 +01:00
If " data_ptr " is given , this must be a talloc ' ed object , create_policy_hnd
talloc_moves this into the handle . If the policy_hnd is closed ,
data_ptr is TALLOC_FREE ( ) ' ed
1998-03-11 21:11:04 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 00:32:10 +00:00
2019-11-04 18:38:14 +01:00
bool create_policy_hnd ( struct pipes_struct * p ,
struct policy_handle * hnd ,
uint8_t handle_type ,
void * data_ptr )
1998-03-11 21:11:04 +00:00
{
2019-11-04 18:38:14 +01:00
struct dcesrv_handle * rpc_hnd = NULL ;
1998-03-11 21:11:04 +00:00
2019-11-04 18:38:14 +01:00
rpc_hnd = dcesrv_handle_create ( p - > dce_call , handle_type ) ;
if ( rpc_hnd = = NULL ) {
return false ;
1998-03-11 21:11:04 +00:00
}
2009-01-07 18:44:52 +01:00
if ( data_ptr ! = NULL ) {
2010-06-07 17:38:01 -04:00
rpc_hnd - > data = talloc_move ( rpc_hnd , & data_ptr ) ;
2009-01-07 18:44:52 +01:00
}
1998-03-11 21:11:04 +00:00
2010-06-07 17:38:01 -04:00
* hnd = rpc_hnd - > wire_handle ;
2019-11-04 18:38:14 +01:00
num_handles + + ;
2009-04-18 16:46:53 +02:00
2010-06-07 17:38:01 -04:00
return true ;
1998-03-11 21:11:04 +00:00
}
/****************************************************************************
2001-03-11 00:32:10 +00:00
find policy by handle - internal version .
1998-03-11 21:11:04 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-11-04 18:38:14 +01:00
static struct dcesrv_handle * find_policy_by_hnd_internal (
2020-05-06 13:56:46 +02:00
struct pipes_struct * p ,
const struct policy_handle * hnd ,
uint8_t handle_type ,
void * * data_p )
2001-03-11 00:32:10 +00:00
{
2019-11-04 18:38:14 +01:00
struct dcesrv_handle * h = NULL ;
2001-03-11 00:32:10 +00:00
2010-06-07 17:38:01 -04:00
if ( data_p ) {
2001-03-11 00:32:10 +00:00
* data_p = NULL ;
2010-06-07 17:38:01 -04:00
}
2001-03-11 00:32:10 +00:00
2019-11-04 18:38:14 +01:00
/*
* Do not pass handle_type to avoid setting the fault_state in the
* pipes_struct if the handle type does not match
*/
h = dcesrv_handle_lookup ( p - > dce_call , hnd , DCESRV_HANDLE_ANY ) ;
if ( h ! = NULL ) {
if ( handle_type ! = DCESRV_HANDLE_ANY & &
h - > wire_handle . handle_type ! = handle_type ) {
/* Just return NULL, do not set a fault
* state in pipes_struct */
return NULL ;
1998-03-11 21:11:04 +00:00
}
2019-11-04 18:38:14 +01:00
if ( data_p ) {
* data_p = h - > data ;
}
return h ;
1998-03-11 21:11:04 +00:00
}
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_CONTEXT_MISMATCH ;
2002-01-25 05:28:37 +00:00
1998-08-17 04:54:06 +00:00
return NULL ;
}
/****************************************************************************
2001-03-11 00:32:10 +00:00
find policy by handle
1998-08-17 04:54:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020-05-18 12:04:33 +02:00
void * _find_policy_by_hnd ( struct pipes_struct * p ,
const struct policy_handle * hnd ,
uint8_t handle_type ,
NTSTATUS * pstatus )
1998-03-11 21:11:04 +00:00
{
2019-11-04 18:38:14 +01:00
struct dcesrv_handle * rpc_hnd = NULL ;
2020-05-18 12:04:33 +02:00
void * data = NULL ;
2010-06-07 17:38:01 -04:00
2020-05-18 12:04:33 +02:00
rpc_hnd = find_policy_by_hnd_internal ( p , hnd , handle_type , & data ) ;
2010-06-07 17:38:01 -04:00
if ( rpc_hnd = = NULL ) {
2020-05-18 12:04:33 +02:00
* pstatus = NT_STATUS_INVALID_HANDLE ;
return NULL ;
2010-06-07 17:38:01 -04:00
}
2020-05-18 12:04:33 +02:00
* pstatus = NT_STATUS_OK ;
return data ;
1998-03-11 21:11:04 +00:00
}
/****************************************************************************
2001-03-11 00:32:10 +00:00
Close a policy .
1998-03-11 21:11:04 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-17 04:54:06 +00:00
2019-11-04 18:38:14 +01:00
bool close_policy_hnd ( struct pipes_struct * p ,
struct policy_handle * hnd )
1998-10-21 22:36:26 +00:00
{
2019-11-04 18:38:14 +01:00
struct dcesrv_handle * rpc_hnd = NULL ;
1998-10-21 22:36:26 +00:00
2020-05-06 13:56:46 +02:00
rpc_hnd = find_policy_by_hnd_internal ( p , hnd , DCESRV_HANDLE_ANY , NULL ) ;
2010-06-07 17:38:01 -04:00
if ( rpc_hnd = = NULL ) {
DEBUG ( 3 , ( " Error closing policy (policy not found) \n " ) ) ;
return false ;
1998-10-21 22:36:26 +00:00
}
2010-06-07 17:38:01 -04:00
TALLOC_FREE ( rpc_hnd ) ;
1999-11-18 22:03:47 +00:00
2019-11-04 18:38:14 +01:00
num_handles - - ;
1998-03-11 21:11:04 +00:00
2019-11-04 18:38:14 +01:00
return true ;
1998-03-11 21:11:04 +00:00
}
2002-07-15 10:35:28 +00:00
/*******************************************************************
Shall we allow access to this rpc ? Currently this function
implements the ' restrict anonymous ' setting by denying access to
anonymous users if the restrict anonymous level is > 0. Further work
will be checking a security descriptor to determine whether a user
token has enough access to access the pipe .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:46:43 +02:00
bool pipe_access_check ( struct pipes_struct * p )
2002-07-15 10:35:28 +00:00
{
/* Don't let anonymous users access this RPC if restrict
anonymous > 0 */
if ( lp_restrict_anonymous ( ) > 0 ) {
2005-02-19 11:09:52 +00:00
/* schannel, so we must be ok */
2010-07-20 13:26:36 -04:00
if ( p - > pipe_bound & &
( p - > auth . auth_type = = DCERPC_AUTH_TYPE_SCHANNEL ) ) {
2005-02-19 11:09:52 +00:00
return True ;
2005-09-30 17:13:37 +00:00
}
2005-02-19 11:09:52 +00:00
2011-07-19 11:57:05 +10:00
if ( security_session_user_level ( p - > session_info , NULL ) < SECURITY_USER ) {
2002-07-15 10:35:28 +00:00
return False ;
2005-09-30 17:13:37 +00:00
}
2002-07-15 10:35:28 +00:00
}
return True ;
}