Revert "smbd: explain that/why we use the raw tevent_context for lease_timeout_handler()"
[garming/samba-autobuild/.git] / source3 / smbd / pipes.c
index 2ff3779b0e9720f4eec4bdc30698854ae2b80024..4be57bc2a5f0dea80515419bdaa2d8763be60958 100644 (file)
@@ -1,21 +1,21 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    Pipe SMB reply routines
    Copyright (C) Andrew Tridgell 1992-1998
    Copyright (C) Luke Kenneth Casson Leighton 1996-1998
    Copyright (C) Paul Ashton  1997-1998.
    Copyright (C) Jeremy Allison 2005.
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "libcli/security/security.h"
 #include "rpc_server/srv_pipe_hnd.h"
 
-#define        PIPE            "\\PIPE\\"
-#define        PIPELEN         strlen(PIPE)
-
-#define MAX_PIPE_NAME_LEN      24
-
 NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
                      struct files_struct **pfsp)
 {
@@ -56,11 +51,10 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
        fsp->can_lock = false;
        fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA;
 
-       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
-                                           &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
+       smb_fname = synthetic_smb_fname(talloc_tos(), name, NULL, NULL, 0);
+       if (smb_fname == NULL) {
                file_free(smb_req, fsp);
-               return status;
+               return NT_STATUS_NO_MEMORY;
        }
        status = fsp_set_smb_fname(fsp, smb_fname);
        TALLOC_FREE(smb_fname);
@@ -70,9 +64,10 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
        }
 
        status = np_open(fsp, name,
-                        conn->sconn->local_address,
                         conn->sconn->remote_address,
+                        conn->sconn->local_address,
                         conn->session_info,
+                        conn->sconn->ev_ctx,
                         conn->sconn->msg_ctx,
                         &fsp->fake_file_handle);
        if (!NT_STATUS_IS_OK(status)) {
@@ -112,15 +107,24 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
        /* If the name doesn't start \PIPE\ then this is directed */
        /* at a mailslot or something we really, really don't understand, */
        /* not just something we really don't understand. */
-       if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) {
-               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+
+#define        PIPE            "PIPE\\"
+#define        PIPELEN         strlen(PIPE)
+
+       fname = pipe_name;
+       while (fname[0] == '\\') {
+               fname++;
+       }
+       if (!strnequal(fname, PIPE, PIPELEN)) {
+               reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
                return;
        }
+       fname += PIPELEN;
+       while (fname[0] == '\\') {
+               fname++;
+       }
 
-       DEBUG(4,("Opening pipe %s.\n", pipe_name));
-
-       /* Strip \PIPE\ off the name. */
-       fname = pipe_name + PIPELEN;
+       DEBUG(4,("Opening pipe %s => %s.\n", pipe_name, fname));
 
 #if 0
        /*
@@ -146,6 +150,9 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
        /* Prepare the reply */
        reply_outbuf(req, 15, 0);
 
+       SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
+       SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
+
        /* Mark the opened file as an existing named pipe in message mode. */
        SSVAL(req->outbuf,smb_vwv9,2);
        SSVAL(req->outbuf,smb_vwv10,0xc700);
@@ -156,9 +163,6 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
        SIVAL(req->outbuf, smb_vwv6, 0);        /* size */
        SSVAL(req->outbuf, smb_vwv8, 0);        /* rmode */
        SSVAL(req->outbuf, smb_vwv11, 0x0001);
-
-       chain_reply(req);
-       return;
 }
 
 /****************************************************************************
@@ -199,10 +203,10 @@ void reply_pipe_write(struct smb_request *req)
 
        data = req->buf + 3;
 
-       DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum,
+       DEBUG(6, ("reply_pipe_write: %s, name: %s len: %d\n", fsp_fnum_dbg(fsp),
                  fsp_str_dbg(fsp), (int)state->numtowrite));
 
-       subreq = np_write_send(state, server_event_context(),
+       subreq = np_write_send(state, req->sconn->ev_ctx,
                               fsp->fake_file_handle, data, state->numtowrite);
        if (subreq == NULL) {
                TALLOC_FREE(state);
@@ -242,7 +246,7 @@ static void pipe_write_done(struct tevent_req *subreq)
        DEBUG(3,("write-IPC nwritten=%d\n", (int)nwritten));
 
  send:
-       if (!srv_send_smb(req->sconn, (char *)req->outbuf,
+       if (!srv_send_smb(req->xconn, (char *)req->outbuf,
                          true, req->seqnum+1,
                          IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
                          &req->pcd)) {
@@ -295,8 +299,8 @@ void reply_pipe_write_and_X(struct smb_request *req)
                ((SVAL(req->vwv+7, 0) & (PIPE_START_MESSAGE|PIPE_RAW_MODE))
                 == (PIPE_START_MESSAGE|PIPE_RAW_MODE));
 
-       DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n",
-                 (int)fsp->fnum, fsp_str_dbg(fsp), (int)state->numtowrite));
+       DEBUG(6, ("reply_pipe_write_and_X: %s, name: %s len: %d\n",
+                 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp), (int)state->numtowrite));
 
        data = (const uint8_t *)smb_base(req->inbuf) + smb_doff;
 
@@ -318,7 +322,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
                state->numtowrite -= 2;
        }
 
-       subreq = np_write_send(state, server_event_context(),
+       subreq = np_write_send(state, req->sconn->ev_ctx,
                               fsp->fake_file_handle, data, state->numtowrite);
        if (subreq == NULL) {
                TALLOC_FREE(state);
@@ -354,18 +358,20 @@ static void pipe_write_andx_done(struct tevent_req *subreq)
 
        reply_outbuf(req, 6, 0);
 
+       SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
+       SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
+
        nwritten = (state->pipe_start_message_raw ? nwritten + 2 : nwritten);
        SSVAL(req->outbuf,smb_vwv2,nwritten);
 
        DEBUG(3,("writeX-IPC nwritten=%d\n", (int)nwritten));
 
  done:
-       chain_reply(req);
        /*
         * We must free here as the ownership of req was
         * moved to the connection struct in reply_pipe_write_and_X().
         */
