2 Unix SMB/CIFS implementation.
5 Copyright (C) Stefan Metzmacher 2009
6 Copyright (C) Jeremy Allison 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30 #include "../librpc/gen_ndr/krb5pac.h"
31 #include "lib/util/iov_buf.h"
33 #include "lib/crypto/sha512.h"
35 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
36 struct tevent_fd
*fde
,
39 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
);
41 static const struct smbd_smb2_dispatch_table
{
48 bool allow_invalid_fileid
;
50 } smbd_smb2_table
[] = {
51 #define _OP(o) .opcode = o, .name = #o
56 _OP(SMB2_OP_SESSSETUP
),
66 * This call needs to be run as root.
68 * smbd_smb2_request_process_tcon()
69 * calls make_connection_snum(), which will call
70 * change_to_user(), when needed.
105 .need_session
= true,
110 .need_session
= true,
113 .allow_invalid_fileid
= true,
119 _OP(SMB2_OP_KEEPALIVE
),
122 _OP(SMB2_OP_QUERY_DIRECTORY
),
123 .need_session
= true,
128 .need_session
= true,
132 _OP(SMB2_OP_GETINFO
),
133 .need_session
= true,
137 _OP(SMB2_OP_SETINFO
),
138 .need_session
= true,
144 .need_session
= true,
149 * as LEASE breaks does not
155 const char *smb2_opcode_name(uint16_t opcode
)
157 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
158 return "Bad SMB2 opcode";
160 return smbd_smb2_table
[opcode
].name
;
163 static const struct smbd_smb2_dispatch_table
*smbd_smb2_call(uint16_t opcode
)
165 const struct smbd_smb2_dispatch_table
*ret
= NULL
;
167 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
171 ret
= &smbd_smb2_table
[opcode
];
173 SMB_ASSERT(ret
->opcode
== opcode
);
178 static void print_req_vectors(const struct smbd_smb2_request
*req
)
182 for (i
= 0; i
< req
->in
.vector_count
; i
++) {
183 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
185 (unsigned int)req
->in
.vector
[i
].iov_len
);
187 for (i
= 0; i
< req
->out
.vector_count
; i
++) {
188 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
190 (unsigned int)req
->out
.vector
[i
].iov_len
);
194 bool smbd_is_smb2_header(const uint8_t *inbuf
, size_t size
)
196 if (size
< (4 + SMB2_HDR_BODY
)) {
200 if (IVAL(inbuf
, 4) != SMB2_MAGIC
) {
207 static NTSTATUS
smbd_initialize_smb2(struct smbXsrv_connection
*xconn
,
208 uint64_t expected_seq_low
)
210 TALLOC_FREE(xconn
->transport
.fde
);
212 xconn
->smb2
.credits
.seq_low
= expected_seq_low
;
213 xconn
->smb2
.credits
.seq_range
= 1;
214 xconn
->smb2
.credits
.granted
= 1;
215 xconn
->smb2
.credits
.max
= lp_smb2_max_credits();
216 xconn
->smb2
.credits
.bitmap
= bitmap_talloc(xconn
,
217 xconn
->smb2
.credits
.max
);
218 if (xconn
->smb2
.credits
.bitmap
== NULL
) {
219 return NT_STATUS_NO_MEMORY
;
222 xconn
->transport
.fde
= tevent_add_fd(xconn
->ev_ctx
,
224 xconn
->transport
.sock
,
226 smbd_smb2_connection_handler
,
228 if (xconn
->transport
.fde
== NULL
) {
229 return NT_STATUS_NO_MEMORY
;
232 /* Ensure child is set to non-blocking mode */
233 set_blocking(xconn
->transport
.sock
, false);
237 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
238 #define _smb2_setlen(_buf,len) do { \
239 uint8_t *buf = (uint8_t *)_buf; \
241 buf[1] = ((len)&0xFF0000)>>16; \
242 buf[2] = ((len)&0xFF00)>>8; \
243 buf[3] = (len)&0xFF; \
246 static bool smb2_setup_nbt_length(struct iovec
*vector
, int count
)
254 len
= iov_buflen(vector
+1, count
-1);
256 if ((len
== -1) || (len
> 0xFFFFFF)) {
260 _smb2_setlen(vector
[0].iov_base
, len
);
264 static int smbd_smb2_request_destructor(struct smbd_smb2_request
*req
)
266 if (req
->first_key
.length
> 0) {
267 data_blob_clear_free(&req
->first_key
);
269 if (req
->last_key
.length
> 0) {
270 data_blob_clear_free(&req
->last_key
);
275 static struct smbd_smb2_request
*smbd_smb2_request_allocate(TALLOC_CTX
*mem_ctx
)
277 TALLOC_CTX
*mem_pool
;
278 struct smbd_smb2_request
*req
;
281 /* Enable this to find subtle valgrind errors. */
282 mem_pool
= talloc_init("smbd_smb2_request_allocate");
284 mem_pool
= talloc_tos();
286 if (mem_pool
== NULL
) {
290 req
= talloc_zero(mem_pool
, struct smbd_smb2_request
);
292 talloc_free(mem_pool
);
295 talloc_reparent(mem_pool
, mem_ctx
, req
);
297 TALLOC_FREE(mem_pool
);
300 req
->last_session_id
= UINT64_MAX
;
301 req
->last_tid
= UINT32_MAX
;
303 talloc_set_destructor(req
, smbd_smb2_request_destructor
);
308 static NTSTATUS
smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection
*xconn
,
312 struct smbd_smb2_request
*req
,
316 TALLOC_CTX
*mem_ctx
= req
;
320 uint8_t *first_hdr
= buf
;
321 size_t verified_buflen
= 0;
326 * Note: index '0' is reserved for the transport protocol
328 iov
= req
->in
._vector
;
330 while (taken
< buflen
) {
331 size_t len
= buflen
- taken
;
332 uint8_t *hdr
= first_hdr
+ taken
;
335 size_t next_command_ofs
;
337 uint8_t *body
= NULL
;
340 struct iovec
*iov_alloc
= NULL
;
342 if (iov
!= req
->in
._vector
) {
346 if (verified_buflen
> taken
) {
347 len
= verified_buflen
- taken
;
354 DEBUG(10, ("%d bytes left, expected at least %d\n",
358 if (IVAL(hdr
, 0) == SMB2_TF_MAGIC
) {
359 struct smbXsrv_session
*s
= NULL
;
361 struct iovec tf_iov
[2];
365 if (xconn
->protocol
< PROTOCOL_SMB2_24
) {
366 DEBUG(10, ("Got SMB2_TRANSFORM header, "
367 "but dialect[0x%04X] is used\n",
368 xconn
->smb2
.server
.dialect
));
372 if (xconn
->smb2
.server
.cipher
== 0) {
373 DEBUG(10, ("Got SMB2_TRANSFORM header, "
374 "but not negotiated "
375 "client[0x%08X] server[0x%08X]\n",
376 xconn
->smb2
.client
.capabilities
,
377 xconn
->smb2
.server
.capabilities
));
381 if (len
< SMB2_TF_HDR_SIZE
) {
382 DEBUG(1, ("%d bytes left, expected at least %d\n",
383 (int)len
, SMB2_TF_HDR_SIZE
));
387 tf_len
= SMB2_TF_HDR_SIZE
;
390 hdr
= first_hdr
+ taken
;
391 enc_len
= IVAL(tf
, SMB2_TF_MSG_SIZE
);
392 uid
= BVAL(tf
, SMB2_TF_SESSION_ID
);
394 if (len
< SMB2_TF_HDR_SIZE
+ enc_len
) {
395 DEBUG(1, ("%d bytes left, expected at least %d\n",
397 (int)(SMB2_TF_HDR_SIZE
+ enc_len
)));
401 status
= smb2srv_session_lookup_conn(xconn
, uid
, now
,
404 DEBUG(1, ("invalid session[%llu] in "
405 "SMB2_TRANSFORM header\n",
406 (unsigned long long)uid
));
407 TALLOC_FREE(iov_alloc
);
408 return NT_STATUS_USER_SESSION_DELETED
;
411 tf_iov
[0].iov_base
= (void *)tf
;
412 tf_iov
[0].iov_len
= tf_len
;
413 tf_iov
[1].iov_base
= (void *)hdr
;
414 tf_iov
[1].iov_len
= enc_len
;
416 status
= smb2_signing_decrypt_pdu(s
->global
->decryption_key
,
417 xconn
->smb2
.server
.cipher
,
419 if (!NT_STATUS_IS_OK(status
)) {
420 TALLOC_FREE(iov_alloc
);
424 verified_buflen
= taken
+ enc_len
;
429 * We need the header plus the body length field
432 if (len
< SMB2_HDR_BODY
+ 2) {
433 DEBUG(10, ("%d bytes left, expected at least %d\n",
434 (int)len
, SMB2_HDR_BODY
));
437 if (IVAL(hdr
, 0) != SMB2_MAGIC
) {
438 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
442 if (SVAL(hdr
, 4) != SMB2_HDR_BODY
) {
443 DEBUG(10, ("Got HDR len %d, expected %d\n",
444 SVAL(hdr
, 4), SMB2_HDR_BODY
));
449 next_command_ofs
= IVAL(hdr
, SMB2_HDR_NEXT_COMMAND
);
450 body_size
= SVAL(hdr
, SMB2_HDR_BODY
);
452 if (next_command_ofs
!= 0) {
453 if (next_command_ofs
< (SMB2_HDR_BODY
+ 2)) {
456 if (next_command_ofs
> full_size
) {
459 full_size
= next_command_ofs
;
466 if (body_size
> (full_size
- SMB2_HDR_BODY
)) {
468 * let the caller handle the error
470 body_size
= full_size
- SMB2_HDR_BODY
;
472 body
= hdr
+ SMB2_HDR_BODY
;
473 dyn
= body
+ body_size
;
474 dyn_size
= full_size
- (SMB2_HDR_BODY
+ body_size
);
476 if (num_iov
>= ARRAY_SIZE(req
->in
._vector
)) {
477 struct iovec
*iov_tmp
= NULL
;
479 iov_tmp
= talloc_realloc(mem_ctx
, iov_alloc
,
482 SMBD_SMB2_NUM_IOV_PER_REQ
);
483 if (iov_tmp
== NULL
) {
484 TALLOC_FREE(iov_alloc
);
485 return NT_STATUS_NO_MEMORY
;
488 if (iov_alloc
== NULL
) {
491 sizeof(req
->in
._vector
));
497 num_iov
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
499 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
500 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
501 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
502 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
503 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
504 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= body_size
;
505 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
506 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= dyn_size
;
516 if (iov
!= req
->in
._vector
) {
519 return NT_STATUS_INVALID_PARAMETER
;
522 static NTSTATUS
smbd_smb2_request_create(struct smbXsrv_connection
*xconn
,
523 const uint8_t *_inpdu
, size_t size
,
524 struct smbd_smb2_request
**_req
)
526 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
527 struct smbd_smb2_request
*req
;
528 uint32_t protocol_version
;
529 uint8_t *inpdu
= NULL
;
530 const uint8_t *inhdr
= NULL
;
532 uint32_t next_command_ofs
;
536 if (size
< (SMB2_HDR_BODY
+ 2)) {
537 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size
));
538 return NT_STATUS_INVALID_PARAMETER
;
543 protocol_version
= IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
);
544 if (protocol_version
!= SMB2_MAGIC
) {
545 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
547 return NT_STATUS_INVALID_PARAMETER
;
550 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
551 if (cmd
!= SMB2_OP_NEGPROT
) {
552 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
554 return NT_STATUS_INVALID_PARAMETER
;
557 next_command_ofs
= IVAL(inhdr
, SMB2_HDR_NEXT_COMMAND
);
558 if (next_command_ofs
!= 0) {
559 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
561 return NT_STATUS_INVALID_PARAMETER
;
564 req
= smbd_smb2_request_allocate(xconn
);
566 return NT_STATUS_NO_MEMORY
;
571 inpdu
= talloc_memdup(req
, _inpdu
, size
);
573 return NT_STATUS_NO_MEMORY
;
576 req
->request_time
= timeval_current();
577 now
= timeval_to_nttime(&req
->request_time
);
579 status
= smbd_smb2_inbuf_parse_compound(xconn
,
583 req
, &req
->in
.vector
,
584 &req
->in
.vector_count
);
585 if (!NT_STATUS_IS_OK(status
)) {
590 req
->current_idx
= 1;
596 static bool smb2_validate_sequence_number(struct smbXsrv_connection
*xconn
,
597 uint64_t message_id
, uint64_t seq_id
)
599 struct bitmap
*credits_bm
= xconn
->smb2
.credits
.bitmap
;
603 seq_tmp
= xconn
->smb2
.credits
.seq_low
;
604 if (seq_id
< seq_tmp
) {
605 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
606 "%llu (sequence id %llu) "
607 "(granted = %u, low = %llu, range = %u)\n",
608 (unsigned long long)message_id
,
609 (unsigned long long)seq_id
,
610 (unsigned int)xconn
->smb2
.credits
.granted
,
611 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
612 (unsigned int)xconn
->smb2
.credits
.seq_range
));
616 seq_tmp
+= xconn
->smb2
.credits
.seq_range
;
617 if (seq_id
>= seq_tmp
) {
618 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
619 "%llu (sequence id %llu) "
620 "(granted = %u, low = %llu, range = %u)\n",
621 (unsigned long long)message_id
,
622 (unsigned long long)seq_id
,
623 (unsigned int)xconn
->smb2
.credits
.granted
,
624 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
625 (unsigned int)xconn
->smb2
.credits
.seq_range
));
629 offset
= seq_id
% xconn
->smb2
.credits
.max
;
631 if (bitmap_query(credits_bm
, offset
)) {
632 DEBUG(0,("smb2_validate_sequence_number: duplicate message_id "
633 "%llu (sequence id %llu) "
634 "(granted = %u, low = %llu, range = %u) "
636 (unsigned long long)message_id
,
637 (unsigned long long)seq_id
,
638 (unsigned int)xconn
->smb2
.credits
.granted
,
639 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
640 (unsigned int)xconn
->smb2
.credits
.seq_range
,
645 /* Mark the message_ids as seen in the bitmap. */
646 bitmap_set(credits_bm
, offset
);
648 if (seq_id
!= xconn
->smb2
.credits
.seq_low
) {
653 * Move the window forward by all the message_id's
656 while (bitmap_query(credits_bm
, offset
)) {
657 DEBUG(10,("smb2_validate_sequence_number: clearing "
658 "id %llu (position %u) from bitmap\n",
659 (unsigned long long)(xconn
->smb2
.credits
.seq_low
),
661 bitmap_clear(credits_bm
, offset
);
663 xconn
->smb2
.credits
.seq_low
+= 1;
664 xconn
->smb2
.credits
.seq_range
-= 1;
665 offset
= xconn
->smb2
.credits
.seq_low
% xconn
->smb2
.credits
.max
;
671 static bool smb2_validate_message_id(struct smbXsrv_connection
*xconn
,
672 const uint8_t *inhdr
)
674 uint64_t message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
675 uint16_t opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
676 uint16_t credit_charge
= 1;
679 if (opcode
== SMB2_OP_CANCEL
) {
680 /* SMB2_CANCEL requests by definition resend messageids. */
684 if (xconn
->smb2
.credits
.multicredit
) {
685 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
686 credit_charge
= MAX(credit_charge
, 1);
689 DEBUG(11, ("smb2_validate_message_id: mid %llu (charge %llu), "
690 "credits_granted %llu, "
691 "seqnum low/range: %llu/%llu\n",
692 (unsigned long long) message_id
,
693 (unsigned long long) credit_charge
,
694 (unsigned long long) xconn
->smb2
.credits
.granted
,
695 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
696 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
698 if (xconn
->smb2
.credits
.granted
< credit_charge
) {
699 DEBUG(0, ("smb2_validate_message_id: client used more "
700 "credits than granted, mid %llu, charge %llu, "
701 "credits_granted %llu, "
702 "seqnum low/range: %llu/%llu\n",
703 (unsigned long long) message_id
,
704 (unsigned long long) credit_charge
,
705 (unsigned long long) xconn
->smb2
.credits
.granted
,
706 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
707 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
712 * now check the message ids
714 * for multi-credit requests we need to check all current mid plus
715 * the implicit mids caused by the credit charge
716 * e.g. current mid = 15, charge 5 => mark 15-19 as used
719 for (i
= 0; i
<= (credit_charge
-1); i
++) {
720 uint64_t id
= message_id
+ i
;
723 DEBUG(11, ("Iterating mid %llu charge %u (sequence %llu)\n",
724 (unsigned long long)message_id
,
726 (unsigned long long)id
));
728 ok
= smb2_validate_sequence_number(xconn
, message_id
, id
);
734 /* substract used credits */
735 xconn
->smb2
.credits
.granted
-= credit_charge
;
740 static NTSTATUS
smbd_smb2_request_validate(struct smbd_smb2_request
*req
)
745 count
= req
->in
.vector_count
;
747 if (count
< 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
748 /* It's not a SMB2 request */
749 return NT_STATUS_INVALID_PARAMETER
;
752 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
753 struct iovec
*hdr
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
754 struct iovec
*body
= SMBD_SMB2_IDX_BODY_IOV(req
,in
,idx
);
755 const uint8_t *inhdr
= NULL
;
757 if (hdr
->iov_len
!= SMB2_HDR_BODY
) {
758 return NT_STATUS_INVALID_PARAMETER
;
761 if (body
->iov_len
< 2) {
762 return NT_STATUS_INVALID_PARAMETER
;
765 inhdr
= (const uint8_t *)hdr
->iov_base
;
767 /* Check the SMB2 header */
768 if (IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
) != SMB2_MAGIC
) {
769 return NT_STATUS_INVALID_PARAMETER
;
772 if (!smb2_validate_message_id(req
->xconn
, inhdr
)) {
773 return NT_STATUS_INVALID_PARAMETER
;
780 static void smb2_set_operation_credit(struct smbXsrv_connection
*xconn
,
781 const struct iovec
*in_vector
,
782 struct iovec
*out_vector
)
784 const uint8_t *inhdr
= (const uint8_t *)in_vector
->iov_base
;
785 uint8_t *outhdr
= (uint8_t *)out_vector
->iov_base
;
786 uint16_t credit_charge
= 1;
787 uint16_t credits_requested
;
791 uint16_t credits_granted
= 0;
792 uint64_t credits_possible
;
793 uint16_t current_max_credits
;
796 * first we grant only 1/16th of the max range.
798 * Windows also starts with the 1/16th and then grants
799 * more later. I was only able to trigger higher
800 * values, when using a very high credit charge.
802 * TODO: scale up depending on load, free memory
804 * Maybe also on the relationship between number
805 * of requests and the used sequence number.
806 * Which means we would grant more credits
807 * for client which use multi credit requests.
809 current_max_credits
= xconn
->smb2
.credits
.max
/ 16;
810 current_max_credits
= MAX(current_max_credits
, 1);
812 if (xconn
->smb2
.credits
.multicredit
) {
813 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
814 credit_charge
= MAX(credit_charge
, 1);
817 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
818 credits_requested
= SVAL(inhdr
, SMB2_HDR_CREDIT
);
819 credits_requested
= MAX(credits_requested
, 1);
820 out_flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
821 out_status
= NT_STATUS(IVAL(outhdr
, SMB2_HDR_STATUS
));
823 SMB_ASSERT(xconn
->smb2
.credits
.max
>= xconn
->smb2
.credits
.granted
);
825 if (xconn
->smb2
.credits
.max
< credit_charge
) {
826 smbd_server_connection_terminate(xconn
,
827 "client error: credit charge > max credits\n");
831 if (out_flags
& SMB2_HDR_FLAG_ASYNC
) {
833 * In case we already send an async interim
834 * response, we should not grant
835 * credits on the final response.
839 uint16_t additional_possible
=
840 xconn
->smb2
.credits
.max
- credit_charge
;
841 uint16_t additional_max
= 0;
842 uint16_t additional_credits
= credits_requested
- 1;
845 case SMB2_OP_NEGPROT
:
847 case SMB2_OP_SESSSETUP
:
849 * Windows 2012 RC1 starts to grant
851 * with a successful session setup
853 if (NT_STATUS_IS_OK(out_status
)) {
859 * We match windows and only grant additional credits
866 additional_max
= MIN(additional_max
, additional_possible
);
867 additional_credits
= MIN(additional_credits
, additional_max
);
869 credits_granted
= credit_charge
+ additional_credits
;
873 * sequence numbers should not wrap
875 * 1. calculate the possible credits until
876 * the sequence numbers start to wrap on 64-bit.
878 * 2. UINT64_MAX is used for Break Notifications.
880 * 2. truncate the possible credits to the maximum
881 * credits we want to grant to the client in total.
883 * 3. remove the range we'll already granted to the client
884 * this makes sure the client consumes the lowest sequence
885 * number, before we can grant additional credits.
887 credits_possible
= UINT64_MAX
- xconn
->smb2
.credits
.seq_low
;
888 if (credits_possible
> 0) {
889 /* remove UINT64_MAX */
890 credits_possible
-= 1;
892 credits_possible
= MIN(credits_possible
, current_max_credits
);
893 credits_possible
-= xconn
->smb2
.credits
.seq_range
;
895 credits_granted
= MIN(credits_granted
, credits_possible
);
897 SSVAL(outhdr
, SMB2_HDR_CREDIT
, credits_granted
);
898 xconn
->smb2
.credits
.granted
+= credits_granted
;
899 xconn
->smb2
.credits
.seq_range
+= credits_granted
;
901 DEBUG(10,("smb2_set_operation_credit: requested %u, charge %u, "
902 "granted %u, current possible/max %u/%u, "
903 "total granted/max/low/range %u/%u/%llu/%u\n",
904 (unsigned int)credits_requested
,
905 (unsigned int)credit_charge
,
906 (unsigned int)credits_granted
,
907 (unsigned int)credits_possible
,
908 (unsigned int)current_max_credits
,
909 (unsigned int)xconn
->smb2
.credits
.granted
,
910 (unsigned int)xconn
->smb2
.credits
.max
,
911 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
912 (unsigned int)xconn
->smb2
.credits
.seq_range
));
915 static void smb2_calculate_credits(const struct smbd_smb2_request
*inreq
,
916 struct smbd_smb2_request
*outreq
)
919 uint16_t total_credits
= 0;
921 count
= outreq
->out
.vector_count
;
923 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
924 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(inreq
,in
,idx
);
925 struct iovec
*outhdr_v
= SMBD_SMB2_IDX_HDR_IOV(outreq
,out
,idx
);
926 uint8_t *outhdr
= (uint8_t *)outhdr_v
->iov_base
;
928 smb2_set_operation_credit(outreq
->xconn
, inhdr_v
, outhdr_v
);
930 /* To match Windows, count up what we
932 total_credits
+= SVAL(outhdr
, SMB2_HDR_CREDIT
);
933 /* Set to zero in all but the last reply. */
934 if (idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
< count
) {
935 SSVAL(outhdr
, SMB2_HDR_CREDIT
, 0);
937 SSVAL(outhdr
, SMB2_HDR_CREDIT
, total_credits
);
942 DATA_BLOB
smbd_smb2_generate_outbody(struct smbd_smb2_request
*req
, size_t size
)
944 if (req
->current_idx
<= 1) {
945 if (size
<= sizeof(req
->out
._body
)) {
946 return data_blob_const(req
->out
._body
, size
);
950 return data_blob_talloc(req
, NULL
, size
);
953 static NTSTATUS
smbd_smb2_request_setup_out(struct smbd_smb2_request
*req
)
955 struct smbXsrv_connection
*xconn
= req
->xconn
;
957 struct iovec
*vector
;
962 count
= req
->in
.vector_count
;
963 if (count
<= ARRAY_SIZE(req
->out
._vector
)) {
965 vector
= req
->out
._vector
;
967 vector
= talloc_zero_array(req
, struct iovec
, count
);
968 if (vector
== NULL
) {
969 return NT_STATUS_NO_MEMORY
;
974 vector
[0].iov_base
= req
->out
.nbt_hdr
;
975 vector
[0].iov_len
= 4;
976 SIVAL(req
->out
.nbt_hdr
, 0, 0);
978 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
979 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
980 const uint8_t *inhdr
= (const uint8_t *)inhdr_v
->iov_base
;
981 uint8_t *outhdr
= NULL
;
982 uint8_t *outbody
= NULL
;
983 uint32_t next_command_ofs
= 0;
984 struct iovec
*current
= &vector
[idx
];
986 if ((idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) < count
) {
987 /* we have a next command -
988 * setup for the error case. */
989 next_command_ofs
= SMB2_HDR_BODY
+ 9;
993 outhdr
= req
->out
._hdr
;
995 outhdr
= talloc_zero_array(mem_ctx
, uint8_t,
997 if (outhdr
== NULL
) {
998 return NT_STATUS_NO_MEMORY
;
1002 outbody
= outhdr
+ SMB2_HDR_BODY
;
1005 * SMBD_SMB2_TF_IOV_OFS might be used later
1007 current
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1008 current
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1010 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)outhdr
;
1011 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1013 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)outbody
;
1014 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1016 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= NULL
;
1017 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 0;
1019 /* setup the SMB2 header */
1020 SIVAL(outhdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1021 SSVAL(outhdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1022 SSVAL(outhdr
, SMB2_HDR_CREDIT_CHARGE
,
1023 SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
));
1024 SIVAL(outhdr
, SMB2_HDR_STATUS
,
1025 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR
));
1026 SSVAL(outhdr
, SMB2_HDR_OPCODE
,
1027 SVAL(inhdr
, SMB2_HDR_OPCODE
));
1028 SIVAL(outhdr
, SMB2_HDR_FLAGS
,
1029 IVAL(inhdr
, SMB2_HDR_FLAGS
) | SMB2_HDR_FLAG_REDIRECT
);
1030 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
1031 SBVAL(outhdr
, SMB2_HDR_MESSAGE_ID
,
1032 BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
));
1033 SIVAL(outhdr
, SMB2_HDR_PID
,
1034 IVAL(inhdr
, SMB2_HDR_PID
));
1035 SIVAL(outhdr
, SMB2_HDR_TID
,
1036 IVAL(inhdr
, SMB2_HDR_TID
));
1037 SBVAL(outhdr
, SMB2_HDR_SESSION_ID
,
1038 BVAL(inhdr
, SMB2_HDR_SESSION_ID
));
1039 memcpy(outhdr
+ SMB2_HDR_SIGNATURE
,
1040 inhdr
+ SMB2_HDR_SIGNATURE
, 16);
1042 /* setup error body header */
1043 SSVAL(outbody
, 0x00, 0x08 + 1);
1044 SSVAL(outbody
, 0x02, 0);
1045 SIVAL(outbody
, 0x04, 0);
1048 req
->out
.vector
= vector
;
1049 req
->out
.vector_count
= count
;
1051 /* setup the length of the NBT packet */
1052 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
1054 return NT_STATUS_INVALID_PARAMETER_MIX
;
1057 DLIST_ADD_END(xconn
->smb2
.requests
, req
);
1059 return NT_STATUS_OK
;
1062 void smbd_server_connection_terminate_ex(struct smbXsrv_connection
*xconn
,
1064 const char *location
)
1066 struct smbXsrv_client
*client
= xconn
->client
;
1068 DEBUG(10,("smbd_server_connection_terminate_ex: conn[%s] reason[%s] at %s\n",
1069 smbXsrv_connection_dbg(xconn
), reason
, location
));
1071 if (client
->connections
->next
!= NULL
) {
1072 /* TODO: cancel pending requests */
1073 DLIST_REMOVE(client
->connections
, xconn
);
1079 * The last connection was disconnected
1081 exit_server_cleanly(reason
);
1084 static bool dup_smb2_vec4(TALLOC_CTX
*ctx
,
1085 struct iovec
*outvec
,
1086 const struct iovec
*srcvec
)
1088 const uint8_t *srctf
;
1090 const uint8_t *srchdr
;
1092 const uint8_t *srcbody
;
1094 const uint8_t *expected_srcbody
;
1095 const uint8_t *srcdyn
;
1097 const uint8_t *expected_srcdyn
;
1103 srctf
= (const uint8_t *)srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
;
1104 srctf_len
= srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
;
1105 srchdr
= (const uint8_t *)srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
;
1106 srchdr_len
= srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
;
1107 srcbody
= (const uint8_t *)srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
;
1108 srcbody_len
= srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
;
1109 expected_srcbody
= srchdr
+ SMB2_HDR_BODY
;
1110 srcdyn
= (const uint8_t *)srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
;
1111 srcdyn_len
= srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
;
1112 expected_srcdyn
= srcbody
+ 8;
1114 if ((srctf_len
!= SMB2_TF_HDR_SIZE
) && (srctf_len
!= 0)) {
1118 if (srchdr_len
!= SMB2_HDR_BODY
) {
1122 if (srctf_len
== SMB2_TF_HDR_SIZE
) {
1123 dsttf
= talloc_memdup(ctx
, srctf
, SMB2_TF_HDR_SIZE
);
1124 if (dsttf
== NULL
) {
1130 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= (void *)dsttf
;
1131 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= srctf_len
;
1133 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1134 * be allocated with size OUTVEC_ALLOC_SIZE. */
1136 dsthdr
= talloc_memdup(ctx
, srchdr
, OUTVEC_ALLOC_SIZE
);
1137 if (dsthdr
== NULL
) {
1140 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)dsthdr
;
1141 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1144 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1145 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1146 * then duplicate this. Else use talloc_memdup().
1149 if ((srcbody
== expected_srcbody
) && (srcbody_len
== 8)) {
1150 dstbody
= dsthdr
+ SMB2_HDR_BODY
;
1152 dstbody
= talloc_memdup(ctx
, srcbody
, srcbody_len
);
1153 if (dstbody
== NULL
) {
1157 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)dstbody
;
1158 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= srcbody_len
;
1161 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1163 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1164 * then duplicate this. Else use talloc_memdup().
1167 if ((srcdyn
== expected_srcdyn
) && (srcdyn_len
== 1)) {
1168 dstdyn
= dsthdr
+ SMB2_HDR_BODY
+ 8;
1169 } else if (srcdyn
== NULL
) {
1172 dstdyn
= talloc_memdup(ctx
, srcdyn
, srcdyn_len
);
1173 if (dstdyn
== NULL
) {
1177 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= (void *)dstdyn
;
1178 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= srcdyn_len
;
1183 static struct smbd_smb2_request
*dup_smb2_req(const struct smbd_smb2_request
*req
)
1185 struct smbd_smb2_request
*newreq
= NULL
;
1186 struct iovec
*outvec
= NULL
;
1187 int count
= req
->out
.vector_count
;
1191 newreq
= smbd_smb2_request_allocate(req
->xconn
);
1196 newreq
->sconn
= req
->sconn
;
1197 newreq
->xconn
= req
->xconn
;
1198 newreq
->session
= req
->session
;
1199 newreq
->do_encryption
= req
->do_encryption
;
1200 newreq
->do_signing
= req
->do_signing
;
1201 newreq
->current_idx
= req
->current_idx
;
1203 outvec
= talloc_zero_array(newreq
, struct iovec
, count
);
1205 TALLOC_FREE(newreq
);
1208 newreq
->out
.vector
= outvec
;
1209 newreq
->out
.vector_count
= count
;
1211 /* Setup the outvec's identically to req. */
1212 outvec
[0].iov_base
= newreq
->out
.nbt_hdr
;
1213 outvec
[0].iov_len
= 4;
1214 memcpy(newreq
->out
.nbt_hdr
, req
->out
.nbt_hdr
, 4);
1216 /* Setup the vectors identically to the ones in req. */
1217 for (i
= 1; i
< count
; i
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1218 if (!dup_smb2_vec4(outvec
, &outvec
[i
], &req
->out
.vector
[i
])) {
1225 TALLOC_FREE(newreq
);
1229 ok
= smb2_setup_nbt_length(newreq
->out
.vector
,
1230 newreq
->out
.vector_count
);
1232 TALLOC_FREE(newreq
);
1239 static NTSTATUS
smb2_send_async_interim_response(const struct smbd_smb2_request
*req
)
1241 struct smbXsrv_connection
*xconn
= req
->xconn
;
1243 struct iovec
*firsttf
= NULL
;
1244 struct iovec
*outhdr_v
= NULL
;
1245 uint8_t *outhdr
= NULL
;
1246 struct smbd_smb2_request
*nreq
= NULL
;
1250 /* Create a new smb2 request we'll use
1251 for the interim return. */
1252 nreq
= dup_smb2_req(req
);
1254 return NT_STATUS_NO_MEMORY
;
1257 /* Lose the last X out vectors. They're the
1258 ones we'll be using for the async reply. */
1259 nreq
->out
.vector_count
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1261 ok
= smb2_setup_nbt_length(nreq
->out
.vector
,
1262 nreq
->out
.vector_count
);
1264 return NT_STATUS_INVALID_PARAMETER_MIX
;
1267 /* Step back to the previous reply. */
1268 nreq
->current_idx
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1269 firsttf
= SMBD_SMB2_IDX_TF_IOV(nreq
,out
,first_idx
);
1270 outhdr_v
= SMBD_SMB2_OUT_HDR_IOV(nreq
);
1271 outhdr
= SMBD_SMB2_OUT_HDR_PTR(nreq
);
1272 /* And end the chain. */
1273 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
1275 /* Calculate outgoing credits */
1276 smb2_calculate_credits(req
, nreq
);
1278 if (DEBUGLEVEL
>= 10) {
1279 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1280 (unsigned int)nreq
->current_idx
);
1281 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1282 (unsigned int)nreq
->out
.vector_count
);
1283 print_req_vectors(nreq
);
1287 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1288 * we need to sign/encrypt here with the last/first key we remembered
1290 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
1291 status
= smb2_signing_encrypt_pdu(req
->first_key
,
1292 xconn
->smb2
.server
.cipher
,
1294 nreq
->out
.vector_count
- first_idx
);
1295 if (!NT_STATUS_IS_OK(status
)) {
1298 } else if (req
->last_key
.length
> 0) {
1299 status
= smb2_signing_sign_pdu(req
->last_key
,
1302 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
1303 if (!NT_STATUS_IS_OK(status
)) {
1308 nreq
->queue_entry
.mem_ctx
= nreq
;
1309 nreq
->queue_entry
.vector
= nreq
->out
.vector
;
1310 nreq
->queue_entry
.count
= nreq
->out
.vector_count
;
1311 DLIST_ADD_END(xconn
->smb2
.send_queue
, &nreq
->queue_entry
);
1312 xconn
->smb2
.send_queue_len
++;
1314 status
= smbd_smb2_flush_send_queue(xconn
);
1315 if (!NT_STATUS_IS_OK(status
)) {
1319 return NT_STATUS_OK
;
1322 struct smbd_smb2_request_pending_state
{
1323 struct smbd_smb2_send_queue queue_entry
;
1324 uint8_t buf
[NBT_HDR_SIZE
+ SMB2_TF_HDR_SIZE
+ SMB2_HDR_BODY
+ 0x08 + 1];
1325 struct iovec vector
[1 + SMBD_SMB2_NUM_IOV_PER_REQ
];
1328 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
1329 struct tevent_timer
*te
,
1330 struct timeval current_time
,
1331 void *private_data
);
1333 NTSTATUS
smbd_smb2_request_pending_queue(struct smbd_smb2_request
*req
,
1334 struct tevent_req
*subreq
,
1335 uint32_t defer_time
)
1338 struct timeval defer_endtime
;
1339 uint8_t *outhdr
= NULL
;
1342 if (!tevent_req_is_in_progress(subreq
)) {
1344 * This is a performance optimization,
1345 * it avoids one tevent_loop iteration,
1346 * which means we avoid one
1347 * talloc_stackframe_pool/talloc_free pair.
1349 tevent_req_notify_callback(subreq
);
1350 return NT_STATUS_OK
;
1353 req
->subreq
= subreq
;
1356 if (req
->async_te
) {
1357 /* We're already async. */
1358 return NT_STATUS_OK
;
1361 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1362 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
1363 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
1364 /* We're already async. */
1365 return NT_STATUS_OK
;
1368 if (req
->in
.vector_count
> req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) {
1370 * We're trying to go async in a compound request
1371 * chain. This is only allowed for opens that cause an
1372 * oplock break or for the last operation in the
1373 * chain, otherwise it is not allowed. See
1374 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
1376 const uint8_t *inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1378 if (SVAL(inhdr
, SMB2_HDR_OPCODE
) != SMB2_OP_CREATE
) {
1380 * Cancel the outstanding request.
1382 bool ok
= tevent_req_cancel(req
->subreq
);
1384 return NT_STATUS_OK
;
1386 TALLOC_FREE(req
->subreq
);
1387 return smbd_smb2_request_error(req
,
1388 NT_STATUS_INTERNAL_ERROR
);
1392 if (DEBUGLEVEL
>= 10) {
1393 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1394 (unsigned int)req
->current_idx
);
1395 print_req_vectors(req
);
1398 if (req
->current_idx
> 1) {
1400 * We're going async in a compound
1401 * chain after the first request has
1402 * already been processed. Send an
1403 * interim response containing the
1404 * set of replies already generated.
1406 int idx
= req
->current_idx
;
1408 status
= smb2_send_async_interim_response(req
);
1409 if (!NT_STATUS_IS_OK(status
)) {
1412 if (req
->first_key
.length
> 0) {
1413 data_blob_clear_free(&req
->first_key
);
1416 req
->current_idx
= 1;
1419 * Re-arrange the in.vectors to remove what
1422 memmove(&req
->in
.vector
[1],
1423 &req
->in
.vector
[idx
],
1424 sizeof(req
->in
.vector
[0])*(req
->in
.vector_count
- idx
));
1425 req
->in
.vector_count
= 1 + (req
->in
.vector_count
- idx
);
1427 /* Re-arrange the out.vectors to match. */
1428 memmove(&req
->out
.vector
[1],
1429 &req
->out
.vector
[idx
],
1430 sizeof(req
->out
.vector
[0])*(req
->out
.vector_count
- idx
));
1431 req
->out
.vector_count
= 1 + (req
->out
.vector_count
- idx
);
1433 if (req
->in
.vector_count
== 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
1435 * We only have one remaining request as
1436 * we've processed everything else.
1437 * This is no longer a compound request.
1439 req
->compound_related
= false;
1440 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1441 flags
= (IVAL(outhdr
, SMB2_HDR_FLAGS
) & ~SMB2_HDR_FLAG_CHAINED
);
1442 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
);
1445 if (req
->last_key
.length
> 0) {
1446 data_blob_clear_free(&req
->last_key
);
1449 defer_endtime
= timeval_current_ofs_usec(defer_time
);
1450 req
->async_te
= tevent_add_timer(req
->sconn
->ev_ctx
,
1452 smbd_smb2_request_pending_timer
,
1454 if (req
->async_te
== NULL
) {
1455 return NT_STATUS_NO_MEMORY
;
1458 return NT_STATUS_OK
;
1461 static DATA_BLOB
smbd_smb2_signing_key(struct smbXsrv_session
*session
,
1462 struct smbXsrv_connection
*xconn
)
1464 struct smbXsrv_channel_global0
*c
= NULL
;
1466 DATA_BLOB key
= data_blob_null
;
1468 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
1469 if (NT_STATUS_IS_OK(status
)) {
1470 key
= c
->signing_key
;
1473 if (key
.length
== 0) {
1474 key
= session
->global
->signing_key
;
1480 static NTSTATUS
smb2_get_new_nonce(struct smbXsrv_session
*session
,
1481 uint64_t *new_nonce_high
,
1482 uint64_t *new_nonce_low
)
1484 uint64_t nonce_high
;
1487 session
->nonce_low
+= 1;
1488 if (session
->nonce_low
== 0) {
1489 session
->nonce_low
+= 1;
1490 session
->nonce_high
+= 1;
1494 * CCM and GCM algorithms must never have their
1495 * nonce wrap, or the security of the whole
1496 * communication and the keys is destroyed.
1497 * We must drop the connection once we have
1498 * transfered too much data.
1500 * NOTE: We assume nonces greater than 8 bytes.
1502 if (session
->nonce_high
>= session
->nonce_high_max
) {
1503 return NT_STATUS_ENCRYPTION_FAILED
;
1506 nonce_high
= session
->nonce_high_random
;
1507 nonce_high
+= session
->nonce_high
;
1508 nonce_low
= session
->nonce_low
;
1510 *new_nonce_high
= nonce_high
;
1511 *new_nonce_low
= nonce_low
;
1512 return NT_STATUS_OK
;
1515 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
1516 struct tevent_timer
*te
,
1517 struct timeval current_time
,
1520 struct smbd_smb2_request
*req
=
1521 talloc_get_type_abort(private_data
,
1522 struct smbd_smb2_request
);
1523 struct smbXsrv_connection
*xconn
= req
->xconn
;
1524 struct smbd_smb2_request_pending_state
*state
= NULL
;
1525 uint8_t *outhdr
= NULL
;
1526 const uint8_t *inhdr
= NULL
;
1529 uint8_t *hdr
= NULL
;
1530 uint8_t *body
= NULL
;
1531 uint8_t *dyn
= NULL
;
1533 uint64_t session_id
= 0;
1534 uint64_t message_id
= 0;
1535 uint64_t nonce_high
= 0;
1536 uint64_t nonce_low
= 0;
1537 uint64_t async_id
= 0;
1541 TALLOC_FREE(req
->async_te
);
1543 /* Ensure our final reply matches the interim one. */
1544 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1545 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1546 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
1547 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
1548 session_id
= BVAL(outhdr
, SMB2_HDR_SESSION_ID
);
1550 async_id
= message_id
; /* keep it simple for now... */
1552 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
1553 SBVAL(outhdr
, SMB2_HDR_ASYNC_ID
, async_id
);
1555 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1557 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
1558 (unsigned long long)async_id
));
1561 * What we send is identical to a smbd_smb2_request_error
1562 * packet with an error status of STATUS_PENDING. Make use
1563 * of this fact sometime when refactoring. JRA.
1566 state
= talloc_zero(req
->xconn
, struct smbd_smb2_request_pending_state
);
1567 if (state
== NULL
) {
1568 smbd_server_connection_terminate(xconn
,
1569 nt_errstr(NT_STATUS_NO_MEMORY
));
1573 tf
= state
->buf
+ NBT_HDR_SIZE
;
1574 tf_len
= SMB2_TF_HDR_SIZE
;
1576 hdr
= tf
+ SMB2_TF_HDR_SIZE
;
1577 body
= hdr
+ SMB2_HDR_BODY
;
1580 if (req
->do_encryption
) {
1581 status
= smb2_get_new_nonce(req
->session
,
1584 if (!NT_STATUS_IS_OK(status
)) {
1585 smbd_server_connection_terminate(xconn
,
1591 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
1592 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
1593 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
1594 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
1596 SIVAL(hdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1597 SSVAL(hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1598 SSVAL(hdr
, SMB2_HDR_EPOCH
, 0);
1599 SIVAL(hdr
, SMB2_HDR_STATUS
, NT_STATUS_V(STATUS_PENDING
));
1600 SSVAL(hdr
, SMB2_HDR_OPCODE
, SVAL(outhdr
, SMB2_HDR_OPCODE
));
1602 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
);
1603 SIVAL(hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
1604 SBVAL(hdr
, SMB2_HDR_MESSAGE_ID
, message_id
);
1605 SBVAL(hdr
, SMB2_HDR_PID
, async_id
);
1606 SBVAL(hdr
, SMB2_HDR_SESSION_ID
,
1607 BVAL(outhdr
, SMB2_HDR_SESSION_ID
));
1608 memcpy(hdr
+SMB2_HDR_SIGNATURE
,
1609 outhdr
+SMB2_HDR_SIGNATURE
, 16);
1611 SSVAL(body
, 0x00, 0x08 + 1);
1613 SCVAL(body
, 0x02, 0);
1614 SCVAL(body
, 0x03, 0);
1615 SIVAL(body
, 0x04, 0);
1616 /* Match W2K8R2... */
1617 SCVAL(dyn
, 0x00, 0x21);
1619 state
->vector
[0].iov_base
= (void *)state
->buf
;
1620 state
->vector
[0].iov_len
= NBT_HDR_SIZE
;
1622 if (req
->do_encryption
) {
1623 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
1624 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
1626 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1627 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1630 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
1631 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1633 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
1634 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1636 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
1637 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 1;
1639 ok
= smb2_setup_nbt_length(state
->vector
,
1640 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
1642 smbd_server_connection_terminate(
1643 xconn
, nt_errstr(NT_STATUS_INTERNAL_ERROR
));
1647 /* Ensure we correctly go through crediting. Grant
1648 the credits now, and zero credits on the final
1650 smb2_set_operation_credit(req
->xconn
,
1651 SMBD_SMB2_IN_HDR_IOV(req
),
1652 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
]);
1654 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
1659 for (i
= 0; i
< ARRAY_SIZE(state
->vector
); i
++) {
1660 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1662 (unsigned int)ARRAY_SIZE(state
->vector
),
1663 (unsigned int)state
->vector
[i
].iov_len
);
1667 if (req
->do_encryption
) {
1668 struct smbXsrv_session
*x
= req
->session
;
1669 DATA_BLOB encryption_key
= x
->global
->encryption_key
;
1671 status
= smb2_signing_encrypt_pdu(encryption_key
,
1672 xconn
->smb2
.server
.cipher
,
1673 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
1674 SMBD_SMB2_NUM_IOV_PER_REQ
);
1675 if (!NT_STATUS_IS_OK(status
)) {
1676 smbd_server_connection_terminate(xconn
,
1680 } else if (req
->do_signing
) {
1681 struct smbXsrv_session
*x
= req
->session
;
1682 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
1684 status
= smb2_signing_sign_pdu(signing_key
,
1686 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
],
1687 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
1688 if (!NT_STATUS_IS_OK(status
)) {
1689 smbd_server_connection_terminate(xconn
,
1695 state
->queue_entry
.mem_ctx
= state
;
1696 state
->queue_entry
.vector
= state
->vector
;
1697 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
1698 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
1699 xconn
->smb2
.send_queue_len
++;
1701 status
= smbd_smb2_flush_send_queue(xconn
);
1702 if (!NT_STATUS_IS_OK(status
)) {
1703 smbd_server_connection_terminate(xconn
,
1709 static NTSTATUS
smbd_smb2_request_process_cancel(struct smbd_smb2_request
*req
)
1711 struct smbXsrv_connection
*xconn
= req
->xconn
;
1712 struct smbd_smb2_request
*cur
;
1713 const uint8_t *inhdr
;
1715 uint64_t search_message_id
;
1716 uint64_t search_async_id
;
1719 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1721 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1722 search_message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
1723 search_async_id
= BVAL(inhdr
, SMB2_HDR_PID
);
1726 * We don't need the request anymore cancel requests never
1729 * We defer the TALLOC_FREE(req) to the caller.
1731 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
1733 for (cur
= xconn
->smb2
.requests
; cur
; cur
= cur
->next
) {
1734 const uint8_t *outhdr
;
1735 uint64_t message_id
;
1738 if (cur
->compound_related
) {
1740 * Never cancel anything in a compound request.
1741 * Way too hard to deal with the result.
1746 outhdr
= SMBD_SMB2_OUT_HDR_PTR(cur
);
1748 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
1749 async_id
= BVAL(outhdr
, SMB2_HDR_PID
);
1751 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
1752 if (search_async_id
== async_id
) {
1753 found_id
= async_id
;
1757 if (search_message_id
== message_id
) {
1758 found_id
= message_id
;
1764 if (cur
&& cur
->subreq
) {
1765 inhdr
= SMBD_SMB2_IN_HDR_PTR(cur
);
1766 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1767 "cancel opcode[%s] mid %llu\n",
1768 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
1769 (unsigned long long)found_id
));
1770 tevent_req_cancel(cur
->subreq
);
1773 return NT_STATUS_OK
;
1776 /*************************************************************
1777 Ensure an incoming tid is a valid one for us to access.
1778 Change to the associated uid credentials and chdir to the
1779 valid tid directory.
1780 *************************************************************/
1782 static NTSTATUS
smbd_smb2_request_check_tcon(struct smbd_smb2_request
*req
)
1784 const uint8_t *inhdr
;
1787 struct smbXsrv_tcon
*tcon
;
1789 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1793 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1795 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1796 in_tid
= IVAL(inhdr
, SMB2_HDR_TID
);
1798 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
1799 in_tid
= req
->last_tid
;
1804 status
= smb2srv_tcon_lookup(req
->session
,
1805 in_tid
, now
, &tcon
);
1806 if (!NT_STATUS_IS_OK(status
)) {
1810 if (!change_to_user(tcon
->compat
, req
->session
->compat
->vuid
)) {
1811 return NT_STATUS_ACCESS_DENIED
;
1814 if (!set_current_service(tcon
->compat
, 0, true)) {
1815 return NT_STATUS_ACCESS_DENIED
;
1819 req
->last_tid
= in_tid
;
1821 return NT_STATUS_OK
;
1824 /*************************************************************
1825 Ensure an incoming session_id is a valid one for us to access.
1826 *************************************************************/
1828 static NTSTATUS
smbd_smb2_request_check_session(struct smbd_smb2_request
*req
)
1830 const uint8_t *inhdr
;
1833 uint64_t in_session_id
;
1834 struct smbXsrv_session
*session
= NULL
;
1835 struct auth_session_info
*session_info
;
1837 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1839 req
->session
= NULL
;
1842 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1844 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1845 in_opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
1846 in_session_id
= BVAL(inhdr
, SMB2_HDR_SESSION_ID
);
1848 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
1849 in_session_id
= req
->last_session_id
;
1852 req
->last_session_id
= 0;
1854 /* look an existing session up */
1855 switch (in_opcode
) {
1856 case SMB2_OP_SESSSETUP
:
1858 * For a session bind request, we don't have the
1859 * channel set up at this point yet, so we defer
1860 * the verification that the connection belongs
1861 * to the session to the session setup code, which
1862 * can look at the session binding flags.
1864 status
= smb2srv_session_lookup_client(req
->xconn
->client
,
1869 status
= smb2srv_session_lookup_conn(req
->xconn
,
1875 req
->session
= session
;
1876 req
->last_session_id
= in_session_id
;
1878 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1879 switch (in_opcode
) {
1880 case SMB2_OP_SESSSETUP
:
1881 status
= NT_STATUS_OK
;
1887 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1888 switch (in_opcode
) {
1890 case SMB2_OP_CREATE
:
1891 case SMB2_OP_GETINFO
:
1892 case SMB2_OP_SETINFO
:
1893 return NT_STATUS_INVALID_HANDLE
;
1896 * Notice the check for
1897 * (session_info == NULL)
1900 status
= NT_STATUS_OK
;
1904 if (!NT_STATUS_IS_OK(status
)) {
1908 session_info
= session
->global
->auth_session_info
;
1909 if (session_info
== NULL
) {
1910 return NT_STATUS_INVALID_HANDLE
;
1913 if (in_session_id
!= req
->xconn
->client
->last_session_id
) {
1914 req
->xconn
->client
->last_session_id
= in_session_id
;
1915 set_current_user_info(session_info
->unix_info
->sanitized_username
,
1916 session_info
->unix_info
->unix_name
,
1917 session_info
->info
->domain_name
);
1920 return NT_STATUS_OK
;
1923 NTSTATUS
smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request
*req
,
1924 uint32_t data_length
)
1926 struct smbXsrv_connection
*xconn
= req
->xconn
;
1927 uint16_t needed_charge
;
1928 uint16_t credit_charge
= 1;
1929 const uint8_t *inhdr
;
1931 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1933 if (xconn
->smb2
.credits
.multicredit
) {
1934 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
1935 credit_charge
= MAX(credit_charge
, 1);
1938 needed_charge
= (data_length
- 1)/ 65536 + 1;
1940 DEBUG(10, ("mid %llu, CreditCharge: %d, NeededCharge: %d\n",
1941 (unsigned long long) BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
),
1942 credit_charge
, needed_charge
));
1944 if (needed_charge
> credit_charge
) {
1945 DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
1946 credit_charge
, needed_charge
));
1947 return NT_STATUS_INVALID_PARAMETER
;
1950 return NT_STATUS_OK
;
1953 NTSTATUS
smbd_smb2_request_verify_sizes(struct smbd_smb2_request
*req
,
1954 size_t expected_body_size
)
1956 struct iovec
*inhdr_v
;
1957 const uint8_t *inhdr
;
1959 const uint8_t *inbody
;
1961 size_t min_dyn_size
= expected_body_size
& 0x00000001;
1962 int max_idx
= req
->in
.vector_count
- SMBD_SMB2_NUM_IOV_PER_REQ
;
1965 * The following should be checked already.
1967 if (req
->in
.vector_count
< SMBD_SMB2_NUM_IOV_PER_REQ
) {
1968 return NT_STATUS_INTERNAL_ERROR
;
1970 if (req
->current_idx
> max_idx
) {
1971 return NT_STATUS_INTERNAL_ERROR
;
1974 inhdr_v
= SMBD_SMB2_IN_HDR_IOV(req
);
1975 if (inhdr_v
->iov_len
!= SMB2_HDR_BODY
) {
1976 return NT_STATUS_INTERNAL_ERROR
;
1978 if (SMBD_SMB2_IN_BODY_LEN(req
) < 2) {
1979 return NT_STATUS_INTERNAL_ERROR
;
1982 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1983 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
1987 case SMB2_OP_GETINFO
:
1991 if (req
->smb1req
!= NULL
&& req
->smb1req
->unread_bytes
> 0) {
1992 if (req
->smb1req
->unread_bytes
< min_dyn_size
) {
1993 return NT_STATUS_INVALID_PARAMETER
;
2002 * Now check the expected body size,
2003 * where the last byte might be in the
2006 if (SMBD_SMB2_IN_BODY_LEN(req
) != (expected_body_size
& 0xFFFFFFFE)) {
2007 return NT_STATUS_INVALID_PARAMETER
;
2009 if (SMBD_SMB2_IN_DYN_LEN(req
) < min_dyn_size
) {
2010 return NT_STATUS_INVALID_PARAMETER
;
2013 inbody
= SMBD_SMB2_IN_BODY_PTR(req
);
2015 body_size
= SVAL(inbody
, 0x00);
2016 if (body_size
!= expected_body_size
) {
2017 return NT_STATUS_INVALID_PARAMETER
;
2020 return NT_STATUS_OK
;
2023 bool smbXsrv_is_encrypted(uint8_t encryption_flags
)
2025 return (!(encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
)
2027 (encryption_flags
& (SMBXSRV_PROCESSED_ENCRYPTED_PACKET
|
2028 SMBXSRV_ENCRYPTION_DESIRED
|
2029 SMBXSRV_ENCRYPTION_REQUIRED
)));
2032 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags
)
2034 return ((encryption_flags
& SMBXSRV_PROCESSED_ENCRYPTED_PACKET
) &&
2035 (encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
));
2038 /* Set a flag if not already set, return true if set */
2039 bool smbXsrv_set_crypto_flag(uint8_t *flags
, uint8_t flag
)
2041 if ((flag
== 0) || (*flags
& flag
)) {
2050 * Update encryption state tracking flags, this can be used to
2051 * determine whether whether the session or tcon is "encrypted".
2053 static void smb2srv_update_crypto_flags(struct smbd_smb2_request
*req
,
2055 bool *update_session_globalp
,
2056 bool *update_tcon_globalp
)
2058 /* Default: assume unecrypted and unsigned */
2059 struct smbXsrv_session
*session
= req
->session
;
2060 struct smbXsrv_tcon
*tcon
= req
->tcon
;
2061 uint8_t encrypt_flag
= SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
;
2062 uint8_t sign_flag
= SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
2063 bool update_session
= false;
2064 bool update_tcon
= false;
2066 if (req
->was_encrypted
&& req
->do_encryption
) {
2067 encrypt_flag
= SMBXSRV_PROCESSED_ENCRYPTED_PACKET
;
2068 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2070 /* Unencrypted packet, can be signed */
2071 if (req
->do_signing
) {
2072 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2073 } else if (opcode
== SMB2_OP_CANCEL
) {
2074 /* Cancel requests are allowed to skip signing */
2075 sign_flag
&= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
2079 update_session
|= smbXsrv_set_crypto_flag(
2080 &session
->global
->encryption_flags
, encrypt_flag
);
2081 update_session
|= smbXsrv_set_crypto_flag(
2082 &session
->global
->signing_flags
, sign_flag
);
2085 update_tcon
|= smbXsrv_set_crypto_flag(
2086 &tcon
->global
->encryption_flags
, encrypt_flag
);
2087 update_tcon
|= smbXsrv_set_crypto_flag(
2088 &tcon
->global
->signing_flags
, sign_flag
);
2091 *update_session_globalp
= update_session
;
2092 *update_tcon_globalp
= update_tcon
;
2096 bool smbXsrv_is_signed(uint8_t signing_flags
)
2099 * Signing is always enabled, so unless we got an unsigned
2100 * packet and at least one signed packet that was not
2101 * encrypted, the session or tcon is "signed".
2103 return (!(signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2104 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2107 bool smbXsrv_is_partially_signed(uint8_t signing_flags
)
2109 return ((signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2110 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2113 static NTSTATUS
smbd_smb2_request_dispatch_update_counts(
2114 struct smbd_smb2_request
*req
,
2117 struct smbXsrv_connection
*xconn
= req
->xconn
;
2118 const uint8_t *inhdr
;
2119 uint16_t channel_sequence
;
2122 struct smbXsrv_open
*op
;
2123 bool update_open
= false;
2124 NTSTATUS status
= NT_STATUS_OK
;
2126 req
->request_counters_updated
= false;
2128 if (xconn
->protocol
< PROTOCOL_SMB2_22
) {
2129 return NT_STATUS_OK
;
2132 if (req
->compat_chain_fsp
== NULL
) {
2133 return NT_STATUS_OK
;
2136 op
= req
->compat_chain_fsp
->op
;
2138 return NT_STATUS_OK
;
2141 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2142 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2143 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
2145 cmp
= channel_sequence
- op
->global
->channel_sequence
;
2147 if (abs(cmp
) > INT16_MAX
) {
2149 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2151 * If the channel sequence number of the request and the one
2152 * known to the server are not equal, the channel sequence
2153 * number and outstanding request counts are only updated
2154 * "... if the unsigned difference using 16-bit arithmetic
2155 * between ChannelSequence and Open.ChannelSequence is less than
2156 * or equal to 0x7FFF ...".
2157 * Otherwise, an error is returned for the modifying
2158 * calls write, set_info, and ioctl.
2160 * There are currently two issues with the description:
2162 * * For the other calls, the document seems to imply
2163 * that processing continues without adapting the
2164 * counters (if the sequence numbers are not equal).
2166 * TODO: This needs clarification!
2168 * * Also, the behaviour if the difference is larger
2169 * than 0x7FFF is not clear. The document seems to
2170 * imply that if such a difference is reached,
2171 * the server starts to ignore the counters or
2172 * in the case of the modifying calls, return errors.
2174 * TODO: This needs clarification!
2176 * At this point Samba tries to be a little more
2177 * clever than the description in the MS-SMB2 document
2178 * by heuristically detecting and properly treating
2179 * a 16 bit overflow of the client-submitted sequence
2182 * If the stored channel squence number is more than
2183 * 0x7FFF larger than the one from the request, then
2184 * the client-provided sequence number has likely
2185 * overflown. We treat this case as valid instead
2188 * The MS-SMB2 behaviour would be setting cmp = -1.
2193 if (!(flags
& SMB2_HDR_FLAG_REPLAY_OPERATION
)) {
2195 op
->request_count
+= 1;
2196 req
->request_counters_updated
= true;
2197 } else if (cmp
> 0) {
2198 op
->pre_request_count
+= op
->request_count
;
2199 op
->request_count
= 1;
2200 op
->global
->channel_sequence
= channel_sequence
;
2202 req
->request_counters_updated
= true;
2203 } else if (modify_call
) {
2204 return NT_STATUS_FILE_NOT_AVAILABLE
;
2207 if (cmp
== 0 && op
->pre_request_count
== 0) {
2208 op
->request_count
+= 1;
2209 req
->request_counters_updated
= true;
2210 } else if (cmp
> 0 && op
->pre_request_count
== 0) {
2211 op
->pre_request_count
+= op
->request_count
;
2212 op
->request_count
= 1;
2213 op
->global
->channel_sequence
= channel_sequence
;
2215 req
->request_counters_updated
= true;
2216 } else if (modify_call
) {
2217 return NT_STATUS_FILE_NOT_AVAILABLE
;
2222 status
= smbXsrv_open_update(op
);
2228 NTSTATUS
smbd_smb2_request_dispatch(struct smbd_smb2_request
*req
)
2230 struct smbXsrv_connection
*xconn
= req
->xconn
;
2231 const struct smbd_smb2_dispatch_table
*call
= NULL
;
2232 const struct iovec
*intf_v
= SMBD_SMB2_IN_TF_IOV(req
);
2233 const uint8_t *inhdr
;
2238 NTSTATUS session_status
;
2239 uint32_t allowed_flags
;
2240 NTSTATUS return_value
;
2241 struct smbXsrv_session
*x
= NULL
;
2242 bool signing_required
= false;
2243 bool encryption_desired
= false;
2244 bool encryption_required
= false;
2246 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2248 DO_PROFILE_INC(request
);
2250 /* TODO: verify more things */
2252 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2253 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2254 mid
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
2255 DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2256 smb2_opcode_name(opcode
),
2257 (unsigned long long)mid
));
2259 if (xconn
->protocol
>= PROTOCOL_SMB2_02
) {
2261 * once the protocol is negotiated
2262 * SMB2_OP_NEGPROT is not allowed anymore
2264 if (opcode
== SMB2_OP_NEGPROT
) {
2265 /* drop the connection */
2266 return NT_STATUS_INVALID_PARAMETER
;
2270 * if the protocol is not negotiated yet
2271 * only SMB2_OP_NEGPROT is allowed.
2273 if (opcode
!= SMB2_OP_NEGPROT
) {
2274 /* drop the connection */
2275 return NT_STATUS_INVALID_PARAMETER
;
2280 * Check if the client provided a valid session id,
2281 * if so smbd_smb2_request_check_session() calls
2282 * set_current_user_info().
2284 * As some command don't require a valid session id
2285 * we defer the check of the session_status
2287 session_status
= smbd_smb2_request_check_session(req
);
2290 signing_required
= x
->global
->signing_flags
& SMBXSRV_SIGNING_REQUIRED
;
2291 encryption_desired
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
;
2292 encryption_required
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
;
2295 req
->do_signing
= false;
2296 req
->do_encryption
= false;
2297 req
->was_encrypted
= false;
2298 if (intf_v
->iov_len
== SMB2_TF_HDR_SIZE
) {
2299 const uint8_t *intf
= SMBD_SMB2_IN_TF_PTR(req
);
2300 uint64_t tf_session_id
= BVAL(intf
, SMB2_TF_SESSION_ID
);
2302 if (x
!= NULL
&& x
->global
->session_wire_id
!= tf_session_id
) {
2303 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2304 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2305 (unsigned long long)x
->global
->session_wire_id
,
2306 (unsigned long long)tf_session_id
));
2308 * TODO: windows allows this...
2309 * should we drop the connection?
2311 * For now we just return ACCESS_DENIED
2312 * (Windows clients never trigger this)
2313 * and wait for an update of [MS-SMB2].
2315 return smbd_smb2_request_error(req
,
2316 NT_STATUS_ACCESS_DENIED
);
2319 req
->was_encrypted
= true;
2322 if (encryption_required
&& !req
->was_encrypted
) {
2323 return smbd_smb2_request_error(req
,
2324 NT_STATUS_ACCESS_DENIED
);
2327 call
= smbd_smb2_call(opcode
);
2329 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2332 allowed_flags
= SMB2_HDR_FLAG_CHAINED
|
2333 SMB2_HDR_FLAG_SIGNED
|
2335 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
2336 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
2338 if (opcode
== SMB2_OP_NEGPROT
) {
2339 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11
) {
2340 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
2343 if (opcode
== SMB2_OP_CANCEL
) {
2344 allowed_flags
|= SMB2_HDR_FLAG_ASYNC
;
2346 if (xconn
->protocol
>= PROTOCOL_SMB2_22
) {
2347 allowed_flags
|= SMB2_HDR_FLAG_REPLAY_OPERATION
;
2349 if ((flags
& ~allowed_flags
) != 0) {
2350 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2353 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
2355 * This check is mostly for giving the correct error code
2356 * for compounded requests.
2358 if (!NT_STATUS_IS_OK(session_status
)) {
2359 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2362 req
->compat_chain_fsp
= NULL
;
2365 if (req
->was_encrypted
) {
2366 signing_required
= false;
2367 } else if (signing_required
|| (flags
& SMB2_HDR_FLAG_SIGNED
)) {
2368 DATA_BLOB signing_key
= data_blob_null
;
2372 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2373 * If the SMB2 header of the SMB2 NEGOTIATE
2374 * request has the SMB2_FLAGS_SIGNED bit set in the
2375 * Flags field, the server MUST fail the request
2376 * with STATUS_INVALID_PARAMETER.
2378 * Microsoft test tool checks this.
2381 if ((opcode
== SMB2_OP_NEGPROT
) &&
2382 (flags
& SMB2_HDR_FLAG_SIGNED
)) {
2383 status
= NT_STATUS_INVALID_PARAMETER
;
2385 status
= NT_STATUS_USER_SESSION_DELETED
;
2387 return smbd_smb2_request_error(req
, status
);
2390 signing_key
= smbd_smb2_signing_key(x
, xconn
);
2393 * If we have a signing key, we should
2396 if (signing_key
.length
> 0) {
2397 req
->do_signing
= true;
2400 status
= smb2_signing_check_pdu(signing_key
,
2402 SMBD_SMB2_IN_HDR_IOV(req
),
2403 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2404 if (!NT_STATUS_IS_OK(status
)) {
2405 return smbd_smb2_request_error(req
, status
);
2409 * Now that we know the request was correctly signed
2410 * we have to sign the response too.
2412 req
->do_signing
= true;
2414 if (!NT_STATUS_IS_OK(session_status
)) {
2415 return smbd_smb2_request_error(req
, session_status
);
2417 } else if (opcode
== SMB2_OP_CANCEL
) {
2418 /* Cancel requests are allowed to skip the signing */
2419 } else if (signing_required
) {
2421 * If signing is required we try to sign
2422 * a possible error response
2424 req
->do_signing
= true;
2425 return smbd_smb2_request_error(req
, NT_STATUS_ACCESS_DENIED
);
2428 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
2429 req
->compound_related
= true;
2432 if (call
->need_session
) {
2433 if (!NT_STATUS_IS_OK(session_status
)) {
2434 return smbd_smb2_request_error(req
, session_status
);
2438 if (call
->need_tcon
) {
2439 SMB_ASSERT(call
->need_session
);
2442 * This call needs to be run as user.
2444 * smbd_smb2_request_check_tcon()
2445 * calls change_to_user() on success.
2447 status
= smbd_smb2_request_check_tcon(req
);
2448 if (!NT_STATUS_IS_OK(status
)) {
2449 return smbd_smb2_request_error(req
, status
);
2451 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
) {
2452 encryption_desired
= true;
2454 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
) {
2455 encryption_required
= true;
2457 if (encryption_required
&& !req
->was_encrypted
) {
2458 return smbd_smb2_request_error(req
,
2459 NT_STATUS_ACCESS_DENIED
);
2463 if (req
->was_encrypted
|| encryption_desired
) {
2464 req
->do_encryption
= true;
2468 bool update_session_global
= false;
2469 bool update_tcon_global
= false;
2471 smb2srv_update_crypto_flags(req
, opcode
,
2472 &update_session_global
,
2473 &update_tcon_global
);
2475 if (update_session_global
) {
2476 status
= smbXsrv_session_update(x
);
2477 if (!NT_STATUS_IS_OK(status
)) {
2478 return smbd_smb2_request_error(req
, status
);
2481 if (update_tcon_global
) {
2482 status
= smbXsrv_tcon_update(req
->tcon
);
2483 if (!NT_STATUS_IS_OK(status
)) {
2484 return smbd_smb2_request_error(req
, status
);
2489 if (call
->fileid_ofs
!= 0) {
2490 size_t needed
= call
->fileid_ofs
+ 16;
2491 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
2492 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
2493 uint64_t file_id_persistent
;
2494 uint64_t file_id_volatile
;
2495 struct files_struct
*fsp
;
2497 SMB_ASSERT(call
->need_tcon
);
2499 if (needed
> body_size
) {
2500 return smbd_smb2_request_error(req
,
2501 NT_STATUS_INVALID_PARAMETER
);
2504 file_id_persistent
= BVAL(body
, call
->fileid_ofs
+ 0);
2505 file_id_volatile
= BVAL(body
, call
->fileid_ofs
+ 8);
2507 fsp
= file_fsp_smb2(req
, file_id_persistent
, file_id_volatile
);
2509 if (!call
->allow_invalid_fileid
) {
2510 return smbd_smb2_request_error(req
,
2511 NT_STATUS_FILE_CLOSED
);
2514 if (file_id_persistent
!= UINT64_MAX
) {
2515 return smbd_smb2_request_error(req
,
2516 NT_STATUS_FILE_CLOSED
);
2518 if (file_id_volatile
!= UINT64_MAX
) {
2519 return smbd_smb2_request_error(req
,
2520 NT_STATUS_FILE_CLOSED
);
2525 status
= smbd_smb2_request_dispatch_update_counts(req
, call
->modify
);
2526 if (!NT_STATUS_IS_OK(status
)) {
2527 return smbd_smb2_request_error(req
, status
);
2530 if (call
->as_root
) {
2531 SMB_ASSERT(call
->fileid_ofs
== 0);
2532 /* This call needs to be run as root */
2533 change_to_root_user();
2535 SMB_ASSERT(call
->need_tcon
);
2538 #define _INBYTES(_r) \
2539 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2542 case SMB2_OP_NEGPROT
:
2543 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot
, profile_p
,
2544 req
->profile
, _INBYTES(req
));
2545 return_value
= smbd_smb2_request_process_negprot(req
);
2548 case SMB2_OP_SESSSETUP
:
2549 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup
, profile_p
,
2550 req
->profile
, _INBYTES(req
));
2551 return_value
= smbd_smb2_request_process_sesssetup(req
);
2554 case SMB2_OP_LOGOFF
:
2555 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff
, profile_p
,
2556 req
->profile
, _INBYTES(req
));
2557 return_value
= smbd_smb2_request_process_logoff(req
);
2561 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon
, profile_p
,
2562 req
->profile
, _INBYTES(req
));
2563 return_value
= smbd_smb2_request_process_tcon(req
);
2567 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis
, profile_p
,
2568 req
->profile
, _INBYTES(req
));
2569 return_value
= smbd_smb2_request_process_tdis(req
);
2572 case SMB2_OP_CREATE
:
2573 if (req
->subreq
== NULL
) {
2574 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create
, profile_p
,
2575 req
->profile
, _INBYTES(req
));
2577 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req
->profile
);
2579 return_value
= smbd_smb2_request_process_create(req
);
2583 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close
, profile_p
,
2584 req
->profile
, _INBYTES(req
));
2585 return_value
= smbd_smb2_request_process_close(req
);
2589 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush
, profile_p
,
2590 req
->profile
, _INBYTES(req
));
2591 return_value
= smbd_smb2_request_process_flush(req
);
2595 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read
, profile_p
,
2596 req
->profile
, _INBYTES(req
));
2597 return_value
= smbd_smb2_request_process_read(req
);
2601 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write
, profile_p
,
2602 req
->profile
, _INBYTES(req
));
2603 return_value
= smbd_smb2_request_process_write(req
);
2607 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock
, profile_p
,
2608 req
->profile
, _INBYTES(req
));
2609 return_value
= smbd_smb2_request_process_lock(req
);
2613 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl
, profile_p
,
2614 req
->profile
, _INBYTES(req
));
2615 return_value
= smbd_smb2_request_process_ioctl(req
);
2618 case SMB2_OP_CANCEL
:
2619 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel
, profile_p
,
2620 req
->profile
, _INBYTES(req
));
2621 return_value
= smbd_smb2_request_process_cancel(req
);
2622 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
, 0);
2625 * We don't need the request anymore cancel requests never
2628 * smbd_smb2_request_process_cancel() already called
2629 * DLIST_REMOVE(xconn->smb2.requests, req);
2635 case SMB2_OP_KEEPALIVE
:
2636 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive
, profile_p
,
2637 req
->profile
, _INBYTES(req
));
2638 return_value
= smbd_smb2_request_process_keepalive(req
);
2641 case SMB2_OP_QUERY_DIRECTORY
:
2642 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find
, profile_p
,
2643 req
->profile
, _INBYTES(req
));
2644 return_value
= smbd_smb2_request_process_query_directory(req
);
2647 case SMB2_OP_NOTIFY
:
2648 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify
, profile_p
,
2649 req
->profile
, _INBYTES(req
));
2650 return_value
= smbd_smb2_request_process_notify(req
);
2653 case SMB2_OP_GETINFO
:
2654 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo
, profile_p
,
2655 req
->profile
, _INBYTES(req
));
2656 return_value
= smbd_smb2_request_process_getinfo(req
);
2659 case SMB2_OP_SETINFO
:
2660 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo
, profile_p
,
2661 req
->profile
, _INBYTES(req
));
2662 return_value
= smbd_smb2_request_process_setinfo(req
);
2666 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break
, profile_p
,
2667 req
->profile
, _INBYTES(req
));
2668 return_value
= smbd_smb2_request_process_break(req
);
2672 return_value
= smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2675 return return_value
;
2678 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request
*req
)
2680 struct smbXsrv_connection
*xconn
= req
->xconn
;
2681 const uint8_t *inhdr
;
2682 uint16_t channel_sequence
;
2683 struct smbXsrv_open
*op
;
2685 if (!req
->request_counters_updated
) {
2689 if (xconn
->protocol
< PROTOCOL_SMB2_22
) {
2693 if (req
->compat_chain_fsp
== NULL
) {
2697 op
= req
->compat_chain_fsp
->op
;
2702 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2703 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
2705 if (op
->global
->channel_sequence
== channel_sequence
) {
2706 SMB_ASSERT(op
->request_count
> 0);
2707 op
->request_count
-= 1;
2709 SMB_ASSERT(op
->pre_request_count
> 0);
2710 op
->pre_request_count
-= 1;
2714 static NTSTATUS
smbd_smb2_request_reply(struct smbd_smb2_request
*req
)
2716 struct smbXsrv_connection
*xconn
= req
->xconn
;
2718 struct iovec
*firsttf
= SMBD_SMB2_IDX_TF_IOV(req
,out
,first_idx
);
2719 struct iovec
*outhdr
= SMBD_SMB2_OUT_HDR_IOV(req
);
2720 struct iovec
*outdyn
= SMBD_SMB2_OUT_DYN_IOV(req
);
2725 TALLOC_FREE(req
->async_te
);
2727 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
2728 smbd_smb2_request_reply_update_counts(req
);
2730 if (req
->do_encryption
&&
2731 (firsttf
->iov_len
== 0) &&
2732 (req
->first_key
.length
== 0) &&
2733 (req
->session
!= NULL
) &&
2734 (req
->session
->global
->encryption_key
.length
!= 0))
2736 DATA_BLOB encryption_key
= req
->session
->global
->encryption_key
;
2738 uint64_t session_id
= req
->session
->global
->session_wire_id
;
2739 uint64_t nonce_high
;
2742 status
= smb2_get_new_nonce(req
->session
,
2745 if (!NT_STATUS_IS_OK(status
)) {
2750 * We need to place the SMB2_TRANSFORM header before the
2755 * we need to remember the encryption key
2756 * and defer the signing/encryption until
2757 * we are sure that we do not change
2760 req
->first_key
= data_blob_dup_talloc(req
, encryption_key
);
2761 if (req
->first_key
.data
== NULL
) {
2762 return NT_STATUS_NO_MEMORY
;
2765 tf
= talloc_zero_array(req
, uint8_t,
2768 return NT_STATUS_NO_MEMORY
;
2771 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2772 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
2773 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
2774 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
2776 firsttf
->iov_base
= (void *)tf
;
2777 firsttf
->iov_len
= SMB2_TF_HDR_SIZE
;
2780 if ((req
->current_idx
> SMBD_SMB2_NUM_IOV_PER_REQ
) &&
2781 (req
->last_key
.length
> 0) &&
2782 (firsttf
->iov_len
== 0))
2784 int last_idx
= req
->current_idx
- SMBD_SMB2_NUM_IOV_PER_REQ
;
2785 struct iovec
*lasthdr
= SMBD_SMB2_IDX_HDR_IOV(req
,out
,last_idx
);
2788 * As we are sure the header of the last request in the
2789 * compound chain will not change, we can to sign here
2790 * with the last signing key we remembered.
2792 status
= smb2_signing_sign_pdu(req
->last_key
,
2795 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2796 if (!NT_STATUS_IS_OK(status
)) {
2800 if (req
->last_key
.length
> 0) {
2801 data_blob_clear_free(&req
->last_key
);
2804 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
,
2805 iov_buflen(outhdr
, SMBD_SMB2_NUM_IOV_PER_REQ
-1));
2807 req
->current_idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
2809 if (req
->current_idx
< req
->out
.vector_count
) {
2811 * We must process the remaining compound
2812 * SMB2 requests before any new incoming SMB2
2813 * requests. This is because incoming SMB2
2814 * requests may include a cancel for a
2815 * compound request we haven't processed
2818 struct tevent_immediate
*im
= tevent_create_immediate(req
);
2820 return NT_STATUS_NO_MEMORY
;
2823 if (req
->do_signing
&& firsttf
->iov_len
== 0) {
2824 struct smbXsrv_session
*x
= req
->session
;
2825 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
2828 * we need to remember the signing key
2829 * and defer the signing until
2830 * we are sure that we do not change
2833 req
->last_key
= data_blob_dup_talloc(req
, signing_key
);
2834 if (req
->last_key
.data
== NULL
) {
2835 return NT_STATUS_NO_MEMORY
;
2839 tevent_schedule_immediate(im
,
2841 smbd_smb2_request_dispatch_immediate
,
2843 return NT_STATUS_OK
;
2846 if (req
->compound_related
) {
2847 req
->compound_related
= false;
2850 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
2852 return NT_STATUS_INVALID_PARAMETER_MIX
;
2855 /* Set credit for these operations (zero credits if this
2856 is a final reply for an async operation). */
2857 smb2_calculate_credits(req
, req
);
2860 * now check if we need to sign the current response
2862 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
2863 status
= smb2_signing_encrypt_pdu(req
->first_key
,
2864 xconn
->smb2
.server
.cipher
,
2866 req
->out
.vector_count
- first_idx
);
2867 if (!NT_STATUS_IS_OK(status
)) {
2870 } else if (req
->do_signing
) {
2871 struct smbXsrv_session
*x
= req
->session
;
2872 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
2874 status
= smb2_signing_sign_pdu(signing_key
,
2877 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2878 if (!NT_STATUS_IS_OK(status
)) {
2882 if (req
->first_key
.length
> 0) {
2883 data_blob_clear_free(&req
->first_key
);
2886 if (req
->preauth
!= NULL
) {
2887 struct hc_sha512state sctx
;
2890 samba_SHA512_Init(&sctx
);
2891 samba_SHA512_Update(&sctx
, req
->preauth
->sha512_value
,
2892 sizeof(req
->preauth
->sha512_value
));
2893 for (i
= 1; i
< req
->in
.vector_count
; i
++) {
2894 samba_SHA512_Update(&sctx
,
2895 req
->in
.vector
[i
].iov_base
,
2896 req
->in
.vector
[i
].iov_len
);
2898 samba_SHA512_Final(req
->preauth
->sha512_value
, &sctx
);
2900 samba_SHA512_Init(&sctx
);
2901 samba_SHA512_Update(&sctx
, req
->preauth
->sha512_value
,
2902 sizeof(req
->preauth
->sha512_value
));
2903 for (i
= 1; i
< req
->out
.vector_count
; i
++) {
2904 samba_SHA512_Update(&sctx
,
2905 req
->out
.vector
[i
].iov_base
,
2906 req
->out
.vector
[i
].iov_len
);
2908 samba_SHA512_Final(req
->preauth
->sha512_value
, &sctx
);
2910 req
->preauth
= NULL
;
2913 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2914 if (req
->out
.vector_count
< (2*SMBD_SMB2_NUM_IOV_PER_REQ
) &&
2915 outdyn
->iov_base
== NULL
&& outdyn
->iov_len
!= 0) {
2916 /* Dynamic part is NULL. Chop it off,
2917 We're going to send it via sendfile. */
2918 req
->out
.vector_count
-= 1;
2922 * We're done with this request -
2923 * move it off the "being processed" queue.
2925 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
2927 req
->queue_entry
.mem_ctx
= req
;
2928 req
->queue_entry
.vector
= req
->out
.vector
;
2929 req
->queue_entry
.count
= req
->out
.vector_count
;
2930 DLIST_ADD_END(xconn
->smb2
.send_queue
, &req
->queue_entry
);
2931 xconn
->smb2
.send_queue_len
++;
2933 status
= smbd_smb2_flush_send_queue(xconn
);
2934 if (!NT_STATUS_IS_OK(status
)) {
2938 return NT_STATUS_OK
;
2941 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
);
2943 void smbd_smb2_request_dispatch_immediate(struct tevent_context
*ctx
,
2944 struct tevent_immediate
*im
,
2947 struct smbd_smb2_request
*req
= talloc_get_type_abort(private_data
,
2948 struct smbd_smb2_request
);
2949 struct smbXsrv_connection
*xconn
= req
->xconn
;
2954 if (DEBUGLEVEL
>= 10) {
2955 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2956 req
->current_idx
, req
->in
.vector_count
));
2957 print_req_vectors(req
);
2960 status
= smbd_smb2_request_dispatch(req
);
2961 if (!NT_STATUS_IS_OK(status
)) {
2962 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
2966 status
= smbd_smb2_request_next_incoming(xconn
);
2967 if (!NT_STATUS_IS_OK(status
)) {
2968 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
2973 NTSTATUS
smbd_smb2_request_done_ex(struct smbd_smb2_request
*req
,
2975 DATA_BLOB body
, DATA_BLOB
*dyn
,
2976 const char *location
)
2979 struct iovec
*outbody_v
;
2980 struct iovec
*outdyn_v
;
2981 uint32_t next_command_ofs
;
2983 DEBUG(10,("smbd_smb2_request_done_ex: "
2984 "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
2985 req
->current_idx
, nt_errstr(status
), (unsigned int)body
.length
,
2987 (unsigned int)(dyn
? dyn
->length
: 0),
2990 if (body
.length
< 2) {
2991 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
2994 if ((body
.length
% 2) != 0) {
2995 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
2998 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2999 outbody_v
= SMBD_SMB2_OUT_BODY_IOV(req
);
3000 outdyn_v
= SMBD_SMB2_OUT_DYN_IOV(req
);
3002 next_command_ofs
= IVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
);
3003 SIVAL(outhdr
, SMB2_HDR_STATUS
, NT_STATUS_V(status
));
3005 outbody_v
->iov_base
= (void *)body
.data
;
3006 outbody_v
->iov_len
= body
.length
;
3009 outdyn_v
->iov_base
= (void *)dyn
->data
;
3010 outdyn_v
->iov_len
= dyn
->length
;
3012 outdyn_v
->iov_base
= NULL
;
3013 outdyn_v
->iov_len
= 0;
3017 * See if we need to recalculate the offset to the next response
3019 * Note that all responses may require padding (including the very last
3022 if (req
->out
.vector_count
>= (2 * SMBD_SMB2_NUM_IOV_PER_REQ
)) {
3023 next_command_ofs
= SMB2_HDR_BODY
;
3024 next_command_ofs
+= SMBD_SMB2_OUT_BODY_LEN(req
);
3025 next_command_ofs
+= SMBD_SMB2_OUT_DYN_LEN(req
);
3028 if ((next_command_ofs
% 8) != 0) {
3029 size_t pad_size
= 8 - (next_command_ofs
% 8);
3030 if (SMBD_SMB2_OUT_DYN_LEN(req
) == 0) {
3032 * if the dyn buffer is empty
3033 * we can use it to add padding
3037 pad
= talloc_zero_array(req
,
3040 return smbd_smb2_request_error(req
,
3041 NT_STATUS_NO_MEMORY
);
3044 outdyn_v
->iov_base
= (void *)pad
;
3045 outdyn_v
->iov_len
= pad_size
;
3048 * For now we copy the dynamic buffer
3049 * and add the padding to the new buffer
3056 old_size
= SMBD_SMB2_OUT_DYN_LEN(req
);
3057 old_dyn
= SMBD_SMB2_OUT_DYN_PTR(req
);
3059 new_size
= old_size
+ pad_size
;
3060 new_dyn
= talloc_zero_array(req
,
3062 if (new_dyn
== NULL
) {
3063 return smbd_smb2_request_error(req
,
3064 NT_STATUS_NO_MEMORY
);
3067 memcpy(new_dyn
, old_dyn
, old_size
);
3068 memset(new_dyn
+ old_size
, 0, pad_size
);
3070 outdyn_v
->iov_base
= (void *)new_dyn
;
3071 outdyn_v
->iov_len
= new_size
;
3073 next_command_ofs
+= pad_size
;
3076 if ((req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) >= req
->out
.vector_count
) {
3077 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
3079 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
3081 return smbd_smb2_request_reply(req
);
3084 NTSTATUS
smbd_smb2_request_error_ex(struct smbd_smb2_request
*req
,
3087 const char *location
)
3089 struct smbXsrv_connection
*xconn
= req
->xconn
;
3092 uint8_t *outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
3093 size_t unread_bytes
= smbd_smb2_unread_bytes(req
);
3095 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3096 "at %s\n", req
->current_idx
, nt_errstr(status
),
3097 info
? " +info" : "", location
);
3100 /* Recvfile error. Drain incoming socket. */
3104 ret
= drain_socket(xconn
->transport
.sock
, unread_bytes
);
3105 if (ret
!= unread_bytes
) {
3109 error
= NT_STATUS_IO_DEVICE_ERROR
;
3111 error
= map_nt_error_from_unix_common(errno
);
3114 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3115 "ret[%u] errno[%d] => %s\n",
3116 (unsigned)unread_bytes
,
3117 (unsigned)ret
, errno
, nt_errstr(error
)));
3122 body
.data
= outhdr
+ SMB2_HDR_BODY
;
3124 SSVAL(body
.data
, 0, 9);
3127 SIVAL(body
.data
, 0x04, info
->length
);
3129 /* Allocated size of req->out.vector[i].iov_base
3130 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3131 * 1 byte without having to do an alloc.
3134 info
->data
= ((uint8_t *)outhdr
) +
3135 OUTVEC_ALLOC_SIZE
- 1;
3137 SCVAL(info
->data
, 0, 0);
3141 * Note: Even if there is an error, continue to process the request.
3145 return smbd_smb2_request_done_ex(req
, status
, body
, info
, __location__
);
3149 struct smbd_smb2_send_break_state
{
3150 struct smbd_smb2_send_queue queue_entry
;
3151 uint8_t nbt_hdr
[NBT_HDR_SIZE
];
3152 uint8_t tf
[SMB2_TF_HDR_SIZE
];
3153 uint8_t hdr
[SMB2_HDR_BODY
];
3154 struct iovec vector
[1+SMBD_SMB2_NUM_IOV_PER_REQ
];
3158 static NTSTATUS
smbd_smb2_send_break(struct smbXsrv_connection
*xconn
,
3159 struct smbXsrv_session
*session
,
3160 struct smbXsrv_tcon
*tcon
,
3161 const uint8_t *body
,
3164 struct smbd_smb2_send_break_state
*state
;
3165 bool do_encryption
= false;
3166 uint64_t session_wire_id
= 0;
3167 uint64_t nonce_high
= 0;
3168 uint64_t nonce_low
= 0;
3173 if (session
!= NULL
) {
3174 session_wire_id
= session
->global
->session_wire_id
;
3175 do_encryption
= session
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
;
3176 if (tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
) {
3177 do_encryption
= true;
3181 statelen
= offsetof(struct smbd_smb2_send_break_state
, body
) +
3184 state
= talloc_zero_size(xconn
, statelen
);
3185 if (state
== NULL
) {
3186 return NT_STATUS_NO_MEMORY
;
3188 talloc_set_name_const(state
, "struct smbd_smb2_send_break_state");
3190 if (do_encryption
) {
3191 status
= smb2_get_new_nonce(session
,
3194 if (!NT_STATUS_IS_OK(status
)) {
3199 SIVAL(state
->tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
3200 SBVAL(state
->tf
, SMB2_TF_NONCE
+0, nonce_low
);
3201 SBVAL(state
->tf
, SMB2_TF_NONCE
+8, nonce_high
);
3202 SBVAL(state
->tf
, SMB2_TF_SESSION_ID
, session_wire_id
);
3204 SIVAL(state
->hdr
, 0, SMB2_MAGIC
);
3205 SSVAL(state
->hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
3206 SSVAL(state
->hdr
, SMB2_HDR_EPOCH
, 0);
3207 SIVAL(state
->hdr
, SMB2_HDR_STATUS
, 0);
3208 SSVAL(state
->hdr
, SMB2_HDR_OPCODE
, SMB2_OP_BREAK
);
3209 SSVAL(state
->hdr
, SMB2_HDR_CREDIT
, 0);
3210 SIVAL(state
->hdr
, SMB2_HDR_FLAGS
, SMB2_HDR_FLAG_REDIRECT
);
3211 SIVAL(state
->hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
3212 SBVAL(state
->hdr
, SMB2_HDR_MESSAGE_ID
, UINT64_MAX
);
3213 SIVAL(state
->hdr
, SMB2_HDR_PID
, 0);
3214 SIVAL(state
->hdr
, SMB2_HDR_TID
, 0);
3215 SBVAL(state
->hdr
, SMB2_HDR_SESSION_ID
, 0);
3216 memset(state
->hdr
+SMB2_HDR_SIGNATURE
, 0, 16);
3218 state
->vector
[0] = (struct iovec
) {
3219 .iov_base
= state
->nbt_hdr
,
3220 .iov_len
= sizeof(state
->nbt_hdr
)
3223 if (do_encryption
) {
3224 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
3225 .iov_base
= state
->tf
,
3226 .iov_len
= sizeof(state
->tf
)
3229 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
3235 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
] = (struct iovec
) {
3236 .iov_base
= state
->hdr
,
3237 .iov_len
= sizeof(state
->hdr
)
3240 memcpy(state
->body
, body
, body_len
);
3242 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
] = (struct iovec
) {
3243 .iov_base
= state
->body
,
3244 .iov_len
= body_len
/* no sizeof(state->body) .. :-) */
3248 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
3251 ok
= smb2_setup_nbt_length(state
->vector
,
3252 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
3254 return NT_STATUS_INVALID_PARAMETER_MIX
;
3257 if (do_encryption
) {
3258 DATA_BLOB encryption_key
= session
->global
->encryption_key
;
3260 status
= smb2_signing_encrypt_pdu(encryption_key
,
3261 xconn
->smb2
.server
.cipher
,
3262 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
3263 SMBD_SMB2_NUM_IOV_PER_REQ
);
3264 if (!NT_STATUS_IS_OK(status
)) {
3269 state
->queue_entry
.mem_ctx
= state
;
3270 state
->queue_entry
.vector
= state
->vector
;
3271 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
3272 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
3273 xconn
->smb2
.send_queue_len
++;
3275 status
= smbd_smb2_flush_send_queue(xconn
);
3276 if (!NT_STATUS_IS_OK(status
)) {
3280 return NT_STATUS_OK
;
3283 NTSTATUS
smbd_smb2_send_oplock_break(struct smbXsrv_connection
*xconn
,
3284 struct smbXsrv_session
*session
,
3285 struct smbXsrv_tcon
*tcon
,
3286 struct smbXsrv_open
*op
,
3287 uint8_t oplock_level
)
3291 SSVAL(body
, 0x00, sizeof(body
));
3292 SCVAL(body
, 0x02, oplock_level
);
3293 SCVAL(body
, 0x03, 0); /* reserved */
3294 SIVAL(body
, 0x04, 0); /* reserved */
3295 SBVAL(body
, 0x08, op
->global
->open_persistent_id
);
3296 SBVAL(body
, 0x10, op
->global
->open_volatile_id
);
3298 return smbd_smb2_send_break(xconn
, NULL
, NULL
, body
, sizeof(body
));
3301 NTSTATUS
smbd_smb2_send_lease_break(struct smbXsrv_connection
*xconn
,
3303 uint32_t lease_flags
,
3304 struct smb2_lease_key
*lease_key
,
3305 uint32_t current_lease_state
,
3306 uint32_t new_lease_state
)
3310 SSVAL(body
, 0x00, sizeof(body
));
3311 SSVAL(body
, 0x02, new_epoch
);
3312 SIVAL(body
, 0x04, lease_flags
);
3313 SBVAL(body
, 0x08, lease_key
->data
[0]);
3314 SBVAL(body
, 0x10, lease_key
->data
[1]);
3315 SIVAL(body
, 0x18, current_lease_state
);
3316 SIVAL(body
, 0x1c, new_lease_state
);
3317 SIVAL(body
, 0x20, 0); /* BreakReason, MUST be 0 */
3318 SIVAL(body
, 0x24, 0); /* AccessMaskHint, MUST be 0 */
3319 SIVAL(body
, 0x28, 0); /* ShareMaskHint, MUST be 0 */
3321 return smbd_smb2_send_break(xconn
, NULL
, NULL
, body
, sizeof(body
));
3324 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state
*state
)
3328 uint64_t file_id_persistent
;
3329 uint64_t file_id_volatile
;
3330 struct smbXsrv_open
*op
= NULL
;
3331 struct files_struct
*fsp
= NULL
;
3332 const uint8_t *body
= NULL
;
3335 * This is only called with a pktbuf
3336 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
3340 if (IVAL(state
->pktbuf
, 0) == SMB2_TF_MAGIC
) {
3341 /* Transform header. Cannot recvfile. */
3344 if (IVAL(state
->pktbuf
, 0) != SMB2_MAGIC
) {
3345 /* Not SMB2. Normal error path will cope. */
3348 if (SVAL(state
->pktbuf
, 4) != SMB2_HDR_BODY
) {
3349 /* Not SMB2. Normal error path will cope. */
3352 if (SVAL(state
->pktbuf
, SMB2_HDR_OPCODE
) != SMB2_OP_WRITE
) {
3353 /* Needs to be a WRITE. */
3356 if (IVAL(state
->pktbuf
, SMB2_HDR_NEXT_COMMAND
) != 0) {
3357 /* Chained. Cannot recvfile. */
3360 flags
= IVAL(state
->pktbuf
, SMB2_HDR_FLAGS
);
3361 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3362 /* Chained. Cannot recvfile. */
3365 if (flags
& SMB2_HDR_FLAG_SIGNED
) {
3366 /* Signed. Cannot recvfile. */
3370 body
= &state
->pktbuf
[SMB2_HDR_BODY
];
3372 file_id_persistent
= BVAL(body
, 0x10);
3373 file_id_volatile
= BVAL(body
, 0x18);
3375 status
= smb2srv_open_lookup(state
->req
->xconn
,
3380 if (!NT_STATUS_IS_OK(status
)) {
3388 if (fsp
->conn
== NULL
) {
3392 if (IS_IPC(fsp
->conn
)) {
3395 if (IS_PRINT(fsp
->conn
)) {
3399 DEBUG(10,("Doing recvfile write len = %u\n",
3400 (unsigned int)(state
->pktfull
- state
->pktlen
)));
3405 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
)
3407 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3408 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
3409 size_t max_send_queue_len
;
3410 size_t cur_send_queue_len
;
3412 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
3414 * we're not supposed to do any io
3416 return NT_STATUS_OK
;
3419 if (state
->req
!= NULL
) {
3421 * if there is already a tstream_readv_pdu
3422 * pending, we are done.
3424 return NT_STATUS_OK
;
3427 max_send_queue_len
= MAX(1, xconn
->smb2
.credits
.max
/16);
3428 cur_send_queue_len
= xconn
->smb2
.send_queue_len
;
3430 if (cur_send_queue_len
> max_send_queue_len
) {
3432 * if we have a lot of requests to send,
3433 * we wait until they are on the wire until we
3434 * ask for the next request.
3436 return NT_STATUS_OK
;
3439 /* ask for the next request */
3440 ZERO_STRUCTP(state
);
3441 state
->req
= smbd_smb2_request_allocate(xconn
);
3442 if (state
->req
== NULL
) {
3443 return NT_STATUS_NO_MEMORY
;
3445 state
->req
->sconn
= sconn
;
3446 state
->req
->xconn
= xconn
;
3447 state
->min_recv_size
= lp_min_receive_file_size();
3449 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3451 return NT_STATUS_OK
;
3454 void smbd_smb2_process_negprot(struct smbXsrv_connection
*xconn
,
3455 uint64_t expected_seq_low
,
3456 const uint8_t *inpdu
, size_t size
)
3458 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3460 struct smbd_smb2_request
*req
= NULL
;
3462 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3463 (unsigned int)size
));
3465 status
= smbd_initialize_smb2(xconn
, expected_seq_low
);
3466 if (!NT_STATUS_IS_OK(status
)) {
3467 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3471 status
= smbd_smb2_request_create(xconn
, inpdu
, size
, &req
);
3472 if (!NT_STATUS_IS_OK(status
)) {
3473 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3477 status
= smbd_smb2_request_validate(req
);
3478 if (!NT_STATUS_IS_OK(status
)) {
3479 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3483 status
= smbd_smb2_request_setup_out(req
);
3484 if (!NT_STATUS_IS_OK(status
)) {
3485 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3491 * this was already counted at the SMB1 layer =>
3492 * smbd_smb2_request_dispatch() should not count it twice.
3494 if (profile_p
->values
.request_stats
.count
> 0) {
3495 profile_p
->values
.request_stats
.count
--;
3498 status
= smbd_smb2_request_dispatch(req
);
3499 if (!NT_STATUS_IS_OK(status
)) {
3500 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3504 status
= smbd_smb2_request_next_incoming(xconn
);
3505 if (!NT_STATUS_IS_OK(status
)) {
3506 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3510 sconn
->num_requests
++;
3513 static int socket_error_from_errno(int ret
,
3527 if (sys_errno
== 0) {
3531 if (sys_errno
== EINTR
) {
3536 if (sys_errno
== EINPROGRESS
) {
3541 if (sys_errno
== EAGAIN
) {
3546 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3547 if (sys_errno
== ENOMEM
) {
3553 #if EWOULDBLOCK != EAGAIN
3554 if (sys_errno
== EWOULDBLOCK
) {
3564 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
)
3570 if (xconn
->smb2
.send_queue
== NULL
) {
3571 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
3572 return NT_STATUS_OK
;
3575 while (xconn
->smb2
.send_queue
!= NULL
) {
3576 struct smbd_smb2_send_queue
*e
= xconn
->smb2
.send_queue
;
3579 if (e
->sendfile_header
!= NULL
) {
3580 NTSTATUS status
= NT_STATUS_INTERNAL_ERROR
;
3585 for (i
=0; i
< e
->count
; i
++) {
3586 size
+= e
->vector
[i
].iov_len
;
3589 if (size
<= e
->sendfile_header
->length
) {
3590 buf
= e
->sendfile_header
->data
;
3592 buf
= talloc_array(e
->mem_ctx
, uint8_t, size
);
3594 return NT_STATUS_NO_MEMORY
;
3599 for (i
=0; i
< e
->count
; i
++) {
3601 e
->vector
[i
].iov_base
,
3602 e
->vector
[i
].iov_len
);
3603 size
+= e
->vector
[i
].iov_len
;
3606 e
->sendfile_header
->data
= buf
;
3607 e
->sendfile_header
->length
= size
;
3608 e
->sendfile_status
= &status
;
3611 xconn
->smb2
.send_queue_len
--;
3612 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
3614 * This triggers the sendfile path via
3617 talloc_free(e
->mem_ctx
);
3619 if (!NT_STATUS_IS_OK(status
)) {
3625 ret
= writev(xconn
->transport
.sock
, e
->vector
, e
->count
);
3627 /* propagate end of file */
3628 return NT_STATUS_INTERNAL_ERROR
;
3630 err
= socket_error_from_errno(ret
, errno
, &retry
);
3633 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
3634 return NT_STATUS_OK
;
3637 return map_nt_error_from_unix_common(err
);
3640 ok
= iov_advance(&e
->vector
, &e
->count
, ret
);
3642 return NT_STATUS_INTERNAL_ERROR
;
3646 /* we have more to write */
3647 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
3648 return NT_STATUS_OK
;
3651 xconn
->smb2
.send_queue_len
--;
3652 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
3653 talloc_free(e
->mem_ctx
);
3656 return NT_STATUS_OK
;
3659 static NTSTATUS
smbd_smb2_io_handler(struct smbXsrv_connection
*xconn
,
3662 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3663 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
3664 struct smbd_smb2_request
*req
= NULL
;
3665 size_t min_recvfile_size
= UINT32_MAX
;
3672 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
3674 * we're not supposed to do any io
3676 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
3677 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
3678 return NT_STATUS_OK
;
3681 if (fde_flags
& TEVENT_FD_WRITE
) {
3682 status
= smbd_smb2_flush_send_queue(xconn
);
3683 if (!NT_STATUS_IS_OK(status
)) {
3688 if (!(fde_flags
& TEVENT_FD_READ
)) {
3689 return NT_STATUS_OK
;
3692 if (state
->req
== NULL
) {
3693 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
3694 return NT_STATUS_OK
;
3698 if (!state
->hdr
.done
) {
3699 state
->hdr
.done
= true;
3701 state
->vector
.iov_base
= (void *)state
->hdr
.nbt
;
3702 state
->vector
.iov_len
= NBT_HDR_SIZE
;
3705 ret
= readv(xconn
->transport
.sock
, &state
->vector
, 1);
3707 /* propagate end of file */
3708 return NT_STATUS_END_OF_FILE
;
3710 err
= socket_error_from_errno(ret
, errno
, &retry
);
3713 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3714 return NT_STATUS_OK
;
3717 return map_nt_error_from_unix_common(err
);
3720 if (ret
< state
->vector
.iov_len
) {
3722 base
= (uint8_t *)state
->vector
.iov_base
;
3724 state
->vector
.iov_base
= (void *)base
;
3725 state
->vector
.iov_len
-= ret
;
3726 /* we have more to read */
3727 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3728 return NT_STATUS_OK
;
3731 if (state
->pktlen
> 0) {
3732 if (state
->doing_receivefile
&& !is_smb2_recvfile_write(state
)) {
3734 * Not a possible receivefile write.
3735 * Read the rest of the data.
3737 state
->doing_receivefile
= false;
3739 state
->pktbuf
= talloc_realloc(state
->req
,
3743 if (state
->pktbuf
== NULL
) {
3744 return NT_STATUS_NO_MEMORY
;
3747 state
->vector
.iov_base
= (void *)(state
->pktbuf
+
3749 state
->vector
.iov_len
= (state
->pktfull
-
3752 state
->pktlen
= state
->pktfull
;
3757 * Either this is a receivefile write so we've
3758 * done a short read, or if not we have all the data.
3764 * Now we analyze the NBT header
3766 if (state
->hdr
.nbt
[0] != 0x00) {
3767 state
->min_recv_size
= 0;
3769 state
->pktfull
= smb2_len(state
->hdr
.nbt
);
3770 if (state
->pktfull
== 0) {
3774 if (state
->min_recv_size
!= 0) {
3775 min_recvfile_size
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
3776 min_recvfile_size
+= state
->min_recv_size
;
3779 if (state
->pktfull
> min_recvfile_size
) {
3781 * Might be a receivefile write. Read the SMB2 HEADER +
3782 * SMB2_WRITE header first. Set 'doing_receivefile'
3783 * as we're *attempting* receivefile write. If this
3784 * turns out not to be a SMB2_WRITE request or otherwise
3785 * not suitable then we'll just read the rest of the data
3786 * the next time this function is called.
3788 state
->pktlen
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
3789 state
->doing_receivefile
= true;
3791 state
->pktlen
= state
->pktfull
;
3794 state
->pktbuf
= talloc_array(state
->req
, uint8_t, state
->pktlen
);
3795 if (state
->pktbuf
== NULL
) {
3796 return NT_STATUS_NO_MEMORY
;
3799 state
->vector
.iov_base
= (void *)state
->pktbuf
;
3800 state
->vector
.iov_len
= state
->pktlen
;
3806 if (state
->hdr
.nbt
[0] != 0x00) {
3807 DEBUG(1,("ignore NBT[0x%02X] msg\n",
3808 state
->hdr
.nbt
[0]));
3811 ZERO_STRUCTP(state
);
3813 state
->min_recv_size
= lp_min_receive_file_size();
3821 req
->request_time
= timeval_current();
3822 now
= timeval_to_nttime(&req
->request_time
);
3824 status
= smbd_smb2_inbuf_parse_compound(xconn
,
3830 &req
->in
.vector_count
);
3831 if (!NT_STATUS_IS_OK(status
)) {
3835 if (state
->doing_receivefile
) {
3836 req
->smb1req
= talloc_zero(req
, struct smb_request
);
3837 if (req
->smb1req
== NULL
) {
3838 return NT_STATUS_NO_MEMORY
;
3840 req
->smb1req
->unread_bytes
= state
->pktfull
- state
->pktlen
;
3843 ZERO_STRUCTP(state
);
3845 req
->current_idx
= 1;
3847 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
3848 req
->current_idx
, req
->in
.vector_count
));
3850 status
= smbd_smb2_request_validate(req
);
3851 if (!NT_STATUS_IS_OK(status
)) {
3855 status
= smbd_smb2_request_setup_out(req
);
3856 if (!NT_STATUS_IS_OK(status
)) {
3860 status
= smbd_smb2_request_dispatch(req
);
3861 if (!NT_STATUS_IS_OK(status
)) {
3865 sconn
->num_requests
++;
3867 /* The timeout_processing function isn't run nearly
3868 often enough to implement 'max log size' without
3869 overrunning the size of the file by many megabytes.
3870 This is especially true if we are running at debug
3871 level 10. Checking every 50 SMB2s is a nice
3872 tradeoff of performance vs log file size overrun. */
3874 if ((sconn
->num_requests
% 50) == 0 &&
3875 need_to_check_log_size()) {
3876 change_to_root_user();
3880 status
= smbd_smb2_request_next_incoming(xconn
);
3881 if (!NT_STATUS_IS_OK(status
)) {
3885 return NT_STATUS_OK
;
3888 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
3889 struct tevent_fd
*fde
,
3893 struct smbXsrv_connection
*xconn
=
3894 talloc_get_type_abort(private_data
,
3895 struct smbXsrv_connection
);
3898 status
= smbd_smb2_io_handler(xconn
, flags
);
3899 if (!NT_STATUS_IS_OK(status
)) {
3900 smbd_server_connection_terminate(xconn
, nt_errstr(status
));