From 11d087aa04f436147e7a9dd1748a43bde24de8e3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 28 Feb 2012 01:21:44 +0100 Subject: s3: Remove chain_reply --- source3/smbd/nttrans.c | 3 - source3/smbd/pipes.c | 5 - source3/smbd/process.c | 270 ----------------------------------------------- source3/smbd/proto.h | 1 - source3/smbd/reply.c | 8 -- source3/smbd/sesssetup.c | 2 - 6 files changed, 289 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index b03e0997a2..fc52ee5be4 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -382,8 +382,6 @@ static void do_ntcreate_pipe_open(connection_struct *conn, } DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname)); - - chain_reply(req); } struct case_semantics_state { @@ -734,7 +732,6 @@ void reply_ntcreate_and_X(struct smb_request *req) DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, smb_fname_str_dbg(smb_fname))); - chain_reply(req); out: END_PROFILE(SMBntcreateX); return; diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index d567537ed6..b39c0f0e59 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -159,9 +159,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; } /**************************************************************************** @@ -366,7 +363,6 @@ static void pipe_write_andx_done(struct tevent_req *subreq) 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(). @@ -493,7 +489,6 @@ static void pipe_read_andx_done(struct tevent_req *subreq) 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(). diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 6167278fcb..8fb45123ad 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1852,21 +1852,6 @@ size_t req_wct_ofs(struct smb_request *req) return buf_size - 4; } -/* - * Hack around reply_nterror & friends not being aware of chained requests, - * generating illegal (i.e. wct==0) chain replies. - */ - -static void fixup_chain_error_packet(struct smb_request *req) -{ - uint8_t *outbuf = req->outbuf; - req->outbuf = NULL; - reply_outbuf(req, 2, 0); - memcpy(req->outbuf, outbuf, smb_wct); - TALLOC_FREE(outbuf); - SCVAL(req->outbuf, smb_vwv0, 0xff); -} - /** * @brief Find the smb_cmd offset of the last command pushed * @param[in] buf The buffer we're building up @@ -2247,261 +2232,6 @@ bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf, return true; } -/**************************************************************************** - Construct a chained reply and add it to the already made reply -****************************************************************************/ - -void chain_reply(struct smb_request *req) -{ - size_t smblen = smb_len(req->inbuf); - size_t already_used, length_needed; - uint8_t chain_cmd; - uint32_t chain_offset; /* uint32_t to avoid overflow */ - - uint8_t wct; - const uint16_t *vwv; - uint16_t buflen; - const uint8_t *buf; - - return; - - if (IVAL(req->outbuf, smb_rcls) != 0) { - fixup_chain_error_packet(req); - } - - /* - * Any of the AndX requests and replies have at least a wct of - * 2. vwv[0] is the next command, vwv[1] is the offset from the - * beginning of the SMB header to the next wct field. - * - * None of the AndX requests put anything valuable in vwv[0] and [1], - * so we can overwrite it here to form the chain. - */ - - if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) { - if (req->chain_outbuf == NULL) { - req->chain_outbuf = talloc_realloc( - req, req->outbuf, uint8_t, - smb_len(req->outbuf) + 4); - if (req->chain_outbuf == NULL) { - smb_panic("talloc failed"); - } - } - req->outbuf = NULL; - goto error; - } - - /* - * Here we assume that this is the end of the chain. For that we need - * to set "next command" to 0xff and the offset to 0. If we later find - * more commands in the chain, this will be overwritten again. - */ - - SCVAL(req->outbuf, smb_vwv0, 0xff); - SCVAL(req->outbuf, smb_vwv0+1, 0); - SSVAL(req->outbuf, smb_vwv1, 0); - - if (req->chain_outbuf == NULL) { - /* - * In req->chain_outbuf we collect all the replies. Start the - * chain by copying in the first reply. - * - * We do the realloc because later on we depend on - * talloc_get_size to determine the length of - * chain_outbuf. The reply_xxx routines might have - * over-allocated (reply_pipe_read_and_X used to be such an - * example). - */ - req->chain_outbuf = talloc_realloc( - req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4); - if (req->chain_outbuf == NULL) { - smb_panic("talloc failed"); - } - req->outbuf = NULL; - } else { - /* - * Update smb headers where subsequent chained commands - * may have updated them. - */ - SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid)); - SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid)); - - if (!smb_splice_chain(&req->chain_outbuf, req->outbuf)) { - goto error; - } - TALLOC_FREE(req->outbuf); - } - - /* - * We use the old request's vwv field to grab the next chained command - * and offset into the chained fields. - */ - - chain_cmd = CVAL(req->vwv+0, 0); - chain_offset = SVAL(req->vwv+1, 0); - - if (chain_cmd == 0xff) { - /* - * End of chain, no more requests from the client. So ship the - * replies. - */ - smb_setlen((char *)(req->chain_outbuf), - talloc_get_size(req->chain_outbuf) - 4); - - if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf, - true, req->seqnum+1, - IS_CONN_ENCRYPTED(req->conn) - ||req->encrypted, - &req->pcd)) { - exit_server_cleanly("chain_reply: srv_send_smb " - "failed."); - } - TALLOC_FREE(req->chain_outbuf); - req->done = true; - return; - } - - /* add a new perfcounter for this element of chain */ - SMB_PERFCOUNT_ADD(&req->pcd); - SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd); - SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen); - - /* - * Check if the client tries to fool us. The chain offset - * needs to point beyond the current request in the chain, it - * needs to strictly grow. Otherwise we might be tricked into - * an endless loop always processing the same request over and - * over again. We used to assume that vwv and the byte buffer - * array in a chain are always attached, but OS/2 the - * Write&X/Read&X chain puts the Read&X vwv array right behind - * the Write&X vwv chain. The Write&X bcc array is put behind - * the Read&X vwv array. So now we check whether the chain - * offset points strictly behind the previous vwv - * array. req->buf points right after the vwv array of the - * previous request. See - * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more - * information. - */ - - already_used = PTR_DIFF(req->buf, smb_base(req->inbuf)); - if (chain_offset <= already_used) { - goto error; - } - - /* - * Next check: Make sure the chain offset does not point beyond the - * overall smb request length. - */ - - length_needed = chain_offset+1; /* wct */ - if (length_needed > smblen) { - goto error; - } - - /* - * Now comes the pointer magic. Goal here is to set up req->vwv and - * req->buf correctly again to be able to call the subsequent - * switch_message(). The chain offset (the former vwv[1]) points at - * the new wct field. - */ - - wct = CVAL(smb_base(req->inbuf), chain_offset); - - /* - * Next consistency check: Make the new vwv array fits in the overall - * smb request. - */ - - length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */ - if (length_needed > smblen) { - goto error; - } - vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1); - - /* - * Now grab the new byte buffer.... - */ - - buflen = SVAL(vwv+wct, 0); - - /* - * .. and check that it fits. - */ - - length_needed += buflen; - if (length_needed > smblen) { - goto error; - } - buf = (const uint8_t *)(vwv+wct+1); - - req->cmd = chain_cmd; - req->wct = wct; - req->vwv = discard_const_p(uint16_t, vwv); - req->buflen = buflen; - req->buf = buf; - - switch_message(chain_cmd, req); - - if (req->outbuf == NULL) { - /* - * This happens if the chained command has suspended itself or - * if it has called srv_send_smb() itself. - */ - return; - } - - /* - * We end up here if the chained command was not itself chained or - * suspended, but for example a close() command. We now need to splice - * the chained commands' outbuf into the already built up chain_outbuf - * and ship the result. - */ - goto done; - - error: - /* - * We end up here if there's any error in the chain syntax. Report a - * DOS error, just like Windows does. - */ - reply_force_doserror(req, ERRSRV, ERRerror); - fixup_chain_error_packet(req); - - done: - /* - * This scary statement intends to set the - * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf - * to the value req->outbuf carries - */ - SSVAL(req->chain_outbuf, smb_flg2, - (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES) - | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)); - - /* - * Transfer the error codes from the subrequest to the main one - */ - SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls)); - SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err)); - - if (!smb_splice_chain(&req->chain_outbuf, req->outbuf)) { - exit_server_cleanly("chain_reply: smb_splice_chain failed\n"); - } - TALLOC_FREE(req->outbuf); - - smb_setlen((char *)(req->chain_outbuf), - talloc_get_size(req->chain_outbuf) - 4); - - show_msg((char *)(req->chain_outbuf)); - - if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf, - true, req->seqnum+1, - IS_CONN_ENCRYPTED(req->conn)||req->encrypted, - &req->pcd)) { - exit_server_cleanly("chain_reply: srv_send_smb failed."); - } - TALLOC_FREE(req->chain_outbuf); - req->done = true; -} - /**************************************************************************** Check if services need reloading. ****************************************************************************/ diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index e5dd762663..f4aa06b061 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -797,7 +797,6 @@ bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf, struct smbd_server_connection *sconn, bool encrypted, uint32_t seqnum, struct smb_request ***reqs, unsigned *num_reqs); -void chain_reply(struct smb_request *req); bool req_is_in_chain(struct smb_request *req); void smbd_process(struct tevent_context *ev_ctx, struct smbd_server_connection *sconn); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1b156b2acc..8b94396578 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -873,8 +873,6 @@ void reply_tcon_and_X(struct smb_request *req) END_PROFILE(SMBtconX); req->tid = conn->cnum; - chain_reply(req); - return; } /**************************************************************************** @@ -2065,7 +2063,6 @@ void reply_open_and_X(struct smb_request *req) SIVAL(req->outbuf, smb_vwv15, SEC_STD_ALL); } - chain_reply(req); out: TALLOC_FREE(smb_fname); END_PROFILE(SMBopenX); @@ -2106,7 +2103,6 @@ void reply_ulogoffX(struct smb_request *req) END_PROFILE(SMBulogoffX); req->vuid = UID_FIELD_INVALID; - chain_reply(req); } /**************************************************************************** @@ -3708,8 +3704,6 @@ nosendfile_read: DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n", fsp->fnum, (int)smb_maxcnt, (int)nread ) ); - - chain_reply(req); return; strict_unlock: @@ -4654,7 +4648,6 @@ void reply_write_and_X(struct smb_request *req) } END_PROFILE(SMBwriteX); - chain_reply(req); return; out: @@ -7853,7 +7846,6 @@ void reply_lockingX(struct smb_request *req) fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks)); END_PROFILE(SMBlockingX); - chain_reply(req); } #undef DBGC_CLASS diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index cc801364cd..6bc1260770 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -791,6 +791,4 @@ void reply_sesssetup_and_X(struct smb_request *req) sconn->smb1.sessions.done_sesssetup = true; END_PROFILE(SMBsesssetupX); - chain_reply(req); - return; } -- cgit