the next step in the dcerpc server code. Added the link between the
authorAndrew Tridgell <tridge@samba.org>
Thu, 11 Dec 2003 09:07:45 +0000 (09:07 +0000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 11 Dec 2003 09:07:45 +0000 (09:07 +0000)
IPC IO routines and the dcerpc endpoint servers.
(This used to be commit 4929c53bc8dddda8a763fdfbcf81a79776d01113)

source4/include/ntvfs.h
source4/libcli/raw/rawtrans.c
source4/librpc/rpc/dcerpc_smb.c
source4/ntvfs/cifs/vfs_cifs.c
source4/ntvfs/ipc/vfs_ipc.c
source4/ntvfs/simple/vfs_simple.c
source4/rpc_server/dcerpc_server.c
source4/smbd/reply.c
source4/smbd/trans2.c

index 6628402a970cb45ddf67a9c8055fe485b90a0373..88122166eefeb7c34f3027428a85fd2b1b646062 100644 (file)
@@ -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);
 };
 
 
index f31b1eaf7e453bdcd68cddd93b3ca7be4ed57055..f7a3b4aa43ede982386179a5b1bffd0c31c4faf9 100644 (file)
@@ -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);
index 8a7a5ca68de4d136fd1bfde508bd1ecffb0d9071..9acae002491270fc5125b3a535a597eb48964437 100644 (file)
@@ -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;
        }
index c61749e2ad5caf28fa98b97b5a916245e3881b63..ba2d6e7d24e828ca989a03960cf0774083a646a6 100644 (file)
@@ -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;
index 7ad02bb8cb5b47ac4078ad9d01619db4b56dc73e..5ab608c46b31f7b02925b0e0e4b6525c0efa784c 100644 (file)
@@ -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);
index 261ce4a19a9d3397bc16ec6473392570d10a7b6a..7972a3565a48b11b6ca8638923ca4dc012e3243b 100644 (file)
@@ -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 */
index c01dc4d9dbc07d16d7eeb12a6f1f4615828d1859..e1d6da2292ec33a7d9f8041793a94b7f316a07b9 100644 (file)
@@ -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
index 759ec1ef05636be5127143b914927acd48313ac7..ce203cbf9303a07a1362a716a76001b99d674989 100644 (file)
@@ -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
 ****************************************************************************/
index 0975f77eedbc23f0ac7c8915208967a93f44a6e8..3115a330e5a7271c28a0c28fff3f7d8bce00bf5d 100644 (file)
@@ -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);
+}
+
+