summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2012-02-28 01:21:44 +0100
committerVolker Lendecke <vl@samba.org>2012-03-10 15:34:12 +0100
commit11d087aa04f436147e7a9dd1748a43bde24de8e3 (patch)
treeecd269d06f41bee3c8616f6971978dfaaffb90b5
parent3b2c9bebc0aa08fe9a65afe5870bea490c5fb33a (diff)
downloadsamba-11d087aa04f436147e7a9dd1748a43bde24de8e3.tar.gz
samba-11d087aa04f436147e7a9dd1748a43bde24de8e3.tar.bz2
samba-11d087aa04f436147e7a9dd1748a43bde24de8e3.zip
s3: Remove chain_reply
<insert your favourite tombstone ascii art here>
-rw-r--r--source3/smbd/nttrans.c3
-rw-r--r--source3/smbd/pipes.c5
-rw-r--r--source3/smbd/process.c270
-rw-r--r--source3/smbd/proto.h1
-rw-r--r--source3/smbd/reply.c8
-rw-r--r--source3/smbd/sesssetup.c2
6 files changed, 0 insertions, 289 deletions
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
@@ -2248,261 +2233,6 @@ bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
}
/****************************************************************************
- 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;
}