From: David Mulder Date: Tue, 15 Mar 2022 20:55:38 +0000 (-0600) Subject: smbd: Move reply_pipe_write_and_X to smb1_pipes.c X-Git-Tag: tevent-0.12.0~115 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d3713860f2a26bcefccfb51d7f8f0419f66eb7f;p=thirdparty%2Fsamba.git smbd: Move reply_pipe_write_and_X to smb1_pipes.c Signed-off-by: David Mulder Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2c4ee8995fe..0469f7f9844 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -240,125 +240,6 @@ static void pipe_write_done(struct tevent_req *subreq) TALLOC_FREE(req); } -/**************************************************************************** - Reply to a write and X. - - This code is basically stolen from reply_write_and_X with some - wrinkles to handle pipes. -****************************************************************************/ - -struct pipe_write_andx_state { - bool pipe_start_message_raw; - size_t numtowrite; -}; - -static void pipe_write_andx_done(struct tevent_req *subreq); - -void reply_pipe_write_and_X(struct smb_request *req) -{ - files_struct *fsp = file_fsp(req, SVAL(req->vwv+2, 0)); - int smb_doff = SVAL(req->vwv+11, 0); - const uint8_t *data; - struct pipe_write_andx_state *state; - struct tevent_req *subreq; - - if (!fsp_is_np(fsp)) { - reply_nterror(req, NT_STATUS_INVALID_HANDLE); - return; - } - - if (fsp->vuid != req->vuid) { - reply_nterror(req, NT_STATUS_INVALID_HANDLE); - return; - } - - state = talloc(req, struct pipe_write_andx_state); - if (state == NULL) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - req->async_priv = state; - - state->numtowrite = SVAL(req->vwv+10, 0); - state->pipe_start_message_raw = - ((SVAL(req->vwv+7, 0) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) - == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); - - 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; - - if (state->pipe_start_message_raw) { - /* - * For the start of a message in named pipe byte mode, - * the first two bytes are a length-of-pdu field. Ignore - * them (we don't trust the client). JRA. - */ - if (state->numtowrite < 2) { - DEBUG(0,("reply_pipe_write_and_X: start of message " - "set and not enough data sent.(%u)\n", - (unsigned int)state->numtowrite )); - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - - data += 2; - state->numtowrite -= 2; - } - - subreq = np_write_send(state, req->sconn->ev_ctx, - fsp->fake_file_handle, data, state->numtowrite); - if (subreq == NULL) { - TALLOC_FREE(state); - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - tevent_req_set_callback(subreq, pipe_write_andx_done, - talloc_move(req->conn, &req)); -} - -static void pipe_write_andx_done(struct tevent_req *subreq) -{ - struct smb_request *req = tevent_req_callback_data( - subreq, struct smb_request); - struct pipe_write_andx_state *state = talloc_get_type_abort( - req->async_priv, struct pipe_write_andx_state); - NTSTATUS status; - ssize_t nwritten = -1; - - status = np_write_recv(subreq, &nwritten); - TALLOC_FREE(subreq); - - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto done; - } - - /* Looks bogus to me now. Is this error message correct ? JRA. */ - if (nwritten != state->numtowrite) { - reply_nterror(req, NT_STATUS_ACCESS_DENIED); - goto done; - } - - 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: - /* - * We must free here as the ownership of req was - * moved to the connection struct in reply_pipe_write_and_X(). - */ - smb_request_done(req); -} - /**************************************************************************** Reply to a read and X. This code is basically stolen from reply_read_and_X with some diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 3c3e9a247fd..d21aa09985a 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -805,7 +805,6 @@ int register_homes_share(const char *username); NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, struct files_struct **pfsp); void reply_pipe_write(struct smb_request *req); -void reply_pipe_write_and_X(struct smb_request *req); void reply_pipe_read_and_X(struct smb_request *req); /* The following definitions come from smbd/posix_acls.c */ diff --git a/source3/smbd/smb1_pipes.c b/source3/smbd/smb1_pipes.c index 18e93a2c26d..2f83295a49c 100644 --- a/source3/smbd/smb1_pipes.c +++ b/source3/smbd/smb1_pipes.c @@ -115,3 +115,122 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) SSVAL(req->outbuf, smb_vwv8, 0); /* rmode */ SSVAL(req->outbuf, smb_vwv11, 0x0001); } + +/**************************************************************************** + Reply to a write and X. + + This code is basically stolen from reply_write_and_X with some + wrinkles to handle pipes. +****************************************************************************/ + +struct pipe_write_andx_state { + bool pipe_start_message_raw; + size_t numtowrite; +}; + +static void pipe_write_andx_done(struct tevent_req *subreq); + +void reply_pipe_write_and_X(struct smb_request *req) +{ + files_struct *fsp = file_fsp(req, SVAL(req->vwv+2, 0)); + int smb_doff = SVAL(req->vwv+11, 0); + const uint8_t *data; + struct pipe_write_andx_state *state; + struct tevent_req *subreq; + + if (!fsp_is_np(fsp)) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; + } + + if (fsp->vuid != req->vuid) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; + } + + state = talloc(req, struct pipe_write_andx_state); + if (state == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + req->async_priv = state; + + state->numtowrite = SVAL(req->vwv+10, 0); + state->pipe_start_message_raw = + ((SVAL(req->vwv+7, 0) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) + == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); + + 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; + + if (state->pipe_start_message_raw) { + /* + * For the start of a message in named pipe byte mode, + * the first two bytes are a length-of-pdu field. Ignore + * them (we don't trust the client). JRA. + */ + if (state->numtowrite < 2) { + DEBUG(0,("reply_pipe_write_and_X: start of message " + "set and not enough data sent.(%u)\n", + (unsigned int)state->numtowrite )); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + data += 2; + state->numtowrite -= 2; + } + + subreq = np_write_send(state, req->sconn->ev_ctx, + fsp->fake_file_handle, data, state->numtowrite); + if (subreq == NULL) { + TALLOC_FREE(state); + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + tevent_req_set_callback(subreq, pipe_write_andx_done, + talloc_move(req->conn, &req)); +} + +static void pipe_write_andx_done(struct tevent_req *subreq) +{ + struct smb_request *req = tevent_req_callback_data( + subreq, struct smb_request); + struct pipe_write_andx_state *state = talloc_get_type_abort( + req->async_priv, struct pipe_write_andx_state); + NTSTATUS status; + ssize_t nwritten = -1; + + status = np_write_recv(subreq, &nwritten); + TALLOC_FREE(subreq); + + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + goto done; + } + + /* Looks bogus to me now. Is this error message correct ? JRA. */ + if (nwritten != state->numtowrite) { + reply_nterror(req, NT_STATUS_ACCESS_DENIED); + goto done; + } + + 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: + /* + * We must free here as the ownership of req was + * moved to the connection struct in reply_pipe_write_and_X(). + */ + smb_request_done(req); +} diff --git a/source3/smbd/smb1_pipes.h b/source3/smbd/smb1_pipes.h index b8eb35e4a43..d86a7d3de1f 100644 --- a/source3/smbd/smb1_pipes.h +++ b/source3/smbd/smb1_pipes.h @@ -21,3 +21,4 @@ */ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req); +void reply_pipe_write_and_X(struct smb_request *req);