Split payload from smbd_smb2_send_break_state
authorSachin Prabhu <sprabhu@redhat.com>
Thu, 19 Sep 2019 16:19:25 +0000 (17:19 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 28 Jan 2020 12:26:51 +0000 (13:26 +0100)
Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
source3/smbd/smb2_server.c

index 2496bcf1775234976a189b1a84122e8f5ec19b69..f3d47a9e3884ff4a1556101250ee2fe62d0bfb65 100644 (file)
@@ -3539,6 +3539,15 @@ struct smbXsrv_connection
        return NULL;
 }
 
+struct smbd_smb2_send_break_state_payload {
+       struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
+       uint8_t nbt_hdr[NBT_HDR_SIZE];
+       uint8_t tf[SMB2_TF_HDR_SIZE];
+       uint8_t hdr[SMB2_HDR_BODY];
+       size_t body_len;
+       uint8_t body[1];
+};
+
 struct smbd_smb2_send_break_state {
        struct smbd_smb2_send_queue queue_entry;
        struct smbXsrv_pending_breaks break_queue_entry;
@@ -3547,19 +3556,15 @@ struct smbd_smb2_send_break_state {
        struct smbXsrv_connection *xconn;
        struct smbXsrv_session *session;
        struct smbXsrv_tcon *tcon;
-       uint8_t nbt_hdr[NBT_HDR_SIZE];
-       uint8_t tf[SMB2_TF_HDR_SIZE];
-       uint8_t hdr[SMB2_HDR_BODY];
-       struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
-       uint8_t body[1];
+
+       struct smbd_smb2_send_break_state_payload payload;
 };
 
 static NTSTATUS smbd_smb2_build_break_state_payload
                                (struct smbXsrv_connection *xconn,
                                 struct smbXsrv_session *session,
                                 struct smbXsrv_tcon *tcon,
-                                const uint8_t *body, size_t body_len,
-                                struct smbd_smb2_send_break_state *state)
+                                struct smbd_smb2_send_break_state_payload *payload)
 {
        bool do_encryption = false;
        uint64_t session_wire_id = 0;
@@ -3587,59 +3592,57 @@ static NTSTATUS smbd_smb2_build_break_state_payload
                }
        }
 
-       SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
-       SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
-       SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
-       SBVAL(state->tf, SMB2_TF_SESSION_ID, session_wire_id);
-
-       SIVAL(state->hdr, 0,                            SMB2_MAGIC);
-       SSVAL(state->hdr, SMB2_HDR_LENGTH,              SMB2_HDR_BODY);
-       SSVAL(state->hdr, SMB2_HDR_EPOCH,               0);
-       SIVAL(state->hdr, SMB2_HDR_STATUS,              0);
-       SSVAL(state->hdr, SMB2_HDR_OPCODE,              SMB2_OP_BREAK);
-       SSVAL(state->hdr, SMB2_HDR_CREDIT,              0);
-       SIVAL(state->hdr, SMB2_HDR_FLAGS,               SMB2_HDR_FLAG_REDIRECT);
-       SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND,        0);
-       SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID,          UINT64_MAX);
-       SIVAL(state->hdr, SMB2_HDR_PID,         0);
-       SIVAL(state->hdr, SMB2_HDR_TID,         0);
-       SBVAL(state->hdr, SMB2_HDR_SESSION_ID,          0);
-       memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
-
-       state->vector[0] = (struct iovec) {
-               .iov_base = state->nbt_hdr,
-               .iov_len  = sizeof(state->nbt_hdr)
+       SIVAL(payload->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
+       SBVAL(payload->tf, SMB2_TF_NONCE+0, nonce_low);
+       SBVAL(payload->tf, SMB2_TF_NONCE+8, nonce_high);
+       SBVAL(payload->tf, SMB2_TF_SESSION_ID, session_wire_id);
+
+       SIVAL(payload->hdr, 0,                          SMB2_MAGIC);
+       SSVAL(payload->hdr, SMB2_HDR_LENGTH,            SMB2_HDR_BODY);
+       SSVAL(payload->hdr, SMB2_HDR_EPOCH,             0);
+       SIVAL(payload->hdr, SMB2_HDR_STATUS,            0);
+       SSVAL(payload->hdr, SMB2_HDR_OPCODE,            SMB2_OP_BREAK);
+       SSVAL(payload->hdr, SMB2_HDR_CREDIT,            0);
+       SIVAL(payload->hdr, SMB2_HDR_FLAGS,             SMB2_HDR_FLAG_REDIRECT);
+       SIVAL(payload->hdr, SMB2_HDR_NEXT_COMMAND,      0);
+       SBVAL(payload->hdr, SMB2_HDR_MESSAGE_ID,                UINT64_MAX);
+       SIVAL(payload->hdr, SMB2_HDR_PID,               0);
+       SIVAL(payload->hdr, SMB2_HDR_TID,               0);
+       SBVAL(payload->hdr, SMB2_HDR_SESSION_ID,                0);
+       memset(payload->hdr+SMB2_HDR_SIGNATURE, 0, 16);
+
+       payload->vector[0] = (struct iovec) {
+               .iov_base = payload->nbt_hdr,
+               .iov_len  = sizeof(payload->nbt_hdr)
        };
 
        if (do_encryption) {
-               state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
-                       .iov_base = state->tf,
-                       .iov_len  = sizeof(state->tf)
+               payload->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
+                       .iov_base = payload->tf,
+                       .iov_len  = sizeof(payload->tf)
                };
        } else {
-               state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
+               payload->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
                        .iov_base = NULL,
                        .iov_len  = 0
                };
        }
 
