ntvfs_ipc => tsocket_npa...
authorStefan Metzmacher <metze@samba.org>
Tue, 17 Mar 2009 07:26:45 +0000 (08:26 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 2 Apr 2009 15:29:47 +0000 (17:29 +0200)
source4/ntvfs/ipc/vfs_ipc.c

index 2f05a86dfab882e90e43f626d5277b0197465d7c..fec98b4fd0bd2eaa18737875c60b9d70c4de7a44 100644 (file)
@@ -32,6 +32,7 @@
 #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
@@ -47,8 +48,9 @@ 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;
 };
 
@@ -193,18 +195,35 @@ 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 backend - used for MSRPC pipes
+  open a file - used for MSRPC pipes
 */
-static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
-                                struct ntvfs_request *req, const char *fname, 
-                                struct pipe_state **ps)
+static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
+                        struct ntvfs_request *req, union smb_open *oi)
 {
-       struct pipe_state *p;
        NTSTATUS status;
-       struct dcerpc_binding *ep_description;
+       struct pipe_state *p;
        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);
@@ -212,155 +231,96 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
        p = talloc(h, struct pipe_state);
        NT_STATUS_HAVE_NO_MEMORY(p);
 
-       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);
+       ret = tsocket_address_npa_client_local(req, &laddr);
+       if (ret != 0) {
 
-       p->handle = h;
-       p->ipc_state = 0x5ff;
+       }
 
-       /*
-         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);
+               //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) {
 
-       /* 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->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;
        p->ipriv = ipriv;
 
-       talloc_set_destructor(p, ipc_fd_destructor);
-
-       status = ntvfs_handle_set_backend_data(h, ipriv->ntvfs, p);
-       NT_STATUS_NOT_OK_RETURN(status);
-
-       *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;
+       ret = tsocket_address_create_socket(laddr, TSOCKET_TYPE_STREAM,
+                                           p, &p->np_sock);
+       if (ret != 0) {
 
-       status = ipc_open_generic(ntvfs, req, oi->ntcreatex.in.fname, &p);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
        }
 
-       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;
-}
-
-/*
-  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;
+       subreq = tsocket_connect_send(p->np_sock, p, raddr);
+       if (!subreq) {
 
-       status = ipc_open_generic(ntvfs, req, fname, &p);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
        }
+       tevent_req_set_callback(subreq, ipc_open_done, p);
 
-       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;
+       /*TODO: reply async */
 }
 
-/*
-  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)
+static void ipc_open_done(struct tevent_req *subreq)
 {
-       struct pipe_state *p;
-       NTSTATUS status;
 
-       status = ipc_open_generic(ntvfs, req, oi->smb2.in.fname, &p);
-       NT_STATUS_NOT_OK_RETURN(status);
+       int ret;
+       int sys_errno;
 
-       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;
+       ret = tsocket_connect_recv(subreq, &sys_errno);
+       if (ret != 0) {
 
-       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;
+       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)) {
+
+       }
 
        switch (oi->generic.level) {
        case RAW_OPEN_NTCREATEX:
-               status = ipc_open_ntcreatex(ntvfs, req, oi);
+               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;
                break;
        case RAW_OPEN_OPENX:
-               status = ipc_open_openx(ntvfs, req, oi);
+               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;
                break;
        case RAW_OPEN_SMB2:
-               status = ipc_open_smb2(ntvfs, req, oi);
+               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;
                break;
        default:
-               status = NT_STATUS_NOT_SUPPORTED;
                break;
        }
 
-       return status;
+       /*TODO: reply async */
 }
 
 /*
@@ -437,12 +397,22 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs,
                data.length = UINT16_MAX;
        }
 
-       if (data.length != 0) {
-               status = dcesrv_output(p->dce_conn, &data, ipc_readx_dcesrv_output);
-               if (NT_STATUS_IS_ERR(status)) {
-                       return status;
-               }
+       subreq = tsocket_readv_queue_send(p->read_queue,
+                                         req);
+       if (!subreq) {
+
        }
+       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;
@@ -474,15 +444,29 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_INVALID_HANDLE;
        }
 
-       status = dcesrv_input(p->dce_conn, &data);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       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) {
+
        }
 
        wr->writex.out.nwritten = data.length;
        wr->writex.out.remaining = 0;
 
-       return NT_STATUS_OK;
+       /* reply async */
 }
 
 /*
@@ -736,30 +720,22 @@ 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;
        }
 
-       /* 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;
-       }
+       p->num_trans++;
 
-       /*
-         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;
-       }
+       subreq = tsocket_writev_queue_send(p->write_queue, req);
+       if (!subreq) {
 
+       }
+       tevent_req_set_callback(subreq, ipc
        trans->out.setup_count = 0;
        trans->out.setup = NULL;
        trans->out.params = data_blob(NULL, 0);