-       TALLOC_FREE(req);
+       smb_request_done(req);
 }
 
 /****************************************************************************
@@ -393,7 +399,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
            is deliberate, instead we always return the next lump of
            data on the pipe */
 #if 0
-       uint32 smb_offs = IVAL(req->vwv+3, 0);
+       uint32_t smb_offs = IVAL(req->vwv+3, 0);
 #endif
 
        if (!fsp_is_np(fsp)) {
@@ -416,8 +422,12 @@ void reply_pipe_read_and_X(struct smb_request *req)
        state->smb_maxcnt = SVAL(req->vwv+5, 0);
        state->smb_mincnt = SVAL(req->vwv+6, 0);
 
-       reply_outbuf(req, 12, state->smb_maxcnt);
-       data = (uint8_t *)smb_buf(req->outbuf);
+       reply_outbuf(req, 12, state->smb_maxcnt + 1 /* padding byte */);
+       SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
+       SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
+       SCVAL(smb_buf(req->outbuf), 0, 0); /* padding byte */
+
+       data = (uint8_t *)smb_buf(req->outbuf) + 1 /* padding byte */;
 
        /*
         * We have to tell the upper layers that we're async.
@@ -425,7 +435,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
        state->outbuf = req->outbuf;
        req->outbuf = NULL;
 
-       subreq = np_read_send(state, server_event_context(),
+       subreq = np_read_send(state, req->sconn->ev_ctx,
                              fsp->fake_file_handle, data,
                              state->smb_maxcnt);
        if (subreq == NULL) {
@@ -449,6 +459,8 @@ static void pipe_read_andx_done(struct tevent_req *subreq)
        status = np_read_recv(subreq, &nread, &is_data_outstanding);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
+               NTSTATUS old = status;
+               status = nt_status_np_pipe(old);
                reply_nterror(req, status);
                goto done;
        }
@@ -456,7 +468,8 @@ static void pipe_read_andx_done(struct tevent_req *subreq)
        req->outbuf = state->outbuf;
        state->outbuf = NULL;
 
-       srv_set_message((char *)req->outbuf, 12, nread, False);
+       srv_set_message((char *)req->outbuf, 12, nread + 1 /* padding byte */,
+                       false);
 
 #if 0
        /*
@@ -474,20 +487,19 @@ static void pipe_read_andx_done(struct tevent_req *subreq)
 
        SSVAL(req->outbuf,smb_vwv5,nread);
        SSVAL(req->outbuf,smb_vwv6,
-             req_wct_ofs(req)
+             (smb_wct - 4)     /* offset from smb header to wct */
              + 1               /* the wct field */
              + 12 * sizeof(uint16_t) /* vwv */
-             + 2);             /* the buflen field */
-       SSVAL(req->outbuf,smb_vwv11,state->smb_maxcnt);
-  
+             + 2               /* the buflen field */
+             + 1);             /* padding byte */
+
        DEBUG(3,("readX-IPC min=%d max=%d nread=%d\n",
                 state->smb_mincnt, state->smb_maxcnt, (int)nread));
 
  done:
-       chain_reply(req);
        /*
         * We must free here as the ownership of req was
         * moved to the connection struct in reply_pipe_read_and_X().
         */
-       TALLOC_FREE(req);
+       smb_request_done(req);
 }