From fcc4efd1ea637c810eed8444080b87d7f92c837a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Dec 2003 09:07:45 +0000 Subject: 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) --- source4/ntvfs/cifs/vfs_cifs.c | 8 +++ source4/ntvfs/ipc/vfs_ipc.c | 146 ++++++++++++++++++++++++++++++++++++-- source4/ntvfs/simple/vfs_simple.c | 7 ++ 3 files changed, 155 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') 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 */ -- cgit