-       state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
-               .iov_base = state->hdr,
-               .iov_len  = sizeof(state->hdr)
+       payload->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
+               .iov_base = payload->hdr,
+               .iov_len  = sizeof(payload->hdr)
        };
 
-       memcpy(state->body, body, body_len);
-
-       state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
-               .iov_base = state->body,
-               .iov_len  = body_len /* no sizeof(state->body) .. :-) */
+       payload->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
+               .iov_base = payload->body,
+               .iov_len  = payload->body_len /* no sizeof(payload->body) .. :-) */
        };
 
        /*
-        * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
+        * payload->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
         */
 
-       ok = smb2_setup_nbt_length(state->vector,
+       ok = smb2_setup_nbt_length(payload->vector,
                                   1 + SMBD_SMB2_NUM_IOV_PER_REQ);
        if (!ok) {
                return NT_STATUS_INVALID_PARAMETER_MIX;
@@ -3651,7 +3654,7 @@ static NTSTATUS smbd_smb2_build_break_state_payload
 
                status = smb2_signing_encrypt_pdu(encryption_key,
                                        xconn->smb2.server.cipher,
-                                       &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
+                                       &payload->vector[1+SMBD_SMB2_TF_IOV_OFS],
                                        SMBD_SMB2_NUM_IOV_PER_REQ);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
@@ -3676,16 +3679,20 @@ static NTSTATUS _smbd_smb2_send_break(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        size_t statelen;
 
-       statelen = offsetof(struct smbd_smb2_send_break_state, body)
-                                                               + body_len;
+       statelen = offsetof(struct smbd_smb2_send_break_state, payload)
+                  + offsetof(struct smbd_smb2_send_break_state_payload, body)
+                  + body_len;
+
        state = talloc_zero_size(client, statelen);
        if (state == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
        talloc_set_name_const(state, "struct smbd_smb2_send_break_state");
 
+       memcpy(state->payload.body, body, body_len);
+       state->payload.body_len = body_len;
        status = smbd_smb2_build_break_state_payload(xconn, session, tcon,
-                                                   body, body_len, state);
+                                                    &state->payload);
        if (!NT_STATUS_IS_OK(status)) {
                goto error;
        }
@@ -3696,8 +3703,8 @@ static NTSTATUS _smbd_smb2_send_break(TALLOC_CTX *mem_ctx,
        state->session = session;
        state->tcon = tcon;
        state->queue_entry.mem_ctx = state->mem_ctx;
-       state->queue_entry.vector = state->vector;
-       state->queue_entry.count = ARRAY_SIZE(state->vector);
+       state->queue_entry.vector = (struct iovec *) &state->payload.vector;
+       state->queue_entry.count = ARRAY_SIZE(state->payload.vector);
 
        state->queue_entry.req = tevent_wait_send(mem_ctx, ev_ctx);
        if (state->queue_entry.req == NULL) {