s3: Remove chain_reply
authorVolker Lendecke <vl@samba.org>
Tue, 28 Feb 2012 00:21:44 +0000 (01:21 +0100)
committerVolker Lendecke <vl@samba.org>
Sat, 10 Mar 2012 14:34:12 +0000 (15:34 +0100)
<insert your favourite tombstone ascii art here>

source3/smbd/nttrans.c
source3/smbd/pipes.c
source3/smbd/process.c
source3/smbd/proto.h
source3/smbd/reply.c
source3/smbd/sesssetup.c

index b03e0997a2ce09f26a0e0c45f72e5756c6a6294a..fc52ee5be451f50adddc8fe46c30547d03a4e9ee 100644 (file)
@@ -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;
index d567537ed6144b0dfc19c099883c174a404b7936..b39c0f0e5959313d7afc0a26987d0ea3315f11fb 100644 (file)
@@ -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().
index 6167278fcb05da9debdae22bef44a5ee91c53955..8fb45123ada64780448830b314f0f417653d4e32 100644 (file)
@@ -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.
 ****************************************************************************/
index e5dd762663771c9c66f6841ceeab12a5289169d9..f4aa06b0610ef4ba9249e2d16bf5210dc3e0d4ec 100644 (file)
@@ -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);
index 1b156b2acc68c142399d14b1ef2e47045307975d..8b94396578697dfedce442ae9543408a6ec3b7ed 100644 (file)
@@ -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
index cc801364cd7f023908e1a7a7c0ad92c6bdcbaf1f..6bc1260770fbe50a9bb8eb19d94c74a875f3d843 100644 (file)
@@ -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;
 }