return true;
}
-static inline NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
+static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
{
int count;
int idx;
count = req->in.vector_count;
-// if (unlikely(count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ)) {
-// /* It's not a SMB2 request */
-// return NT_STATUS_INVALID_PARAMETER;
-// }
-//
+ if (unlikely(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 += 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);
+ struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
const uint8_t *inhdr = NULL;
bool ok;
-// if (unlikely(hdr->iov_len != SMB2_HDR_BODY)) {
-// return NT_STATUS_INVALID_PARAMETER;
-// }
-//
-// if (unlikely(body->iov_len < 2)) {
-// return NT_STATUS_INVALID_PARAMETER;
-// }
-//
+ if (unlikely(hdr->iov_len != SMB2_HDR_BODY)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (unlikely(body->iov_len < 2)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
inhdr = (const uint8_t *)hdr->iov_base;
-//
-// /* Check the SMB2 header */
-// if (unlikely(IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC)) {
-// return NT_STATUS_INVALID_PARAMETER;
-// }
+
+ /* Check the SMB2 header */
+ if (unlikely(IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
ok = smb2_validate_message_id(req->sconn, inhdr);
if (unlikely(!ok)) {
credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
-//
-// SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
-//
-// if (unlikely(sconn->smb2.max_credits < credit_charge)) {
-// smbd_server_connection_terminate(sconn,
-// "client error: credit charge > max credits\n");
-// return;
-// }
-//
-// if (out_flags & SMB2_HDR_FLAG_ASYNC) {
-// /*
-// * In case we already send an async interim
-// * response, we should not grant
-// * credits on the final response.
-// */
-// credits_granted = 0;
-// } else if (credits_requested > 0) {
-// uint16_t additional_max = 0;
-// uint16_t additional_credits = credits_requested - 1;
-//
-// switch (cmd) {
-// case SMB2_OP_NEGPROT:
-// break;
-// case SMB2_OP_SESSSETUP:
-// /*
-// * Windows 2012 RC1 starts to grant
-// * additional credits
-// * with a successful session setup
-// */
-// if (NT_STATUS_IS_OK(out_status)) {
-// additional_max = 32;
-// }
-// break;
-// default:
-// /*
-// * We match windows and only grant additional credits
-// * in chunks of 32.
-// */
-// additional_max = 32;
-// break;
-// }
-//
-// additional_credits = MIN(additional_credits, additional_max);
-//
-// credits_granted = credit_charge + additional_credits;
-// } else if (sconn->smb2.credits_granted == 0) {
-// /*
-// * Make sure the client has always at least one credit
-// */
-// credits_granted = 1;
-// }
-//
-// /*
-// * sequence numbers should not wrap
-// *
-// * 1. calculate the possible credits until
-// * the sequence numbers start to wrap on 64-bit.
-// *
-// * 2. UINT64_MAX is used for Break Notifications.
-// *
-// * 2. truncate the possible credits to the maximum
-// * credits we want to grant to the client in total.
-// *
-// * 3. remove the range we'll already granted to the client
-// * this makes sure the client consumes the lowest sequence
-// * number, before we can grant additional credits.
-// */
-// credits_possible = UINT64_MAX - sconn->smb2.seqnum_low;
-// if (credits_possible > 0) {
-// /* remove UINT64_MAX */
-// credits_possible -= 1;
-// }
-// credits_possible = MIN(credits_possible, current_max_credits);
-// credits_possible -= sconn->smb2.seqnum_range;
-//
-// credits_granted = MIN(credits_granted, credits_possible);
-//
- credits_granted = MAX(2,credit_charge);
+
+ SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
+
+ if (unlikely(sconn->smb2.max_credits < credit_charge)) {
+ smbd_server_connection_terminate(sconn,
+ "client error: credit charge > max credits\n");
+ return;
+ }
+
+ if (out_flags & SMB2_HDR_FLAG_ASYNC) {
+ /*
+ * In case we already send an async interim
+ * response, we should not grant
+ * credits on the final response.
+ */
+ credits_granted = 0;
+ } else if (credits_requested > 0) {
+ uint16_t additional_max = 0;
+ uint16_t additional_credits = credits_requested - 1;
+
+ switch (cmd) {
+ case SMB2_OP_NEGPROT:
+ break;
+ case SMB2_OP_SESSSETUP:
+ /*
+ * Windows 2012 RC1 starts to grant
+ * additional credits
+ * with a successful session setup
+ */
+ if (NT_STATUS_IS_OK(out_status)) {
+ additional_max = 32;
+ }
+ break;
+ default:
+ /*
+ * We match windows and only grant additional credits
+ * in chunks of 32.
+ */
+ additional_max = 32;
+ break;
+ }
+
+ additional_credits = MIN(additional_credits, additional_max);
+
+ credits_granted = credit_charge + additional_credits;
+ } else if (sconn->smb2.credits_granted == 0) {
+ /*
+ * Make sure the client has always at least one credit
+ */
+ credits_granted = 1;
+ }
+
+ /*
+ * sequence numbers should not wrap
+ *
+ * 1. calculate the possible credits until
+ * the sequence numbers start to wrap on 64-bit.
+ *
+ * 2. UINT64_MAX is used for Break Notifications.
+ *
+ * 2. truncate the possible credits to the maximum
+ * credits we want to grant to the client in total.
+ *
+ * 3. remove the range we'll already granted to the client
+ * this makes sure the client consumes the lowest sequence
+ * number, before we can grant additional credits.
+ */
+ credits_possible = UINT64_MAX - sconn->smb2.seqnum_low;
+ if (credits_possible > 0) {
+ /* remove UINT64_MAX */
+ credits_possible -= 1;
+ }
+ credits_possible = MIN(credits_possible, current_max_credits);
+ credits_possible -= sconn->smb2.seqnum_range;
+
+ credits_granted = MIN(credits_granted, credits_possible);
+
SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
sconn->smb2.credits_granted += credits_granted;
sconn->smb2.seqnum_range += credits_granted;
return;
}
- status = NT_STATUS_OK;//smbd_smb2_request_validate(req);
+ status = smbd_smb2_request_validate(req);
if (unlikely(!NT_STATUS_IS_OK(status))) {
smbd_server_connection_terminate(sconn, nt_errstr(status));
return;
DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
req->current_idx, req->in.vector_count));
- status = NT_STATUS_OK;//smbd_smb2_request_validate(req);
+ status = smbd_smb2_request_validate(req);
if (unlikely(!NT_STATUS_IS_OK(status))) {
return status;
}