Revert "ntvfs_ipc => tsocket_npa..."
authorStefan Metzmacher <metze@samba.org>
Wed, 18 Mar 2009 14:22:10 +0000 (15:22 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 2 Apr 2009 15:29:48 +0000 (17:29 +0200)
This reverts commit b9d1d9906f7a500bb7d3b2b0f3109c85b26a86cb.

source4/ntvfs/ipc/vfs_ipc.c

index fec98b4fd0bd2eaa18737875c60b9d70c4de7a44..2f05a86dfab882e90e43f626d5277b0197465d7c 100644 (file)
@@ -32,7 +32,6 @@
 #include "rpc_server/dcerpc_server.h"
 #include "libcli/raw/ioctl.h"
 #include "param/param.h"
-#include "../lib/tsocket/tsocket.h"
 
 /* this is the private structure used to keep the state of an open
    ipc$ connection. It needs to keep information about all open
@@ -48,9 +47,8 @@ struct ipc_private {
                struct ipc_private *ipriv;
                const char *pipe_name;
                struct ntvfs_handle *handle;
+               struct dcesrv_connection *dce_conn;
                uint16_t ipc_state;
-               uint16_t fmode;
-               struct tsocket_context *npipe;
        } *pipe_list;
 };
 
@@ -195,35 +193,18 @@ static struct socket_address *ipc_get_peer_addr(struct dcesrv_connection *dce_co
        return ntvfs_get_peer_addr(ipriv->ntvfs, mem_ctx);
 }
 
-static void ipc_open_done(struct tevent_req *subreq);
-
 /*
-  open a file - used for MSRPC pipes
+  open a file backend - used for MSRPC pipes
 */
-static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
-                        struct ntvfs_request *req, union smb_open *oi)
+static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
+                                struct ntvfs_request *req, const char *fname, 
+                                struct pipe_state **ps)
 {
-       NTSTATUS status;
        struct pipe_state *p;
+       NTSTATUS status;
+       struct dcerpc_binding *ep_description;
        struct ipc_private *ipriv = ntvfs->private_data;
        struct ntvfs_handle *h;
-       struct tsocket_address *laddr;
-       struct tsocket_address *raddr;
-
-       switch (oi->generic.level) {
-       case RAW_OPEN_NTCREATEX:
-               fname = oi->ntcreatex.in.fname);
-               break;
-       case RAW_OPEN_OPENX:
-               fname = oi->openx.in.fname;
-               break;
-       case RAW_OPEN_SMB2:
-               fname = oi->smb2.in.fname;
-               break;
-       default:
-               status = NT_STATUS_NOT_SUPPORTED;
-               break;
-       }
 
        status = ntvfs_handle_new(ntvfs, req, &h);
        NT_STATUS_NOT_OK_RETURN(status);
@@ -231,96 +212,155 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
        p = talloc(h, struct pipe_state);
        NT_STATUS_HAVE_NO_MEMORY(p);
 
-       while (fname[0] == '\\') fname++;
-
-       ret = tsocket_address_npa_client_local(req, &laddr);
-       if (ret != 0) {
-
-       }
-
-               //Vreturn ipc_rap_call(req, ntvfs->ctx->event_ctx, ntvfs->ctx->lp_ctx, trans);
-       ret = tsocket_address_npa_client_remote(req,
-                                               directory,
-                                               fname,
-                                               &laddr);
-       if (ret != 0) {
+       ep_description = talloc(req, struct dcerpc_binding);
+       NT_STATUS_HAVE_NO_MEMORY(ep_description);
 
-       }
+       while (fname[0] == '\\') fname++;
 
        p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname);
        NT_STATUS_HAVE_NO_MEMORY(p->pipe_name);
 
        p->handle = h;
        p->ipc_state = 0x5ff;
