summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c8
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c146
-rw-r--r--source4/ntvfs/simple/vfs_simple.c7
3 files changed, 155 insertions, 6 deletions
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 */