diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-12-11 09:07:45 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-12-11 09:07:45 +0000 |
commit | fcc4efd1ea637c810eed8444080b87d7f92c837a (patch) | |
tree | 9f72b2b7b5780acc182e84532a54ae6dc26afb3a /source4 | |
parent | e5ed18db65f33ef0b0151fc34b02e049b14d1ecd (diff) | |
download | samba-fcc4efd1ea637c810eed8444080b87d7f92c837a.tar.gz samba-fcc4efd1ea637c810eed8444080b87d7f92c837a.tar.xz samba-fcc4efd1ea637c810eed8444080b87d7f92c837a.zip |
the next step in the dcerpc server code. Added the link between the
IPC IO routines and the dcerpc endpoint servers.
(This used to be commit 4929c53bc8dddda8a763fdfbcf81a79776d01113)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/include/ntvfs.h | 5 | ||||
-rw-r--r-- | source4/libcli/raw/rawtrans.c | 8 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_smb.c | 2 | ||||
-rw-r--r-- | source4/ntvfs/cifs/vfs_cifs.c | 8 | ||||
-rw-r--r-- | source4/ntvfs/ipc/vfs_ipc.c | 146 | ||||
-rw-r--r-- | source4/ntvfs/simple/vfs_simple.c | 7 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_server.c | 18 | ||||
-rw-r--r-- | source4/smbd/reply.c | 18 | ||||
-rw-r--r-- | source4/smbd/trans2.c | 53 |
9 files changed, 232 insertions, 33 deletions
diff --git a/source4/include/ntvfs.h b/source4/include/ntvfs.h index 6628402a97..88122166ee 100644 --- a/source4/include/ntvfs.h +++ b/source4/include/ntvfs.h @@ -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); }; diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index f31b1eaf7e..f7a3b4aa43 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -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); diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index 8a7a5ca68d..9acae00249 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -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; } diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c61749e2ad..ba2d6e7d24 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -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; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7ad02bb8cb..5ab608c46b 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -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); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 261ce4a19a..7972a3565a 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -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 */ diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c01dc4d9db..e1d6da2292 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -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 diff --git a/source4/smbd/reply.c b/source4/smbd/reply.c index 759ec1ef05..ce203cbf93 100644 --- a/source4/smbd/reply.c +++ b/source4/smbd/reply.c @@ -2169,24 +2169,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 ****************************************************************************/ void reply_findclose(struct request_context *req) diff --git a/source4/smbd/trans2.c b/source4/smbd/trans2.c index 0975f77eed..3115a330e5 100644 --- a/source4/smbd/trans2.c +++ b/source4/smbd/trans2.c @@ -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); +} + + |