2003-12-11 01:21:04 +03:00
/*
Unix SMB / CIFS implementation .
server side dcerpc core code
2005-01-11 19:53:02 +03:00
Copyright ( C ) Andrew Tridgell 2003 - 2005
Copyright ( C ) Stefan ( metze ) Metzmacher 2004 - 2005
2003-12-11 01:21: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-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-12-11 01:21: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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-12-11 01:21:04 +03:00
*/
# include "includes.h"
2004-11-02 05:57:18 +03:00
# include "auth/auth.h"
2006-11-07 03:48:36 +03:00
# include "auth/gensec/gensec.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"
2008-04-02 06:53:27 +04:00
# include "rpc_server/dcerpc_server_proto.h"
2010-10-30 04:33:53 +04:00
# include "rpc_server/common/proto.h"
2008-04-02 06:53:27 +04:00
# include "librpc/rpc/dcerpc_proto.h"
2005-09-28 18:35:51 +04:00
# include "system/filesys.h"
2006-04-02 16:02:01 +04:00
# include "libcli/security/security.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2010-10-11 02:49:13 +04:00
# include "../lib/tsocket/tsocket.h"
# include "../libcli/named_pipe_auth/npa_tstream.h"
# include "smbd/service_stream.h"
# include "../lib/tsocket/tsocket.h"
# include "lib/socket/socket.h"
# include "smbd/process_model.h"
# include "lib/messaging/irpc.h"
2011-02-24 03:55:45 +03:00
# include "librpc/rpc/rpc_common.h"
2011-12-03 10:03:35 +04:00
# include "lib/util/samba_modules.h"
2014-01-08 13:35:48 +04:00
# include "librpc/gen_ndr/ndr_dcerpc.h"
2003-12-11 01:21:04 +03:00
2007-01-16 17:44:23 +03:00
extern const struct dcesrv_interface dcesrv_mgmt_interface ;
2015-10-06 11:18:06 +03:00
static NTSTATUS dcesrv_negotiate_contexts ( struct dcesrv_call_state * call ,
2015-06-28 14:15:33 +03:00
const struct dcerpc_bind * b ,
2015-10-06 11:18:06 +03:00
struct dcerpc_ack_ctx * ack_ctx_list ) ;
2009-09-22 08:36:54 +04:00
/*
find an association group given a assoc_group_id
*/
static struct dcesrv_assoc_group * dcesrv_assoc_group_find ( struct dcesrv_context * dce_ctx ,
uint32_t id )
{
void * id_ptr ;
id_ptr = idr_find ( dce_ctx - > assoc_groups_idr , id ) ;
if ( id_ptr = = NULL ) {
return NULL ;
}
return talloc_get_type_abort ( id_ptr , struct dcesrv_assoc_group ) ;
}
/*
take a reference to an existing association group
*/
static struct dcesrv_assoc_group * dcesrv_assoc_group_reference ( TALLOC_CTX * mem_ctx ,
struct dcesrv_context * dce_ctx ,
uint32_t id )
{
struct dcesrv_assoc_group * assoc_group ;
assoc_group = dcesrv_assoc_group_find ( dce_ctx , id ) ;
if ( assoc_group = = NULL ) {
2015-07-15 11:18:13 +03:00
DEBUG ( 2 , ( __location__ " : Failed to find assoc_group 0x%08x \n " , id ) ) ;
2009-09-22 08:36:54 +04:00
return NULL ;
}
return talloc_reference ( mem_ctx , assoc_group ) ;
}
2009-09-22 11:18:03 +04:00
static int dcesrv_assoc_group_destructor ( struct dcesrv_assoc_group * assoc_group )
{
int ret ;
ret = idr_remove ( assoc_group - > dce_ctx - > assoc_groups_idr , assoc_group - > id ) ;
if ( ret ! = 0 ) {
DEBUG ( 0 , ( __location__ " : Failed to remove assoc_group 0x%08x \n " ,
assoc_group - > id ) ) ;
}
return 0 ;
}
2009-09-22 08:36:54 +04:00
/*
allocate a new association group
*/
static struct dcesrv_assoc_group * dcesrv_assoc_group_new ( TALLOC_CTX * mem_ctx ,
struct dcesrv_context * dce_ctx )
{
struct dcesrv_assoc_group * assoc_group ;
int id ;
assoc_group = talloc_zero ( mem_ctx , struct dcesrv_assoc_group ) ;
if ( assoc_group = = NULL ) {
return NULL ;
}
id = idr_get_new_random ( dce_ctx - > assoc_groups_idr , assoc_group , UINT16_MAX ) ;
if ( id = = - 1 ) {
talloc_free ( assoc_group ) ;
DEBUG ( 0 , ( __location__ " : Out of association groups! \n " ) ) ;
return NULL ;
}
assoc_group - > id = id ;
2009-09-22 11:18:03 +04:00
assoc_group - > dce_ctx = dce_ctx ;
talloc_set_destructor ( assoc_group , dcesrv_assoc_group_destructor ) ;
2009-09-22 08:36:54 +04:00
return assoc_group ;
}
2003-12-11 01:21:04 +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
see if two endpoints match
2003-12-11 01:21:04 +03:00
*/
2007-09-03 17:13:25 +04:00
static bool endpoints_match ( const struct dcerpc_binding * ep1 ,
2004-10-21 21:40:55 +04:00
const struct dcerpc_binding * ep2 )
2003-12-11 01:21:04 +03:00
{
2014-01-30 22:00:09 +04:00
enum dcerpc_transport_t t1 ;
enum dcerpc_transport_t t2 ;
const char * e1 ;
const char * e2 ;
t1 = dcerpc_binding_get_transport ( ep1 ) ;
t2 = dcerpc_binding_get_transport ( ep2 ) ;
e1 = dcerpc_binding_get_string_option ( ep1 , " endpoint " ) ;
e2 = dcerpc_binding_get_string_option ( ep2 , " endpoint " ) ;
if ( t1 ! = t2 ) {
2007-09-03 17:13:25 +04:00
return false ;
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
}
2014-01-30 22:00:09 +04:00
if ( ! e1 | | ! e2 ) {
return e1 = = e2 ;
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
}
2014-01-30 22:00:09 +04:00
if ( strcasecmp ( e1 , e2 ) ! = 0 ) {
2007-09-03 17:13:25 +04:00
return false ;
2014-01-30 22:00:09 +04:00
}
2004-10-21 21:40:55 +04:00
2007-09-03 17:13:25 +04:00
return true ;
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
}
/*
find an endpoint in the dcesrv_context
*/
static struct dcesrv_endpoint * find_endpoint ( struct dcesrv_context * dce_ctx ,
2004-10-21 21:40:55 +04:00
const struct dcerpc_binding * ep_description )
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
{
struct dcesrv_endpoint * ep ;
for ( ep = dce_ctx - > endpoint_list ; ep ; ep = ep - > next ) {
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
if ( endpoints_match ( ep - > ep_description , ep_description ) ) {
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
return ep ;
}
}
return NULL ;
}
2005-01-10 15:15:26 +03:00
/*
find a registered context_id from a bind or alter_context
*/
static struct dcesrv_connection_context * dcesrv_find_context ( struct dcesrv_connection * conn ,
2015-07-15 11:15:31 +03:00
uint16_t context_id )
2005-01-10 15:15:26 +03:00
{
struct dcesrv_connection_context * c ;
for ( c = conn - > contexts ; c ; c = c - > next ) {
if ( c - > context_id = = context_id ) return c ;
}
return NULL ;
}
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
/*
see if a uuid and if_version match to an interface
*/
2007-10-07 02:25:41 +04:00
static bool interface_match ( const struct dcesrv_interface * if1 ,
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
const struct dcesrv_interface * if2 )
{
2006-03-26 04:59:17 +04:00
return ( if1 - > syntax_id . if_version = = if2 - > syntax_id . if_version & &
GUID_equal ( & if1 - > syntax_id . uuid , & if2 - > syntax_id . uuid ) ) ;
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
}
/*
find the interface operations on an endpoint
*/
static const struct dcesrv_interface * find_interface ( const struct dcesrv_endpoint * endpoint ,
2005-01-10 15:15:26 +03:00
const struct dcesrv_interface * iface )
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
{
struct dcesrv_if_list * ifl ;
for ( ifl = endpoint - > interface_list ; ifl ; ifl = ifl - > next ) {
if ( interface_match ( & ( ifl - > iface ) , iface ) ) {
return & ( ifl - > iface ) ;
}
}
return NULL ;
}
/*
see if a uuid and if_version match to an interface
*/
2007-10-07 02:25:41 +04:00
static bool interface_match_by_uuid ( const struct dcesrv_interface * iface ,
2005-12-27 19:22:35 +03:00
const struct GUID * uuid , uint32_t if_version )
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
{
2006-03-26 04:59:17 +04:00
return ( iface - > syntax_id . if_version = = if_version & &
GUID_equal ( & iface - > syntax_id . uuid , uuid ) ) ;
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
}
/*
find the interface operations on an endpoint by uuid
*/
static const struct dcesrv_interface * find_interface_by_uuid ( const struct dcesrv_endpoint * endpoint ,
2005-12-27 19:22:35 +03:00
const struct GUID * uuid , uint32_t if_version )
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
{
struct dcesrv_if_list * ifl ;
for ( ifl = endpoint - > interface_list ; ifl ; ifl = ifl - > next ) {
if ( interface_match_by_uuid ( & ( ifl - > iface ) , uuid , if_version ) ) {
return & ( ifl - > iface ) ;
2003-12-11 01:21:04 +03:00
}
}
return NULL ;
}
2003-12-12 08:01:41 +03:00
/*
2006-09-11 10:17:12 +04:00
find the earlier parts of a fragmented call awaiting reassembily
2003-12-12 08:01:41 +03:00
*/
2006-09-11 10:17:12 +04:00
static struct dcesrv_call_state * dcesrv_find_fragmented_call ( struct dcesrv_connection * dce_conn , uint16_t call_id )
2003-12-12 08:01:41 +03:00
{
struct dcesrv_call_state * c ;
2006-09-11 10:17:12 +04:00
for ( c = dce_conn - > incoming_fragmented_call_list ; c ; c = c - > next ) {
2003-12-12 08:01:41 +03:00
if ( c - > pkt . call_id = = call_id ) {
return c ;
}
}
return NULL ;
}
2003-12-11 01:21:04 +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
register an interface on an endpoint
2003-12-11 01:21:04 +03:00
*/
2006-05-01 22:11:15 +04:00
_PUBLIC_ NTSTATUS dcesrv_interface_register ( struct dcesrv_context * dce_ctx ,
r1294: A nice, large, commit...
This implements gensec for Samba's server side, and brings gensec up
to the standards of a full subsystem.
This means that use of the subsystem is by gensec_* functions, not
function pointers in structures (this is internal). This causes
changes in all the existing gensec users.
Our RPC server no longer contains it's own generalised security
scheme, and now calls gensec directly.
Gensec has also taken over the role of auth/auth_ntlmssp.c
An important part of gensec, is the output of the 'session_info'
struct. This is now reference counted, so that we can correctly free
it when a pipe is closed, no matter if it was inherited, or created by
per-pipe authentication.
The schannel code is reworked, to be in the same file for client and
server.
ntlm_auth is reworked to use gensec.
The major problem with this code is the way it relies on subsystem
auto-initialisation. The primary reason for this commit now.is to
allow these problems to be looked at, and fixed.
There are problems with the new code:
- I've tested it with smbtorture, but currently don't have VMware and
valgrind working (this I'll fix soon).
- The SPNEGO code is client-only at this point.
- We still do not do kerberos.
Andrew Bartlett
(This used to be commit 07fd885fd488fd1051eacc905a2d4962f8a018ec)
2004-06-29 13:40:10 +04:00
const char * ep_name ,
const struct dcesrv_interface * iface ,
const struct security_descriptor * sd )
2003-12-11 01:21:04 +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
struct dcesrv_endpoint * ep ;
struct dcesrv_if_list * ifl ;
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
struct dcerpc_binding * binding ;
2007-10-07 02:25:41 +04:00
bool add_ep = false ;
2004-10-18 19:18:05 +04:00
NTSTATUS status ;
status = dcerpc_parse_binding ( dce_ctx , ep_name , & binding ) ;
2003-12-14 02:25:15 +03:00
2004-10-18 19:18:05 +04:00
if ( NT_STATUS_IS_ERR ( status ) ) {
DEBUG ( 0 , ( " Trouble parsing binding string '%s' \n " , ep_name ) ) ;
return status ;
}
2003-12-14 02:25:15 +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
/* check if this endpoint exists
*/
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
if ( ( ep = find_endpoint ( dce_ctx , binding ) ) = = NULL ) {
2015-06-26 09:10:46 +03:00
ep = talloc_zero ( dce_ctx , struct dcesrv_endpoint ) ;
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
if ( ! ep ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( ep ) ;
2014-02-06 21:59:53 +04:00
ep - > ep_description = talloc_move ( ep , & binding ) ;
2007-10-07 02:25:41 +04:00
add_ep = true ;
2007-01-16 17:44:23 +03:00
/* add mgmt interface */
2015-06-26 09:10:46 +03:00
ifl = talloc_zero ( ep , struct dcesrv_if_list ) ;
2007-01-16 17:44:23 +03:00
if ( ! ifl ) {
return NT_STATUS_NO_MEMORY ;
}
memcpy ( & ( ifl - > iface ) , & dcesrv_mgmt_interface ,
sizeof ( struct dcesrv_interface ) ) ;
DLIST_ADD ( ep - > interface_list , ifl ) ;
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-14 02:25:15 +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
/* see if the interface is already registered on te endpoint */
if ( find_interface ( ep , iface ) ! = NULL ) {
DEBUG ( 0 , ( " dcesrv_interface_register: interface '%s' already registered on endpoint '%s' \n " ,
2004-12-20 17:37:54 +03:00
iface - > name , ep_name ) ) ;
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
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
/* talloc a new interface list element */
2015-06-26 09:10:46 +03:00
ifl = talloc_zero ( ep , struct dcesrv_if_list ) ;
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
if ( ! ifl ) {
return NT_STATUS_NO_MEMORY ;
}
/* copy the given interface struct to the one on the endpoints interface list */
memcpy ( & ( ifl - > iface ) , iface , sizeof ( struct dcesrv_interface ) ) ;
/* if we have a security descriptor given,
* we should see if we can set it up on the endpoint
*/
if ( sd ! = NULL ) {
/* if there's currently no security descriptor given on the endpoint
* we try to set it
*/
if ( ep - > sd = = NULL ) {
2014-02-06 21:59:53 +04:00
ep - > sd = security_descriptor_copy ( ep , sd ) ;
2003-12-14 02:25:15 +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
/* if now there's no security descriptor given on the endpoint
* something goes wrong , either we failed to copy the security descriptor
* or there was already one on the endpoint
*/
if ( ep - > sd ! = NULL ) {
DEBUG ( 0 , ( " dcesrv_interface_register: interface '%s' failed to setup a security descriptor \n "
" on endpoint '%s' \n " ,
2004-12-20 17:37:54 +03:00
iface - > name , ep_name ) ) ;
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
if ( add_ep ) free ( ep ) ;
free ( ifl ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
2003-12-14 02:25:15 +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
}
2003-12-14 02:25:15 +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
/* finally add the interface on the endpoint */
DLIST_ADD ( ep - > interface_list , ifl ) ;
/* if it's a new endpoint add it to the dcesrv_context */
if ( add_ep ) {
DLIST_ADD ( dce_ctx - > endpoint_list , ep ) ;
2003-12-11 01:21:04 +03:00
}
2003-12-14 02:25:15 +03:00
2004-02-02 16:28:29 +03:00
DEBUG ( 4 , ( " dcesrv_interface_register: interface '%s' registered on endpoint '%s' \n " ,
2004-12-20 17:37:54 +03:00
iface - > name , ep_name ) ) ;
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
return NT_STATUS_OK ;
2003-12-11 01:21:04 +03:00
}
2008-11-23 13:24:29 +03:00
NTSTATUS dcesrv_inherited_session_key ( struct dcesrv_connection * p ,
DATA_BLOB * session_key )
2004-09-12 07:18:24 +04:00
{
if ( p - > auth_state . session_info - > session_key . length ) {
* session_key = p - > auth_state . session_info - > session_key ;
return NT_STATUS_OK ;
}
return NT_STATUS_NO_USER_SESSION_KEY ;
}
/*
fetch the user session key - may be default ( above ) or the SMB session key
2008-07-23 10:19:54 +04:00
The key is always truncated to 16 bytes
2004-09-12 07:18:24 +04:00
*/
2006-05-01 22:11:15 +04:00
_PUBLIC_ NTSTATUS dcesrv_fetch_session_key ( struct dcesrv_connection * p ,
2004-09-12 07:18:24 +04:00
DATA_BLOB * session_key )
{
2008-07-23 10:19:54 +04:00
NTSTATUS status = p - > auth_state . session_key ( p , session_key ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
session_key - > length = MIN ( session_key - > length , 16 ) ;
return NT_STATUS_OK ;
2004-09-12 07:18:24 +04:00
}
2003-12-11 01:21:04 +03:00
/*
connect to a dcerpc endpoint
*/
2008-04-02 06:53:27 +04:00
_PUBLIC_ NTSTATUS dcesrv_endpoint_connect ( struct dcesrv_context * dce_ctx ,
2005-01-11 19:53:02 +03:00
TALLOC_CTX * mem_ctx ,
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
const struct dcesrv_endpoint * ep ,
2006-03-22 19:23:19 +03:00
struct auth_session_info * session_info ,
2008-12-29 22:24:57 +03:00
struct tevent_context * event_ctx ,
2011-05-03 04:40:33 +04:00
struct imessaging_context * msg_ctx ,
2007-01-10 13:52:09 +03:00
struct server_id server_id ,
2006-03-07 14:02:47 +03:00
uint32_t state_flags ,
2005-01-11 19:53:02 +03:00
struct dcesrv_connection * * _p )
2003-12-11 01:21:04 +03:00
{
2005-01-11 19:53:02 +03:00
struct dcesrv_connection * p ;
2006-03-22 19:23:19 +03:00
if ( ! session_info ) {
return NT_STATUS_ACCESS_DENIED ;
}
2014-01-08 13:57:19 +04:00
p = talloc_zero ( mem_ctx , struct dcesrv_connection ) ;
2005-01-11 19:53:02 +03:00
NT_STATUS_HAVE_NO_MEMORY ( p ) ;
2006-03-22 19:23:19 +03:00
if ( ! talloc_reference ( p , session_info ) ) {
talloc_free ( p ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-01-11 19:53:02 +03:00
p - > dce_ctx = dce_ctx ;
p - > endpoint = ep ;
2014-02-03 06:46:08 +04:00
p - > packet_log_dir = lpcfg_lock_directory ( dce_ctx - > lp_ctx ) ;
2006-03-22 19:23:19 +03:00
p - > auth_state . session_info = session_info ;
2005-01-11 19:53:02 +03:00
p - > auth_state . session_key = dcesrv_generic_session_key ;
2006-03-16 21:46:49 +03:00
p - > event_ctx = event_ctx ;
2006-05-21 15:39:50 +04:00
p - > msg_ctx = msg_ctx ;
p - > server_id = server_id ;
2006-03-07 14:02:47 +03:00
p - > state_flags = state_flags ;
2015-06-26 09:10:46 +03:00
p - > allow_bind = true ;
2015-06-26 09:10:46 +03:00
p - > max_recv_frag = 5840 ;
p - > max_xmit_frag = 5840 ;
2016-06-22 18:18:28 +03:00
p - > max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE ;
2005-01-11 19:53:02 +03:00
2015-10-06 11:18:06 +03:00
/*
* For now we only support NDR32 .
*/
p - > preferred_transfer = & ndr_transfer_syntax_ndr ;
2005-01-11 19:53:02 +03:00
* _p = p ;
2003-12-11 01:21:04 +03:00
return NT_STATUS_OK ;
}
2007-03-14 01:58:23 +03:00
/*
move a call from an existing linked list to the specified list . This
prevents bugs where we forget to remove the call from a previous
list when moving it .
*/
static void dcesrv_call_set_list ( struct dcesrv_call_state * call ,
enum dcesrv_call_list list )
{
switch ( call - > list ) {
case DCESRV_LIST_NONE :
break ;
case DCESRV_LIST_CALL_LIST :
DLIST_REMOVE ( call - > conn - > call_list , call ) ;
break ;
case DCESRV_LIST_FRAGMENTED_CALL_LIST :
DLIST_REMOVE ( call - > conn - > incoming_fragmented_call_list , call ) ;
break ;
case DCESRV_LIST_PENDING_CALL_LIST :
DLIST_REMOVE ( call - > conn - > pending_call_list , call ) ;
break ;
}
call - > list = list ;
switch ( list ) {
case DCESRV_LIST_NONE :
break ;
case DCESRV_LIST_CALL_LIST :
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( call - > conn - > call_list , call ) ;
2007-03-14 01:58:23 +03:00
break ;
case DCESRV_LIST_FRAGMENTED_CALL_LIST :
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( call - > conn - > incoming_fragmented_call_list , call ) ;
2007-03-14 01:58:23 +03:00
break ;
case DCESRV_LIST_PENDING_CALL_LIST :
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( call - > conn - > pending_call_list , call ) ;
2007-03-14 01:58:23 +03:00
break ;
}
}
2015-06-26 09:10:46 +03:00
static void dcesrv_call_disconnect_after ( struct dcesrv_call_state * call ,
const char * reason )
{
if ( call - > conn - > terminate ! = NULL ) {
return ;
}
2015-06-26 09:10:46 +03:00
call - > conn - > allow_bind = false ;
call - > conn - > allow_alter = false ;
call - > conn - > allow_auth3 = false ;
call - > conn - > allow_request = false ;
2015-06-26 09:10:46 +03:00
call - > terminate_reason = talloc_strdup ( call , reason ) ;
if ( call - > terminate_reason = = NULL ) {
call - > terminate_reason = __location__ ;
}
}
2003-12-12 09:12:41 +03:00
/*
return a dcerpc bind_nak
*/
2004-05-25 20:24:13 +04:00
static NTSTATUS dcesrv_bind_nak ( struct dcesrv_call_state * call , uint32_t reason )
2003-12-12 09:12:41 +03:00
{
2005-06-06 03:05:37 +04:00
struct ncacn_packet pkt ;
2014-03-27 01:42:19 +04:00
struct dcerpc_bind_nak_version version ;
2005-09-08 15:26:05 +04:00
struct data_blob_list_item * rep ;
2003-12-12 09:12:41 +03:00
NTSTATUS status ;
2015-06-26 09:10:46 +03:00
static const uint8_t _pad [ 3 ] = { 0 , } ;
2003-12-12 09:12:41 +03:00
2015-06-26 09:10:46 +03:00
/*
* We add the call to the pending_call_list
* in order to defer the termination .
*/
dcesrv_call_disconnect_after ( call , " dcesrv_bind_nak " ) ;
2004-05-02 14:07:25 +04:00
/* setup a bind_nak */
2010-07-16 08:32:42 +04:00
dcesrv_init_hdr ( & pkt , lpcfg_rpc_big_endian ( call - > conn - > dce_ctx - > lp_ctx ) ) ;
2003-12-12 09:12:41 +03:00
pkt . auth_length = 0 ;
pkt . call_id = call - > pkt . call_id ;
pkt . ptype = DCERPC_PKT_BIND_NAK ;
pkt . pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST ;
pkt . u . bind_nak . reject_reason = reason ;
2014-03-27 01:42:19 +04:00
version . rpc_vers = 5 ;
version . rpc_vers_minor = 0 ;
pkt . u . bind_nak . num_versions = 1 ;
pkt . u . bind_nak . versions = & version ;
2015-06-26 09:10:46 +03:00
pkt . u . bind_nak . _pad = data_blob_const ( _pad , sizeof ( _pad ) ) ;
2003-12-12 09:12:41 +03:00
2015-06-26 09:10:46 +03:00
rep = talloc_zero ( call , struct data_blob_list_item ) ;
2005-07-01 10:05:49 +04:00
if ( ! rep ) {
return NT_STATUS_NO_MEMORY ;
}
2005-06-30 23:24:29 +04:00
2010-05-09 19:20:01 +04:00
status = ncacn_push_auth ( & rep - > blob , call , & pkt , NULL ) ;
2005-07-01 10:05:49 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2003-12-12 06:59:09 +03:00
2005-09-08 15:26:05 +04:00
dcerpc_set_frag_length ( & rep - > blob , rep - > blob . length ) ;
2003-12-12 08:30:00 +03:00
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( call - > replies , rep ) ;
2007-03-14 01:58:23 +03:00
dcesrv_call_set_list ( call , DCESRV_LIST_CALL_LIST ) ;
2003-12-12 06:59:09 +03:00
2009-04-07 23:02:55 +04:00
if ( call - > conn - > call_list & & call - > conn - > call_list - > replies ) {
if ( call - > conn - > transport . report_output_data ) {
call - > conn - > transport . report_output_data ( call - > conn ) ;
}
}
2003-12-12 06:59:09 +03:00
return NT_STATUS_OK ;
}
2015-06-26 09:10:46 +03:00
static NTSTATUS dcesrv_fault_disconnect ( struct dcesrv_call_state * call ,
uint32_t fault_code )
{
/*
* We add the call to the pending_call_list
* in order to defer the termination .
*/
dcesrv_call_disconnect_after ( call , " dcesrv_fault_disconnect " ) ;
return dcesrv_fault_with_flags ( call , fault_code ,
DCERPC_PFC_FLAG_DID_NOT_EXECUTE ) ;
}
2008-12-09 18:16:31 +03:00
static int dcesrv_connection_context_destructor ( struct dcesrv_connection_context * c )
{
DLIST_REMOVE ( c - > conn - > contexts , c ) ;
2010-09-15 15:50:36 +04:00
if ( c - > iface & & c - > iface - > unbind ) {
2008-12-09 18:16:31 +03:00
c - > iface - > unbind ( c , c - > iface ) ;
2015-04-06 12:26:58 +03:00
c - > iface = NULL ;
2008-12-09 18:16:31 +03:00
}
return 0 ;
}
2003-12-12 06:59:09 +03:00
2015-07-14 10:12:18 +03:00
static void dcesrv_prepare_context_auth ( struct dcesrv_call_state * dce_call )
{
2016-03-10 04:46:59 +03:00
struct loadparm_context * lp_ctx = dce_call - > conn - > dce_ctx - > lp_ctx ;
const struct dcesrv_endpoint * endpoint = dce_call - > conn - > endpoint ;
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport ( endpoint - > ep_description ) ;
2015-07-14 10:12:18 +03:00
struct dcesrv_connection_context * context = dce_call - > context ;
2016-03-10 04:46:59 +03:00
const struct dcesrv_interface * iface = context - > iface ;
2015-07-14 10:12:18 +03:00
context - > min_auth_level = DCERPC_AUTH_LEVEL_NONE ;
2016-03-10 04:46:59 +03:00
if ( transport = = NCALRPC ) {
context - > allow_connect = true ;
return ;
}
/*
* allow overwrite per interface
* allow dcerpc auth level connect : < interface >
*/
context - > allow_connect = lpcfg_allow_dcerpc_auth_level_connect ( lp_ctx ) ;
context - > allow_connect = lpcfg_parm_bool ( lp_ctx , NULL ,
" allow dcerpc auth level connect " ,
iface - > name ,
context - > allow_connect ) ;
2015-07-14 10:12:18 +03:00
}
NTSTATUS dcesrv_interface_bind_require_integrity ( struct dcesrv_call_state * dce_call ,
const struct dcesrv_interface * iface )
{
if ( dce_call - > context = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
2016-08-31 22:43:14 +03:00
/*
* For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET ( 4 )
* has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY ( 5 ) .
*/
dce_call - > context - > min_auth_level = DCERPC_AUTH_LEVEL_PACKET ;
2015-07-14 10:12:18 +03:00
return NT_STATUS_OK ;
}
NTSTATUS dcesrv_interface_bind_require_privacy ( struct dcesrv_call_state * dce_call ,
const struct dcesrv_interface * iface )
{
if ( dce_call - > context = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
dce_call - > context - > min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY ;
return NT_STATUS_OK ;
}
2016-03-10 04:46:59 +03:00
_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect ( struct dcesrv_call_state * dce_call ,
const struct dcesrv_interface * iface )
{
struct loadparm_context * lp_ctx = dce_call - > conn - > dce_ctx - > lp_ctx ;
const struct dcesrv_endpoint * endpoint = dce_call - > conn - > endpoint ;
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport ( endpoint - > ep_description ) ;
struct dcesrv_connection_context * context = dce_call - > context ;
if ( context = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
if ( transport = = NCALRPC ) {
context - > allow_connect = true ;
return NT_STATUS_OK ;
}
/*
* allow overwrite per interface
* allow dcerpc auth level connect : < interface >
*/
context - > allow_connect = false ;
context - > allow_connect = lpcfg_parm_bool ( lp_ctx , NULL ,
" allow dcerpc auth level connect " ,
iface - > name ,
context - > allow_connect ) ;
return NT_STATUS_OK ;
}
_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect ( struct dcesrv_call_state * dce_call ,
const struct dcesrv_interface * iface )
{
struct loadparm_context * lp_ctx = dce_call - > conn - > dce_ctx - > lp_ctx ;
const struct dcesrv_endpoint * endpoint = dce_call - > conn - > endpoint ;
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport ( endpoint - > ep_description ) ;
struct dcesrv_connection_context * context = dce_call - > context ;
if ( context = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
if ( transport = = NCALRPC ) {
context - > allow_connect = true ;
return NT_STATUS_OK ;
}
/*
* allow overwrite per interface
* allow dcerpc auth level connect : < interface >
*/
context - > allow_connect = true ;
context - > allow_connect = lpcfg_parm_bool ( lp_ctx , NULL ,
" allow dcerpc auth level connect " ,
iface - > name ,
context - > allow_connect ) ;
return NT_STATUS_OK ;
}
2003-12-12 06:59:09 +03:00
/*
handle a bind request
*/
static NTSTATUS dcesrv_bind ( struct dcesrv_call_state * call )
{
2005-06-06 03:05:37 +04:00
struct ncacn_packet pkt ;
2005-09-08 15:26:05 +04:00
struct data_blob_list_item * rep ;
2003-12-12 06:59:09 +03:00
NTSTATUS status ;
2008-08-07 00:28:04 +04:00
uint32_t extra_flags = 0 ;
2015-06-26 09:10:46 +03:00
uint16_t max_req = 0 ;
uint16_t max_rep = 0 ;
2015-06-26 09:10:46 +03:00
const char * ep_prefix = " " ;
const char * endpoint = NULL ;
2015-10-06 11:18:06 +03:00
struct dcerpc_ack_ctx * ack_ctx_list = NULL ;
2015-10-06 11:18:06 +03:00
struct dcerpc_ack_ctx * ack_features = NULL ;
2015-10-06 11:18:06 +03:00
size_t i ;
2015-06-26 09:10:46 +03:00
2015-06-26 09:10:46 +03:00
status = dcerpc_verify_ncacn_packet_header ( & call - > pkt ,
DCERPC_PKT_BIND ,
call - > pkt . u . bind . auth_info . length ,
0 , /* required flags */
DCERPC_PFC_FLAG_FIRST |
DCERPC_PFC_FLAG_LAST |
DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
0x08 | /* this is not defined, but should be ignored */
DCERPC_PFC_FLAG_CONC_MPX |
DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
DCERPC_PFC_FLAG_MAYBE |
DCERPC_PFC_FLAG_OBJECT_UUID ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return dcesrv_bind_nak ( call ,
DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED ) ;
}
2015-06-26 09:10:46 +03:00
/* max_recv_frag and max_xmit_frag result always in the same value! */
max_req = MIN ( call - > pkt . u . bind . max_xmit_frag ,
call - > pkt . u . bind . max_recv_frag ) ;
/*
* The values are between 2048 and 5840 tested against Windows 2012 R2
* via ncacn_ip_tcp on port 135.
*/
max_req = MAX ( 2048 , max_req ) ;
max_rep = MIN ( max_req , call - > conn - > max_recv_frag ) ;
/* They are truncated to an 8 byte boundary. */
max_rep & = 0xFFF8 ;
/* max_recv_frag and max_xmit_frag result always in the same value! */
call - > conn - > max_recv_frag = max_rep ;
call - > conn - > max_xmit_frag = max_rep ;
2003-12-12 06:59:09 +03:00
2008-07-23 16:41:16 +04:00
/*
2009-09-22 08:36:54 +04:00
if provided , check the assoc_group is valid
2008-07-23 16:41:16 +04:00
*/
2015-07-15 11:18:13 +03:00
if ( call - > pkt . u . bind . assoc_group_id ! = 0 ) {
call - > conn - > assoc_group = dcesrv_assoc_group_reference ( call - > conn ,
call - > conn - > dce_ctx ,
call - > pkt . u . bind . assoc_group_id ) ;
} else {
call - > conn - > assoc_group = dcesrv_assoc_group_new ( call - > conn ,
call - > conn - > dce_ctx ) ;
}
if ( call - > conn - > assoc_group = = NULL ) {
return dcesrv_bind_nak ( call , 0 ) ;
2007-08-22 08:43:17 +04:00
}
2015-10-06 11:18:06 +03:00
if ( call - > pkt . u . bind . num_contexts < 1 ) {
2003-12-12 09:12:41 +03:00
return dcesrv_bind_nak ( call , 0 ) ;
2003-12-12 06:59:09 +03:00
}
2015-10-06 11:18:06 +03:00
ack_ctx_list = talloc_zero_array ( call , struct dcerpc_ack_ctx ,
call - > pkt . u . bind . num_contexts ) ;
if ( ack_ctx_list = = NULL ) {
return dcesrv_bind_nak ( call , 0 ) ;
2003-12-12 06:59:09 +03:00
}
2015-10-06 11:18:06 +03:00
2015-06-28 14:15:33 +03:00
/*
2015-10-06 11:18:06 +03:00
* Set some sane defaults ( required by dcesrv_negotiate_contexts ( ) /
* dcesrv_check_or_create_context ( ) ) and do some protocol validation
* and set sane defaults .
2015-06-28 14:15:33 +03:00
*/
2015-10-06 11:18:06 +03:00
for ( i = 0 ; i < call - > pkt . u . bind . num_contexts ; i + + ) {
const struct dcerpc_ctx_list * c = & call - > pkt . u . bind . ctx_list [ i ] ;
struct dcerpc_ack_ctx * a = & ack_ctx_list [ i ] ;
2015-10-06 11:18:06 +03:00
bool is_feature = false ;
uint64_t features = 0 ;
2003-12-12 06:59:09 +03:00
2015-10-06 11:18:06 +03:00
if ( c - > num_transfer_syntaxes = = 0 ) {
return dcesrv_bind_nak ( call , 0 ) ;
}
a - > result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION ;
a - > reason . value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED ;
2015-10-06 11:18:06 +03:00
/*
* It ' s only treated as bind time feature request , if the first
* transfer_syntax matches , all others are ignored .
*/
is_feature = dcerpc_extract_bind_time_features ( c - > transfer_syntaxes [ 0 ] ,
& features ) ;
if ( ! is_feature ) {
continue ;
}
if ( ack_features ! = NULL ) {
/*
* Only one bind time feature context is allowed .
*/
return dcesrv_bind_nak ( call , 0 ) ;
}
ack_features = a ;
a - > result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK ;
a - > reason . negotiate = 0 ;
if ( features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING ) {
/* not supported yet */
}
if ( features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN ) {
2015-10-06 11:18:06 +03:00
a - > reason . negotiate | =
DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN ;
2015-10-06 11:18:06 +03:00
}
call - > conn - > bind_time_features = a - > reason . negotiate ;
2015-10-06 11:18:06 +03:00
}
/*
* Try to negotiate one new presentation context .
*/
status = dcesrv_negotiate_contexts ( call , & call - > pkt . u . bind , ack_ctx_list ) ;
2015-06-28 14:15:33 +03:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_RPC_PROTOCOL_ERROR ) ) {
return dcesrv_bind_nak ( call , 0 ) ;
2003-12-12 06:59:09 +03:00
}
2015-06-28 14:15:33 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2005-01-10 15:15:26 +03:00
}
2015-03-25 07:06:03 +03:00
if ( ( call - > pkt . pfc_flags & DCERPC_PFC_FLAG_CONC_MPX ) & &
( call - > state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED ) ) {
2016-08-16 07:40:21 +03:00
call - > conn - > state_flags | = DCESRV_CALL_STATE_FLAG_MULTIPLEXED ;
2015-03-25 07:06:03 +03:00
extra_flags | = DCERPC_PFC_FLAG_CONC_MPX ;
}
2015-04-06 12:26:58 +03:00
if ( call - > state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL ) {
2016-08-16 07:40:21 +03:00
call - > conn - > state_flags | = DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL ;
2015-04-06 12:26:58 +03:00
}
2003-12-14 04:09:10 +03:00
/* handle any authentication that is being requested */
if ( ! dcesrv_auth_bind ( call ) ) {
2015-07-10 14:55:27 +03:00
struct dcesrv_auth * auth = & call - > conn - > auth_state ;
TALLOC_FREE ( call - > context ) ;
2016-08-31 22:39:25 +03:00
if ( auth - > auth_level = = DCERPC_AUTH_LEVEL_NONE ) {
2015-07-10 14:55:27 +03:00
/*
2016-08-31 22:39:25 +03:00
* With DCERPC_AUTH_LEVEL_NONE , we get the
* reject_reason in auth - > auth_context_id .
2015-07-10 14:55:27 +03:00
*/
2016-08-31 22:39:25 +03:00
return dcesrv_bind_nak ( call , auth - > auth_context_id ) ;
2015-07-10 14:55:27 +03:00
}
2016-08-31 22:39:25 +03:00
/*
* This must a be a temporary failure e . g . talloc or invalid
* configuration , e . g . no machine account .
*/
2015-07-10 14:55:27 +03:00
return dcesrv_bind_nak ( call ,
2016-08-31 22:39:25 +03:00
DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION ) ;
2003-12-14 04:09:10 +03:00
}
2003-12-12 06:59:09 +03:00
/* setup a bind_ack */
2010-07-16 08:32:42 +04:00
dcesrv_init_hdr ( & pkt , lpcfg_rpc_big_endian ( call - > conn - > dce_ctx - > lp_ctx ) ) ;
2003-12-12 06:59:09 +03:00
pkt . auth_length = 0 ;
pkt . call_id = call - > pkt . call_id ;
pkt . ptype = DCERPC_PKT_BIND_ACK ;
2008-08-07 00:28:04 +04:00
pkt . pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags ;
2015-06-26 09:10:46 +03:00
pkt . u . bind_ack . max_xmit_frag = call - > conn - > max_xmit_frag ;
pkt . u . bind_ack . max_recv_frag = call - > conn - > max_recv_frag ;
2015-07-15 11:18:13 +03:00
pkt . u . bind_ack . assoc_group_id = call - > conn - > assoc_group - > id ;
2008-12-16 03:25:29 +03:00
2015-06-28 14:15:33 +03:00
endpoint = dcerpc_binding_get_string_option (
2015-06-26 09:10:46 +03:00
call - > conn - > endpoint - > ep_description ,
" endpoint " ) ;
if ( endpoint = = NULL ) {
endpoint = " " ;
}
if ( strncasecmp ( endpoint , " \\ pipe \\ " , 6 ) = = 0 ) {
/*
* TODO : check if this is really needed
*
* Or if we should fix this in our idl files .
*/
ep_prefix = " \\ PIPE \\ " ;
endpoint + = 6 ;
}
pkt . u . bind_ack . secondary_address = talloc_asprintf ( call , " %s%s " ,
ep_prefix ,
endpoint ) ;
if ( pkt . u . bind_ack . secondary_address = = NULL ) {
TALLOC_FREE ( call - > context ) ;
return NT_STATUS_NO_MEMORY ;
2003-12-12 09:12:41 +03:00
}
2015-10-06 11:18:06 +03:00
pkt . u . bind_ack . num_results = call - > pkt . u . bind . num_contexts ;
pkt . u . bind_ack . ctx_list = ack_ctx_list ;
2015-06-28 14:15:33 +03:00
pkt . u . bind_ack . auth_info = data_blob_null ;
2003-12-12 06:59:09 +03:00
2007-08-17 09:28:39 +04:00
status = dcesrv_auth_bind_ack ( call , & pkt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2015-06-28 14:15:33 +03:00
TALLOC_FREE ( call - > context ) ;
2003-12-14 04:09:10 +03:00
return dcesrv_bind_nak ( call , 0 ) ;
2003-12-12 06:59:09 +03:00
}
2015-06-26 09:10:46 +03:00
rep = talloc_zero ( call , struct data_blob_list_item ) ;
2005-07-01 10:05:49 +04:00
if ( ! rep ) {
2015-06-28 14:15:33 +03:00
TALLOC_FREE ( call - > context ) ;
2005-07-01 10:05:49 +04:00
return NT_STATUS_NO_MEMORY ;
}
2005-06-30 23:24:29 +04:00
2010-05-09 19:20:01 +04:00
status = ncacn_push_auth ( & rep - > blob , call , & pkt ,
2015-06-26 09:10:46 +03:00
call - > out_auth_info ) ;
2005-07-01 10:05:49 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2015-06-28 14:15:33 +03:00
TALLOC_FREE ( call - > context ) ;
2005-07-01 10:05:49 +04:00
return status ;
}
2003-12-14 04:09:10 +03:00
2005-09-08 15:26:05 +04:00
dcerpc_set_frag_length ( & rep - > blob , rep - > blob . length ) ;
2003-12-12 08:30:00 +03:00
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( call - > replies , rep ) ;
2007-03-14 01:58:23 +03:00
dcesrv_call_set_list ( call , DCESRV_LIST_CALL_LIST ) ;
2003-12-14 13:45:50 +03:00
2009-04-07 23:02:55 +04:00
if ( call - > conn - > call_list & & call - > conn - > call_list - > replies ) {
if ( call - > conn - > transport . report_output_data ) {
call - > conn - > transport . report_output_data ( call - > conn ) ;
}
}
2003-12-14 13:45:50 +03:00
return NT_STATUS_OK ;
}
/*
handle a auth3 request
*/
static NTSTATUS dcesrv_auth3 ( struct dcesrv_call_state * call )
{
2015-06-26 09:10:46 +03:00
NTSTATUS status ;
2015-06-26 09:10:46 +03:00
if ( ! call - > conn - > allow_auth3 ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-06-26 09:10:46 +03:00
if ( call - > conn - > auth_state . auth_finished ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-06-26 09:10:46 +03:00
status = dcerpc_verify_ncacn_packet_header ( & call - > pkt ,
DCERPC_PKT_AUTH3 ,
call - > pkt . u . auth3 . auth_info . length ,
0 , /* required flags */
DCERPC_PFC_FLAG_FIRST |
DCERPC_PFC_FLAG_LAST |
DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
0x08 | /* this is not defined, but should be ignored */
DCERPC_PFC_FLAG_CONC_MPX |
DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
DCERPC_PFC_FLAG_MAYBE |
DCERPC_PFC_FLAG_OBJECT_UUID ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
2003-12-14 13:45:50 +03:00
/* handle the auth3 in the auth code */
if ( ! dcesrv_auth_auth3 ( call ) ) {
2015-07-14 17:18:45 +03:00
call - > conn - > auth_state . auth_invalid = true ;
2016-06-23 14:50:39 +03:00
if ( call - > fault_code ! = 0 ) {
return dcesrv_fault_disconnect ( call , call - > fault_code ) ;
}
2003-12-14 13:45:50 +03:00
}
2004-09-25 15:24:10 +04:00
talloc_free ( call ) ;
2003-12-12 06:59:09 +03:00
2003-12-14 13:45:50 +03:00
/* we don't send a reply to a auth3 request, except by a
fault */
2003-12-12 06:59:09 +03:00
return NT_STATUS_OK ;
}
2005-01-10 15:39:42 +03:00
2015-06-28 14:15:33 +03:00
static NTSTATUS dcesrv_check_or_create_context ( struct dcesrv_call_state * call ,
const struct dcerpc_bind * b ,
const struct dcerpc_ctx_list * ctx ,
struct dcerpc_ack_ctx * ack ,
2015-10-06 11:18:06 +03:00
bool validate_only ,
2015-06-28 14:15:33 +03:00
const struct ndr_syntax_id * supported_transfer )
2005-01-10 15:39:42 +03:00
{
2015-06-28 14:15:33 +03:00
uint32_t if_version ;
2005-01-10 15:39:42 +03:00
struct dcesrv_connection_context * context ;
const struct dcesrv_interface * iface ;
2015-06-28 14:15:33 +03:00
struct GUID uuid ;
2008-05-15 15:55:23 +04:00
NTSTATUS status ;
2015-06-28 14:15:33 +03:00
const struct ndr_syntax_id * selected_transfer = NULL ;
size_t i ;
bool ok ;
2005-01-10 15:39:42 +03:00
2015-06-28 14:15:33 +03:00
if ( b = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
if ( ctx = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
if ( ctx - > num_transfer_syntaxes < 1 ) {
return NT_STATUS_INTERNAL_ERROR ;
}
if ( ack = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
if ( supported_transfer = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
}
2005-01-10 15:39:42 +03:00
2015-06-28 14:15:33 +03:00
switch ( ack - > result ) {
case DCERPC_BIND_ACK_RESULT_ACCEPTANCE :
2015-10-06 11:18:06 +03:00
case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK :
2015-06-28 14:15:33 +03:00
/*
* We is already completed .
*/
return NT_STATUS_OK ;
default :
break ;
2005-01-10 15:39:42 +03:00
}
2015-06-28 14:15:33 +03:00
ack - > result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION ;
ack - > reason . value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED ;
if_version = ctx - > abstract_syntax . if_version ;
uuid = ctx - > abstract_syntax . uuid ;
2005-12-27 19:22:35 +03:00
iface = find_interface_by_uuid ( call - > conn - > endpoint , & uuid , if_version ) ;
2005-01-10 15:39:42 +03:00
if ( iface = = NULL ) {
2005-12-27 19:22:35 +03:00
char * uuid_str = GUID_string ( call , & uuid ) ;
DEBUG ( 2 , ( " Request for unknown dcerpc interface %s/%d \n " , uuid_str , if_version ) ) ;
talloc_free ( uuid_str ) ;
2015-06-28 14:15:33 +03:00
/*
* We report this only via ack - > result
*/
return NT_STATUS_OK ;
}
ack - > result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION ;
ack - > reason . value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED ;
2015-10-06 11:18:06 +03:00
if ( validate_only ) {
/*
* We report this only via ack - > result
*/
return NT_STATUS_OK ;
}
2015-06-28 14:15:33 +03:00
for ( i = 0 ; i < ctx - > num_transfer_syntaxes ; i + + ) {
/*
* we only do NDR encoded dcerpc for now .
*/
ok = ndr_syntax_id_equal ( & ctx - > transfer_syntaxes [ i ] ,
supported_transfer ) ;
if ( ok ) {
selected_transfer = supported_transfer ;
break ;
}
2005-01-10 15:39:42 +03:00
}
2015-06-28 14:15:33 +03:00
context = dcesrv_find_context ( call - > conn , ctx - > context_id ) ;
if ( context ! = NULL ) {
ok = ndr_syntax_id_equal ( & context - > iface - > syntax_id ,
& ctx - > abstract_syntax ) ;
if ( ! ok ) {
return NT_STATUS_RPC_PROTOCOL_ERROR ;
}
if ( selected_transfer ! = NULL ) {
ok = ndr_syntax_id_equal ( & context - > transfer_syntax ,
selected_transfer ) ;
if ( ! ok ) {
return NT_STATUS_RPC_PROTOCOL_ERROR ;
}
ack - > result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE ;
ack - > reason . value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED ;
ack - > syntax = context - > transfer_syntax ;
}
/*
* We report this only via ack - > result
*/
return NT_STATUS_OK ;
}
if ( selected_transfer = = NULL ) {
/*
* We report this only via ack - > result
*/
return NT_STATUS_OK ;
}
ack - > result = DCERPC_BIND_ACK_RESULT_USER_REJECTION ;
ack - > reason . value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED ;
2005-01-10 15:39:42 +03:00
/* add this context to the list of available context_ids */
2015-06-26 09:10:46 +03:00
context = talloc_zero ( call - > conn , struct dcesrv_connection_context ) ;
2005-01-10 15:39:42 +03:00
if ( context = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
context - > conn = call - > conn ;
2015-06-28 14:15:33 +03:00
context - > context_id = ctx - > context_id ;
2005-01-10 15:39:42 +03:00
context - > iface = iface ;
2015-06-28 14:15:33 +03:00
context - > transfer_syntax = * selected_transfer ;
2009-02-02 12:01:36 +03:00
context - > private_data = NULL ;
2005-01-10 15:39:42 +03:00
DLIST_ADD ( call - > conn - > contexts , context ) ;
call - > context = context ;
2008-12-09 18:16:31 +03:00
talloc_set_destructor ( context , dcesrv_connection_context_destructor ) ;
2005-01-10 15:39:42 +03:00
2015-07-14 10:12:18 +03:00
dcesrv_prepare_context_auth ( call ) ;
2016-09-15 19:18:01 +03:00
/*
* Multiplex is supported by default
*/
call - > state_flags | = DCESRV_CALL_STATE_FLAG_MULTIPLEXED ;
2010-02-19 10:02:46 +03:00
status = iface - > bind ( call , iface , if_version ) ;
2015-06-28 14:15:33 +03:00
call - > context = NULL ;
2008-12-09 18:16:31 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
/* we don't want to trigger the iface->unbind() hook */
context - > iface = NULL ;
talloc_free ( context ) ;
2015-06-28 14:15:33 +03:00
/*
* We report this only via ack - > result
*/
return NT_STATUS_OK ;
2008-05-15 15:55:23 +04:00
}
2015-06-28 14:15:33 +03:00
ack - > result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE ;
ack - > reason . value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED ;
ack - > syntax = context - > transfer_syntax ;
2005-01-10 15:39:42 +03:00
return NT_STATUS_OK ;
}
2015-10-06 11:18:06 +03:00
static NTSTATUS dcesrv_negotiate_contexts ( struct dcesrv_call_state * call ,
const struct dcerpc_bind * b ,
struct dcerpc_ack_ctx * ack_ctx_list )
{
NTSTATUS status ;
size_t i ;
bool validate_only = false ;
bool preferred_ndr32 ;
/*
* Try to negotiate one new presentation context ,
* using our preferred transfer syntax .
*/
for ( i = 0 ; i < b - > num_contexts ; i + + ) {
const struct dcerpc_ctx_list * c = & b - > ctx_list [ i ] ;
struct dcerpc_ack_ctx * a = & ack_ctx_list [ i ] ;
status = dcesrv_check_or_create_context ( call , b , c , a ,
validate_only ,
call - > conn - > preferred_transfer ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( a - > result = = DCERPC_BIND_ACK_RESULT_ACCEPTANCE ) {
/*
* We managed to negotiate one context .
*
* = > we ' re done .
*/
validate_only = true ;
}
}
preferred_ndr32 = ndr_syntax_id_equal ( & ndr_transfer_syntax_ndr ,
call - > conn - > preferred_transfer ) ;
if ( preferred_ndr32 ) {
/*
* We ' re done .
*/
return NT_STATUS_OK ;
}
/*
* Try to negotiate one new presentation context ,
* using NDR 32 as fallback .
*/
for ( i = 0 ; i < b - > num_contexts ; i + + ) {
const struct dcerpc_ctx_list * c = & b - > ctx_list [ i ] ;
struct dcerpc_ack_ctx * a = & ack_ctx_list [ i ] ;
status = dcesrv_check_or_create_context ( call , b , c , a ,
validate_only ,
& ndr_transfer_syntax_ndr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( a - > result = = DCERPC_BIND_ACK_RESULT_ACCEPTANCE ) {
/*
* We managed to negotiate one context .
*
* = > we ' re done .
*/
validate_only = true ;
}
}
return NT_STATUS_OK ;
}
2015-04-24 23:19:30 +03:00
/*
handle a alter context request
*/
static NTSTATUS dcesrv_alter ( struct dcesrv_call_state * call )
{
NTSTATUS status ;
2015-06-26 09:10:46 +03:00
bool auth_ok = false ;
2015-06-28 14:15:33 +03:00
struct ncacn_packet pkt ;
uint32_t extra_flags = 0 ;
struct data_blob_list_item * rep = NULL ;
2015-10-06 11:18:06 +03:00
struct dcerpc_ack_ctx * ack_ctx_list = NULL ;
size_t i ;
2015-04-24 23:19:30 +03:00
2015-06-26 09:10:46 +03:00
if ( ! call - > conn - > allow_alter ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-06-26 09:10:46 +03:00
status = dcerpc_verify_ncacn_packet_header ( & call - > pkt ,
DCERPC_PKT_ALTER ,
call - > pkt . u . alter . auth_info . length ,
0 , /* required flags */
DCERPC_PFC_FLAG_FIRST |
DCERPC_PFC_FLAG_LAST |
DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
0x08 | /* this is not defined, but should be ignored */
DCERPC_PFC_FLAG_CONC_MPX |
DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
DCERPC_PFC_FLAG_MAYBE |
DCERPC_PFC_FLAG_OBJECT_UUID ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-06-26 09:10:46 +03:00
auth_ok = dcesrv_auth_alter ( call ) ;
if ( ! auth_ok ) {
2016-06-23 14:50:39 +03:00
if ( call - > fault_code ! = 0 ) {
return dcesrv_fault_disconnect ( call , call - > fault_code ) ;
2015-06-26 09:10:46 +03:00
}
2015-04-24 23:19:30 +03:00
}
2015-06-26 09:10:46 +03:00
if ( call - > pkt . u . alter . num_contexts < 1 ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-04-24 23:19:30 +03:00
2015-10-06 11:18:06 +03:00
ack_ctx_list = talloc_zero_array ( call , struct dcerpc_ack_ctx ,
call - > pkt . u . alter . num_contexts ) ;
if ( ack_ctx_list = = NULL ) {
2015-06-28 14:15:33 +03:00
return NT_STATUS_NO_MEMORY ;
}
2015-10-06 11:18:06 +03:00
2015-06-28 14:15:33 +03:00
/*
2015-10-06 11:18:06 +03:00
* Set some sane defaults ( required by dcesrv_negotiate_contexts ( ) /
* dcesrv_check_or_create_context ( ) ) and do some protocol validation
* and set sane defaults .
2015-06-28 14:15:33 +03:00
*/
2015-10-06 11:18:06 +03:00
for ( i = 0 ; i < call - > pkt . u . alter . num_contexts ; i + + ) {
const struct dcerpc_ctx_list * c = & call - > pkt . u . alter . ctx_list [ i ] ;
struct dcerpc_ack_ctx * a = & ack_ctx_list [ i ] ;
2015-06-26 09:10:46 +03:00
2015-10-06 11:18:06 +03:00
if ( c - > num_transfer_syntaxes = = 0 ) {
return dcesrv_fault_disconnect ( call ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
a - > result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION ;
a - > reason . value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED ;
}
/*
* Try to negotiate one new presentation context .
*/
status = dcesrv_negotiate_contexts ( call , & call - > pkt . u . alter , ack_ctx_list ) ;
2015-06-28 14:15:33 +03:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_RPC_PROTOCOL_ERROR ) ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2015-06-26 09:10:46 +03:00
2015-06-28 14:15:33 +03:00
if ( ( call - > pkt . pfc_flags & DCERPC_PFC_FLAG_CONC_MPX ) & &
( call - > state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED ) ) {
call - > conn - > state_flags | = DCESRV_CALL_STATE_FLAG_MULTIPLEXED ;
extra_flags | = DCERPC_PFC_FLAG_CONC_MPX ;
}
2015-06-26 09:10:46 +03:00
2015-06-28 14:15:33 +03:00
if ( call - > state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL ) {
call - > conn - > state_flags | = DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL ;
2015-04-24 23:19:30 +03:00
}
2015-06-26 09:10:46 +03:00
/* handle any authentication that is being requested */
if ( ! auth_ok ) {
if ( call - > in_auth_info . auth_type ! =
call - > conn - > auth_state . auth_type )
{
return dcesrv_fault_disconnect ( call ,
DCERPC_FAULT_SEC_PKG_ERROR ) ;
}
return dcesrv_fault_disconnect ( call , DCERPC_FAULT_ACCESS_DENIED ) ;
}
2016-08-16 07:33:41 +03:00
dcesrv_init_hdr ( & pkt , lpcfg_rpc_big_endian ( call - > conn - > dce_ctx - > lp_ctx ) ) ;
pkt . auth_length = 0 ;
pkt . call_id = call - > pkt . call_id ;
pkt . ptype = DCERPC_PKT_ALTER_RESP ;
pkt . pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags ;
pkt . u . alter_resp . max_xmit_frag = call - > conn - > max_xmit_frag ;
pkt . u . alter_resp . max_recv_frag = call - > conn - > max_recv_frag ;
pkt . u . alter_resp . assoc_group_id = call - > conn - > assoc_group - > id ;
pkt . u . alter_resp . secondary_address = " " ;
2015-10-06 11:18:06 +03:00
pkt . u . alter_resp . num_results = call - > pkt . u . alter . num_contexts ;
pkt . u . alter_resp . ctx_list = ack_ctx_list ;
2015-06-28 14:15:33 +03:00
pkt . u . alter_resp . auth_info = data_blob_null ;
2016-08-16 07:33:41 +03:00
status = dcesrv_auth_alter_ack ( call , & pkt ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return dcesrv_fault_disconnect ( call , DCERPC_FAULT_SEC_PKG_ERROR ) ;
}
rep = talloc_zero ( call , struct data_blob_list_item ) ;
if ( ! rep ) {
return NT_STATUS_NO_MEMORY ;
}
status = ncacn_push_auth ( & rep - > blob , call , & pkt , call - > out_auth_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
dcerpc_set_frag_length ( & rep - > blob , rep - > blob . length ) ;
DLIST_ADD_END ( call - > replies , rep ) ;
dcesrv_call_set_list ( call , DCESRV_LIST_CALL_LIST ) ;
if ( call - > conn - > call_list & & call - > conn - > call_list - > replies ) {
if ( call - > conn - > transport . report_output_data ) {
call - > conn - > transport . report_output_data ( call - > conn ) ;
}
}
return NT_STATUS_OK ;
}
2010-09-16 11:04:53 +04:00
/*
possibly save the call for inspection with ndrdump
*/
static void dcesrv_save_call ( struct dcesrv_call_state * call , const char * why )
{
# ifdef DEVELOPER
char * fname ;
2010-09-17 00:08:10 +04:00
const char * dump_dir ;
2010-09-16 11:04:53 +04:00
dump_dir = lpcfg_parm_string ( call - > conn - > dce_ctx - > lp_ctx , NULL , " dcesrv " , " stubs directory " ) ;
if ( ! dump_dir ) {
return ;
}
fname = talloc_asprintf ( call , " %s/RPC-%s-%u-%s.dat " ,
dump_dir ,
call - > context - > iface - > name ,
call - > pkt . u . request . opnum ,
why ) ;
if ( file_save ( fname , call - > pkt . u . request . stub_and_verifier . data , call - > pkt . u . request . stub_and_verifier . length ) ) {
DEBUG ( 0 , ( " RPC SAVED %s \n " , fname ) ) ;
}
talloc_free ( fname ) ;
# endif
}
2014-01-08 13:35:48 +04:00
static NTSTATUS dcesrv_check_verification_trailer ( struct dcesrv_call_state * call )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
const uint32_t bitmask1 = call - > conn - > auth_state . client_hdr_signing ?
DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0 ;
const struct dcerpc_sec_vt_pcontext pcontext = {
. abstract_syntax = call - > context - > iface - > syntax_id ,
2015-06-28 14:15:33 +03:00
. transfer_syntax = call - > context - > transfer_syntax ,
2014-01-08 13:35:48 +04:00
} ;
const struct dcerpc_sec_vt_header2 header2 =
dcerpc_sec_vt_header2_from_ncacn_packet ( & call - > pkt ) ;
enum ndr_err_code ndr_err ;
struct dcerpc_sec_verification_trailer * vt = NULL ;
NTSTATUS status = NT_STATUS_OK ;
bool ok ;
SMB_ASSERT ( call - > pkt . ptype = = DCERPC_PKT_REQUEST ) ;
ndr_err = ndr_pop_dcerpc_sec_verification_trailer ( call - > ndr_pull ,
frame , & vt ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
status = ndr_map_error2ntstatus ( ndr_err ) ;
goto done ;
}
ok = dcerpc_sec_verification_trailer_check ( vt , & bitmask1 ,
& pcontext , & header2 ) ;
if ( ! ok ) {
status = NT_STATUS_ACCESS_DENIED ;
goto done ;
}
done :
TALLOC_FREE ( frame ) ;
return status ;
}
2003-12-12 06:59:09 +03:00
/*
handle a dcerpc request packet
*/
static NTSTATUS dcesrv_request ( struct dcesrv_call_state * call )
{
2015-07-14 10:12:18 +03:00
const struct dcesrv_endpoint * endpoint = call - > conn - > endpoint ;
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport ( endpoint - > ep_description ) ;
2003-12-12 06:59:09 +03:00
struct ndr_pull * pull ;
NTSTATUS status ;
2015-06-26 09:10:46 +03:00
if ( ! call - > conn - > allow_request ) {
return dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
}
2005-05-10 20:30:51 +04:00
/* if authenticated, and the mech we use can't do async replies, don't use them... */
if ( call - > conn - > auth_state . gensec_security & &
! gensec_have_feature ( call - > conn - > auth_state . gensec_security , GENSEC_FEATURE_ASYNC_REPLIES ) ) {
2005-05-10 15:04:04 +04:00
call - > state_flags & = ~ DCESRV_CALL_STATE_FLAG_MAY_ASYNC ;
}
2016-09-14 02:16:19 +03:00
if ( call - > context = = NULL ) {
2016-08-18 15:17:58 +03:00
return dcesrv_fault_with_flags ( call , DCERPC_NCA_S_UNKNOWN_IF ,
DCERPC_PFC_FLAG_DID_NOT_EXECUTE ) ;
2004-05-11 19:39:23 +04:00
}
2016-03-10 18:02:31 +03:00
switch ( call - > conn - > auth_state . auth_level ) {
2016-03-10 04:46:59 +03:00
case DCERPC_AUTH_LEVEL_NONE :
2016-08-31 22:43:14 +03:00
case DCERPC_AUTH_LEVEL_PACKET :
2016-03-10 04:46:59 +03:00
case DCERPC_AUTH_LEVEL_INTEGRITY :
case DCERPC_AUTH_LEVEL_PRIVACY :
break ;
default :
2016-09-14 02:16:19 +03:00
if ( ! call - > context - > allow_connect ) {
2016-03-10 04:46:59 +03:00
char * addr ;
addr = tsocket_address_string ( call - > conn - > remote_address ,
call ) ;
DEBUG ( 2 , ( " %s: restrict auth_level_connect access "
" to [%s] with auth[type=0x%x,level=0x%x] "
" on [%s] from [%s] \n " ,
2016-09-14 02:16:19 +03:00
__func__ , call - > context - > iface - > name ,
2016-03-10 18:02:31 +03:00
call - > conn - > auth_state . auth_type ,
call - > conn - > auth_state . auth_level ,
2016-03-10 04:46:59 +03:00
derpc_transport_string_by_transport ( transport ) ,
addr ) ) ;
return dcesrv_fault ( call , DCERPC_FAULT_ACCESS_DENIED ) ;
}
break ;
}
2016-09-14 02:16:19 +03:00
if ( call - > conn - > auth_state . auth_level < call - > context - > min_auth_level ) {
2015-07-14 10:12:18 +03:00
char * addr ;
addr = tsocket_address_string ( call - > conn - > remote_address , call ) ;
DEBUG ( 2 , ( " %s: restrict access by min_auth_level[0x%x] "
" to [%s] with auth[type=0x%x,level=0x%x] "
" on [%s] from [%s] \n " ,
__func__ ,
2016-09-14 02:16:19 +03:00
call - > context - > min_auth_level ,
call - > context - > iface - > name ,
2016-03-10 18:02:31 +03:00
call - > conn - > auth_state . auth_type ,
call - > conn - > auth_state . auth_level ,
2015-07-14 10:12:18 +03:00
derpc_transport_string_by_transport ( transport ) ,
addr ) ) ;
return dcesrv_fault ( call , DCERPC_FAULT_ACCESS_DENIED ) ;
}
2010-05-09 19:20:01 +04:00
pull = ndr_pull_init_blob ( & call - > pkt . u . request . stub_and_verifier , call ) ;
2005-01-11 19:53:02 +03:00
NT_STATUS_HAVE_NO_MEMORY ( pull ) ;
r6973: Merge new version of pidl into the main SAMBA_4_0 branch.
The main difference in this new version is the extra data structure generated
between the IDL data structure and the NDR parser:
IDL -> NDR -> { ndr_parser, ndr_header, eparser, etc }
This makes the ndr_parser.pm internals much more sane.
Other changes include:
- Remove unnecessary calls with NDR_BUFFERS (for example, GUID doesn't have any buffers, just scalars) as well as some (unnecessary) nested setting of flags.
- Parse array loops in the C code rather then calling ndr_pull_array(). This allows us to have, for example, arrays of pointers or arrays of pointers to arrays, etc..
- Use if() {} rather then if () goto foo; everywhere
- NDR_IN no longer implies LIBNDR_FLAG_REF_ALLOC
- By default, top level pointers are now "ref" (as is the default in
most other IDL compilers). This can be overridden using the
default_pointer_top() property.
- initial work on new ethereal parser generators by Alan DeKok and me
- pidl now writes errors in the standard format used by compilers, which
is parsable by most editors
- ability to warn about the fact that pidl extension(s) have been used,
useful for making sure IDL files work with other IDL compilers.
oh, and there's probably some other things I can't think of right now..
(This used to be commit 13cf227615f6b9e0e5fa62e59197024410254f01)
2005-05-25 17:50:27 +04:00
pull - > flags | = LIBNDR_FLAG_REF_ALLOC ;
2005-01-11 19:53:02 +03:00
call - > ndr_pull = pull ;
2003-12-12 06:59:09 +03:00
2003-12-17 05:06:44 +03:00
if ( ! ( call - > pkt . drep [ 0 ] & DCERPC_DREP_LE ) ) {
pull - > flags | = LIBNDR_FLAG_BIGENDIAN ;
}
2014-01-08 13:35:48 +04:00
status = dcesrv_check_verification_trailer ( call ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
uint32_t faultcode = DCERPC_FAULT_OTHER ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_ACCESS_DENIED ) ) {
faultcode = DCERPC_FAULT_ACCESS_DENIED ;
}
DEBUG ( 10 , ( " dcesrv_check_verification_trailer failed: %s \n " ,
nt_errstr ( status ) ) ) ;
return dcesrv_fault ( call , faultcode ) ;
}
2003-12-12 06:59:09 +03:00
/* unravel the NDR for the packet */
2016-09-14 02:16:19 +03:00
status = call - > context - > iface - > ndr_pull ( call , call , pull , & call - > r ) ;
2003-12-12 06:59:09 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-08-29 19:37:00 +03:00
uint8_t extra_flags = 0 ;
2010-08-17 12:25:45 +04:00
if ( call - > fault_code = = DCERPC_FAULT_OP_RNG_ERROR ) {
/* we got an unknown call */
DEBUG ( 3 , ( __location__ " : Unknown RPC call %u on %s \n " ,
2016-09-14 02:16:19 +03:00
call - > pkt . u . request . opnum ,
call - > context - > iface - > name ) ) ;
2010-09-16 11:04:53 +04:00
dcesrv_save_call ( call , " unknown " ) ;
2016-08-29 19:37:00 +03:00
extra_flags | = DCERPC_PFC_FLAG_DID_NOT_EXECUTE ;
2010-09-16 11:04:53 +04:00
} else {
dcesrv_save_call ( call , " pullfail " ) ;
2010-08-17 12:25:45 +04:00
}
2016-08-29 19:37:00 +03:00
return dcesrv_fault_with_flags ( call , call - > fault_code , extra_flags ) ;
2003-12-12 06:59:09 +03:00
}
2004-09-13 05:23:09 +04:00
if ( pull - > offset ! = pull - > data_size ) {
2010-09-16 11:04:53 +04:00
dcesrv_save_call ( call , " extrabytes " ) ;
2004-09-13 05:23:09 +04:00
DEBUG ( 3 , ( " Warning: %d extra bytes in incoming RPC request \n " ,
pull - > data_size - pull - > offset ) ) ;
}
2003-12-12 06:59:09 +03:00
/* call the dispatch function */
2016-09-14 02:16:19 +03:00
status = call - > context - > iface - > dispatch ( call , call , call - > r ) ;
2005-01-11 19:53:02 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-08-18 14:12:55 +04:00
DEBUG ( 5 , ( " dcerpc fault in call %s:%02x - %s \n " ,
2016-09-14 02:16:19 +03:00
call - > context - > iface - > name ,
2005-08-18 14:12:55 +04:00
call - > pkt . u . request . opnum ,
dcerpc_errstr ( pull , call - > fault_code ) ) ) ;
2005-01-11 19:53:02 +03:00
return dcesrv_fault ( call , call - > fault_code ) ;
}
/* add the call to the pending list */
2007-03-14 01:58:23 +03:00
dcesrv_call_set_list ( call , DCESRV_LIST_PENDING_CALL_LIST ) ;
2005-01-11 19:53:02 +03:00
if ( call - > state_flags & DCESRV_CALL_STATE_FLAG_ASYNC ) {
return NT_STATUS_OK ;
}
return dcesrv_reply ( call ) ;
}
2003-12-12 06:59:09 +03:00
2007-03-14 01:58:23 +03:00
/*
remove the call from the right list when freed
*/
static int dcesrv_call_dequeue ( struct dcesrv_call_state * call )
{
dcesrv_call_set_list ( call , DCESRV_LIST_NONE ) ;
return 0 ;
}
2010-04-26 15:06:07 +04:00
_PUBLIC_ const struct tsocket_address * dcesrv_connection_get_local_address ( struct dcesrv_connection * conn )
{
return conn - > local_address ;
}
_PUBLIC_ const struct tsocket_address * dcesrv_connection_get_remote_address ( struct dcesrv_connection * conn )
{
return conn - > remote_address ;
}
2003-12-11 12:07:45 +03:00
/*
2003-12-14 04:09:10 +03:00
process some input to a dcerpc endpoint server .
2003-12-11 12:07:45 +03:00
*/
2015-06-26 09:10:46 +03:00
static NTSTATUS dcesrv_process_ncacn_packet ( struct dcesrv_connection * dce_conn ,
struct ncacn_packet * pkt ,
DATA_BLOB blob )
2003-12-11 12:07:45 +03:00
{
2003-12-12 06:59:09 +03:00
NTSTATUS status ;
struct dcesrv_call_state * call ;
2015-07-17 06:01:26 +03:00
struct dcesrv_call_state * existing = NULL ;
2003-12-13 14:44:28 +03:00
2006-07-31 17:40:49 +04:00
call = talloc_zero ( dce_conn , struct dcesrv_call_state ) ;
2003-12-12 06:59:09 +03:00
if ( ! call ) {
2009-04-07 16:37:05 +04:00
data_blob_free ( & blob ) ;
talloc_free ( pkt ) ;
2003-12-12 06:59:09 +03:00
return NT_STATUS_NO_MEMORY ;
}
2006-07-31 17:40:49 +04:00
call - > conn = dce_conn ;
call - > event_ctx = dce_conn - > event_ctx ;
call - > msg_ctx = dce_conn - > msg_ctx ;
call - > state_flags = call - > conn - > state_flags ;
call - > time = timeval_current ( ) ;
2007-03-14 01:58:23 +03:00
call - > list = DCESRV_LIST_NONE ;
2009-04-07 16:37:05 +04:00
talloc_steal ( call , pkt ) ;
talloc_steal ( call , blob . data ) ;
call - > pkt = * pkt ;
2003-12-12 06:59:09 +03:00
2009-04-07 16:37:05 +04:00
talloc_set_destructor ( call , dcesrv_call_dequeue ) ;
2003-12-12 06:59:09 +03:00
2015-06-26 09:10:46 +03:00
if ( call - > conn - > allow_bind ) {
/*
* Only one bind is possible per connection
*/
call - > conn - > allow_bind = false ;
return dcesrv_bind ( call ) ;
}
2003-12-14 13:45:50 +03:00
/* we have to check the signing here, before combining the
pdus */
2015-06-26 09:10:46 +03:00
if ( call - > pkt . ptype = = DCERPC_PKT_REQUEST ) {
2015-06-26 09:10:46 +03:00
if ( ! call - > conn - > allow_request ) {
return dcesrv_fault_disconnect ( call ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-06-26 09:10:46 +03:00
status = dcerpc_verify_ncacn_packet_header ( & call - > pkt ,
DCERPC_PKT_REQUEST ,
call - > pkt . u . request . stub_and_verifier . length ,
0 , /* required_flags */
DCERPC_PFC_FLAG_FIRST |
DCERPC_PFC_FLAG_LAST |
DCERPC_PFC_FLAG_PENDING_CANCEL |
0x08 | /* this is not defined, but should be ignored */
DCERPC_PFC_FLAG_CONC_MPX |
DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
DCERPC_PFC_FLAG_MAYBE |
DCERPC_PFC_FLAG_OBJECT_UUID ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return dcesrv_fault_disconnect ( call ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-07-15 18:21:05 +03:00
if ( call - > pkt . frag_length > DCERPC_FRAG_MAX_SIZE ) {
/*
* We don ' t use dcesrv_fault_disconnect ( )
* here , because we don ' t want to set
* DCERPC_PFC_FLAG_DID_NOT_EXECUTE
*
* Note that we don ' t check against the negotiated
* max_recv_frag , but a hard coded value .
*/
dcesrv_call_disconnect_after ( call ,
" dcesrv_auth_request - frag_length too large " ) ;
return dcesrv_fault ( call ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-07-17 06:01:26 +03:00
if ( call - > pkt . pfc_flags & DCERPC_PFC_FLAG_FIRST ) {
2016-09-16 13:35:54 +03:00
if ( dce_conn - > pending_call_list ! = NULL ) {
/*
* concurrent requests are only allowed
* if DCERPC_PFC_FLAG_CONC_MPX was negotiated .
*/
if ( ! ( dce_conn - > state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED ) ) {
dcesrv_call_disconnect_after ( call ,
" dcesrv_auth_request - "
" existing pending call without CONN_MPX " ) ;
return dcesrv_fault ( call ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
}
2015-07-17 06:01:26 +03:00
/* only one request is possible in the fragmented list */
if ( dce_conn - > incoming_fragmented_call_list ! = NULL ) {
2016-09-16 13:35:54 +03:00
if ( ! ( dce_conn - > state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED ) ) {
/*
* Without DCERPC_PFC_FLAG_CONC_MPX
* we need to return the FAULT on the
* already existing call .
*
* This is important to get the
* call_id and context_id right .
*/
TALLOC_FREE ( call ) ;
call = dce_conn - > incoming_fragmented_call_list ;
}
2015-07-17 06:01:26 +03:00
dcesrv_call_disconnect_after ( call ,
" dcesrv_auth_request - "
" existing fragmented call " ) ;
return dcesrv_fault ( call ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
2015-07-15 11:18:13 +03:00
if ( call - > pkt . pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL ) {
return dcesrv_fault_disconnect ( call ,
DCERPC_FAULT_NO_CALL_ACTIVE ) ;
}
2016-09-14 02:16:19 +03:00
call - > context = dcesrv_find_context ( call - > conn ,
call - > pkt . u . request . context_id ) ;
if ( call - > context = = NULL ) {
return dcesrv_fault_with_flags ( call , DCERPC_NCA_S_UNKNOWN_IF ,
DCERPC_PFC_FLAG_DID_NOT_EXECUTE ) ;
}
2015-07-17 06:01:26 +03:00
} else {
const struct dcerpc_request * nr = & call - > pkt . u . request ;
const struct dcerpc_request * er = NULL ;
int cmp ;
existing = dcesrv_find_fragmented_call ( dce_conn ,
call - > pkt . call_id ) ;
if ( existing = = NULL ) {
dcesrv_call_disconnect_after ( call ,
" dcesrv_auth_request - "
" no existing fragmented call " ) ;
return dcesrv_fault ( call ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
er = & existing - > pkt . u . request ;
if ( call - > pkt . ptype ! = existing - > pkt . ptype ) {
/* trying to play silly buggers are we? */
return dcesrv_fault_disconnect ( existing ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
cmp = memcmp ( call - > pkt . drep , existing - > pkt . drep ,
sizeof ( pkt - > drep ) ) ;
if ( cmp ! = 0 ) {
return dcesrv_fault_disconnect ( existing ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
if ( nr - > context_id ! = er - > context_id ) {
return dcesrv_fault_disconnect ( existing ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
if ( nr - > opnum ! = er - > opnum ) {
return dcesrv_fault_disconnect ( existing ,
DCERPC_NCA_S_PROTO_ERROR ) ;
}
}
2015-10-28 15:04:38 +03:00
}
if ( call - > pkt . ptype = = DCERPC_PKT_REQUEST ) {
bool ok ;
uint8_t payload_offset = DCERPC_REQUEST_LENGTH ;
2015-07-17 06:01:26 +03:00
2015-10-28 15:04:38 +03:00
if ( call - > pkt . pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID ) {
payload_offset + = 16 ;
}
ok = dcesrv_auth_pkt_pull ( call , & blob ,
0 , /* required_flags */
DCERPC_PFC_FLAG_FIRST |
DCERPC_PFC_FLAG_LAST |
DCERPC_PFC_FLAG_PENDING_CANCEL |
0x08 | /* this is not defined, but should be ignored */
DCERPC_PFC_FLAG_CONC_MPX |
DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
DCERPC_PFC_FLAG_MAYBE |
DCERPC_PFC_FLAG_OBJECT_UUID ,
payload_offset ,
& call - > pkt . u . request . stub_and_verifier ) ;
if ( ! ok ) {
2015-06-26 09:10:46 +03:00
/*
* We don ' t use dcesrv_fault_disconnect ( )
* here , because we don ' t want to set
* DCERPC_PFC_FLAG_DID_NOT_EXECUTE
*/
dcesrv_call_disconnect_after ( call ,
" dcesrv_auth_request - failed " ) ;
2016-09-01 11:31:04 +03:00
if ( call - > fault_code = = 0 ) {
call - > fault_code = DCERPC_FAULT_ACCESS_DENIED ;
}
return dcesrv_fault ( call , call - > fault_code ) ;
2015-06-26 09:10:46 +03:00
}
2003-12-14 13:45:50 +03:00
}
2003-12-12 08:01:41 +03:00
/* see if this is a continued packet */
2015-07-17 06:01:26 +03:00
if ( existing ! = NULL ) {
struct dcerpc_request * er = & existing - > pkt . u . request ;
const struct dcerpc_request * nr = & call - > pkt . u . request ;
2015-06-29 15:18:09 +03:00
size_t available ;
size_t alloc_size ;
size_t alloc_hint ;
2003-12-12 08:01:41 +03:00
2015-06-29 15:18:09 +03:00
/*
* Up to 4 MByte are allowed by all fragments
*/
2016-06-22 18:18:28 +03:00
available = dce_conn - > max_total_request_size ;
2015-07-17 06:01:26 +03:00
if ( er - > stub_and_verifier . length > available ) {
dcesrv_call_disconnect_after ( existing ,
" dcesrv_auth_request - existing payload too large " ) ;
return dcesrv_fault ( existing , DCERPC_FAULT_ACCESS_DENIED ) ;
2015-06-29 15:18:09 +03:00
}
2015-07-17 06:01:26 +03:00
available - = er - > stub_and_verifier . length ;
if ( nr - > alloc_hint > available ) {
dcesrv_call_disconnect_after ( existing ,
2015-06-29 15:18:09 +03:00
" dcesrv_auth_request - alloc hint too large " ) ;
2015-07-17 06:01:26 +03:00
return dcesrv_fault ( existing , DCERPC_FAULT_ACCESS_DENIED ) ;
2015-06-29 15:18:09 +03:00
}
2015-07-17 06:01:26 +03:00
if ( nr - > stub_and_verifier . length > available ) {
dcesrv_call_disconnect_after ( existing ,
2015-06-29 15:18:09 +03:00
" dcesrv_auth_request - new payload too large " ) ;
2015-07-17 06:01:26 +03:00
return dcesrv_fault ( existing , DCERPC_FAULT_ACCESS_DENIED ) ;
2015-06-29 15:18:09 +03:00
}
2015-07-17 06:01:26 +03:00
alloc_hint = er - > stub_and_verifier . length + nr - > alloc_hint ;
2015-06-29 15:18:09 +03:00
/* allocate at least 1 byte */
alloc_hint = MAX ( alloc_hint , 1 ) ;
2015-07-17 06:01:26 +03:00
alloc_size = er - > stub_and_verifier . length +
nr - > stub_and_verifier . length ;
2015-06-29 15:18:09 +03:00
alloc_size = MAX ( alloc_size , alloc_hint ) ;
2003-12-12 08:01:41 +03:00
2015-07-17 06:01:26 +03:00
er - > stub_and_verifier . data =
talloc_realloc ( existing ,
er - > stub_and_verifier . data ,
2005-01-07 07:39:16 +03:00
uint8_t , alloc_size ) ;
2015-07-17 06:01:26 +03:00
if ( er - > stub_and_verifier . data = = NULL ) {
TALLOC_FREE ( call ) ;
return dcesrv_fault_with_flags ( existing ,
2015-06-29 15:18:09 +03:00
DCERPC_FAULT_OUT_OF_RESOURCES ,
DCERPC_PFC_FLAG_DID_NOT_EXECUTE ) ;
2003-12-12 08:01:41 +03:00
}
2015-07-17 06:01:26 +03:00
memcpy ( er - > stub_and_verifier . data +
er - > stub_and_verifier . length ,
nr - > stub_and_verifier . data ,
nr - > stub_and_verifier . length ) ;
er - > stub_and_verifier . length + = nr - > stub_and_verifier . length ;
2003-12-12 08:01:41 +03:00
2015-07-17 06:01:26 +03:00
existing - > pkt . pfc_flags | = ( call - > pkt . pfc_flags & DCERPC_PFC_FLAG_LAST ) ;
2004-09-27 08:11:37 +04:00
2015-07-17 06:01:26 +03:00
TALLOC_FREE ( call ) ;
call = existing ;
2003-12-12 08:01:41 +03:00
}
/* this may not be the last pdu in the chain - if its isn't then
2006-09-11 10:17:12 +04:00
just put it on the incoming_fragmented_call_list and wait for the rest */
2004-12-12 11:35:11 +03:00
if ( call - > pkt . ptype = = DCERPC_PKT_REQUEST & &
! ( call - > pkt . pfc_flags & DCERPC_PFC_FLAG_LAST ) ) {
2015-06-29 15:18:09 +03:00
/*
* Up to 4 MByte are allowed by all fragments
*/
2016-06-22 18:18:28 +03:00
if ( call - > pkt . u . request . alloc_hint > dce_conn - > max_total_request_size ) {
2015-06-29 15:18:09 +03:00
dcesrv_call_disconnect_after ( call ,
" dcesrv_auth_request - initial alloc hint too large " ) ;
return dcesrv_fault ( call , DCERPC_FAULT_ACCESS_DENIED ) ;
}
2007-03-14 01:58:23 +03:00
dcesrv_call_set_list ( call , DCESRV_LIST_FRAGMENTED_CALL_LIST ) ;
2003-12-12 08:01:41 +03:00
return NT_STATUS_OK ;
2006-09-21 10:34:21 +04:00
}
/* This removes any fragments we may have had stashed away */
2007-03-14 01:58:23 +03:00
dcesrv_call_set_list ( call , DCESRV_LIST_NONE ) ;
2003-12-12 06:59:09 +03:00
switch ( call - > pkt . ptype ) {
case DCERPC_PKT_BIND :
2015-06-26 09:10:46 +03:00
status = dcesrv_bind_nak ( call ,
DCERPC_BIND_NAK_REASON_NOT_SPECIFIED ) ;
2003-12-12 06:59:09 +03:00
break ;
2003-12-14 13:45:50 +03:00
case DCERPC_PKT_AUTH3 :
status = dcesrv_auth3 ( call ) ;
break ;
2004-12-06 20:48:51 +03:00
case DCERPC_PKT_ALTER :
status = dcesrv_alter ( call ) ;
break ;
2003-12-12 06:59:09 +03:00
case DCERPC_PKT_REQUEST :
status = dcesrv_request ( call ) ;
break ;
2015-06-26 09:10:46 +03:00
case DCERPC_PKT_CO_CANCEL :
case DCERPC_PKT_ORPHANED :
/*
* Window just ignores CO_CANCEL and ORPHANED ,
* so we do . . .
*/
status = NT_STATUS_OK ;
TALLOC_FREE ( call ) ;
break ;
2015-10-13 15:36:56 +03:00
case DCERPC_PKT_BIND_ACK :
case DCERPC_PKT_BIND_NAK :
case DCERPC_PKT_ALTER_RESP :
case DCERPC_PKT_RESPONSE :
case DCERPC_PKT_FAULT :
case DCERPC_PKT_SHUTDOWN :
2003-12-12 06:59:09 +03:00
default :
2015-06-26 09:10:46 +03:00
status = dcesrv_fault_disconnect ( call , DCERPC_NCA_S_PROTO_ERROR ) ;
2003-12-12 06:59:09 +03:00
break ;
}
/* if we are going to be sending a reply then add
it to the list of pending calls . We add it to the end to keep the call
list in the order we will answer */
2003-12-14 13:45:50 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-09-25 15:24:10 +04:00
talloc_free ( call ) ;
2003-12-12 06:59:09 +03:00
}
return status ;
2003-12-11 12:07:45 +03:00
}
2007-12-04 22:05:00 +03:00
_PUBLIC_ NTSTATUS dcesrv_init_context ( TALLOC_CTX * mem_ctx ,
struct loadparm_context * lp_ctx ,
const char * * endpoint_servers , struct dcesrv_context * * _dce_ctx )
2003-12-11 01:21:04 +03:00
{
2005-01-11 19:53:02 +03:00
NTSTATUS status ;
struct dcesrv_context * dce_ctx ;
2003-12-11 01:21:04 +03:00
int i ;
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
if ( ! endpoint_servers ) {
2005-01-11 19:53:02 +03:00
DEBUG ( 0 , ( " dcesrv_init_context: no endpoint servers configured \n " ) ) ;
return NT_STATUS_INTERNAL_ERROR ;
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
}
2015-06-26 09:10:46 +03:00
dce_ctx = talloc_zero ( mem_ctx , struct dcesrv_context ) ;
2005-01-11 19:53:02 +03:00
NT_STATUS_HAVE_NO_MEMORY ( dce_ctx ) ;
2015-11-04 12:15:13 +03:00
if ( uid_wrapper_enabled ( ) ) {
setenv ( " UID_WRAPPER_MYUID " , " 1 " , 1 ) ;
}
2015-01-22 14:24:31 +03:00
dce_ctx - > initial_euid = geteuid ( ) ;
2015-11-04 12:15:13 +03:00
if ( uid_wrapper_enabled ( ) ) {
unsetenv ( " UID_WRAPPER_MYUID " ) ;
}
2005-01-11 19:53:02 +03:00
dce_ctx - > endpoint_list = NULL ;
2007-12-04 22:05:00 +03:00
dce_ctx - > lp_ctx = lp_ctx ;
2009-09-22 08:36:54 +04:00
dce_ctx - > assoc_groups_idr = idr_init ( dce_ctx ) ;
NT_STATUS_HAVE_NO_MEMORY ( dce_ctx - > assoc_groups_idr ) ;
2013-07-09 18:38:59 +04:00
dce_ctx - > broken_connections = NULL ;
2005-01-11 19:53:02 +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
for ( i = 0 ; endpoint_servers [ i ] ; i + + ) {
const struct dcesrv_endpoint_server * ep_server ;
2005-01-11 19:53:02 +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
ep_server = dcesrv_ep_server_byname ( endpoint_servers [ i ] ) ;
if ( ! ep_server ) {
DEBUG ( 0 , ( " dcesrv_init_context: failed to find endpoint server = '%s' \n " , endpoint_servers [ i ] ) ) ;
2005-01-11 19:53:02 +03:00
return NT_STATUS_INTERNAL_ERROR ;
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
}
2005-01-11 19:53:02 +03:00
status = ep_server - > init_server ( dce_ctx , ep_server ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcesrv_init_context: failed to init endpoint server = '%s': %s \n " , endpoint_servers [ i ] ,
nt_errstr ( status ) ) ) ;
return status ;
2003-12-11 01:21:04 +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
2005-01-11 19:53:02 +03:00
* _dce_ctx = dce_ctx ;
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
return NT_STATUS_OK ;
2003-12-11 01:21:04 +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
/* the list of currently registered DCERPC endpoint servers.
*/
2004-12-03 09:24:38 +03:00
static struct ep_server {
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
struct dcesrv_endpoint_server * ep_server ;
} * ep_servers = NULL ;
static int num_ep_servers ;
2003-12-11 01:21:04 +03:00
2003-12-13 05:20:40 +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
register a DCERPC endpoint server .
The ' name ' can be later used by other backends to find the operations
structure for this backend .
The ' type ' is used to specify whether this is for a disk , printer or IPC $ share
*/
2006-05-01 22:11:15 +04:00
_PUBLIC_ NTSTATUS dcerpc_register_ep_server ( const void * _ep_server )
2003-12-13 05:20:40 +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
const struct dcesrv_endpoint_server * ep_server = _ep_server ;
if ( dcesrv_ep_server_byname ( ep_server - > name ) ! = NULL ) {
/* its already registered! */
2004-02-02 16:28:29 +03:00
DEBUG ( 0 , ( " DCERPC endpoint server '%s' already registered \n " ,
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
ep_server - > name ) ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
2003-12-13 13:58:48 +03:00
}
2003-12-13 05:20:40 +03:00
2004-12-03 09:24:38 +03:00
ep_servers = realloc_p ( ep_servers , struct ep_server , num_ep_servers + 1 ) ;
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
if ( ! ep_servers ) {
2004-06-20 14:00:32 +04:00
smb_panic ( " out of memory in dcerpc_register " ) ;
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
}
ep_servers [ num_ep_servers ] . ep_server = smb_xmemdup ( ep_server , sizeof ( * ep_server ) ) ;
ep_servers [ num_ep_servers ] . ep_server - > name = smb_xstrdup ( ep_server - > name ) ;
num_ep_servers + + ;
2004-02-02 16:28:29 +03:00
DEBUG ( 3 , ( " DCERPC endpoint server '%s' registered \n " ,
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
ep_server - > name ) ) ;
2003-12-13 05:20:40 +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
return NT_STATUS_OK ;
}
2003-12-13 05:20:40 +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
/*
return the operations structure for a named backend of the specified type
*/
const struct dcesrv_endpoint_server * dcesrv_ep_server_byname ( const char * name )
2003-12-14 16:22:12 +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
int i ;
for ( i = 0 ; i < num_ep_servers ; i + + ) {
if ( strcmp ( ep_servers [ i ] . ep_server - > name , name ) = = 0 ) {
return ep_servers [ i ] . ep_server ;
}
2003-12-14 16:22:12 +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
return NULL ;
2003-12-14 16:22:12 +03:00
}
2008-12-09 11:22:31 +03:00
void dcerpc_server_init ( struct loadparm_context * lp_ctx )
{
static bool initialized ;
2010-11-01 07:38:37 +03:00
# define _MODULE_PROTO(init) extern NTSTATUS init(void);
STATIC_dcerpc_server_MODULES_PROTO ;
2011-12-03 10:03:35 +04:00
init_module_fn static_init [ ] = { STATIC_dcerpc_server_MODULES } ;
init_module_fn * shared_init ;
2008-12-09 11:22:31 +03:00
if ( initialized ) {
return ;
}
initialized = true ;
2011-12-03 10:03:35 +04:00
shared_init = load_samba_modules ( NULL , " dcerpc_server " ) ;
2008-12-09 11:22:31 +03:00
2011-12-03 10:03:35 +04:00
run_init_functions ( static_init ) ;
run_init_functions ( shared_init ) ;
2008-12-09 11:22:31 +03:00
talloc_free ( shared_init ) ;
}
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
/*
return the DCERPC module version , and the size of some critical types
This can be used by endpoint server modules to either detect compilation errors , or provide
multiple implementations for different smbd compilation options in one module
*/
const struct dcesrv_critical_sizes * dcerpc_module_version ( void )
{
static const struct dcesrv_critical_sizes critical_sizes = {
DCERPC_MODULE_VERSION ,
sizeof ( struct dcesrv_context ) ,
sizeof ( struct dcesrv_endpoint ) ,
sizeof ( struct dcesrv_endpoint_server ) ,
sizeof ( struct dcesrv_interface ) ,
sizeof ( struct dcesrv_if_list ) ,
sizeof ( struct dcesrv_connection ) ,
sizeof ( struct dcesrv_call_state ) ,
sizeof ( struct dcesrv_auth ) ,
sizeof ( struct dcesrv_handle )
} ;
return & critical_sizes ;
}
2003-12-14 16:22:12 +03:00
2010-10-11 02:49:13 +04:00
static void dcesrv_terminate_connection ( struct dcesrv_connection * dce_conn , const char * reason )
{
2013-07-09 18:38:59 +04:00
struct dcesrv_context * dce_ctx = dce_conn - > dce_ctx ;
2010-10-11 02:49:13 +04:00
struct stream_connection * srv_conn ;
srv_conn = talloc_get_type ( dce_conn - > transport . private_data ,
struct stream_connection ) ;
2015-06-26 09:10:46 +03:00
dce_conn - > allow_bind = false ;
dce_conn - > allow_auth3 = false ;
dce_conn - > allow_alter = false ;
dce_conn - > allow_request = false ;
2013-07-09 18:38:59 +04:00
if ( dce_conn - > pending_call_list = = NULL ) {
char * full_reason = talloc_asprintf ( dce_conn , " dcesrv: %s " , reason ) ;
DLIST_REMOVE ( dce_ctx - > broken_connections , dce_conn ) ;
stream_terminate_connection ( srv_conn , full_reason ? full_reason : reason ) ;
return ;
}
if ( dce_conn - > terminate ! = NULL ) {
return ;
}
DEBUG ( 3 , ( " dcesrv: terminating connection due to '%s' defered due to pending calls \n " ,
reason ) ) ;
dce_conn - > terminate = talloc_strdup ( dce_conn , reason ) ;
if ( dce_conn - > terminate = = NULL ) {
dce_conn - > terminate = " dcesrv: defered terminating connection - no memory " ;
}
2016-02-05 13:32:18 +03:00
DLIST_ADD_END ( dce_ctx - > broken_connections , dce_conn ) ;
2010-10-11 02:49:13 +04:00
}
2013-07-09 18:38:59 +04:00
static void dcesrv_cleanup_broken_connections ( struct dcesrv_context * dce_ctx )
{
struct dcesrv_connection * cur , * next ;
next = dce_ctx - > broken_connections ;
while ( next ! = NULL ) {
cur = next ;
next = cur - > next ;
2015-04-06 12:26:58 +03:00
if ( cur - > state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL ) {
struct dcesrv_connection_context * context_cur , * context_next ;
context_next = cur - > contexts ;
while ( context_next ! = NULL ) {
context_cur = context_next ;
context_next = context_cur - > next ;
dcesrv_connection_context_destructor ( context_cur ) ;
}
}
2013-07-09 18:38:59 +04:00
dcesrv_terminate_connection ( cur , cur - > terminate ) ;
}
}
2010-10-13 14:06:46 +04:00
/* We need this include to be able to compile on some plateforms
* ( ie . freebsd 7.2 ) as it seems that < sys / uio . h > is not included
* correctly .
* It has to be that deep because otherwise we have a conflict on
* const struct dcesrv_interface declaration .
* This is mostly due to socket_wrapper defining # define bind swrap_bind
* which conflict with the bind used before .
*/
# include "system/network.h"
2010-10-11 02:49:13 +04:00
struct dcesrv_sock_reply_state {
struct dcesrv_connection * dce_conn ;
struct dcesrv_call_state * call ;
struct iovec iov ;
} ;
static void dcesrv_sock_reply_done ( struct tevent_req * subreq ) ;
2015-06-26 09:10:46 +03:00
static void dcesrv_call_terminate_step1 ( struct tevent_req * subreq ) ;
2010-10-11 02:49:13 +04:00
static void dcesrv_sock_report_output_data ( struct dcesrv_connection * dce_conn )
{
struct dcesrv_call_state * call ;
call = dce_conn - > call_list ;
if ( ! call | | ! call - > replies ) {
return ;
}
while ( call - > replies ) {
struct data_blob_list_item * rep = call - > replies ;
struct dcesrv_sock_reply_state * substate ;
struct tevent_req * subreq ;
2015-06-26 09:10:46 +03:00
substate = talloc_zero ( call , struct dcesrv_sock_reply_state ) ;
2010-10-11 02:49:13 +04:00
if ( ! substate ) {
dcesrv_terminate_connection ( dce_conn , " no memory " ) ;
return ;
}
substate - > dce_conn = dce_conn ;
substate - > call = NULL ;
DLIST_REMOVE ( call - > replies , rep ) ;
2015-06-26 09:10:46 +03:00
if ( call - > replies = = NULL & & call - > terminate_reason = = NULL ) {
2010-10-11 02:49:13 +04:00
substate - > call = call ;
}
substate - > iov . iov_base = ( void * ) rep - > blob . data ;
substate - > iov . iov_len = rep - > blob . length ;
subreq = tstream_writev_queue_send ( substate ,
dce_conn - > event_ctx ,
dce_conn - > stream ,
dce_conn - > send_queue ,
& substate - > iov , 1 ) ;
if ( ! subreq ) {
dcesrv_terminate_connection ( dce_conn , " no memory " ) ;
return ;
}
tevent_req_set_callback ( subreq , dcesrv_sock_reply_done ,
substate ) ;
}
2015-06-26 09:10:46 +03:00
if ( call - > terminate_reason ! = NULL ) {
struct tevent_req * subreq ;
subreq = tevent_queue_wait_send ( call ,
dce_conn - > event_ctx ,
dce_conn - > send_queue ) ;
if ( ! subreq ) {
dcesrv_terminate_connection ( dce_conn , __location__ ) ;
return ;
}
tevent_req_set_callback ( subreq , dcesrv_call_terminate_step1 ,
call ) ;
}
2010-10-11 02:49:13 +04:00
DLIST_REMOVE ( call - > conn - > call_list , call ) ;
call - > list = DCESRV_LIST_NONE ;
}
static void dcesrv_sock_reply_done ( struct tevent_req * subreq )
{
struct dcesrv_sock_reply_state * substate = tevent_req_callback_data ( subreq ,
struct dcesrv_sock_reply_state ) ;
int ret ;
int sys_errno ;
NTSTATUS status ;
struct dcesrv_call_state * call = substate - > call ;
ret = tstream_writev_queue_recv ( subreq , & sys_errno ) ;
TALLOC_FREE ( subreq ) ;
if ( ret = = - 1 ) {
2011-06-20 08:55:32 +04:00
status = map_nt_error_from_unix_common ( sys_errno ) ;
2010-10-11 02:49:13 +04:00
dcesrv_terminate_connection ( substate - > dce_conn , nt_errstr ( status ) ) ;
return ;
}
talloc_free ( substate ) ;
if ( call ) {
talloc_free ( call ) ;
}
}
2015-06-26 09:10:46 +03:00
static void dcesrv_call_terminate_step2 ( struct tevent_req * subreq ) ;
static void dcesrv_call_terminate_step1 ( struct tevent_req * subreq )
{
struct dcesrv_call_state * call = tevent_req_callback_data ( subreq ,
struct dcesrv_call_state ) ;
bool ok ;
struct timeval tv ;
/* make sure we stop send queue before removing subreq */
tevent_queue_stop ( call - > conn - > send_queue ) ;
ok = tevent_queue_wait_recv ( subreq ) ;
TALLOC_FREE ( subreq ) ;
if ( ! ok ) {
dcesrv_terminate_connection ( call - > conn , __location__ ) ;
return ;
}
/* disconnect after 200 usecs */
tv = timeval_current_ofs_usec ( 200 ) ;
subreq = tevent_wakeup_send ( call , call - > conn - > event_ctx , tv ) ;
if ( subreq = = NULL ) {
dcesrv_terminate_connection ( call - > conn , __location__ ) ;
return ;
}
tevent_req_set_callback ( subreq , dcesrv_call_terminate_step2 ,
call ) ;
}
static void dcesrv_call_terminate_step2 ( struct tevent_req * subreq )
{
struct dcesrv_call_state * call = tevent_req_callback_data ( subreq ,
struct dcesrv_call_state ) ;
bool ok ;
2010-10-11 02:49:13 +04:00
2015-06-26 09:10:46 +03:00
ok = tevent_wakeup_recv ( subreq ) ;
TALLOC_FREE ( subreq ) ;
if ( ! ok ) {
dcesrv_terminate_connection ( call - > conn , __location__ ) ;
return ;
}
2010-10-11 02:49:13 +04:00
2015-06-26 09:10:46 +03:00
dcesrv_terminate_connection ( call - > conn , call - > terminate_reason ) ;
}
2010-10-11 02:49:13 +04:00
struct dcesrv_socket_context {
const struct dcesrv_endpoint * endpoint ;
struct dcesrv_context * dcesrv_ctx ;
} ;
static void dcesrv_read_fragment_done ( struct tevent_req * subreq ) ;
static void dcesrv_sock_accept ( struct stream_connection * srv_conn )
{
NTSTATUS status ;
struct dcesrv_socket_context * dcesrv_sock =
talloc_get_type ( srv_conn - > private_data , struct dcesrv_socket_context ) ;
2014-01-30 22:01:34 +04:00
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport ( dcesrv_sock - > endpoint - > ep_description ) ;
2010-10-11 02:49:13 +04:00
struct dcesrv_connection * dcesrv_conn = NULL ;
int ret ;
struct tevent_req * subreq ;
struct loadparm_context * lp_ctx = dcesrv_sock - > dcesrv_ctx - > lp_ctx ;
2013-07-09 18:38:59 +04:00
dcesrv_cleanup_broken_connections ( dcesrv_sock - > dcesrv_ctx ) ;
2010-10-11 02:49:13 +04:00
if ( ! srv_conn - > session_info ) {
status = auth_anonymous_session_info ( srv_conn ,
lp_ctx ,
& srv_conn - > session_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcesrv_sock_accept: auth_anonymous_session_info failed: %s \n " ,
nt_errstr ( status ) ) ) ;
stream_terminate_connection ( srv_conn , nt_errstr ( status ) ) ;
return ;
}
}
status = dcesrv_endpoint_connect ( dcesrv_sock - > dcesrv_ctx ,
srv_conn ,
dcesrv_sock - > endpoint ,
srv_conn - > session_info ,
srv_conn - > event . ctx ,
srv_conn - > msg_ctx ,
srv_conn - > server_id ,
DCESRV_CALL_STATE_FLAG_MAY_ASYNC ,
& dcesrv_conn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s \n " ,
nt_errstr ( status ) ) ) ;
stream_terminate_connection ( srv_conn , nt_errstr ( status ) ) ;
return ;
}
dcesrv_conn - > transport . private_data = srv_conn ;
dcesrv_conn - > transport . report_output_data = dcesrv_sock_report_output_data ;
TALLOC_FREE ( srv_conn - > event . fde ) ;
dcesrv_conn - > send_queue = tevent_queue_create ( dcesrv_conn , " dcesrv send queue " ) ;
if ( ! dcesrv_conn - > send_queue ) {
status = NT_STATUS_NO_MEMORY ;
DEBUG ( 0 , ( " dcesrv_sock_accept: tevent_queue_create(%s) \n " ,
nt_errstr ( status ) ) ) ;
stream_terminate_connection ( srv_conn , nt_errstr ( status ) ) ;
return ;
}
2014-01-30 22:01:34 +04:00
if ( transport = = NCACN_NP ) {
2010-10-11 02:49:13 +04:00
dcesrv_conn - > auth_state . session_key = dcesrv_inherited_session_key ;
dcesrv_conn - > stream = talloc_move ( dcesrv_conn ,
& srv_conn - > tstream ) ;
} else {
ret = tstream_bsd_existing_socket ( dcesrv_conn ,
socket_get_fd ( srv_conn - > socket ) ,
& dcesrv_conn - > stream ) ;
if ( ret = = - 1 ) {
2011-06-20 08:55:32 +04:00
status = map_nt_error_from_unix_common ( errno ) ;
2010-10-11 02:49:13 +04:00
DEBUG ( 0 , ( " dcesrv_sock_accept: "
" failed to setup tstream: %s \n " ,
nt_errstr ( status ) ) ) ;
stream_terminate_connection ( srv_conn , nt_errstr ( status ) ) ;
return ;
}
socket_set_flags ( srv_conn - > socket , SOCKET_FLAG_NOCLOSE ) ;
}
dcesrv_conn - > local_address = srv_conn - > local_address ;
dcesrv_conn - > remote_address = srv_conn - > remote_address ;
2015-01-22 14:24:31 +03:00
if ( transport = = NCALRPC ) {
uid_t uid ;
gid_t gid ;
2016-06-07 11:01:32 +03:00
int sock_fd ;
2015-01-22 14:24:31 +03:00
2016-06-07 11:01:32 +03:00
sock_fd = socket_get_fd ( srv_conn - > socket ) ;
if ( sock_fd = = - 1 ) {
stream_terminate_connection (
srv_conn , " socket_get_fd failed \n " ) ;
return ;
}
ret = getpeereid ( sock_fd , & uid , & gid ) ;
2015-01-22 14:24:31 +03:00
if ( ret = = - 1 ) {
status = map_nt_error_from_unix_common ( errno ) ;
DEBUG ( 0 , ( " dcesrv_sock_accept: "
" getpeereid() failed for NCALRPC: %s \n " ,
nt_errstr ( status ) ) ) ;
stream_terminate_connection ( srv_conn , nt_errstr ( status ) ) ;
return ;
}
if ( uid = = dcesrv_conn - > dce_ctx - > initial_euid ) {
struct tsocket_address * r = NULL ;
ret = tsocket_address_unix_from_path ( dcesrv_conn ,
" /root/ncalrpc_as_system " ,
& r ) ;
if ( ret = = - 1 ) {
status = map_nt_error_from_unix_common ( errno ) ;
DEBUG ( 0 , ( " dcesrv_sock_accept: "
" tsocket_address_unix_from_path() failed for NCALRPC: %s \n " ,
nt_errstr ( status ) ) ) ;
stream_terminate_connection ( srv_conn , nt_errstr ( status ) ) ;
return ;
}
dcesrv_conn - > remote_address = r ;
}
}
2010-10-11 02:49:13 +04:00
srv_conn - > private_data = dcesrv_conn ;
irpc_add_name ( srv_conn - > msg_ctx , " rpc_server " ) ;
subreq = dcerpc_read_ncacn_packet_send ( dcesrv_conn ,
dcesrv_conn - > event_ctx ,
dcesrv_conn - > stream ) ;
if ( ! subreq ) {
status = NT_STATUS_NO_MEMORY ;
DEBUG ( 0 , ( " dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s) \n " ,
nt_errstr ( status ) ) ) ;
stream_terminate_connection ( srv_conn , nt_errstr ( status ) ) ;
return ;
}
tevent_req_set_callback ( subreq , dcesrv_read_fragment_done , dcesrv_conn ) ;
return ;
}
static void dcesrv_read_fragment_done ( struct tevent_req * subreq )
{
struct dcesrv_connection * dce_conn = tevent_req_callback_data ( subreq ,
struct dcesrv_connection ) ;
2013-07-09 18:38:59 +04:00
struct dcesrv_context * dce_ctx = dce_conn - > dce_ctx ;
2010-10-11 02:49:13 +04:00
struct ncacn_packet * pkt ;
DATA_BLOB buffer ;
NTSTATUS status ;
2013-07-09 18:38:59 +04:00
if ( dce_conn - > terminate ) {
/*
* if the current connection is broken
* we need to clean it up before any other connection
*/
dcesrv_terminate_connection ( dce_conn , dce_conn - > terminate ) ;
dcesrv_cleanup_broken_connections ( dce_ctx ) ;
return ;
}
dcesrv_cleanup_broken_connections ( dce_ctx ) ;
2010-10-11 02:49:13 +04:00
status = dcerpc_read_ncacn_packet_recv ( subreq , dce_conn ,
& pkt , & buffer ) ;
TALLOC_FREE ( subreq ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
dcesrv_terminate_connection ( dce_conn , nt_errstr ( status ) ) ;
return ;
}
status = dcesrv_process_ncacn_packet ( dce_conn , pkt , buffer ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
dcesrv_terminate_connection ( dce_conn , nt_errstr ( status ) ) ;
return ;
}
subreq = dcerpc_read_ncacn_packet_send ( dce_conn ,
dce_conn - > event_ctx ,
dce_conn - > stream ) ;
if ( ! subreq ) {
status = NT_STATUS_NO_MEMORY ;
dcesrv_terminate_connection ( dce_conn , nt_errstr ( status ) ) ;
return ;
}
tevent_req_set_callback ( subreq , dcesrv_read_fragment_done , dce_conn ) ;
}
static void dcesrv_sock_recv ( struct stream_connection * conn , uint16_t flags )
{
struct dcesrv_connection * dce_conn = talloc_get_type ( conn - > private_data ,
struct dcesrv_connection ) ;
dcesrv_terminate_connection ( dce_conn , " dcesrv_sock_recv triggered " ) ;
}
static void dcesrv_sock_send ( struct stream_connection * conn , uint16_t flags )
{
struct dcesrv_connection * dce_conn = talloc_get_type ( conn - > private_data ,
struct dcesrv_connection ) ;
dcesrv_terminate_connection ( dce_conn , " dcesrv_sock_send triggered " ) ;
}
static const struct stream_server_ops dcesrv_stream_ops = {
. name = " rpc " ,
. accept_connection = dcesrv_sock_accept ,
. recv_handler = dcesrv_sock_recv ,
. send_handler = dcesrv_sock_send ,
} ;
static NTSTATUS dcesrv_add_ep_unix ( struct dcesrv_context * dce_ctx ,
struct loadparm_context * lp_ctx ,
struct dcesrv_endpoint * e ,
struct tevent_context * event_ctx , const struct model_ops * model_ops )
{
struct dcesrv_socket_context * dcesrv_sock ;
uint16_t port = 1 ;
NTSTATUS status ;
2014-02-04 14:32:03 +04:00
const char * endpoint ;
2010-10-11 02:49:13 +04:00
2015-06-26 09:10:46 +03:00
dcesrv_sock = talloc_zero ( event_ctx , struct dcesrv_socket_context ) ;
2010-10-11 02:49:13 +04:00
NT_STATUS_HAVE_NO_MEMORY ( dcesrv_sock ) ;
/* remember the endpoint of this socket */
dcesrv_sock - > endpoint = e ;
dcesrv_sock - > dcesrv_ctx = talloc_reference ( dcesrv_sock , dce_ctx ) ;
2014-02-04 14:32:03 +04:00
endpoint = dcerpc_binding_get_string_option ( e - > ep_description , " endpoint " ) ;
2010-11-15 02:12:22 +03:00
status = stream_setup_socket ( dcesrv_sock , event_ctx , lp_ctx ,
2010-10-11 02:49:13 +04:00
model_ops , & dcesrv_stream_ops ,
2014-02-04 14:32:03 +04:00
" unix " , endpoint , & port ,
2010-10-11 02:49:13 +04:00
lpcfg_socket_options ( lp_ctx ) ,
dcesrv_sock ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " service_setup_stream_socket(path=%s) failed - %s \n " ,
2014-02-04 14:32:03 +04:00
endpoint , nt_errstr ( status ) ) ) ;
2010-10-11 02:49:13 +04:00
}
return status ;
}
static NTSTATUS dcesrv_add_ep_ncalrpc ( struct dcesrv_context * dce_ctx ,
struct loadparm_context * lp_ctx ,
struct dcesrv_endpoint * e ,
struct tevent_context * event_ctx , const struct model_ops * model_ops )
{
struct dcesrv_socket_context * dcesrv_sock ;
uint16_t port = 1 ;
char * full_path ;
NTSTATUS status ;
2014-02-04 14:32:03 +04:00
const char * endpoint ;
endpoint = dcerpc_binding_get_string_option ( e - > ep_description , " endpoint " ) ;
2010-10-11 02:49:13 +04:00
2014-02-04 14:32:03 +04:00
if ( endpoint = = NULL ) {
/*
* No identifier specified : use DEFAULT .
*
* TODO : DO NOT hardcode this value anywhere else . Rather , specify
* no endpoint and let the epmapper worry about it .
*/
endpoint = " DEFAULT " ;
status = dcerpc_binding_set_string_option ( e - > ep_description ,
" endpoint " ,
endpoint ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcerpc_binding_set_string_option() failed - %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
2010-10-11 02:49:13 +04:00
}
full_path = talloc_asprintf ( dce_ctx , " %s/%s " , lpcfg_ncalrpc_dir ( lp_ctx ) ,
2014-02-04 14:32:03 +04:00
endpoint ) ;
2010-10-11 02:49:13 +04:00
2015-06-26 09:10:46 +03:00
dcesrv_sock = talloc_zero ( event_ctx , struct dcesrv_socket_context ) ;
2010-10-11 02:49:13 +04:00
NT_STATUS_HAVE_NO_MEMORY ( dcesrv_sock ) ;
/* remember the endpoint of this socket */
dcesrv_sock - > endpoint = e ;
dcesrv_sock - > dcesrv_ctx = talloc_reference ( dcesrv_sock , dce_ctx ) ;
2010-11-15 02:12:22 +03:00
status = stream_setup_socket ( dcesrv_sock , event_ctx , lp_ctx ,
2010-10-11 02:49:13 +04:00
model_ops , & dcesrv_stream_ops ,
" unix " , full_path , & port ,
lpcfg_socket_options ( lp_ctx ) ,
dcesrv_sock ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " service_setup_stream_socket(identifier=%s,path=%s) failed - %s \n " ,
2014-02-04 14:32:03 +04:00
endpoint , full_path , nt_errstr ( status ) ) ) ;
2010-10-11 02:49:13 +04:00
}
return status ;
}
static NTSTATUS dcesrv_add_ep_np ( struct dcesrv_context * dce_ctx ,
struct loadparm_context * lp_ctx ,
struct dcesrv_endpoint * e ,
struct tevent_context * event_ctx , const struct model_ops * model_ops )
{
struct dcesrv_socket_context * dcesrv_sock ;
NTSTATUS status ;
2014-02-04 14:32:03 +04:00
const char * endpoint ;
endpoint = dcerpc_binding_get_string_option ( e - > ep_description , " endpoint " ) ;
if ( endpoint = = NULL ) {
2010-10-11 02:49:13 +04:00
DEBUG ( 0 , ( " Endpoint mandatory for named pipes \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2015-06-26 09:10:46 +03:00
dcesrv_sock = talloc_zero ( event_ctx , struct dcesrv_socket_context ) ;
2010-10-11 02:49:13 +04:00
NT_STATUS_HAVE_NO_MEMORY ( dcesrv_sock ) ;
/* remember the endpoint of this socket */
dcesrv_sock - > endpoint = e ;
dcesrv_sock - > dcesrv_ctx = talloc_reference ( dcesrv_sock , dce_ctx ) ;
2010-11-15 02:12:22 +03:00
status = tstream_setup_named_pipe ( dce_ctx , event_ctx , lp_ctx ,
2010-10-11 02:49:13 +04:00
model_ops , & dcesrv_stream_ops ,
2014-02-04 14:32:03 +04:00
endpoint ,
2010-10-11 02:49:13 +04:00
dcesrv_sock ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " stream_setup_named_pipe(pipe=%s) failed - %s \n " ,
2014-02-04 14:32:03 +04:00
endpoint , nt_errstr ( status ) ) ) ;
2010-10-11 02:49:13 +04:00
return status ;
}
return NT_STATUS_OK ;
}
/*
add a socket address to the list of events , one event per dcerpc endpoint
*/
static NTSTATUS add_socket_rpc_tcp_iface ( struct dcesrv_context * dce_ctx , struct dcesrv_endpoint * e ,
struct tevent_context * event_ctx , const struct model_ops * model_ops ,
const char * address )
{
struct dcesrv_socket_context * dcesrv_sock ;
uint16_t port = 0 ;
NTSTATUS status ;
2014-02-04 14:32:03 +04:00
const char * endpoint ;
char port_str [ 6 ] ;
endpoint = dcerpc_binding_get_string_option ( e - > ep_description , " endpoint " ) ;
if ( endpoint ! = NULL ) {
port = atoi ( endpoint ) ;
2010-10-11 02:49:13 +04:00
}
2015-06-26 09:10:46 +03:00
dcesrv_sock = talloc_zero ( event_ctx , struct dcesrv_socket_context ) ;
2010-10-11 02:49:13 +04:00
NT_STATUS_HAVE_NO_MEMORY ( dcesrv_sock ) ;
/* remember the endpoint of this socket */
dcesrv_sock - > endpoint = e ;
dcesrv_sock - > dcesrv_ctx = talloc_reference ( dcesrv_sock , dce_ctx ) ;
2010-11-15 02:12:22 +03:00
status = stream_setup_socket ( dcesrv_sock , event_ctx , dce_ctx - > lp_ctx ,
2010-10-11 02:49:13 +04:00
model_ops , & dcesrv_stream_ops ,
2011-05-12 14:36:33 +04:00
" ip " , address , & port ,
2010-10-11 02:49:13 +04:00
lpcfg_socket_options ( dce_ctx - > lp_ctx ) ,
dcesrv_sock ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " service_setup_stream_socket(address=%s,port=%u) failed - %s \n " ,
address , port , nt_errstr ( status ) ) ) ;
2014-02-04 14:32:03 +04:00
return status ;
2010-10-11 02:49:13 +04:00
}
2014-02-04 14:32:03 +04:00
snprintf ( port_str , sizeof ( port_str ) , " %u " , port ) ;
status = dcerpc_binding_set_string_option ( e - > ep_description ,
" endpoint " , port_str ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcerpc_binding_set_string_option(endpoint, %s) failed - %s \n " ,
port_str , nt_errstr ( status ) ) ) ;
return status ;
2010-10-11 02:49:13 +04:00
}
2014-02-04 14:32:03 +04:00
return NT_STATUS_OK ;
2010-10-11 02:49:13 +04:00
}
# include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
static NTSTATUS dcesrv_add_ep_tcp ( struct dcesrv_context * dce_ctx ,
struct loadparm_context * lp_ctx ,
struct dcesrv_endpoint * e ,
struct tevent_context * event_ctx , const struct model_ops * model_ops )
{
NTSTATUS status ;
/* Add TCP/IP sockets */
if ( lpcfg_interfaces ( lp_ctx ) & & lpcfg_bind_interfaces_only ( lp_ctx ) ) {
int num_interfaces ;
int i ;
struct interface * ifaces ;
2011-06-02 09:40:28 +04:00
load_interface_list ( dce_ctx , lp_ctx , & ifaces ) ;
2010-10-11 02:49:13 +04:00
2011-05-02 09:57:19 +04:00
num_interfaces = iface_list_count ( ifaces ) ;
2010-10-11 02:49:13 +04:00
for ( i = 0 ; i < num_interfaces ; i + + ) {
2011-05-02 09:57:19 +04:00
const char * address = iface_list_n_ip ( ifaces , i ) ;
2010-10-11 02:49:13 +04:00
status = add_socket_rpc_tcp_iface ( dce_ctx , e , event_ctx , model_ops , address ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
}
} else {
2014-02-27 13:28:23 +04:00
char * * wcard ;
2011-05-12 14:35:02 +04:00
int i ;
2014-06-05 23:32:30 +04:00
int num_binds = 0 ;
2014-02-27 13:28:23 +04:00
wcard = iface_list_wildcard ( dce_ctx ) ;
2011-05-12 14:35:02 +04:00
NT_STATUS_HAVE_NO_MEMORY ( wcard ) ;
for ( i = 0 ; wcard [ i ] ; i + + ) {
status = add_socket_rpc_tcp_iface ( dce_ctx , e , event_ctx , model_ops , wcard [ i ] ) ;
2014-06-05 23:32:30 +04:00
if ( NT_STATUS_IS_OK ( status ) ) {
num_binds + + ;
}
2011-05-12 14:35:02 +04:00
}
talloc_free ( wcard ) ;
2014-06-05 23:32:30 +04:00
if ( num_binds = = 0 ) {
return NT_STATUS_INVALID_PARAMETER_MIX ;
}
2010-10-11 02:49:13 +04:00
}
return NT_STATUS_OK ;
}
NTSTATUS dcesrv_add_ep ( struct dcesrv_context * dce_ctx ,
struct loadparm_context * lp_ctx ,
struct dcesrv_endpoint * e ,
struct tevent_context * event_ctx ,
const struct model_ops * model_ops )
{
2014-01-30 22:01:34 +04:00
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport ( e - > ep_description ) ;
switch ( transport ) {
2010-10-11 02:49:13 +04:00
case NCACN_UNIX_STREAM :
return dcesrv_add_ep_unix ( dce_ctx , lp_ctx , e , event_ctx , model_ops ) ;
case NCALRPC :
return dcesrv_add_ep_ncalrpc ( dce_ctx , lp_ctx , e , event_ctx , model_ops ) ;
case NCACN_IP_TCP :
return dcesrv_add_ep_tcp ( dce_ctx , lp_ctx , e , event_ctx , model_ops ) ;
case NCACN_NP :
return dcesrv_add_ep_np ( dce_ctx , lp_ctx , e , event_ctx , model_ops ) ;
default :
return NT_STATUS_NOT_SUPPORTED ;
}
}
2011-02-25 05:13:01 +03:00
/**
* retrieve credentials from a dce_call
*/
_PUBLIC_ struct cli_credentials * dcesrv_call_credentials ( struct dcesrv_call_state * dce_call )
{
return dce_call - > conn - > auth_state . session_info - > credentials ;
}
/**
* returns true if this is an authenticated call
*/
_PUBLIC_ bool dcesrv_call_authenticated ( struct dcesrv_call_state * dce_call )
{
enum security_user_level level ;
level = security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) ;
return level > = SECURITY_USER ;
}
2011-03-15 06:43:24 +03:00
/**
* retrieve account_name for a dce_call
*/
_PUBLIC_ const char * dcesrv_call_account_name ( struct dcesrv_call_state * dce_call )
{
return dce_call - > context - > conn - > auth_state . session_info - > info - > account_name ;
}