1998-03-12 00:11:04 +03:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
1998-03-12 00:11:04 +03:00
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 1997 ,
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997 ,
2001-03-11 03:32:10 +03:00
* Copyright ( C ) Jeremy Allison 2001.
1998-03-12 00:11:04 +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-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
1998-03-12 00:11:04 +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 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
1998-03-12 00:11:04 +03:00
*/
# include "includes.h"
2011-10-27 14:00:53 +04:00
# include "system/passwd.h" /* uid_wrapper */
2010-05-05 03:39:16 +04:00
# include "../librpc/gen_ndr/ndr_lsa.h"
2010-05-28 04:18:21 +04:00
# include "../librpc/gen_ndr/ndr_samr.h"
2011-03-24 14:08:15 +03:00
# include "auth.h"
2011-07-21 17:53:10 +04:00
# include "rpc_server/rpc_pipes.h"
2011-07-19 05:57:05 +04:00
# include "../libcli/security/security.h"
2011-07-21 19:02:59 +04:00
# include "lib/tsocket/tsocket.h"
2013-09-18 12:58:16 +04:00
# include "librpc/ndr/ndr_table.h"
2020-05-06 14:56:46 +03:00
# include "librpc/rpc/dcesrv_core.h"
1998-03-12 00:11:04 +03:00
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2019-11-04 20:38:14 +03:00
static size_t num_handles = 0 ;
2011-07-21 17:53:10 +04:00
bool check_open_pipes ( void )
{
2019-11-04 20:38:14 +03:00
if ( num_handles > 0 ) {
return true ;
2011-07-21 17:53:10 +04:00
}
2019-11-04 20:38:14 +03:00
return false ;
2002-03-30 03:45:26 +03:00
}
2019-11-04 20:38:14 +03:00
size_t num_pipe_handles ( void )
2009-04-18 18:10:57 +04:00
{
2019-11-04 20:38:14 +03:00
return num_handles ;
1998-03-12 00:11:04 +03:00
}
/****************************************************************************
find first available policy slot . creates a policy handle for you .
2009-01-07 20:44:52 +03: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-12 00:11:04 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
2021-08-09 16:12:31 +03:00
struct hnd_cnt {
bool _dummy ;
} ;
static int hnd_cnt_destructor ( struct hnd_cnt * cnt )
{
num_handles - - ;
return 0 ;
}
2019-11-04 20:38:14 +03:00
bool create_policy_hnd ( struct pipes_struct * p ,
struct policy_handle * hnd ,
uint8_t handle_type ,
void * data_ptr )
1998-03-12 00:11:04 +03:00
{
2019-11-04 20:38:14 +03:00
struct dcesrv_handle * rpc_hnd = NULL ;
2021-08-09 16:12:31 +03:00
struct hnd_cnt * cnt = NULL ;
1998-03-12 00:11:04 +03:00
2019-11-04 20:38:14 +03:00
rpc_hnd = dcesrv_handle_create ( p - > dce_call , handle_type ) ;
if ( rpc_hnd = = NULL ) {
return false ;
1998-03-12 00:11:04 +03:00
}
2021-08-09 16:12:31 +03:00
cnt = talloc_zero ( rpc_hnd , struct hnd_cnt ) ;
if ( cnt = = NULL ) {
TALLOC_FREE ( rpc_hnd ) ;
return false ;
}
talloc_set_destructor ( cnt , hnd_cnt_destructor ) ;
2009-01-07 20:44:52 +03:00
if ( data_ptr ! = NULL ) {
2010-06-08 01:38:01 +04:00
rpc_hnd - > data = talloc_move ( rpc_hnd , & data_ptr ) ;
2009-01-07 20:44:52 +03:00
}
1998-03-12 00:11:04 +03:00
2010-06-08 01:38:01 +04:00
* hnd = rpc_hnd - > wire_handle ;
2019-11-04 20:38:14 +03:00
num_handles + + ;
2009-04-18 18:46:53 +04:00
2010-06-08 01:38:01 +04:00
return true ;
1998-03-12 00:11:04 +03:00
}
/****************************************************************************
2001-03-11 03:32:10 +03:00
find policy by handle - internal version .
1998-03-12 00:11:04 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-11-04 20:38:14 +03:00
static struct dcesrv_handle * find_policy_by_hnd_internal (
2020-05-06 14:56:46 +03:00
struct pipes_struct * p ,
const struct policy_handle * hnd ,
uint8_t handle_type ,
void * * data_p )
2001-03-11 03:32:10 +03:00
{
2019-11-04 20:38:14 +03:00
struct dcesrv_handle * h = NULL ;
2001-03-11 03:32:10 +03:00
2010-06-08 01:38:01 +04:00
if ( data_p ) {
2001-03-11 03:32:10 +03:00
* data_p = NULL ;
2010-06-08 01:38:01 +04:00
}
2001-03-11 03:32:10 +03:00
2021-09-16 15:08:28 +03:00
/*
* Do not pass an empty policy_handle to dcesrv_handle_lookup ( ) or
* it will create a new empty handle
*/
if ( ndr_policy_handle_empty ( hnd ) ) {
p - > fault_state = DCERPC_FAULT_CONTEXT_MISMATCH ;
return NULL ;
}
2019-11-04 20:38:14 +03: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 ) ;
2021-01-11 23:25:40 +03:00
if ( h = = NULL ) {
p - > fault_state = DCERPC_FAULT_CONTEXT_MISMATCH ;
return 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-12 00:11:04 +03:00
}
2021-01-11 23:25:40 +03:00
if ( data_p ) {
* data_p = h - > data ;
}
2002-01-25 08:28:37 +03:00
2021-01-11 23:25:40 +03:00
return h ;
1998-08-17 08:54:06 +04:00
}
/****************************************************************************
2001-03-11 03:32:10 +03:00
find policy by handle
1998-08-17 08:54:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020-05-18 13:04:33 +03:00
void * _find_policy_by_hnd ( struct pipes_struct * p ,
const struct policy_handle * hnd ,
uint8_t handle_type ,
NTSTATUS * pstatus )
1998-03-12 00:11:04 +03:00
{
2019-11-04 20:38:14 +03:00
struct dcesrv_handle * rpc_hnd = NULL ;
2020-05-18 13:04:33 +03:00
void * data = NULL ;
2010-06-08 01:38:01 +04:00
2020-05-18 13:04:33 +03:00
rpc_hnd = find_policy_by_hnd_internal ( p , hnd , handle_type , & data ) ;
2010-06-08 01:38:01 +04:00
if ( rpc_hnd = = NULL ) {
2020-05-18 13:04:33 +03:00
* pstatus = NT_STATUS_INVALID_HANDLE ;
return NULL ;
2010-06-08 01:38:01 +04:00
}
2020-05-18 13:04:33 +03:00
* pstatus = NT_STATUS_OK ;
return data ;
1998-03-12 00:11:04 +03:00
}
/****************************************************************************
2001-03-11 03:32:10 +03:00
Close a policy .
1998-03-12 00:11:04 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-17 08:54:06 +04:00
2019-11-04 20:38:14 +03:00
bool close_policy_hnd ( struct pipes_struct * p ,
struct policy_handle * hnd )
1998-10-22 02:36:26 +04:00
{
2019-11-04 20:38:14 +03:00
struct dcesrv_handle * rpc_hnd = NULL ;
1998-10-22 02:36:26 +04:00
2020-05-06 14:56:46 +03:00
rpc_hnd = find_policy_by_hnd_internal ( p , hnd , DCESRV_HANDLE_ANY , NULL ) ;
2010-06-08 01:38:01 +04:00
if ( rpc_hnd = = NULL ) {
DEBUG ( 3 , ( " Error closing policy (policy not found) \n " ) ) ;
return false ;
1998-10-22 02:36:26 +04:00
}
2010-06-08 01:38:01 +04:00
TALLOC_FREE ( rpc_hnd ) ;
1999-11-19 01:03:47 +03:00
2019-11-04 20:38:14 +03:00
return true ;
1998-03-12 00:11:04 +03:00
}
2002-07-15 14:35:28 +04: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 11:46:43 +04:00
bool pipe_access_check ( struct pipes_struct * p )
2002-07-15 14:35:28 +04:00
{
/* Don't let anonymous users access this RPC if restrict
anonymous > 0 */
if ( lp_restrict_anonymous ( ) > 0 ) {
2005-02-19 14:09:52 +03:00
/* schannel, so we must be ok */
2010-07-20 21:26:36 +04:00
if ( p - > pipe_bound & &
( p - > auth . auth_type = = DCERPC_AUTH_TYPE_SCHANNEL ) ) {
2005-02-19 14:09:52 +03:00
return True ;
2005-09-30 21:13:37 +04:00
}
2005-02-19 14:09:52 +03:00
2011-07-19 05:57:05 +04:00
if ( security_session_user_level ( p - > session_info , NULL ) < SECURITY_USER ) {
2002-07-15 14:35:28 +04:00
return False ;
2005-09-30 21:13:37 +04:00
}
2002-07-15 14:35:28 +04:00
}
return True ;
}