-       p->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
+
+       /*
+         we're all set, now ask the dcerpc server subsystem to open the 
+         endpoint. At this stage the pipe isn't bound, so we don't
+         know what interface the user actually wants, just that they want
+         one of the interfaces attached to this pipe endpoint.
+       */
+       ep_description->transport = NCACN_NP;
+       ep_description->endpoint = talloc_reference(ep_description, p->pipe_name);
+
+       /* The session info is refcount-increased in the 
+        * dcesrv_endpoint_search_connect() function
+        */
+       status = dcesrv_endpoint_search_connect(ipriv->dcesrv,
+                                               p,
+                                               ep_description, 
+                                               h->session_info,
+                                               ntvfs->ctx->event_ctx,
+                                               ntvfs->ctx->msg_ctx,
+                                               ntvfs->ctx->server_id,
+                                               0,
+                                               &p->dce_conn);
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       p->dce_conn->transport.private_data             = ipriv;
+       p->dce_conn->transport.report_output_data       = NULL;
+       p->dce_conn->transport.get_my_addr              = ipc_get_my_addr;
+       p->dce_conn->transport.get_peer_addr            = ipc_get_peer_addr;
+       
+       DLIST_ADD(ipriv->pipe_list, p);
+
        p->ipriv = ipriv;
 
-       ret = tsocket_address_create_socket(laddr, TSOCKET_TYPE_STREAM,
-                                           p, &p->np_sock);
-       if (ret != 0) {
+       talloc_set_destructor(p, ipc_fd_destructor);
 
-       }
+       status = ntvfs_handle_set_backend_data(h, ipriv->ntvfs, p);
+       NT_STATUS_NOT_OK_RETURN(status);
 
-       subreq = tsocket_connect_send(p->np_sock, p, raddr);
-       if (!subreq) {
+       *ps = p;
+       return NT_STATUS_OK;
+}
+
+/*
+  open a file with ntcreatex - used for MSRPC pipes
+*/
+static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs,
+                                  struct ntvfs_request *req, union smb_open *oi)
+{
+       struct pipe_state *p;
+       NTSTATUS status;
 
+       status = ipc_open_generic(ntvfs, req, oi->ntcreatex.in.fname, &p);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
-       tevent_req_set_callback(subreq, ipc_open_done, p);
 
-       /*TODO: reply async */
+       ZERO_STRUCT(oi->ntcreatex.out);
+       oi->ntcreatex.out.file.ntvfs= p->handle;
+       oi->ntcreatex.out.ipc_state = p->ipc_state;
+       oi->ntcreatex.out.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
+
+       return status;
 }
 
-static void ipc_open_done(struct tevent_req *subreq)
+/*
+  open a file with openx - used for MSRPC pipes
+*/
+static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs,
+                              struct ntvfs_request *req, union smb_open *oi)
 {
+       struct pipe_state *p;
+       NTSTATUS status;
+       const char *fname = oi->openx.in.fname;
+
+       status = ipc_open_generic(ntvfs, req, fname, &p);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       ZERO_STRUCT(oi->openx.out);
+       oi->openx.out.file.ntvfs= p->handle;
+       oi->openx.out.ftype     = 2;
+       oi->openx.out.devstate  = p->ipc_state;
+       
+       return status;
+}
 
