mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
the next step in the dcerpc server code. Added the link between the
IPC IO routines and the dcerpc endpoint servers.
This commit is contained in:
parent
c598590a11
commit
4929c53bc8
@ -75,8 +75,11 @@ struct ntvfs_ops {
|
||||
/* printing specific operations */
|
||||
NTSTATUS (*lpq)(struct request_context *req, union smb_lpq *lpq);
|
||||
|
||||
/* trans interfaces - only used by CIFS backend to prover complete passthru for testing */
|
||||
/* trans2 interface - only used by CIFS backend to prover complete passthru for testing */
|
||||
NTSTATUS (*trans2)(struct request_context *req, struct smb_trans2 *trans2);
|
||||
|
||||
/* trans interface - used by IPC backend for pipes and RAP calls */
|
||||
NTSTATUS (*trans)(struct request_context *req, struct smb_trans2 *trans);
|
||||
};
|
||||
|
||||
|
||||
|
@ -233,6 +233,11 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree,
|
||||
/* make sure we don't leak data via the padding */
|
||||
memset(req->out.data, 0, padding);
|
||||
|
||||
if (command == SMBtrans && parms->in.trans_name) {
|
||||
namelen = cli_req_append_string(req, parms->in.trans_name,
|
||||
STR_TERMINATE);
|
||||
}
|
||||
|
||||
/* primary request */
|
||||
SSVAL(req->out.vwv,VWV(0),parms->in.params.length);
|
||||
SSVAL(req->out.vwv,VWV(1),parms->in.data.length);
|
||||
@ -243,9 +248,6 @@ struct cli_request *smb_raw_trans_send_backend(struct cli_tree *tree,
|
||||
SIVAL(req->out.vwv,VWV(6),parms->in.timeout);
|
||||
SSVAL(req->out.vwv,VWV(8),0); /* reserved */
|
||||
SSVAL(req->out.vwv,VWV(9),parms->in.params.length);
|
||||
if (command == SMBtrans && parms->in.trans_name)
|
||||
namelen = cli_req_append_string(req, parms->in.trans_name,
|
||||
STR_TERMINATE);
|
||||
SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)+namelen);
|
||||
SSVAL(req->out.vwv,VWV(11),parms->in.data.length);
|
||||
SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)+namelen);
|
||||
|
@ -309,7 +309,7 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
|
||||
union smb_open io;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
asprintf(&name, "\\pipe\\%s", pipe_name);
|
||||
asprintf(&name, "\\%s", pipe_name);
|
||||
if (!name) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
@ -669,6 +669,13 @@ static NTSTATUS cvfs_trans2(struct request_context *req, struct smb_trans2 *tran
|
||||
ASYNC_RECV_TAIL(trans2, async_trans2);
|
||||
}
|
||||
|
||||
|
||||
/* SMBtrans - not used on file shares */
|
||||
static NTSTATUS cvfs_trans(struct request_context *req, struct smb_trans2 *trans2)
|
||||
{
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem
|
||||
*/
|
||||
@ -709,6 +716,7 @@ NTSTATUS ntvfs_cifs_init(void)
|
||||
ops.search_first = cvfs_search_first;
|
||||
ops.search_next = cvfs_search_next;
|
||||
ops.search_close = cvfs_search_close;
|
||||
ops.trans = cvfs_trans;
|
||||
|
||||
/* only define this one for trans2 testing */
|
||||
ops.trans2 = cvfs_trans2;
|
||||
|
@ -220,11 +220,9 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
|
||||
return NT_STATUS_TOO_MANY_OPENED_FILES;
|
||||
}
|
||||
|
||||
if (strncasecmp(p->pipe_name, "\\pipe\\", 6) != 0) {
|
||||
talloc_destroy(mem_ctx);
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
while (p->pipe_name[0] == '\\') {
|
||||
p->pipe_name++;
|
||||
}
|
||||
p->pipe_name += 6;
|
||||
|
||||
/*
|
||||
we're all set, now ask the dcerpc server subsystem to open the
|
||||
@ -293,7 +291,51 @@ static NTSTATUS ipc_copy(struct request_context *req, struct smb_copy *cp)
|
||||
*/
|
||||
static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd)
|
||||
{
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
struct ipc_private *private = req->conn->ntvfs_private;
|
||||
DATA_BLOB data;
|
||||
uint16 fnum;
|
||||
struct pipe_state *p;
|
||||
NTSTATUS status;
|
||||
|
||||
switch (rd->generic.level) {
|
||||
case RAW_READ_READ:
|
||||
fnum = rd->read.in.fnum;
|
||||
data.length = rd->read.in.count;
|
||||
data.data = rd->read.out.data;
|
||||
break;
|
||||
case RAW_READ_READX:
|
||||
fnum = rd->readx.in.fnum;
|
||||
data.length = rd->readx.in.maxcnt;
|
||||
data.data = rd->readx.out.data;
|
||||
break;
|
||||
default:
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
p = pipe_state_find(private, fnum);
|
||||
if (!p) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
status = dcesrv_output(p->pipe_state, &data);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (rd->generic.level) {
|
||||
case RAW_READ_READ:
|
||||
rd->read.out.nread = data.length;
|
||||
break;
|
||||
case RAW_READ_READX:
|
||||
rd->readx.out.remaining = 0;
|
||||
rd->readx.out.compaction_mode = 0;
|
||||
rd->readx.out.nread = data.length;
|
||||
break;
|
||||
default:
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -301,7 +343,52 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd)
|
||||
*/
|
||||
static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr)
|
||||
{
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
struct ipc_private *private = req->conn->ntvfs_private;
|
||||
DATA_BLOB data;
|
||||
uint16 fnum;
|
||||
struct pipe_state *p;
|
||||
NTSTATUS status;
|
||||
|
||||
switch (wr->generic.level) {
|
||||
case RAW_WRITE_WRITE:
|
||||
fnum = wr->write.in.fnum;
|
||||
data.data = wr->write.in.data;
|
||||
data.length = wr->write.in.count;
|
||||
break;
|
||||
|
||||
case RAW_WRITE_WRITEX:
|
||||
fnum = wr->writex.in.fnum;
|
||||
data.data = wr->writex.in.data;
|
||||
data.length = wr->writex.in.count;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
p = pipe_state_find(private, fnum);
|
||||
if (!p) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
status = dcesrv_input(p->pipe_state, &data);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (wr->generic.level) {
|
||||
case RAW_WRITE_WRITE:
|
||||
wr->write.out.nwritten = data.length;
|
||||
break;
|
||||
case RAW_WRITE_WRITEX:
|
||||
wr->writex.out.nwritten = data.length;
|
||||
wr->writex.out.remaining = 0;
|
||||
break;
|
||||
default:
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -421,6 +508,52 @@ NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *i
|
||||
}
|
||||
|
||||
|
||||
/* SMBtrans - used to provide access to SMB pipes */
|
||||
static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans)
|
||||
{
|
||||
struct pipe_state *p;
|
||||
struct ipc_private *private = req->conn->ntvfs_private;
|
||||
NTSTATUS status;
|
||||
|
||||
if (trans->in.setup_count != 2 ||
|
||||
trans->in.setup[0] != TRANSACT_DCERPCCMD) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* the fnum is in setup[1] */
|
||||
p = pipe_state_find(private, trans->in.setup[1]);
|
||||
if (!p) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* pass the data to the dcerpc server. Note that we don't
|
||||
expect this to fail, and things like NDR faults are not
|
||||
reported at this stage. Those sorts of errors happen in the
|
||||
dcesrv_output stage */
|
||||
status = dcesrv_input(p->pipe_state, &trans->in.data);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
now ask the dcerpc system for some output. This doesn't yet handle
|
||||
async calls. Again, we only expect NT_STATUS_OK. If the call fails then
|
||||
the error is encoded at the dcerpc level
|
||||
*/
|
||||
status = dcesrv_output(p->pipe_state, &trans->out.data);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
trans->out.setup_count = 0;
|
||||
trans->out.setup = NULL;
|
||||
trans->out.params = data_blob(NULL, 0);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
initialialise the IPC backend, registering ourselves with the ntvfs subsystem
|
||||
*/
|
||||
@ -460,6 +593,7 @@ NTSTATUS ntvfs_ipc_init(void)
|
||||
ops.search_first = ipc_search_first;
|
||||
ops.search_next = ipc_search_next;
|
||||
ops.search_close = ipc_search_close;
|
||||
ops.trans = ipc_trans;
|
||||
|
||||
/* register ourselves with the NTVFS subsystem. */
|
||||
ret = register_backend("ntvfs", &ops);
|
||||
|
@ -803,6 +803,12 @@ static NTSTATUS svfs_search_close(struct request_context *req, union smb_search_
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* SMBtrans - not used on file shares */
|
||||
static NTSTATUS svfs_trans(struct request_context *req, struct smb_trans2 *trans2)
|
||||
{
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem
|
||||
@ -844,6 +850,7 @@ NTSTATUS ntvfs_simple_init(void)
|
||||
ops.search_first = svfs_search_first;
|
||||
ops.search_next = svfs_search_next;
|
||||
ops.search_close = svfs_search_close;
|
||||
ops.trans = svfs_trans;
|
||||
|
||||
/* register ourselves with the NTVFS subsystem. We register under the name 'default'
|
||||
as we wish to be the default backend */
|
||||
|
@ -108,6 +108,24 @@ void dcesrv_endpoint_disconnect(struct dcesrv_state *p)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
provide some input to a dcerpc endpoint server. This passes data
|
||||
from a dcerpc client into the server
|
||||
*/
|
||||
NTSTATUS dcesrv_input(struct dcesrv_state *p, const DATA_BLOB *data)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
retrieve some output from a dcerpc server. The amount of data that
|
||||
is wanted is in data->length
|
||||
*/
|
||||
NTSTATUS dcesrv_output(struct dcesrv_state *p, DATA_BLOB *data)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
a useful function for implementing the query endpoint op
|
||||
|
@ -2168,24 +2168,6 @@ void reply_ulogoffX(struct request_context *req)
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an SMBtrans request
|
||||
****************************************************************************/
|
||||
void reply_trans(struct request_context *req)
|
||||
{
|
||||
req_reply_error(req, NT_STATUS_FOOBAR);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an SMBtranss2 request
|
||||
****************************************************************************/
|
||||
void reply_transs2(struct request_context *req)
|
||||
{
|
||||
req_reply_error(req, NT_STATUS_FOOBAR);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an SMBfindclose request
|
||||
****************************************************************************/
|
||||
|
@ -1214,10 +1214,20 @@ static NTSTATUS trans2_backend(struct request_context *req, struct smb_trans2 *t
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
backend for trans requests
|
||||
*/
|
||||
static NTSTATUS trans_backend(struct request_context *req, struct smb_trans2 *trans)
|
||||
{
|
||||
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an SMBtrans2 request
|
||||
Reply to an SMBtrans or SMBtrans2 request
|
||||
****************************************************************************/
|
||||
void reply_trans2(struct request_context *req)
|
||||
void reply_trans_generic(struct request_context *req, uint8 command)
|
||||
{
|
||||
struct smb_trans2 trans;
|
||||
int i;
|
||||
@ -1262,6 +1272,10 @@ void reply_trans2(struct request_context *req)
|
||||
trans.in.setup[i] = SVAL(req->in.vwv, VWV(14+i));
|
||||
}
|
||||
|
||||
if (command == SMBtrans) {
|
||||
req_pull_string(req, &trans.in.trans_name, req->in.data, -1, STR_TERMINATE);
|
||||
}
|
||||
|
||||
if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans.in.params) ||
|
||||
!req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans.in.data)) {
|
||||
req_reply_error(req, NT_STATUS_FOOBAR);
|
||||
@ -1271,12 +1285,16 @@ void reply_trans2(struct request_context *req)
|
||||
/* is it a partial request? if so, then send a 'send more' message */
|
||||
if (param_total > param_count ||
|
||||
data_total > data_count) {
|
||||
DEBUG(0,("REWRITE: not handling partial trans2 requests!\n"));
|
||||
DEBUG(0,("REWRITE: not handling partial trans requests!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* its a full request, give it to the backend */
|
||||
status = trans2_backend(req, &trans);
|
||||
if (command == SMBtrans) {
|
||||
status = trans_backend(req, &trans);
|
||||
} else {
|
||||
status = trans2_backend(req, &trans);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
req_reply_error(req, status);
|
||||
@ -1353,3 +1371,30 @@ void reply_trans2(struct request_context *req)
|
||||
req_send_reply(req);
|
||||
} while (params_left != 0 || data_left != 0);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an SMBtrans2
|
||||
****************************************************************************/
|
||||
void reply_trans2(struct request_context *req)
|
||||
{
|
||||
reply_trans_generic(req, SMBtrans2);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an SMBtrans
|
||||
****************************************************************************/
|
||||
void reply_trans(struct request_context *req)
|
||||
{
|
||||
reply_trans_generic(req, SMBtrans);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an SMBtranss2 request
|
||||
****************************************************************************/
|
||||
void reply_transs2(struct request_context *req)
|
||||
{
|
||||
req_reply_error(req, NT_STATUS_FOOBAR);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user