2003-12-13 05:20:40 +03:00
/*
Unix SMB / CIFS implementation .
server side dcerpc handle code
Copyright ( C ) Andrew Tridgell 2003
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"
2008-10-11 23:31:42 +04:00
# include "../lib/util/dlinklist.h"
2004-11-02 10:42:47 +03:00
# include "rpc_server/dcerpc_server.h"
2010-08-14 07:30:51 +04:00
# include "libcli/security/security.h"
2009-09-22 11:18:03 +04:00
# include "auth/session.h"
2003-12-13 05:20:40 +03:00
2005-01-10 15:15:26 +03:00
/*
destroy a rpc handle
*/
2006-05-24 11:35:06 +04:00
static int dcesrv_handle_destructor ( struct dcesrv_handle * h )
2005-01-10 15:15:26 +03:00
{
2009-09-22 11:18:03 +04:00
DLIST_REMOVE ( h - > assoc_group - > handles , h ) ;
2005-01-10 15:15:26 +03:00
return 0 ;
}
2003-12-13 05:20:40 +03:00
/*
allocate a new rpc handle
*/
2006-05-01 22:11:15 +04:00
_PUBLIC_ struct dcesrv_handle * dcesrv_handle_new ( struct dcesrv_connection_context * context ,
2009-09-22 11:18:03 +04:00
uint8_t handle_type )
2003-12-13 05:20:40 +03:00
{
struct dcesrv_handle * h ;
2009-09-22 11:18:03 +04:00
struct dom_sid * sid ;
2003-12-13 05:20:40 +03:00
2016-11-14 01:24:03 +03:00
/*
* For simplicty , ensure we abort here for an interface that has no handles ( programmer error )
*/
SMB_ASSERT ( ( context - > iface - > flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED ) = = 0 ) ;
2010-08-20 06:15:15 +04:00
sid = & context - > conn - > auth_state . session_info - > security_token - > sids [ PRIMARY_USER_SID_INDEX ] ;
2009-09-22 11:18:03 +04:00
2015-07-15 11:18:13 +03:00
h = talloc_zero ( context - > conn - > assoc_group , struct dcesrv_handle ) ;
2003-12-13 05:20:40 +03:00
if ( ! h ) {
return NULL ;
}
h - > data = NULL ;
2009-09-22 11:18:03 +04:00
h - > sid = dom_sid_dup ( h , sid ) ;
if ( h - > sid = = NULL ) {
talloc_free ( h ) ;
return NULL ;
}
2015-07-15 11:18:13 +03:00
h - > assoc_group = context - > conn - > assoc_group ;
2009-09-22 11:18:03 +04:00
h - > iface = context - > iface ;
2003-12-16 12:50:49 +03:00
h - > wire_handle . handle_type = handle_type ;
2004-11-25 23:03:46 +03:00
h - > wire_handle . uuid = GUID_random ( ) ;
2003-12-13 05:20:40 +03:00
2015-07-15 11:18:13 +03:00
DLIST_ADD ( context - > conn - > assoc_group - > handles , h ) ;
2003-12-13 05:20:40 +03:00
2005-01-10 15:15:26 +03:00
talloc_set_destructor ( h , dcesrv_handle_destructor ) ;
2003-12-13 05:20:40 +03:00
2005-01-10 15:15:26 +03:00
return h ;
2003-12-13 05:20:40 +03:00
}
2007-08-26 19:16:40 +04:00
/**
2003-12-13 05:20:40 +03:00
find an internal handle given a wire handle . If the wire handle is NULL then
allocate a new handle
*/
2007-08-26 19:16:40 +04:00
_PUBLIC_ struct dcesrv_handle * dcesrv_handle_fetch (
struct dcesrv_connection_context * context ,
2003-12-13 05:20:40 +03:00
struct policy_handle * p ,
2004-05-25 21:50:17 +04:00
uint8_t handle_type )
2003-12-13 05:20:40 +03:00
{
struct dcesrv_handle * h ;
2009-09-22 11:18:03 +04:00
struct dom_sid * sid ;
2016-11-14 01:24:03 +03:00
/*
* For simplicty , ensure we abort here for an interface that has no handles ( programmer error )
*/
SMB_ASSERT ( ( context - > iface - > flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED ) = = 0 ) ;
2010-08-20 06:15:15 +04:00
sid = & context - > conn - > auth_state . session_info - > security_token - > sids [ PRIMARY_USER_SID_INDEX ] ;
2003-12-13 05:20:40 +03:00
2012-03-18 20:44:24 +04:00
if ( ndr_policy_handle_empty ( p ) ) {
2009-09-22 08:36:54 +04:00
/* TODO: we should probably return a NULL handle here */
2005-01-10 15:15:26 +03:00
return dcesrv_handle_new ( context , handle_type ) ;
2003-12-13 05:20:40 +03:00
}
2015-07-15 11:18:13 +03:00
for ( h = context - > conn - > assoc_group - > handles ; h ; h = h - > next ) {
2003-12-16 12:50:49 +03:00
if ( h - > wire_handle . handle_type = = p - > handle_type & &
2004-11-25 23:03:46 +03:00
GUID_equal ( & p - > uuid , & h - > wire_handle . uuid ) ) {
2004-04-27 11:12:10 +04:00
if ( handle_type ! = DCESRV_HANDLE_ANY & &
p - > handle_type ! = handle_type ) {
2003-12-16 12:50:49 +03:00
DEBUG ( 0 , ( " client gave us the wrong handle type (%d should be %d) \n " ,
p - > handle_type , handle_type ) ) ;
return NULL ;
}
2009-09-22 11:18:03 +04:00
if ( ! dom_sid_equal ( h - > sid , sid ) ) {
DEBUG ( 0 , ( __location__ " : Attempt to use invalid sid %s - %s \n " ,
dom_sid_string ( context , h - > sid ) ,
dom_sid_string ( context , sid ) ) ) ;
return NULL ;
}
if ( h - > iface ! = context - > iface ) {
DEBUG ( 0 , ( __location__ " : Attempt to use invalid iface \n " ) ) ;
return NULL ;
}
2003-12-13 05:20:40 +03:00
return h ;
}
}
return NULL ;
}