-       int ret;
-       int sys_errno;
+/*
+  open a file with SMB2 Create - used for MSRPC pipes
+*/
+static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs,
+                             struct ntvfs_request *req, union smb_open *oi)
+{
+       struct pipe_state *p;
+       NTSTATUS status;
 
-       ret = tsocket_connect_recv(subreq, &sys_errno);
-       if (ret != 0) {
+       status = ipc_open_generic(ntvfs, req, oi->smb2.in.fname, &p);
+       NT_STATUS_NOT_OK_RETURN(status);
 
-       }
+       ZERO_STRUCT(oi->smb2.out);
+       oi->smb2.out.file.ntvfs         = p->handle;
+       oi->smb2.out.oplock_level       = oi->smb2.in.oplock_level;
+       oi->smb2.out.create_action      = NTCREATEX_ACTION_EXISTED;
+       oi->smb2.out.create_time        = 0;
+       oi->smb2.out.access_time        = 0;
+       oi->smb2.out.write_time         = 0;
+       oi->smb2.out.change_time        = 0;
+       oi->smb2.out.alloc_size         = 4096;
+       oi->smb2.out.size               = 0;
+       oi->smb2.out.file_attr          = FILE_ATTRIBUTE_NORMAL;
+       oi->smb2.out.reserved2          = 0;
 
-       DLIST_ADD(ipriv->pipe_list, p);
-       talloc_set_destructor(p, ipc_fd_destructor);
-       status = ntvfs_handle_set_backend_data(h, ipriv->ntvfs, p);
-       if (!NT_STATUS_IS_OK(status)) {
+       return status;
+}
 
-       }
+/*
+  open a file - used for MSRPC pipes
+*/
+static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
+                               struct ntvfs_request *req, union smb_open *oi)
+{
+       NTSTATUS status;
 
        switch (oi->generic.level) {
        case RAW_OPEN_NTCREATEX:
-               ZERO_STRUCT(oi->ntcreatex.out);
-               oi->ntcreatex.out.file.ntvfs= p->handle;
-               oi->ntcreatex.out.ipc_state = p->ipc_state;
-               oi->ntcreatex.out.file_type = p->file_type;
-FILE_TYPE_MESSAGE_MODE_PIPE;
+               status = ipc_open_ntcreatex(ntvfs, req, oi);
                break;
        case RAW_OPEN_OPENX:
-               ZERO_STRUCT(oi->openx.out);
-               oi->openx.out.file.ntvfs= p->handle;
-               oi->openx.out.ftype     = p->file_type;
-               oi->openx.out.devstate  = p->ipc_state;
+               status = ipc_open_openx(ntvfs, req, oi);
                break;
        case RAW_OPEN_SMB2:
-               ZERO_STRUCT(oi->smb2.out);
-               oi->smb2.out.file.ntvfs         = p->handle;
-               oi->smb2.out.oplock_level       = oi->smb2.in.oplock_level;
-               oi->smb2.out.create_action      = NTCREATEX_ACTION_EXISTED;
-               oi->smb2.out.create_time        = 0;
-               oi->smb2.out.access_time        = 0;
-               oi->smb2.out.write_time         = 0;
-               oi->smb2.out.change_time        = 0;
-               oi->smb2.out.alloc_size         = 4096;
-               oi->smb2.out.size               = 0;
-               oi->smb2.out.file_attr          = FILE_ATTRIBUTE_NORMAL;
-               oi->smb2.out.reserved2          = 0;
+               status = ipc_open_smb2(ntvfs, req, oi);
                break;
        default:
+               status = NT_STATUS_NOT_SUPPORTED;
                break;
        }
 
-       /*TODO: reply async */
+       return status;
 }
 
 /*
@@ -397,22 +437,12 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs,
                data.length = UINT16_MAX;
        }
 
-       subreq = tsocket_readv_queue_send(p->read_queue,
-                                         req);
-       if (!subreq) {
-
+       if (data.length != 0) {
+               status = dcesrv_output(p->dce_conn, &data, ipc_readx_dcesrv_output);
+               if (NT_STATUS_IS_ERR(status)) {
+                       return status;
+               }
        }
-       tevent_req_set_callback(subreq, ipc_read_done, req);
-
-       /* reply async */
-}
-
-static void ipc_read_done(struct tevent_req *subreq)
-{
-       int ret;
-       int sys_errno;
-
-       ret = tsocket_readv_queue_recv(subreq, &sys_errno);
 
        rd->readx.out.remaining = 0;
        rd->readx.out.compaction_mode = 0;
@@ -444,29 +474,15 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_INVALID_HANDLE;
        }
 
-       subreq = tsocket_writev_queue_send(p->write_queue, req);
-       if (!subreq) {
-
-       }
-       tevent_req_set_callback(subreq, ipc_write_done, req);
-
-       /* reply async */
-}
-
-static void ipc_write_done(struct tevent_req *subreq)
-{
-       int ret;
-       int sys_errno;
-
-       ret = tsocket_writev_queue_recv(subreq, &sys_errno);
-       if (ret != 0) {
-
+       status = dcesrv_input(p->dce_conn, &data);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        wr->writex.out.nwritten = data.length;
        wr->writex.out.remaining = 0;
 
-       /* reply async */
+       return NT_STATUS_OK;
 }
 
 /*
@@ -720,22 +736,30 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_INVALID_HANDLE;
        }
 
-       if (p->num_trans || p->num_reads) {
-               return NT_STATUS_PIPE_BUSY;
-       }
-
        trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data);
        if (!trans->out.data.data) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       p->num_trans++;
-
-       subreq = tsocket_writev_queue_send(p->write_queue, req);
-       if (!subreq) {
+       /* 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->dce_conn, &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->dce_conn, &trans->out.data, ipc_trans_dcesrv_output);
+       if (NT_STATUS_IS_ERR(status)) {
+               return status;
        }
-       tevent_req_set_callback(subreq, ipc
+
        trans->out.setup_count = 0;
        trans->out.setup = NULL;
        trans->out.params = data_blob(NULL, 0);