2010-06-10 22:36:19 +04:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
1998-03-12 00:11:04 +03:00
* RPC Pipe client / server routines
1998-10-20 22:27:49 +04:00
* Copyright ( C ) Andrew Tridgell 1992 - 1998 ,
2005-09-30 21:13:37 +04:00
* Largely re - written : 2005
* Copyright ( C ) Jeremy Allison 1998 - 2005
2010-06-10 22:36:19 +04:00
*
1998-03-12 00:11:04 +03:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
1998-03-12 00:11:04 +03:00
* ( at your option ) any later version .
2010-06-10 22:36:19 +04:00
*
1998-03-12 00:11:04 +03:00
* 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 .
2010-06-10 22:36:19 +04:00
*
1998-03-12 00:11:04 +03:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
1998-03-12 00:11:04 +03:00
*/
# include "includes.h"
2010-08-18 18:44:47 +04:00
# include "fake_file.h"
2010-08-18 20:26:17 +04:00
# include "rpc_dce.h"
2011-03-25 00:33:07 +03:00
# include "ntdomain.h"
2011-04-30 01:32:28 +04:00
# include "rpc_server/rpc_ncacn_np.h"
# include "rpc_server/srv_pipe_hnd.h"
2021-06-18 20:11:19 +03:00
# include "rpc_client/local_np.h"
2011-08-03 14:13:56 +04:00
# include "rpc_server/rpc_server.h"
2011-08-11 00:13:42 +04:00
# include "rpc_server/rpc_config.h"
2011-04-28 19:26:40 +04:00
# include "../lib/tsocket/tsocket.h"
2011-04-28 19:38:09 +04:00
# include "../lib/util/tevent_ntstatus.h"
2013-09-18 12:58:16 +04:00
# include "librpc/ndr/ndr_table.h"
1998-03-12 00:11:04 +03:00
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2008-10-13 01:01:38 +04:00
bool fsp_is_np ( struct files_struct * fsp )
{
Add proxied named pipe support
This is a central piece of the "merged build" thing: Forward named pipes from
samba3 to samba4. This patch is not finished yet, as we will have to forward
the smb-level authentication information to samba4, but I'm pushing this patch
already to demonstrate the implementation without clutter.
It adds an intermediate parameter
np:proxy = srvsvc samr winreg wkssvc ... and so on
that states which of the pipes should be forwarded to the s4 unix domain socket
DEFAULT. The parameter is intermediate because once we have a proper endpoint
mapper implementation, this information will be retrieved out of a database.
If anybody wants to try this, do the merged build and configure s4 with
server services = samba3_smb, rpc, nbt, wrepl, ldap, cldap, kdc, drepl
samba3:smbd = /data/inst/sbin/smbd
and s3 with
auth methods = guest netlogond
np:proxy = srvsvc samr winreg wkssvc netlogon ntlsa ntsvcs lsass lsarpc netdfs \
rpcecho initshutdown epmapper svcctl eventlog drsuapi
Then run rpcclient against samba4. It will fork s3, which authenticates against
s4, and then forwards the rpc requests to s4.
Volker
2008-10-25 17:37:13 +04:00
enum FAKE_FILE_TYPE type ;
if ( ( fsp = = NULL ) | | ( fsp - > fake_file_handle = = NULL ) ) {
return false ;
}
type = fsp - > fake_file_handle - > type ;
2013-10-23 19:16:10 +04:00
return ( type = = FAKE_FILE_TYPE_NAMED_PIPE_PROXY ) ;
Add proxied named pipe support
This is a central piece of the "merged build" thing: Forward named pipes from
samba3 to samba4. This patch is not finished yet, as we will have to forward
the smb-level authentication information to samba4, but I'm pushing this patch
already to demonstrate the implementation without clutter.
It adds an intermediate parameter
np:proxy = srvsvc samr winreg wkssvc ... and so on
that states which of the pipes should be forwarded to the s4 unix domain socket
DEFAULT. The parameter is intermediate because once we have a proper endpoint
mapper implementation, this information will be retrieved out of a database.
If anybody wants to try this, do the merged build and configure s4 with
server services = samba3_smb, rpc, nbt, wrepl, ldap, cldap, kdc, drepl
samba3:smbd = /data/inst/sbin/smbd
and s3 with
auth methods = guest netlogond
np:proxy = srvsvc samr winreg wkssvc netlogon ntlsa ntsvcs lsass lsarpc netdfs \
rpcecho initshutdown epmapper svcctl eventlog drsuapi
Then run rpcclient against samba4. It will fork s3, which authenticates against
s4, and then forwards the rpc requests to s4.
Volker
2008-10-25 17:37:13 +04:00
}
2009-01-20 17:21:04 +03:00
NTSTATUS np_open ( TALLOC_CTX * mem_ctx , const char * name ,
2017-03-23 04:05:56 +03:00
const struct tsocket_address * remote_client_address ,
const struct tsocket_address * local_server_address ,
2011-07-18 07:06:47 +04:00
struct auth_session_info * session_info ,
2013-10-23 19:03:37 +04:00
struct tevent_context * ev_ctx ,
2010-08-08 11:11:45 +04:00
struct messaging_context * msg_ctx ,
2019-02-27 23:36:22 +03:00
struct dcesrv_context * dce_ctx ,
2009-01-20 17:21:04 +03:00
struct fake_file_handle * * phandle )
2008-10-13 01:01:38 +04:00
{
2009-01-20 17:21:04 +03:00
struct fake_file_handle * handle ;
2013-09-24 17:03:48 +04:00
struct npa_state * npa = NULL ;
2021-06-18 20:11:19 +03:00
int ret ;
2008-10-13 01:01:38 +04:00
2009-01-20 17:21:04 +03:00
handle = talloc ( mem_ctx , struct fake_file_handle ) ;
if ( handle = = NULL ) {
2008-10-13 01:01:38 +04:00
return NT_STATUS_NO_MEMORY ;
}
2021-06-18 20:11:19 +03:00
npa = npa_state_init ( handle ) ;
if ( npa = = NULL ) {
TALLOC_FREE ( handle ) ;
return NT_STATUS_NO_MEMORY ;
2010-09-14 15:37:46 +04:00
}
2021-06-18 20:11:19 +03:00
* handle = ( struct fake_file_handle ) {
. type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY ,
. private_data = npa ,
} ;
ret = local_np_connect (
name ,
NCACN_NP ,
NULL ,
remote_client_address ,
NULL ,
local_server_address ,
session_info ,
false ,
npa ,
& npa - > stream ) ;
if ( ret ! = 0 ) {
DBG_DEBUG ( " local_np_connect failed: %s \n " ,
strerror ( ret ) ) ;
TALLOC_FREE ( handle ) ;
return map_nt_error_from_unix ( ret ) ;
2008-10-13 01:01:38 +04:00
}
2009-01-20 17:21:04 +03:00
* phandle = handle ;
2008-10-13 01:01:38 +04:00
return NT_STATUS_OK ;
}
2010-04-28 17:05:30 +04:00
bool np_read_in_progress ( struct fake_file_handle * handle )
{
if ( handle - > type = = FAKE_FILE_TYPE_NAMED_PIPE_PROXY ) {
2013-09-24 17:03:48 +04:00
struct npa_state * p =
talloc_get_type_abort ( handle - > private_data ,
struct npa_state ) ;
2010-04-28 17:05:30 +04:00
size_t read_count ;
read_count = tevent_queue_length ( p - > read_queue ) ;
if ( read_count > 0 ) {
return true ;
}
return false ;
}
return false ;
}
2009-01-31 14:43:25 +03:00
struct np_write_state {
2013-02-18 12:57:48 +04:00
struct tevent_context * ev ;
2013-09-24 17:03:48 +04:00
struct npa_state * p ;
2009-02-23 00:01:35 +03:00
struct iovec iov ;
2009-01-31 14:43:25 +03:00
ssize_t nwritten ;
} ;
2009-02-23 00:01:35 +03:00
static void np_write_done ( struct tevent_req * subreq ) ;
2009-01-31 14:43:25 +03:00
2013-02-18 12:57:48 +04:00
struct tevent_req * np_write_send ( TALLOC_CTX * mem_ctx , struct tevent_context * ev ,
2009-03-17 11:17:16 +03:00
struct fake_file_handle * handle ,
const uint8_t * data , size_t len )
2008-10-13 01:01:38 +04:00
{
2009-03-17 11:17:16 +03:00
struct tevent_req * req ;
2009-01-31 14:43:25 +03:00
struct np_write_state * state ;
2022-08-10 09:39:12 +03:00
struct npa_state * p = NULL ;
struct tevent_req * subreq = NULL ;
2009-01-31 14:43:25 +03:00
2021-05-13 21:24:09 +03:00
DBG_INFO ( " len: %zu \n " , len ) ;
2008-10-13 01:01:38 +04:00
dump_data ( 50 , data , len ) ;
2009-03-17 11:17:16 +03:00
req = tevent_req_create ( mem_ctx , & state , struct np_write_state ) ;
if ( req = = NULL ) {
2009-01-31 14:43:25 +03:00
return NULL ;
}
2022-08-10 09:39:12 +03:00
if ( handle - > type ! = FAKE_FILE_TYPE_NAMED_PIPE_PROXY ) {
tevent_req_nterror ( req , NT_STATUS_INVALID_HANDLE ) ;
return tevent_req_post ( req , ev ) ;
}
2009-01-31 16:33:38 +03:00
if ( len = = 0 ) {
state - > nwritten = 0 ;
2022-08-10 09:39:12 +03:00
tevent_req_done ( req ) ;
return tevent_req_post ( req , ev ) ;
2009-01-31 16:33:38 +03:00
}
2022-08-10 09:39:12 +03:00
p = talloc_get_type_abort ( handle - > private_data , struct npa_state ) ;
2009-01-31 14:43:25 +03:00
2022-08-10 09:39:12 +03:00
state - > ev = ev ;
state - > p = p ;
state - > iov . iov_base = discard_const_p ( void , data ) ;
state - > iov . iov_len = len ;
subreq = tstream_writev_queue_send (
state , ev , p - > stream , p - > write_queue , & state - > iov , 1 ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
Add proxied named pipe support
This is a central piece of the "merged build" thing: Forward named pipes from
samba3 to samba4. This patch is not finished yet, as we will have to forward
the smb-level authentication information to samba4, but I'm pushing this patch
already to demonstrate the implementation without clutter.
It adds an intermediate parameter
np:proxy = srvsvc samr winreg wkssvc ... and so on
that states which of the pipes should be forwarded to the s4 unix domain socket
DEFAULT. The parameter is intermediate because once we have a proper endpoint
mapper implementation, this information will be retrieved out of a database.
If anybody wants to try this, do the merged build and configure s4 with
server services = samba3_smb, rpc, nbt, wrepl, ldap, cldap, kdc, drepl
samba3:smbd = /data/inst/sbin/smbd
and s3 with
auth methods = guest netlogond
np:proxy = srvsvc samr winreg wkssvc netlogon ntlsa ntsvcs lsass lsarpc netdfs \
rpcecho initshutdown epmapper svcctl eventlog drsuapi
Then run rpcclient against samba4. It will fork s3, which authenticates against
s4, and then forwards the rpc requests to s4.
Volker
2008-10-25 17:37:13 +04:00
}
2022-08-10 09:39:12 +03:00
tevent_req_set_callback ( subreq , np_write_done , req ) ;
return req ;
2009-01-31 14:43:25 +03:00
}
2008-10-13 01:01:38 +04:00
2009-02-23 00:01:35 +03:00
static void np_write_done ( struct tevent_req * subreq )
2009-01-31 14:43:25 +03:00
{
2009-03-17 11:17:16 +03:00
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct np_write_state * state = tevent_req_data (
req , struct np_write_state ) ;
2009-02-10 17:28:56 +03:00
ssize_t received ;
2009-02-04 11:07:36 +03:00
int err ;
2009-01-31 14:43:25 +03:00
2010-04-27 17:15:09 +04:00
received = tstream_writev_queue_recv ( subreq , & err ) ;
2009-02-10 17:28:56 +03:00
if ( received < 0 ) {
2009-03-17 11:17:16 +03:00
tevent_req_nterror ( req , map_nt_error_from_unix ( err ) ) ;
2009-01-31 14:43:25 +03:00
return ;
}
2009-02-10 17:28:56 +03:00
state - > nwritten = received ;
2009-03-17 11:17:16 +03:00
tevent_req_done ( req ) ;
2009-01-31 14:43:25 +03:00
}
2009-03-17 11:17:16 +03:00
NTSTATUS np_write_recv ( struct tevent_req * req , ssize_t * pnwritten )
2009-01-31 14:43:25 +03:00
{
2009-03-17 11:17:16 +03:00
struct np_write_state * state = tevent_req_data (
req , struct np_write_state ) ;
2009-01-31 14:43:25 +03:00
NTSTATUS status ;
2009-03-17 11:17:16 +03:00
if ( tevent_req_is_nterror ( req , & status ) ) {
2009-01-31 14:43:25 +03:00
return status ;
}
* pnwritten = state - > nwritten ;
return NT_STATUS_OK ;
}
2010-04-27 17:15:09 +04:00
struct np_ipc_readv_next_vector_state {
uint8_t * buf ;
size_t len ;
off_t ofs ;
size_t remaining ;
} ;
static void np_ipc_readv_next_vector_init ( struct np_ipc_readv_next_vector_state * s ,
uint8_t * buf , size_t len )
{
ZERO_STRUCTP ( s ) ;
s - > buf = buf ;
s - > len = MIN ( len , UINT16_MAX ) ;
}
static int np_ipc_readv_next_vector ( struct tstream_context * stream ,
void * private_data ,
TALLOC_CTX * mem_ctx ,
struct iovec * * _vector ,
size_t * count )
2009-02-09 10:10:09 +03:00
{
2010-04-27 17:15:09 +04:00
struct np_ipc_readv_next_vector_state * state =
( struct np_ipc_readv_next_vector_state * ) private_data ;
struct iovec * vector ;
ssize_t pending ;
size_t wanted ;
if ( state - > ofs = = state - > len ) {
* _vector = NULL ;
* count = 0 ;
return 0 ;
}
2009-02-09 10:10:09 +03:00
2010-04-27 17:15:09 +04:00
pending = tstream_pending_bytes ( stream ) ;
if ( pending = = - 1 ) {
return - 1 ;
}
if ( pending = = 0 & & state - > ofs ! = 0 ) {
/* return a short read */
* _vector = NULL ;
* count = 0 ;
2009-02-09 10:10:09 +03:00
return 0 ;
}
2010-04-27 17:15:09 +04:00
if ( pending = = 0 ) {
/* we want at least one byte and recheck again */
wanted = 1 ;
} else {
size_t missing = state - > len - state - > ofs ;
if ( pending > missing ) {
/* there's more available */
state - > remaining = pending - missing ;
wanted = missing ;
} else {
/* read what we can get and recheck in the next cycle */
wanted = pending ;
}
}
vector = talloc_array ( mem_ctx , struct iovec , 1 ) ;
if ( ! vector ) {
2009-02-09 10:10:09 +03:00
return - 1 ;
}
2010-04-27 17:15:09 +04:00
vector [ 0 ] . iov_base = state - > buf + state - > ofs ;
vector [ 0 ] . iov_len = wanted ;
state - > ofs + = wanted ;
* _vector = vector ;
* count = 1 ;
return 0 ;
2009-02-09 10:10:09 +03:00
}
2009-01-31 15:36:09 +03:00
struct np_read_state {
2013-09-24 17:03:48 +04:00
struct npa_state * p ;
2010-04-27 17:15:09 +04:00
struct np_ipc_readv_next_vector_state next_vector ;
2009-02-09 10:10:09 +03:00
2012-03-05 18:56:55 +04:00
ssize_t nread ;
2009-01-31 15:36:09 +03:00
bool is_data_outstanding ;
} ;
2009-02-23 01:17:15 +03:00
static void np_read_done ( struct tevent_req * subreq ) ;
2009-01-31 15:36:09 +03:00
2013-02-18 12:57:48 +04:00
struct tevent_req * np_read_send ( TALLOC_CTX * mem_ctx , struct tevent_context * ev ,
2009-03-17 11:34:17 +03:00
struct fake_file_handle * handle ,
uint8_t * data , size_t len )
2008-10-13 01:01:38 +04:00
{
2009-03-17 11:34:17 +03:00
struct tevent_req * req ;
2009-01-31 15:36:09 +03:00
struct np_read_state * state ;
2022-08-10 09:39:12 +03:00
struct npa_state * p = NULL ;
struct tevent_req * subreq = NULL ;
2009-01-31 15:36:09 +03:00
2009-03-17 11:34:17 +03:00
req = tevent_req_create ( mem_ctx , & state , struct np_read_state ) ;
if ( req = = NULL ) {
2009-01-31 15:36:09 +03:00
return NULL ;
}
2022-08-10 09:39:12 +03:00
if ( handle - > type ! = FAKE_FILE_TYPE_NAMED_PIPE_PROXY ) {
tevent_req_nterror ( req , NT_STATUS_INVALID_HANDLE ) ;
return tevent_req_post ( req , ev ) ;
2009-01-31 15:36:09 +03:00
}
2022-08-10 09:39:12 +03:00
p = talloc_get_type_abort ( handle - > private_data , struct npa_state ) ;
np_ipc_readv_next_vector_init ( & state - > next_vector , data , len ) ;
subreq = tstream_readv_pdu_queue_send (
state ,
ev ,
p - > stream ,
p - > read_queue ,
np_ipc_readv_next_vector ,
& state - > next_vector ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
2009-01-31 15:36:09 +03:00
}
2022-08-10 09:39:12 +03:00
tevent_req_set_callback ( subreq , np_read_done , req ) ;
return req ;
2009-02-09 10:10:09 +03:00
}
2009-02-23 01:17:15 +03:00
static void np_read_done ( struct tevent_req * subreq )
2009-01-31 15:36:09 +03:00
{
2009-03-17 11:34:17 +03:00
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct np_read_state * state = tevent_req_data (
req , struct np_read_state ) ;
2010-04-27 17:15:09 +04:00
ssize_t ret ;
2009-02-09 10:10:09 +03:00
int err ;
2009-01-31 15:36:09 +03:00
2010-04-27 17:15:09 +04:00
ret = tstream_readv_pdu_queue_recv ( subreq , & err ) ;
2009-02-09 10:10:09 +03:00
TALLOC_FREE ( subreq ) ;
2010-04-27 17:15:09 +04:00
if ( ret = = - 1 ) {
2009-03-17 11:34:17 +03:00
tevent_req_nterror ( req , map_nt_error_from_unix ( err ) ) ;
2009-02-05 13:15:06 +03:00
return ;
}
2010-04-27 17:15:09 +04:00
state - > nread = ret ;
state - > is_data_outstanding = ( state - > next_vector . remaining > 0 ) ;
2009-02-05 00:35:23 +03:00
2009-03-17 11:34:17 +03:00
tevent_req_done ( req ) ;
2009-02-09 10:10:09 +03:00
return ;
2009-01-31 15:36:09 +03:00
}
2009-03-17 11:34:17 +03:00
NTSTATUS np_read_recv ( struct tevent_req * req , ssize_t * nread ,
2009-01-31 15:36:09 +03:00
bool * is_data_outstanding )
{
2009-03-17 11:34:17 +03:00
struct np_read_state * state = tevent_req_data (
req , struct np_read_state ) ;
2009-01-31 15:36:09 +03:00
NTSTATUS status ;
2009-03-17 11:34:17 +03:00
if ( tevent_req_is_nterror ( req , & status ) ) {
2009-01-31 15:36:09 +03:00
return status ;
}
2010-06-16 17:03:37 +04:00
DEBUG ( 10 , ( " Received %d bytes. There is %smore data outstanding \n " ,
( int ) state - > nread , state - > is_data_outstanding ? " " : " no " ) ) ;
2009-01-31 15:36:09 +03:00
* nread = state - > nread ;
* is_data_outstanding = state - > is_data_outstanding ;
return NT_STATUS_OK ;
}