[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Tue Aug 7 12:30:03 MDT 2012
The branch, master has been updated
via c301691 s3:smb2_server: fix SMB2 signing of compound responses
via 40f771e s3:smb2_server: there's no need to copy req->out.vector when we just keep the last request
via 8d63efe s3:smb2_server: use memmove instead of copying single vector elements
via 9b8973d s3:smb2_server: make use of SMBD_SMB2_OUT_HDR_PTR() smbd_smb2_request_pending_queue()
via bfc87a4 s3:smb2_server: check for compound based on SMBD_SMB2_NUM_IOV_PER_REQ
via 5730272 s3:smb2_server: make use of SMBD_SMB2_OUT_*_IOV smbd_smb2_request_reply()
via 727b1d1 s3:smb2_server: check for compound based on SMBD_SMB2_NUM_IOV_PER_REQ
via 2da6217 s3:smb2_server: make use of SMBD_SMB2_*_IOV_OFS
via d609bb9 s3:smb2_server: make use of helper macros in smb2_calculate_credits()
via efaea8e s3:smb2_server: make use of helper macros in smbd_smb2_request_validate()
via 4e6e1ec s3:smb2_server: make use of SMBD_SMB2_NUM_IOV_PER_REQ
via 337604a s3:smb2_server: add some more SMBD_SMB2_* defines/macros
from d825adf s3-param: Remove never-reached condition for popts == NULL
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit c3016915a1ea381976b747c4e185d4046e7995ca
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 14:24:28 2012 +0200
s3:smb2_server: fix SMB2 signing of compound responses
We need to defer the signing until we know the response
doesn't change anymore before it goes over the wire.
metze
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Tue Aug 7 20:29:30 CEST 2012 on sn-devel-104
commit 40f771e0105a0d13d83d66d99d9412acf6b73978
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 13:02:14 2012 +0200
s3:smb2_server: there's no need to copy req->out.vector when we just keep the last request
metze
commit 8d63efe27397f0f45b774e04e6146f87a84ba799
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 13:00:50 2012 +0200
s3:smb2_server: use memmove instead of copying single vector elements
metze
commit 9b8973d3b528169bf70a57f3cc17f35e51dfc81e
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:57:14 2012 +0200
s3:smb2_server: make use of SMBD_SMB2_OUT_HDR_PTR() smbd_smb2_request_pending_queue()
metze
commit bfc87a4a76294b26f6031547e18228afd4d535e5
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:56:23 2012 +0200
s3:smb2_server: check for compound based on SMBD_SMB2_NUM_IOV_PER_REQ
metze
commit 5730272690b5f4d854a4c7e8b0d68040b159d6aa
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:55:28 2012 +0200
s3:smb2_server: make use of SMBD_SMB2_OUT_*_IOV smbd_smb2_request_reply()
metze
commit 727b1d1fa867e1421cc01f4eee95f8001d315a12
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:47:44 2012 +0200
s3:smb2_server: check for compound based on SMBD_SMB2_NUM_IOV_PER_REQ
metze
commit 2da62179de7d2547703ff6ae78f80518abed91b8
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:41:07 2012 +0200
s3:smb2_server: make use of SMBD_SMB2_*_IOV_OFS
metze
commit d609bb9b4201f50322278e949fe036fe70c1e77f
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:31:36 2012 +0200
s3:smb2_server: make use of helper macros in smb2_calculate_credits()
metze
commit efaea8e0e1ca389ac7bd82f2d9a3401f92094fe4
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:30:54 2012 +0200
s3:smb2_server: make use of helper macros in smbd_smb2_request_validate()
metze
commit 4e6e1ecb6eb948c9651c6a1e17319c75191a1bac
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:26:38 2012 +0200
s3:smb2_server: make use of SMBD_SMB2_NUM_IOV_PER_REQ
metze
commit 337604a0cff2c4a09b4e29b88650149db897b8b2
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 12:22:06 2012 +0200
s3:smb2_server: add some more SMBD_SMB2_* defines/macros
metze
-----------------------------------------------------------------------
Summary of changes:
source3/smbd/globals.h | 34 ++++++-
source3/smbd/smb2_server.c | 228 +++++++++++++++++++++++++++-----------------
2 files changed, 169 insertions(+), 93 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 967fe85..7b2d31d 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -460,6 +460,12 @@ struct smbd_smb2_request {
bool cancelled;
bool compound_related;
+ /*
+ * the signing/encryption key for the last
+ * request/response of a compound chain
+ */
+ DATA_BLOB last_key;
+
struct timeval request_time;
/* fake smb1 request. */
@@ -474,21 +480,37 @@ struct smbd_smb2_request {
*/
struct tevent_req *subreq;
-#define SMBD_SMB2_IN_HDR_IOV(req) (&req->in.vector[req->current_idx+0])
+#define SMBD_SMB2_HDR_IOV_OFS 0
+#define SMBD_SMB2_BODY_IOV_OFS 1
+#define SMBD_SMB2_DYN_IOV_OFS 2
+
+#define SMBD_SMB2_NUM_IOV_PER_REQ 3
+
+#define SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,ofs) \
+ (&req->dir.vector[(idx)+(ofs)])
+
+#define SMBD_SMB2_IDX_HDR_IOV(req,dir,idx) \
+ SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,SMBD_SMB2_HDR_IOV_OFS)
+#define SMBD_SMB2_IDX_BODY_IOV(req,dir,idx) \
+ SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,SMBD_SMB2_BODY_IOV_OFS)
+#define SMBD_SMB2_IDX_DYN_IOV(req,dir,idx) \
+ SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,SMBD_SMB2_DYN_IOV_OFS)
+
+#define SMBD_SMB2_IN_HDR_IOV(req) SMBD_SMB2_IDX_HDR_IOV(req,in,req->current_idx)
#define SMBD_SMB2_IN_HDR_PTR(req) (uint8_t *)(SMBD_SMB2_IN_HDR_IOV(req)->iov_base)
-#define SMBD_SMB2_IN_BODY_IOV(req) (&req->in.vector[req->current_idx+1])
+#define SMBD_SMB2_IN_BODY_IOV(req) SMBD_SMB2_IDX_BODY_IOV(req,in,req->current_idx)
#define SMBD_SMB2_IN_BODY_PTR(req) (uint8_t *)(SMBD_SMB2_IN_BODY_IOV(req)->iov_base)
#define SMBD_SMB2_IN_BODY_LEN(req) (SMBD_SMB2_IN_BODY_IOV(req)->iov_len)
-#define SMBD_SMB2_IN_DYN_IOV(req) (&req->in.vector[req->current_idx+2])
+#define SMBD_SMB2_IN_DYN_IOV(req) SMBD_SMB2_IDX_DYN_IOV(req,in,req->current_idx)
#define SMBD_SMB2_IN_DYN_PTR(req) (uint8_t *)(SMBD_SMB2_IN_DYN_IOV(req)->iov_base)
#define SMBD_SMB2_IN_DYN_LEN(req) (SMBD_SMB2_IN_DYN_IOV(req)->iov_len)
-#define SMBD_SMB2_OUT_HDR_IOV(req) (&req->out.vector[req->current_idx+0])
+#define SMBD_SMB2_OUT_HDR_IOV(req) SMBD_SMB2_IDX_HDR_IOV(req,out,req->current_idx)
#define SMBD_SMB2_OUT_HDR_PTR(req) (uint8_t *)(SMBD_SMB2_OUT_HDR_IOV(req)->iov_base)
-#define SMBD_SMB2_OUT_BODY_IOV(req) (&req->out.vector[req->current_idx+1])
+#define SMBD_SMB2_OUT_BODY_IOV(req) SMBD_SMB2_IDX_BODY_IOV(req,out,req->current_idx)
#define SMBD_SMB2_OUT_BODY_PTR(req) (uint8_t *)(SMBD_SMB2_OUT_BODY_IOV(req)->iov_base)
#define SMBD_SMB2_OUT_BODY_LEN(req) (SMBD_SMB2_OUT_BODY_IOV(req)->iov_len)
-#define SMBD_SMB2_OUT_DYN_IOV(req) (&req->out.vector[req->current_idx+2])
+#define SMBD_SMB2_OUT_DYN_IOV(req) SMBD_SMB2_IDX_DYN_IOV(req,out,req->current_idx)
#define SMBD_SMB2_OUT_DYN_PTR(req) (uint8_t *)(SMBD_SMB2_OUT_DYN_IOV(req)->iov_base)
#define SMBD_SMB2_OUT_DYN_LEN(req) (SMBD_SMB2_OUT_DYN_IOV(req)->iov_len)
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 4e3259a..afd001c 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -235,6 +235,12 @@ static void smb2_setup_nbt_length(struct iovec *vector, int count)
_smb2_setlen(vector[0].iov_base, len);
}
+static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
+{
+ data_blob_clear_free(&req->last_key);
+ return 0;
+}
+
static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
{
TALLOC_CTX *mem_pool;
@@ -261,6 +267,8 @@ static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
req->last_session_id = UINT64_MAX;
req->last_tid = UINT32_MAX;
+ talloc_set_destructor(req, smbd_smb2_request_destructor);
+
return req;
}
@@ -292,6 +300,9 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn,
size_t full_size;
size_t next_command_ofs;
uint16_t body_size;
+ uint8_t *body = NULL;
+ uint32_t dyn_size;
+ uint8_t *dyn = NULL;
struct iovec *iov_tmp;
/*
@@ -338,23 +349,26 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn,
*/
body_size = full_size - SMB2_HDR_BODY;
}
+ body = hdr + SMB2_HDR_BODY;
+ dyn = body + body_size;
+ dyn_size = full_size - (SMB2_HDR_BODY + body_size);
iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
- num_iov + 3);
+ num_iov + SMBD_SMB2_NUM_IOV_PER_REQ);
if (iov_tmp == NULL) {
TALLOC_FREE(iov);
return NT_STATUS_NO_MEMORY;
}
iov = iov_tmp;
cur = &iov[num_iov];
- num_iov += 3;
+ num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
- cur[0].iov_base = hdr;
- cur[0].iov_len = SMB2_HDR_BODY;
- cur[1].iov_base = hdr + SMB2_HDR_BODY;
- cur[1].iov_len = body_size;
- cur[2].iov_base = hdr + SMB2_HDR_BODY + body_size;
- cur[2].iov_len = full_size - (SMB2_HDR_BODY + body_size);
+ cur[SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
+ cur[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
+ cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
+ cur[SMBD_SMB2_BODY_IOV_OFS].iov_len = body_size;
+ cur[SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
+ cur[SMBD_SMB2_DYN_IOV_OFS].iov_len = dyn_size;
taken += full_size;
}
@@ -584,24 +598,26 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
count = req->in.vector_count;
- if (count < 4) {
+ if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
/* It's not a SMB2 request */
return NT_STATUS_INVALID_PARAMETER;
}
- for (idx=1; idx < count; idx += 3) {
+ for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
+ struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
+ struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
const uint8_t *inhdr = NULL;
uint32_t flags;
- if (req->in.vector[idx].iov_len != SMB2_HDR_BODY) {
+ if (hdr->iov_len != SMB2_HDR_BODY) {
return NT_STATUS_INVALID_PARAMETER;
}
- if (req->in.vector[idx+1].iov_len < 2) {
+ if (body->iov_len < 2) {
return NT_STATUS_INVALID_PARAMETER;
}
- inhdr = (const uint8_t *)req->in.vector[idx].iov_base;
+ inhdr = (const uint8_t *)hdr->iov_base;
/* Check the SMB2 header */
if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
@@ -799,16 +815,18 @@ static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
count = outreq->out.vector_count;
- for (idx=1; idx < count; idx += 3) {
- uint8_t *outhdr = (uint8_t *)outreq->out.vector[idx].iov_base;
- smb2_set_operation_credit(outreq->sconn,
- &inreq->in.vector[idx],
- &outreq->out.vector[idx]);
+ for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
+ struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
+ struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
+ uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
+
+ smb2_set_operation_credit(outreq->sconn, inhdr_v, outhdr_v);
+
/* To match Windows, count up what we
just granted. */
total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
/* Set to zero in all but the last reply. */
- if (idx + 3 < count) {
+ if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
} else {
SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
@@ -832,21 +850,20 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
vector[0].iov_len = 4;
SIVAL(req->out.nbt_hdr, 0, 0);
- for (idx=1; idx < count; idx += 3) {
- const uint8_t *inhdr = NULL;
+ for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
+ struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
+ const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
uint8_t *outhdr = NULL;
uint8_t *outbody = NULL;
uint32_t next_command_ofs = 0;
struct iovec *current = &vector[idx];
- if ((idx + 3) < count) {
+ if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
/* we have a next command -
* setup for the error case. */
next_command_ofs = SMB2_HDR_BODY + 9;
}
- inhdr = (const uint8_t *)req->in.vector[idx].iov_base;
-
outhdr = talloc_zero_array(vector, uint8_t,
OUTVEC_ALLOC_SIZE);
if (outhdr == NULL) {
@@ -855,14 +872,14 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
outbody = outhdr + SMB2_HDR_BODY;
- current[0].iov_base = (void *)outhdr;
- current[0].iov_len = SMB2_HDR_BODY;
+ current[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)outhdr;
+ current[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
- current[1].iov_base = (void *)outbody;
- current[1].iov_len = 8;
+ current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
+ current[SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
- current[2].iov_base = NULL;
- current[2].iov_len = 0;
+ current[SMBD_SMB2_DYN_IOV_OFS].iov_base = NULL;
+ current[SMBD_SMB2_DYN_IOV_OFS].iov_len = 0;
/* setup the SMB2 header */
SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
@@ -1013,7 +1030,7 @@ static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *re
memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
/* Setup the vectors identically to the ones in req. */
- for (i = 1; i < count; i += 3) {
+ for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
if (!dup_smb2_vec3(outvec, &outvec[i], &req->out.vector[i])) {
break;
}
@@ -1035,9 +1052,11 @@ static void smbd_smb2_request_writev_done(struct tevent_req *subreq);
static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
{
- int i = 0;
+ struct smbXsrv_connection *conn = req->sconn->conn;
+ struct iovec *outhdr_v = NULL;
uint8_t *outhdr = NULL;
struct smbd_smb2_request *nreq = NULL;
+ NTSTATUS status;
/* Create a new smb2 request we'll use
for the interim return. */
@@ -1046,36 +1065,37 @@ static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request
return NT_STATUS_NO_MEMORY;
}
- /* Lose the last 3 out vectors. They're the
+ /* Lose the last X out vectors. They're the
ones we'll be using for the async reply. */
- nreq->out.vector_count -= 3;
+ nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
smb2_setup_nbt_length(nreq->out.vector,
nreq->out.vector_count);
/* Step back to the previous reply. */
- i = nreq->current_idx - 3;
- outhdr = (uint8_t *)nreq->out.vector[i].iov_base;
+ nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
+ outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
+ outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
/* And end the chain. */
SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
/* Calculate outgoing credits */
smb2_calculate_credits(req, nreq);
- /* Re-sign if needed. */
- if (nreq->do_signing) {
- NTSTATUS status;
- struct smbXsrv_session *x = nreq->session;
- struct smbXsrv_connection *conn = x->connection;
- DATA_BLOB signing_key = x->global->channels[0].signing_key;
-
- status = smb2_signing_sign_pdu(signing_key,
+ /*
+ * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
+ * we need to sign here with the last signing key we remembered
+ */
+ if (req->last_key.length > 0) {
+ status = smb2_signing_sign_pdu(req->last_key,
conn->protocol,
- &nreq->out.vector[i], 3);
+ outhdr_v,
+ SMBD_SMB2_NUM_IOV_PER_REQ);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
+
if (DEBUGLEVEL >= 10) {
dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
(unsigned int)nreq->current_idx );
@@ -1161,7 +1181,7 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
return NT_STATUS_OK;
}
- if (req->in.vector_count > i + 3) {
+ if (req->in.vector_count > i + SMBD_SMB2_NUM_IOV_PER_REQ) {
/*
* We're trying to go async in a compound
* request chain. This is not allowed.
@@ -1178,10 +1198,9 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
print_req_vectors(req);
}
- if (req->out.vector_count > 4) {
- struct iovec *outvec = NULL;
-
- /* This is a compound reply. We
+ if (req->out.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ)) {
+ /*
+ * This is a compound reply. We
* must do an interim response
* followed by the async response
* to match W2K8R2.
@@ -1205,43 +1224,28 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
req->compound_related = false;
req->sconn->smb2.compound_related_in_progress = false;
+ req->current_idx = 1;
+
/* Re-arrange the in.vectors. */
- req->in.vector[1] = req->in.vector[i];
- req->in.vector[2] = req->in.vector[i+1];
- req->in.vector[3] = req->in.vector[i+2];
- req->in.vector_count = 4;
+ memmove(&req->in.vector[req->current_idx],
+ &req->in.vector[i],
+ sizeof(req->in.vector[0])*SMBD_SMB2_NUM_IOV_PER_REQ);
+ req->in.vector_count = req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ;
/* Reset the new in size. */
- smb2_setup_nbt_length(req->in.vector, 4);
-
- /* Now recreate the out.vectors. */
- outvec = talloc_zero_array(req, struct iovec, 4);
- if (!outvec) {
- return NT_STATUS_NO_MEMORY;
- }
-
- /* 0 is always boilerplate and must
- * be of size 4 for the length field. */
-
- outvec[0].iov_base = req->out.nbt_hdr;
- outvec[0].iov_len = 4;
- SIVAL(req->out.nbt_hdr, 0, 0);
-
- if (!dup_smb2_vec3(outvec, &outvec[1], &req->out.vector[i])) {
- return NT_STATUS_NO_MEMORY;
- }
-
- TALLOC_FREE(req->out.vector);
+ smb2_setup_nbt_length(req->in.vector, req->in.vector_count);
- req->out.vector = outvec;
-
- req->current_idx = 1;
- req->out.vector_count = 4;
+ /* Re-arrange the out.vectors. */
+ memmove(&req->out.vector[req->current_idx],
+ &req->out.vector[i],
+ sizeof(req->out.vector[0])*SMBD_SMB2_NUM_IOV_PER_REQ);
+ req->out.vector_count = req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ;
- outhdr = (uint8_t *)req->out.vector[1].iov_base;
+ outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
}
+ data_blob_clear_free(&req->last_key);
defer_endtime = timeval_current_ofs_usec(defer_time);
req->async_te = tevent_add_timer(req->sconn->ev_ctx,
@@ -1749,7 +1753,8 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
req->do_signing = true;
status = smb2_signing_check_pdu(signing_key,
conn->protocol,
- SMBD_SMB2_IN_HDR_IOV(req), 3);
+ SMBD_SMB2_IN_HDR_IOV(req),
+ SMBD_SMB2_NUM_IOV_PER_REQ);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
@@ -1968,13 +1973,23 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
{
+ struct smbXsrv_connection *conn = req->sconn->conn;
struct tevent_req *subreq;
- int i = req->current_idx;
+ struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
+ struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
+ struct iovec *lasthdr = NULL;
req->subreq = NULL;
TALLOC_FREE(req->async_te);
- req->current_idx += 3;
+ if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
+ (req->last_key.length > 0)) {
+ int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
+
+ lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
+ }
+
+ req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
if (req->current_idx < req->out.vector_count) {
/*
@@ -1989,6 +2004,25 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
if (!im) {
return NT_STATUS_NO_MEMORY;
}
+
+ data_blob_clear_free(&req->last_key);
+
+ if (req->do_signing) {
+ struct smbXsrv_session *x = req->session;
+ DATA_BLOB signing_key = x->global->channels[0].signing_key;
+
+ /*
+ * we need to remember the signing key
+ * and defer the signing until
+ * we are sure that we do not change
+ * the header again.
+ */
+ req->last_key = data_blob_dup_talloc(req, signing_key);
+ if (req->last_key.data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
tevent_schedule_immediate(im,
req->sconn->ev_ctx,
smbd_smb2_request_dispatch_immediate,
@@ -2006,15 +2040,36 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
is a final reply for an async operation). */
smb2_calculate_credits(req, req);
+ /*
+ * As we are sure the header of the last request in the
+ * compound chain will not change, we can to sign here
+ * with the last signing key we remembered.
+ */
+ if (lasthdr != NULL) {
+ NTSTATUS status;
+
+ status = smb2_signing_sign_pdu(req->last_key,
+ conn->protocol,
+ lasthdr,
+ SMBD_SMB2_NUM_IOV_PER_REQ);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+ data_blob_clear_free(&req->last_key);
+
+ /*
+ * now check if we need to sign the current response
+ */
if (req->do_signing) {
NTSTATUS status;
struct smbXsrv_session *x = req->session;
- struct smbXsrv_connection *conn = x->connection;
DATA_BLOB signing_key = x->global->channels[0].signing_key;
status = smb2_signing_sign_pdu(signing_key,
conn->protocol,
- &req->out.vector[i], 3);
+ outhdr,
+ SMBD_SMB2_NUM_IOV_PER_REQ);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -2026,9 +2081,8 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
}
/* I am a sick, sick man... :-). Sendfile hack ... JRA. */
- if (req->out.vector_count == 4 &&
- req->out.vector[3].iov_base == NULL &&
- req->out.vector[3].iov_len != 0) {
+ if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
+ outdyn->iov_base == NULL && outdyn->iov_len != 0) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list