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
;
49 } smbd_smb2_table
[] = {
50 #define _OP(o) .opcode = o, .name = #o
55 _OP(SMB2_OP_SESSSETUP
),
65 * This call needs to be run as root.
67 * smbd_smb2_request_process_tcon()
68 * calls make_connection_snum(), which will call
69 * change_to_user(), when needed.
103 .need_session
= true,
108 .need_session
= true,
111 .allow_invalid_fileid
= true,
116 _OP(SMB2_OP_KEEPALIVE
),
119 _OP(SMB2_OP_QUERY_DIRECTORY
),
120 .need_session
= true,
125 .need_session
= true,
129 _OP(SMB2_OP_GETINFO
),
130 .need_session
= true,
134 _OP(SMB2_OP_SETINFO
),
135 .need_session
= true,
140 .need_session
= true,
145 * as LEASE breaks does not
151 const char *smb2_opcode_name(uint16_t opcode
)
153 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
154 return "Bad SMB2 opcode";
156 return smbd_smb2_table
[opcode
].name
;
159 static const struct smbd_smb2_dispatch_table
*smbd_smb2_call(uint16_t opcode
)
161 const struct smbd_smb2_dispatch_table
*ret
= NULL
;
163 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
167 ret
= &smbd_smb2_table
[opcode
];
169 SMB_ASSERT(ret
->opcode
== opcode
);
174 static void print_req_vectors(const struct smbd_smb2_request
*req
)
178 for (i
= 0; i
< req
->in
.vector_count
; i
++) {
179 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
181 (unsigned int)req
->in
.vector
[i
].iov_len
);
183 for (i
= 0; i
< req
->out
.vector_count
; i
++) {
184 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
186 (unsigned int)req
->out
.vector
[i
].iov_len
);
190 bool smbd_is_smb2_header(const uint8_t *inbuf
, size_t size
)
192 if (size
< (4 + SMB2_HDR_BODY
)) {
196 if (IVAL(inbuf
, 4) != SMB2_MAGIC
) {
203 static NTSTATUS
smbd_initialize_smb2(struct smbXsrv_connection
*xconn
,
204 uint64_t expected_seq_low
)
206 TALLOC_FREE(xconn
->transport
.fde
);
208 xconn
->smb2
.credits
.seq_low
= expected_seq_low
;
209 xconn
->smb2
.credits
.seq_range
= 1;
210 xconn
->smb2
.credits
.granted
= 1;
211 xconn
->smb2
.credits
.max
= lp_smb2_max_credits();
212 xconn
->smb2
.credits
.bitmap
= bitmap_talloc(xconn
,
213 xconn
->smb2
.credits
.max
);
214 if (xconn
->smb2
.credits
.bitmap
== NULL
) {
215 return NT_STATUS_NO_MEMORY
;
218 xconn
->transport
.fde
= tevent_add_fd(xconn
->ev_ctx
,
220 xconn
->transport
.sock
,
222 smbd_smb2_connection_handler
,
224 if (xconn
->transport
.fde
== NULL
) {
225 return NT_STATUS_NO_MEMORY
;
228 /* Ensure child is set to non-blocking mode */
229 set_blocking(xconn
->transport
.sock
, false);
233 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
234 #define _smb2_setlen(_buf,len) do { \
235 uint8_t *buf = (uint8_t *)_buf; \
237 buf[1] = ((len)&0xFF0000)>>16; \
238 buf[2] = ((len)&0xFF00)>>8; \
239 buf[3] = (len)&0xFF; \
242 static bool smb2_setup_nbt_length(struct iovec
*vector
, int count
)
250 len
= iov_buflen(vector
+1, count
-1);
252 if ((len
== -1) || (len
> 0xFFFFFF)) {
256 _smb2_setlen(vector
[0].iov_base
, len
);
260 static int smbd_smb2_request_destructor(struct smbd_smb2_request
*req
)
262 if (req
->first_key
.length
> 0) {
263 data_blob_clear_free(&req
->first_key
);
265 if (req
->last_key
.length
> 0) {
266 data_blob_clear_free(&req
->last_key
);
271 static struct smbd_smb2_request
*smbd_smb2_request_allocate(TALLOC_CTX
*mem_ctx
)
273 TALLOC_CTX
*mem_pool
;
274 struct smbd_smb2_request
*req
;
277 /* Enable this to find subtle valgrind errors. */
278 mem_pool
= talloc_init("smbd_smb2_request_allocate");
280 mem_pool
= talloc_tos();
282 if (mem_pool
== NULL
) {
286 req
= talloc_zero(mem_pool
, struct smbd_smb2_request
);
288 talloc_free(mem_pool
);
291 talloc_reparent(mem_pool
, mem_ctx
, req
);
293 TALLOC_FREE(mem_pool
);
296 req
->last_session_id
= UINT64_MAX
;
297 req
->last_tid
= UINT32_MAX
;
299 talloc_set_destructor(req
, smbd_smb2_request_destructor
);
304 static NTSTATUS
smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection
*xconn
,
308 struct smbd_smb2_request
*req
,
312 TALLOC_CTX
*mem_ctx
= req
;
316 uint8_t *first_hdr
= buf
;
317 size_t verified_buflen
= 0;
322 * Note: index '0' is reserved for the transport protocol
324 iov
= req
->in
._vector
;
326 while (taken
< buflen
) {
327 size_t len
= buflen
- taken
;
328 uint8_t *hdr
= first_hdr
+ taken
;
331 size_t next_command_ofs
;
333 uint8_t *body
= NULL
;
336 struct iovec
*iov_alloc
= NULL
;
338 if (iov
!= req
->in
._vector
) {
342 if (verified_buflen
> taken
) {
343 len
= verified_buflen
- taken
;
350 DEBUG(10, ("%d bytes left, expected at least %d\n",
354 if (IVAL(hdr
, 0) == SMB2_TF_MAGIC
) {
355 struct smbXsrv_session
*s
= NULL
;
357 struct iovec tf_iov
[2];
361 if (xconn
->protocol
< PROTOCOL_SMB2_24
) {
362 DEBUG(10, ("Got SMB2_TRANSFORM header, "
363 "but dialect[0x%04X] is used\n",
364 xconn
->smb2
.server
.dialect
));
368 if (xconn
->smb2
.server
.cipher
== 0) {
369 DEBUG(10, ("Got SMB2_TRANSFORM header, "
370 "but not negotiated "
371 "client[0x%08X] server[0x%08X]\n",
372 xconn
->smb2
.client
.capabilities
,
373 xconn
->smb2
.server
.capabilities
));
377 if (len
< SMB2_TF_HDR_SIZE
) {
378 DEBUG(1, ("%d bytes left, expected at least %d\n",
379 (int)len
, SMB2_TF_HDR_SIZE
));
383 tf_len
= SMB2_TF_HDR_SIZE
;
386 hdr
= first_hdr
+ taken
;
387 enc_len
= IVAL(tf
, SMB2_TF_MSG_SIZE
);
388 uid
= BVAL(tf
, SMB2_TF_SESSION_ID
);
390 if (len
< SMB2_TF_HDR_SIZE
+ enc_len
) {
391 DEBUG(1, ("%d bytes left, expected at least %d\n",
393 (int)(SMB2_TF_HDR_SIZE
+ enc_len
)));
397 status
= smb2srv_session_lookup_conn(xconn
, uid
, now
,
400 DEBUG(1, ("invalid session[%llu] in "
401 "SMB2_TRANSFORM header\n",
402 (unsigned long long)uid
));
403 TALLOC_FREE(iov_alloc
);
404 return NT_STATUS_USER_SESSION_DELETED
;
407 tf_iov
[0].iov_base
= (void *)tf
;
408 tf_iov
[0].iov_len
= tf_len
;
409 tf_iov
[1].iov_base
= (void *)hdr
;
410 tf_iov
[1].iov_len
= enc_len
;
412 status
= smb2_signing_decrypt_pdu(s
->global
->decryption_key
,
413 xconn
->smb2
.server
.cipher
,
415 if (!NT_STATUS_IS_OK(status
)) {
416 TALLOC_FREE(iov_alloc
);
420 verified_buflen
= taken
+ enc_len
;
425 * We need the header plus the body length field
428 if (len
< SMB2_HDR_BODY
+ 2) {
429 DEBUG(10, ("%d bytes left, expected at least %d\n",
430 (int)len
, SMB2_HDR_BODY
));
433 if (IVAL(hdr
, 0) != SMB2_MAGIC
) {
434 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
438 if (SVAL(hdr
, 4) != SMB2_HDR_BODY
) {
439 DEBUG(10, ("Got HDR len %d, expected %d\n",
440 SVAL(hdr
, 4), SMB2_HDR_BODY
));
445 next_command_ofs
= IVAL(hdr
, SMB2_HDR_NEXT_COMMAND
);
446 body_size
= SVAL(hdr
, SMB2_HDR_BODY
);
448 if (next_command_ofs
!= 0) {
449 if (next_command_ofs
< (SMB2_HDR_BODY
+ 2)) {
452 if (next_command_ofs
> full_size
) {
455 full_size
= next_command_ofs
;
462 if (body_size
> (full_size
- SMB2_HDR_BODY
)) {
464 * let the caller handle the error
466 body_size
= full_size
- SMB2_HDR_BODY
;
468 body
= hdr
+ SMB2_HDR_BODY
;
469 dyn
= body
+ body_size
;
470 dyn_size
= full_size
- (SMB2_HDR_BODY
+ body_size
);
472 if (num_iov
>= ARRAY_SIZE(req
->in
._vector
)) {
473 struct iovec
*iov_tmp
= NULL
;
475 iov_tmp
= talloc_realloc(mem_ctx
, iov_alloc
,
478 SMBD_SMB2_NUM_IOV_PER_REQ
);
479 if (iov_tmp
== NULL
) {
480 TALLOC_FREE(iov_alloc
);
481 return NT_STATUS_NO_MEMORY
;
484 if (iov_alloc
== NULL
) {
487 sizeof(req
->in
._vector
));
493 num_iov
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
495 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
496 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
497 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
498 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
499 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
500 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= body_size
;
501 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
502 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= dyn_size
;
512 if (iov
!= req
->in
._vector
) {
515 return NT_STATUS_INVALID_PARAMETER
;
518 static NTSTATUS
smbd_smb2_request_create(struct smbXsrv_connection
*xconn
,
519 const uint8_t *_inpdu
, size_t size
,
520 struct smbd_smb2_request
**_req
)
522 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
523 struct smbd_smb2_request
*req
;
524 uint32_t protocol_version
;
525 uint8_t *inpdu
= NULL
;
526 const uint8_t *inhdr
= NULL
;
528 uint32_t next_command_ofs
;
532 if (size
< (SMB2_HDR_BODY
+ 2)) {
533 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size
));
534 return NT_STATUS_INVALID_PARAMETER
;
539 protocol_version
= IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
);
540 if (protocol_version
!= SMB2_MAGIC
) {
541 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
543 return NT_STATUS_INVALID_PARAMETER
;
546 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
547 if (cmd
!= SMB2_OP_NEGPROT
) {
548 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
550 return NT_STATUS_INVALID_PARAMETER
;
553 next_command_ofs
= IVAL(inhdr
, SMB2_HDR_NEXT_COMMAND
);
554 if (next_command_ofs
!= 0) {
555 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
557 return NT_STATUS_INVALID_PARAMETER
;
560 req
= smbd_smb2_request_allocate(xconn
);
562 return NT_STATUS_NO_MEMORY
;
567 inpdu
= talloc_memdup(req
, _inpdu
, size
);
569 return NT_STATUS_NO_MEMORY
;
572 req
->request_time
= timeval_current();
573 now
= timeval_to_nttime(&req
->request_time
);
575 status
= smbd_smb2_inbuf_parse_compound(xconn
,
579 req
, &req
->in
.vector
,
580 &req
->in
.vector_count
);
581 if (!NT_STATUS_IS_OK(status
)) {
586 req
->current_idx
= 1;
592 static bool smb2_validate_sequence_number(struct smbXsrv_connection
*xconn
,
593 uint64_t message_id
, uint64_t seq_id
)
595 struct bitmap
*credits_bm
= xconn
->smb2
.credits
.bitmap
;
599 seq_tmp
= xconn
->smb2
.credits
.seq_low
;
600 if (seq_id
< seq_tmp
) {
601 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
602 "%llu (sequence id %llu) "
603 "(granted = %u, low = %llu, range = %u)\n",
604 (unsigned long long)message_id
,
605 (unsigned long long)seq_id
,
606 (unsigned int)xconn
->smb2
.credits
.granted
,
607 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
608 (unsigned int)xconn
->smb2
.credits
.seq_range
));
612 seq_tmp
+= xconn
->smb2
.credits
.seq_range
;
613 if (seq_id
>= seq_tmp
) {
614 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
615 "%llu (sequence id %llu) "
616 "(granted = %u, low = %llu, range = %u)\n",
617 (unsigned long long)message_id
,
618 (unsigned long long)seq_id
,
619 (unsigned int)xconn
->smb2
.credits
.granted
,
620 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
621 (unsigned int)xconn
->smb2
.credits
.seq_range
));
625 offset
= seq_id
% xconn
->smb2
.credits
.max
;
627 if (bitmap_query(credits_bm
, offset
)) {
628 DEBUG(0,("smb2_validate_sequence_number: duplicate message_id "
629 "%llu (sequence id %llu) "
630 "(granted = %u, low = %llu, range = %u) "
632 (unsigned long long)message_id
,
633 (unsigned long long)seq_id
,
634 (unsigned int)xconn
->smb2
.credits
.granted
,
635 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
636 (unsigned int)xconn
->smb2
.credits
.seq_range
,
641 /* Mark the message_ids as seen in the bitmap. */
642 bitmap_set(credits_bm
, offset
);
644 if (seq_id
!= xconn
->smb2
.credits
.seq_low
) {
649 * Move the window forward by all the message_id's
652 while (bitmap_query(credits_bm
, offset
)) {
653 DEBUG(10,("smb2_validate_sequence_number: clearing "
654 "id %llu (position %u) from bitmap\n",
655 (unsigned long long)(xconn
->smb2
.credits
.seq_low
),
657 bitmap_clear(credits_bm
, offset
);
659 xconn
->smb2
.credits
.seq_low
+= 1;
660 xconn
->smb2
.credits
.seq_range
-= 1;
661 offset
= xconn
->smb2
.credits
.seq_low
% xconn
->smb2
.credits
.max
;
667 static bool smb2_validate_message_id(struct smbXsrv_connection
*xconn
,
668 const uint8_t *inhdr
)
670 uint64_t message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
671 uint16_t opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
672 uint16_t credit_charge
= 1;
675 if (opcode
== SMB2_OP_CANCEL
) {
676 /* SMB2_CANCEL requests by definition resend messageids. */
680 if (xconn
->smb2
.credits
.multicredit
) {
681 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
682 credit_charge
= MAX(credit_charge
, 1);
685 DEBUG(11, ("smb2_validate_message_id: mid %llu (charge %llu), "
686 "credits_granted %llu, "
687 "seqnum low/range: %llu/%llu\n",
688 (unsigned long long) message_id
,
689 (unsigned long long) credit_charge
,
690 (unsigned long long) xconn
->smb2
.credits
.granted
,
691 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
692 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
694 if (xconn
->smb2
.credits
.granted
< credit_charge
) {
695 DEBUG(0, ("smb2_validate_message_id: client used more "
696 "credits than granted, mid %llu, charge %llu, "
697 "credits_granted %llu, "
698 "seqnum low/range: %llu/%llu\n",
699 (unsigned long long) message_id
,
700 (unsigned long long) credit_charge
,
701 (unsigned long long) xconn
->smb2
.credits
.granted
,
702 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
703 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
708 * now check the message ids
710 * for multi-credit requests we need to check all current mid plus
711 * the implicit mids caused by the credit charge
712 * e.g. current mid = 15, charge 5 => mark 15-19 as used
715 for (i
= 0; i
<= (credit_charge
-1); i
++) {
716 uint64_t id
= message_id
+ i
;
719 DEBUG(11, ("Iterating mid %llu charge %u (sequence %llu)\n",
720 (unsigned long long)message_id
,
722 (unsigned long long)id
));
724 ok
= smb2_validate_sequence_number(xconn
, message_id
, id
);
730 /* substract used credits */
731 xconn
->smb2
.credits
.granted
-= credit_charge
;
736 static NTSTATUS
smbd_smb2_request_validate(struct smbd_smb2_request
*req
)
741 count
= req
->in
.vector_count
;
743 if (count
< 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
744 /* It's not a SMB2 request */
745 return NT_STATUS_INVALID_PARAMETER
;
748 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
749 struct iovec
*hdr
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
750 struct iovec
*body
= SMBD_SMB2_IDX_BODY_IOV(req
,in
,idx
);
751 const uint8_t *inhdr
= NULL
;
753 if (hdr
->iov_len
!= SMB2_HDR_BODY
) {
754 return NT_STATUS_INVALID_PARAMETER
;
757 if (body
->iov_len
< 2) {
758 return NT_STATUS_INVALID_PARAMETER
;
761 inhdr
= (const uint8_t *)hdr
->iov_base
;
763 /* Check the SMB2 header */
764 if (IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
) != SMB2_MAGIC
) {
765 return NT_STATUS_INVALID_PARAMETER
;
768 if (!smb2_validate_message_id(req
->xconn
, inhdr
)) {
769 return NT_STATUS_INVALID_PARAMETER
;
776 static void smb2_set_operation_credit(struct smbXsrv_connection
*xconn
,
777 const struct iovec
*in_vector
,
778 struct iovec
*out_vector
)
780 const uint8_t *inhdr
= (const uint8_t *)in_vector
->iov_base
;
781 uint8_t *outhdr
= (uint8_t *)out_vector
->iov_base
;
782 uint16_t credit_charge
= 1;
783 uint16_t credits_requested
;
787 uint16_t credits_granted
= 0;
788 uint64_t credits_possible
;
789 uint16_t current_max_credits
;
792 * first we grant only 1/16th of the max range.
794 * Windows also starts with the 1/16th and then grants
795 * more later. I was only able to trigger higher
796 * values, when using a very high credit charge.
798 * TODO: scale up depending on load, free memory
800 * Maybe also on the relationship between number
801 * of requests and the used sequence number.
802 * Which means we would grant more credits
803 * for client which use multi credit requests.
805 current_max_credits
= xconn
->smb2
.credits
.max
/ 16;
806 current_max_credits
= MAX(current_max_credits
, 1);
808 if (xconn
->smb2
.credits
.multicredit
) {
809 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
810 credit_charge
= MAX(credit_charge
, 1);
813 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
814 credits_requested
= SVAL(inhdr
, SMB2_HDR_CREDIT
);
815 credits_requested
= MAX(credits_requested
, 1);
816 out_flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
817 out_status
= NT_STATUS(IVAL(outhdr
, SMB2_HDR_STATUS
));
819 SMB_ASSERT(xconn
->smb2
.credits
.max
>= xconn
->smb2
.credits
.granted
);
821 if (xconn
->smb2
.credits
.max
< credit_charge
) {
822 smbd_server_connection_terminate(xconn
,
823 "client error: credit charge > max credits\n");
827 if (out_flags
& SMB2_HDR_FLAG_ASYNC
) {
829 * In case we already send an async interim
830 * response, we should not grant
831 * credits on the final response.
835 uint16_t additional_possible
=
836 xconn
->smb2
.credits
.max
- credit_charge
;
837 uint16_t additional_max
= 0;
838 uint16_t additional_credits
= credits_requested
- 1;
841 case SMB2_OP_NEGPROT
:
843 case SMB2_OP_SESSSETUP
:
845 * Windows 2012 RC1 starts to grant
847 * with a successful session setup
849 if (NT_STATUS_IS_OK(out_status
)) {
855 * We match windows and only grant additional credits
862 additional_max
= MIN(additional_max
, additional_possible
);
863 additional_credits
= MIN(additional_credits
, additional_max
);
865 credits_granted
= credit_charge
+ additional_credits
;
869 * sequence numbers should not wrap
871 * 1. calculate the possible credits until
872 * the sequence numbers start to wrap on 64-bit.
874 * 2. UINT64_MAX is used for Break Notifications.
876 * 2. truncate the possible credits to the maximum
877 * credits we want to grant to the client in total.
879 * 3. remove the range we'll already granted to the client
880 * this makes sure the client consumes the lowest sequence
881 * number, before we can grant additional credits.
883 credits_possible
= UINT64_MAX
- xconn
->smb2
.credits
.seq_low
;
884 if (credits_possible
> 0) {
885 /* remove UINT64_MAX */
886 credits_possible
-= 1;
888 credits_possible
= MIN(credits_possible
, current_max_credits
);
889 credits_possible
-= xconn
->smb2
.credits
.seq_range
;
891 credits_granted
= MIN(credits_granted
, credits_possible
);
893 SSVAL(outhdr
, SMB2_HDR_CREDIT
, credits_granted
);
894 xconn
->smb2
.credits
.granted
+= credits_granted
;
895 xconn
->smb2
.credits
.seq_range
+= credits_granted
;
897 DEBUG(10,("smb2_set_operation_credit: requested %u, charge %u, "
898 "granted %u, current possible/max %u/%u, "
899 "total granted/max/low/range %u/%u/%llu/%u\n",
900 (unsigned int)credits_requested
,
901 (unsigned int)credit_charge
,
902 (unsigned int)credits_granted
,
903 (unsigned int)credits_possible
,
904 (unsigned int)current_max_credits
,
905 (unsigned int)xconn
->smb2
.credits
.granted
,
906 (unsigned int)xconn
->smb2
.credits
.max
,
907 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
908 (unsigned int)xconn
->smb2
.credits
.seq_range
));
911 static void smb2_calculate_credits(const struct smbd_smb2_request
*inreq
,
912 struct smbd_smb2_request
*outreq
)
915 uint16_t total_credits
= 0;
917 count
= outreq
->out
.vector_count
;
919 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
920 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(inreq
,in
,idx
);
921 struct iovec
*outhdr_v
= SMBD_SMB2_IDX_HDR_IOV(outreq
,out
,idx
);
922 uint8_t *outhdr
= (uint8_t *)outhdr_v
->iov_base
;
924 smb2_set_operation_credit(outreq
->xconn
, inhdr_v
, outhdr_v
);
926 /* To match Windows, count up what we
928 total_credits
+= SVAL(outhdr
, SMB2_HDR_CREDIT
);
929 /* Set to zero in all but the last reply. */
930 if (idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
< count
) {
931 SSVAL(outhdr
, SMB2_HDR_CREDIT
, 0);
933 SSVAL(outhdr
, SMB2_HDR_CREDIT
, total_credits
);
938 DATA_BLOB
smbd_smb2_generate_outbody(struct smbd_smb2_request
*req
, size_t size
)
940 if (req
->current_idx
<= 1) {
941 if (size
<= sizeof(req
->out
._body
)) {
942 return data_blob_const(req
->out
._body
, size
);
946 return data_blob_talloc(req
, NULL
, size
);
949 static NTSTATUS
smbd_smb2_request_setup_out(struct smbd_smb2_request
*req
)
951 struct smbXsrv_connection
*xconn
= req
->xconn
;
953 struct iovec
*vector
;
958 count
= req
->in
.vector_count
;
959 if (count
<= ARRAY_SIZE(req
->out
._vector
)) {
961 vector
= req
->out
._vector
;
963 vector
= talloc_zero_array(req
, struct iovec
, count
);
964 if (vector
== NULL
) {
965 return NT_STATUS_NO_MEMORY
;
970 vector
[0].iov_base
= req
->out
.nbt_hdr
;
971 vector
[0].iov_len
= 4;
972 SIVAL(req
->out
.nbt_hdr
, 0, 0);
974 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
975 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
976 const uint8_t *inhdr
= (const uint8_t *)inhdr_v
->iov_base
;
977 uint8_t *outhdr
= NULL
;
978 uint8_t *outbody
= NULL
;
979 uint32_t next_command_ofs
= 0;
980 struct iovec
*current
= &vector
[idx
];
982 if ((idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) < count
) {
983 /* we have a next command -
984 * setup for the error case. */
985 next_command_ofs
= SMB2_HDR_BODY
+ 9;
989 outhdr
= req
->out
._hdr
;
991 outhdr
= talloc_zero_array(mem_ctx
, uint8_t,
993 if (outhdr
== NULL
) {
994 return NT_STATUS_NO_MEMORY
;
998 outbody
= outhdr
+ SMB2_HDR_BODY
;
1001 * SMBD_SMB2_TF_IOV_OFS might be used later
1003 current
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1004 current
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1006 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)outhdr
;
1007 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1009 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)outbody
;
1010 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1012 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= NULL
;
1013 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 0;
1015 /* setup the SMB2 header */
1016 SIVAL(outhdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1017 SSVAL(outhdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1018 SSVAL(outhdr
, SMB2_HDR_CREDIT_CHARGE
,
1019 SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
));
1020 SIVAL(outhdr
, SMB2_HDR_STATUS
,
1021 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR
));
1022 SSVAL(outhdr
, SMB2_HDR_OPCODE
,
1023 SVAL(inhdr
, SMB2_HDR_OPCODE
));
1024 SIVAL(outhdr
, SMB2_HDR_FLAGS
,
1025 IVAL(inhdr
, SMB2_HDR_FLAGS
) | SMB2_HDR_FLAG_REDIRECT
);
1026 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
1027 SBVAL(outhdr
, SMB2_HDR_MESSAGE_ID
,
1028 BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
));
1029 SIVAL(outhdr
, SMB2_HDR_PID
,
1030 IVAL(inhdr
, SMB2_HDR_PID
));
1031 SIVAL(outhdr
, SMB2_HDR_TID
,
1032 IVAL(inhdr
, SMB2_HDR_TID
));
1033 SBVAL(outhdr
, SMB2_HDR_SESSION_ID
,
1034 BVAL(inhdr
, SMB2_HDR_SESSION_ID
));
1035 memcpy(outhdr
+ SMB2_HDR_SIGNATURE
,
1036 inhdr
+ SMB2_HDR_SIGNATURE
, 16);
1038 /* setup error body header */
1039 SSVAL(outbody
, 0x00, 0x08 + 1);
1040 SSVAL(outbody
, 0x02, 0);
1041 SIVAL(outbody
, 0x04, 0);
1044 req
->out
.vector
= vector
;
1045 req
->out
.vector_count
= count
;
1047 /* setup the length of the NBT packet */
1048 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
1050 return NT_STATUS_INVALID_PARAMETER_MIX
;
1053 DLIST_ADD_END(xconn
->smb2
.requests
, req
, struct smbd_smb2_request
*);
1055 return NT_STATUS_OK
;
1058 void smbd_server_connection_terminate_ex(struct smbXsrv_connection
*xconn
,
1060 const char *location
)
1062 DEBUG(10,("smbd_server_connection_terminate_ex: reason[%s] at %s\n",
1064 exit_server_cleanly(reason
);
1067 static bool dup_smb2_vec4(TALLOC_CTX
*ctx
,
1068 struct iovec
*outvec
,
1069 const struct iovec
*srcvec
)
1071 const uint8_t *srctf
;
1073 const uint8_t *srchdr
;
1075 const uint8_t *srcbody
;
1077 const uint8_t *expected_srcbody
;
1078 const uint8_t *srcdyn
;
1080 const uint8_t *expected_srcdyn
;
1086 srctf
= (const uint8_t *)srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
;
1087 srctf_len
= srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
;
1088 srchdr
= (const uint8_t *)srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
;
1089 srchdr_len
= srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
;
1090 srcbody
= (const uint8_t *)srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
;
1091 srcbody_len
= srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
;
1092 expected_srcbody
= srchdr
+ SMB2_HDR_BODY
;
1093 srcdyn
= (const uint8_t *)srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
;
1094 srcdyn_len
= srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
;
1095 expected_srcdyn
= srcbody
+ 8;
1097 if ((srctf_len
!= SMB2_TF_HDR_SIZE
) && (srctf_len
!= 0)) {
1101 if (srchdr_len
!= SMB2_HDR_BODY
) {
1105 if (srctf_len
== SMB2_TF_HDR_SIZE
) {
1106 dsttf
= talloc_memdup(ctx
, srctf
, SMB2_TF_HDR_SIZE
);
1107 if (dsttf
== NULL
) {
1113 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= (void *)dsttf
;
1114 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= srctf_len
;
1116 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1117 * be allocated with size OUTVEC_ALLOC_SIZE. */
1119 dsthdr
= talloc_memdup(ctx
, srchdr
, OUTVEC_ALLOC_SIZE
);
1120 if (dsthdr
== NULL
) {
1123 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)dsthdr
;
1124 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1127 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1128 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1129 * then duplicate this. Else use talloc_memdup().
1132 if ((srcbody
== expected_srcbody
) && (srcbody_len
== 8)) {
1133 dstbody
= dsthdr
+ SMB2_HDR_BODY
;
1135 dstbody
= talloc_memdup(ctx
, srcbody
, srcbody_len
);
1136 if (dstbody
== NULL
) {
1140 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)dstbody
;
1141 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= srcbody_len
;
1144 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1146 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1147 * then duplicate this. Else use talloc_memdup().
1150 if ((srcdyn
== expected_srcdyn
) && (srcdyn_len
== 1)) {
1151 dstdyn
= dsthdr
+ SMB2_HDR_BODY
+ 8;
1152 } else if (srcdyn
== NULL
) {
1155 dstdyn
= talloc_memdup(ctx
, srcdyn
, srcdyn_len
);
1156 if (dstdyn
== NULL
) {
1160 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= (void *)dstdyn
;
1161 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= srcdyn_len
;
1166 static struct smbd_smb2_request
*dup_smb2_req(const struct smbd_smb2_request
*req
)
1168 struct smbd_smb2_request
*newreq
= NULL
;
1169 struct iovec
*outvec
= NULL
;
1170 int count
= req
->out
.vector_count
;
1174 newreq
= smbd_smb2_request_allocate(req
->xconn
);
1179 newreq
->sconn
= req
->sconn
;
1180 newreq
->xconn
= req
->xconn
;
1181 newreq
->session
= req
->session
;
1182 newreq
->do_encryption
= req
->do_encryption
;
1183 newreq
->do_signing
= req
->do_signing
;
1184 newreq
->current_idx
= req
->current_idx
;
1186 outvec
= talloc_zero_array(newreq
, struct iovec
, count
);
1188 TALLOC_FREE(newreq
);
1191 newreq
->out
.vector
= outvec
;
1192 newreq
->out
.vector_count
= count
;
1194 /* Setup the outvec's identically to req. */
1195 outvec
[0].iov_base
= newreq
->out
.nbt_hdr
;
1196 outvec
[0].iov_len
= 4;
1197 memcpy(newreq
->out
.nbt_hdr
, req
->out
.nbt_hdr
, 4);
1199 /* Setup the vectors identically to the ones in req. */
1200 for (i
= 1; i
< count
; i
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1201 if (!dup_smb2_vec4(outvec
, &outvec
[i
], &req
->out
.vector
[i
])) {
1208 TALLOC_FREE(newreq
);
1212 ok
= smb2_setup_nbt_length(newreq
->out
.vector
,
1213 newreq
->out
.vector_count
);
1215 TALLOC_FREE(newreq
);
1222 static NTSTATUS
smb2_send_async_interim_response(const struct smbd_smb2_request
*req
)
1224 struct smbXsrv_connection
*xconn
= req
->xconn
;
1226 struct iovec
*firsttf
= NULL
;
1227 struct iovec
*outhdr_v
= NULL
;
1228 uint8_t *outhdr
= NULL
;
1229 struct smbd_smb2_request
*nreq
= NULL
;
1233 /* Create a new smb2 request we'll use
1234 for the interim return. */
1235 nreq
= dup_smb2_req(req
);
1237 return NT_STATUS_NO_MEMORY
;
1240 /* Lose the last X out vectors. They're the
1241 ones we'll be using for the async reply. */
1242 nreq
->out
.vector_count
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1244 ok
= smb2_setup_nbt_length(nreq
->out
.vector
,
1245 nreq
->out
.vector_count
);
1247 return NT_STATUS_INVALID_PARAMETER_MIX
;
1250 /* Step back to the previous reply. */
1251 nreq
->current_idx
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1252 firsttf
= SMBD_SMB2_IDX_TF_IOV(nreq
,out
,first_idx
);
1253 outhdr_v
= SMBD_SMB2_OUT_HDR_IOV(nreq
);
1254 outhdr
= SMBD_SMB2_OUT_HDR_PTR(nreq
);
1255 /* And end the chain. */
1256 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
1258 /* Calculate outgoing credits */
1259 smb2_calculate_credits(req
, nreq
);
1261 if (DEBUGLEVEL
>= 10) {
1262 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1263 (unsigned int)nreq
->current_idx
);
1264 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1265 (unsigned int)nreq
->out
.vector_count
);
1266 print_req_vectors(nreq
);
1270 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1271 * we need to sign/encrypt here with the last/first key we remembered
1273 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
1274 status
= smb2_signing_encrypt_pdu(req
->first_key
,
1275 xconn
->smb2
.server
.cipher
,
1277 nreq
->out
.vector_count
- first_idx
);
1278 if (!NT_STATUS_IS_OK(status
)) {
1281 } else if (req
->last_key
.length
> 0) {
1282 status
= smb2_signing_sign_pdu(req
->last_key
,
1285 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
1286 if (!NT_STATUS_IS_OK(status
)) {
1291 nreq
->queue_entry
.mem_ctx
= nreq
;
1292 nreq
->queue_entry
.vector
= nreq
->out
.vector
;
1293 nreq
->queue_entry
.count
= nreq
->out
.vector_count
;
1294 DLIST_ADD_END(xconn
->smb2
.send_queue
, &nreq
->queue_entry
, NULL
);
1295 xconn
->smb2
.send_queue_len
++;
1297 status
= smbd_smb2_flush_send_queue(xconn
);
1298 if (!NT_STATUS_IS_OK(status
)) {
1302 return NT_STATUS_OK
;
1305 struct smbd_smb2_request_pending_state
{
1306 struct smbd_smb2_send_queue queue_entry
;
1307 uint8_t buf
[NBT_HDR_SIZE
+ SMB2_TF_HDR_SIZE
+ SMB2_HDR_BODY
+ 0x08 + 1];
1308 struct iovec vector
[1 + SMBD_SMB2_NUM_IOV_PER_REQ
];
1311 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
1312 struct tevent_timer
*te
,
1313 struct timeval current_time
,
1314 void *private_data
);
1316 NTSTATUS
smbd_smb2_request_pending_queue(struct smbd_smb2_request
*req
,
1317 struct tevent_req
*subreq
,
1318 uint32_t defer_time
)
1321 struct timeval defer_endtime
;
1322 uint8_t *outhdr
= NULL
;
1325 if (!tevent_req_is_in_progress(subreq
)) {
1327 * This is a performance optimization,
1328 * it avoids one tevent_loop iteration,
1329 * which means we avoid one
1330 * talloc_stackframe_pool/talloc_free pair.
1332 tevent_req_notify_callback(subreq
);
1333 return NT_STATUS_OK
;
1336 req
->subreq
= subreq
;
1339 if (req
->async_te
) {
1340 /* We're already async. */
1341 return NT_STATUS_OK
;
1344 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1345 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
1346 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
1347 /* We're already async. */
1348 return NT_STATUS_OK
;
1351 if (req
->in
.vector_count
> req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) {
1353 * We're trying to go async in a compound request
1354 * chain. This is only allowed for opens that cause an
1355 * oplock break or for the last operation in the
1356 * chain, otherwise it is not allowed. See
1357 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
1359 const uint8_t *inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1361 if (SVAL(inhdr
, SMB2_HDR_OPCODE
) != SMB2_OP_CREATE
) {
1363 * Cancel the outstanding request.
1365 bool ok
= tevent_req_cancel(req
->subreq
);
1367 return NT_STATUS_OK
;
1369 TALLOC_FREE(req
->subreq
);
1370 return smbd_smb2_request_error(req
,
1371 NT_STATUS_INTERNAL_ERROR
);
1375 if (DEBUGLEVEL
>= 10) {
1376 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1377 (unsigned int)req
->current_idx
);
1378 print_req_vectors(req
);
1381 if (req
->current_idx
> 1) {
1383 * We're going async in a compound
1384 * chain after the first request has
1385 * already been processed. Send an
1386 * interim response containing the
1387 * set of replies already generated.
1389 int idx
= req
->current_idx
;
1391 status
= smb2_send_async_interim_response(req
);
1392 if (!NT_STATUS_IS_OK(status
)) {
1395 if (req
->first_key
.length
> 0) {
1396 data_blob_clear_free(&req
->first_key
);
1399 req
->current_idx
= 1;
1402 * Re-arrange the in.vectors to remove what
1405 memmove(&req
->in
.vector
[1],
1406 &req
->in
.vector
[idx
],
1407 sizeof(req
->in
.vector
[0])*(req
->in
.vector_count
- idx
));
1408 req
->in
.vector_count
= 1 + (req
->in
.vector_count
- idx
);
1410 /* Re-arrange the out.vectors to match. */
1411 memmove(&req
->out
.vector
[1],
1412 &req
->out
.vector
[idx
],
1413 sizeof(req
->out
.vector
[0])*(req
->out
.vector_count
- idx
));
1414 req
->out
.vector_count
= 1 + (req
->out
.vector_count
- idx
);
1416 if (req
->in
.vector_count
== 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
1418 * We only have one remaining request as
1419 * we've processed everything else.
1420 * This is no longer a compound request.
1422 req
->compound_related
= false;
1423 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1424 flags
= (IVAL(outhdr
, SMB2_HDR_FLAGS
) & ~SMB2_HDR_FLAG_CHAINED
);
1425 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
);
1428 if (req
->last_key
.length
> 0) {
1429 data_blob_clear_free(&req
->last_key
);
1432 defer_endtime
= timeval_current_ofs_usec(defer_time
);
1433 req
->async_te
= tevent_add_timer(req
->sconn
->ev_ctx
,
1435 smbd_smb2_request_pending_timer
,
1437 if (req
->async_te
== NULL
) {
1438 return NT_STATUS_NO_MEMORY
;
1441 return NT_STATUS_OK
;
1444 static DATA_BLOB
smbd_smb2_signing_key(struct smbXsrv_session
*session
,
1445 struct smbXsrv_connection
*xconn
)
1447 struct smbXsrv_channel_global0
*c
= NULL
;
1449 DATA_BLOB key
= data_blob_null
;
1451 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
1452 if (NT_STATUS_IS_OK(status
)) {
1453 key
= c
->signing_key
;
1456 if (key
.length
== 0) {
1457 key
= session
->global
->signing_key
;
1463 static NTSTATUS
smb2_get_new_nonce(struct smbXsrv_session
*session
,
1464 uint64_t *new_nonce_high
,
1465 uint64_t *new_nonce_low
)
1467 uint64_t nonce_high
;
1470 session
->nonce_low
+= 1;
1471 if (session
->nonce_low
== 0) {
1472 session
->nonce_low
+= 1;
1473 session
->nonce_high
+= 1;
1477 * CCM and GCM algorithms must never have their
1478 * nonce wrap, or the security of the whole
1479 * communication and the keys is destroyed.
1480 * We must drop the connection once we have
1481 * transfered too much data.
1483 * NOTE: We assume nonces greater than 8 bytes.
1485 if (session
->nonce_high
>= session
->nonce_high_max
) {
1486 return NT_STATUS_ENCRYPTION_FAILED
;
1489 nonce_high
= session
->nonce_high_random
;
1490 nonce_high
+= session
->nonce_high
;
1491 nonce_low
= session
->nonce_low
;
1493 *new_nonce_high
= nonce_high
;
1494 *new_nonce_low
= nonce_low
;
1495 return NT_STATUS_OK
;
1498 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
1499 struct tevent_timer
*te
,
1500 struct timeval current_time
,
1503 struct smbd_smb2_request
*req
=
1504 talloc_get_type_abort(private_data
,
1505 struct smbd_smb2_request
);
1506 struct smbXsrv_connection
*xconn
= req
->xconn
;
1507 struct smbd_smb2_request_pending_state
*state
= NULL
;
1508 uint8_t *outhdr
= NULL
;
1509 const uint8_t *inhdr
= NULL
;
1512 uint8_t *hdr
= NULL
;
1513 uint8_t *body
= NULL
;
1514 uint8_t *dyn
= NULL
;
1516 uint64_t session_id
= 0;
1517 uint64_t message_id
= 0;
1518 uint64_t nonce_high
= 0;
1519 uint64_t nonce_low
= 0;
1520 uint64_t async_id
= 0;
1524 TALLOC_FREE(req
->async_te
);
1526 /* Ensure our final reply matches the interim one. */
1527 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1528 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1529 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
1530 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
1531 session_id
= BVAL(outhdr
, SMB2_HDR_SESSION_ID
);
1533 async_id
= message_id
; /* keep it simple for now... */
1535 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
1536 SBVAL(outhdr
, SMB2_HDR_ASYNC_ID
, async_id
);
1538 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1540 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
1541 (unsigned long long)async_id
));
1544 * What we send is identical to a smbd_smb2_request_error
1545 * packet with an error status of STATUS_PENDING. Make use
1546 * of this fact sometime when refactoring. JRA.
1549 state
= talloc_zero(req
->xconn
, struct smbd_smb2_request_pending_state
);
1550 if (state
== NULL
) {
1551 smbd_server_connection_terminate(xconn
,
1552 nt_errstr(NT_STATUS_NO_MEMORY
));
1556 tf
= state
->buf
+ NBT_HDR_SIZE
;
1557 tf_len
= SMB2_TF_HDR_SIZE
;
1559 hdr
= tf
+ SMB2_TF_HDR_SIZE
;
1560 body
= hdr
+ SMB2_HDR_BODY
;
1563 if (req
->do_encryption
) {
1564 status
= smb2_get_new_nonce(req
->session
,
1567 if (!NT_STATUS_IS_OK(status
)) {
1568 smbd_server_connection_terminate(xconn
,
1574 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
1575 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
1576 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
1577 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
1579 SIVAL(hdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1580 SSVAL(hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1581 SSVAL(hdr
, SMB2_HDR_EPOCH
, 0);
1582 SIVAL(hdr
, SMB2_HDR_STATUS
, NT_STATUS_V(STATUS_PENDING
));
1583 SSVAL(hdr
, SMB2_HDR_OPCODE
, SVAL(outhdr
, SMB2_HDR_OPCODE
));
1585 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
);
1586 SIVAL(hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
1587 SBVAL(hdr
, SMB2_HDR_MESSAGE_ID
, message_id
);
1588 SBVAL(hdr
, SMB2_HDR_PID
, async_id
);
1589 SBVAL(hdr
, SMB2_HDR_SESSION_ID
,
1590 BVAL(outhdr
, SMB2_HDR_SESSION_ID
));
1591 memcpy(hdr
+SMB2_HDR_SIGNATURE
,
1592 outhdr
+SMB2_HDR_SIGNATURE
, 16);
1594 SSVAL(body
, 0x00, 0x08 + 1);
1596 SCVAL(body
, 0x02, 0);
1597 SCVAL(body
, 0x03, 0);
1598 SIVAL(body
, 0x04, 0);
1599 /* Match W2K8R2... */
1600 SCVAL(dyn
, 0x00, 0x21);
1602 state
->vector
[0].iov_base
= (void *)state
->buf
;
1603 state
->vector
[0].iov_len
= NBT_HDR_SIZE
;
1605 if (req
->do_encryption
) {
1606 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
1607 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
1609 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1610 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1613 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
1614 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1616 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
1617 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1619 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
1620 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 1;
1622 ok
= smb2_setup_nbt_length(state
->vector
,
1623 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
1625 smbd_server_connection_terminate(
1626 xconn
, nt_errstr(NT_STATUS_INTERNAL_ERROR
));
1630 /* Ensure we correctly go through crediting. Grant
1631 the credits now, and zero credits on the final
1633 smb2_set_operation_credit(req
->xconn
,
1634 SMBD_SMB2_IN_HDR_IOV(req
),
1635 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
]);
1637 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
1642 for (i
= 0; i
< ARRAY_SIZE(state
->vector
); i
++) {
1643 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1645 (unsigned int)ARRAY_SIZE(state
->vector
),
1646 (unsigned int)state
->vector
[i
].iov_len
);
1650 if (req
->do_encryption
) {
1651 struct smbXsrv_session
*x
= req
->session
;
1652 DATA_BLOB encryption_key
= x
->global
->encryption_key
;
1654 status
= smb2_signing_encrypt_pdu(encryption_key
,
1655 xconn
->smb2
.server
.cipher
,
1656 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
1657 SMBD_SMB2_NUM_IOV_PER_REQ
);
1658 if (!NT_STATUS_IS_OK(status
)) {
1659 smbd_server_connection_terminate(xconn
,
1663 } else if (req
->do_signing
) {
1664 struct smbXsrv_session
*x
= req
->session
;
1665 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
1667 status
= smb2_signing_sign_pdu(signing_key
,
1669 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
],
1670 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
1671 if (!NT_STATUS_IS_OK(status
)) {
1672 smbd_server_connection_terminate(xconn
,
1678 state
->queue_entry
.mem_ctx
= state
;
1679 state
->queue_entry
.vector
= state
->vector
;
1680 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
1681 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
, NULL
);
1682 xconn
->smb2
.send_queue_len
++;
1684 status
= smbd_smb2_flush_send_queue(xconn
);
1685 if (!NT_STATUS_IS_OK(status
)) {
1686 smbd_server_connection_terminate(xconn
,
1692 static NTSTATUS
smbd_smb2_request_process_cancel(struct smbd_smb2_request
*req
)
1694 struct smbXsrv_connection
*xconn
= req
->xconn
;
1695 struct smbd_smb2_request
*cur
;
1696 const uint8_t *inhdr
;
1698 uint64_t search_message_id
;
1699 uint64_t search_async_id
;
1702 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1704 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1705 search_message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
1706 search_async_id
= BVAL(inhdr
, SMB2_HDR_PID
);
1709 * We don't need the request anymore cancel requests never
1712 * We defer the TALLOC_FREE(req) to the caller.
1714 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
1716 for (cur
= xconn
->smb2
.requests
; cur
; cur
= cur
->next
) {
1717 const uint8_t *outhdr
;
1718 uint64_t message_id
;
1721 if (cur
->compound_related
) {
1723 * Never cancel anything in a compound request.
1724 * Way too hard to deal with the result.
1729 outhdr
= SMBD_SMB2_OUT_HDR_PTR(cur
);
1731 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
1732 async_id
= BVAL(outhdr
, SMB2_HDR_PID
);
1734 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
1735 if (search_async_id
== async_id
) {
1736 found_id
= async_id
;
1740 if (search_message_id
== message_id
) {
1741 found_id
= message_id
;
1747 if (cur
&& cur
->subreq
) {
1748 inhdr
= SMBD_SMB2_IN_HDR_PTR(cur
);
1749 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1750 "cancel opcode[%s] mid %llu\n",
1751 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
1752 (unsigned long long)found_id
));
1753 tevent_req_cancel(cur
->subreq
);
1756 return NT_STATUS_OK
;
1759 /*************************************************************
1760 Ensure an incoming tid is a valid one for us to access.
1761 Change to the associated uid credentials and chdir to the
1762 valid tid directory.
1763 *************************************************************/
1765 static NTSTATUS
smbd_smb2_request_check_tcon(struct smbd_smb2_request
*req
)
1767 const uint8_t *inhdr
;
1770 struct smbXsrv_tcon
*tcon
;
1772 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1776 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1778 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1779 in_tid
= IVAL(inhdr
, SMB2_HDR_TID
);
1781 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
1782 in_tid
= req
->last_tid
;
1787 status
= smb2srv_tcon_lookup(req
->session
,
1788 in_tid
, now
, &tcon
);
1789 if (!NT_STATUS_IS_OK(status
)) {
1793 if (!change_to_user(tcon
->compat
, req
->session
->compat
->vuid
)) {
1794 return NT_STATUS_ACCESS_DENIED
;
1797 /* should we pass FLAG_CASELESS_PATHNAMES here? */
1798 if (!set_current_service(tcon
->compat
, 0, true)) {
1799 return NT_STATUS_ACCESS_DENIED
;
1803 req
->last_tid
= in_tid
;
1805 return NT_STATUS_OK
;
1808 /*************************************************************
1809 Ensure an incoming session_id is a valid one for us to access.
1810 *************************************************************/
1812 static NTSTATUS
smbd_smb2_request_check_session(struct smbd_smb2_request
*req
)
1814 const uint8_t *inhdr
;
1817 uint64_t in_session_id
;
1818 struct smbXsrv_session
*session
= NULL
;
1819 struct auth_session_info
*session_info
;
1821 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1823 req
->session
= NULL
;
1826 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1828 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1829 in_opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
1830 in_session_id
= BVAL(inhdr
, SMB2_HDR_SESSION_ID
);
1832 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
1833 in_session_id
= req
->last_session_id
;
1836 req
->last_session_id
= 0;
1838 /* look an existing session up */
1839 switch (in_opcode
) {
1840 case SMB2_OP_SESSSETUP
:
1842 * For a session bind request, we don't have the
1843 * channel set up at this point yet, so we defer
1844 * the verification that the connection belongs
1845 * to the session to the session setup code, which
1846 * can look at the session binding flags.
1848 status
= smb2srv_session_lookup_client(req
->xconn
->client
,
1853 status
= smb2srv_session_lookup_conn(req
->xconn
,
1859 req
->session
= session
;
1860 req
->last_session_id
= in_session_id
;
1862 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1863 switch (in_opcode
) {
1864 case SMB2_OP_SESSSETUP
:
1865 status
= NT_STATUS_OK
;
1871 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1872 switch (in_opcode
) {
1874 case SMB2_OP_CREATE
:
1875 case SMB2_OP_GETINFO
:
1876 case SMB2_OP_SETINFO
:
1877 return NT_STATUS_INVALID_HANDLE
;
1880 * Notice the check for
1881 * (session_info == NULL)
1884 status
= NT_STATUS_OK
;
1888 if (!NT_STATUS_IS_OK(status
)) {
1892 session_info
= session
->global
->auth_session_info
;
1893 if (session_info
== NULL
) {
1894 return NT_STATUS_INVALID_HANDLE
;
1897 if (in_session_id
!= req
->xconn
->client
->last_session_id
) {
1898 req
->xconn
->client
->last_session_id
= in_session_id
;
1899 set_current_user_info(session_info
->unix_info
->sanitized_username
,
1900 session_info
->unix_info
->unix_name
,
1901 session_info
->info
->domain_name
);
1904 return NT_STATUS_OK
;
1907 NTSTATUS
smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request
*req
,
1908 uint32_t data_length
)
1910 struct smbXsrv_connection
*xconn
= req
->xconn
;
1911 uint16_t needed_charge
;
1912 uint16_t credit_charge
= 1;
1913 const uint8_t *inhdr
;
1915 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1917 if (xconn
->smb2
.credits
.multicredit
) {
1918 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
1919 credit_charge
= MAX(credit_charge
, 1);
1922 needed_charge
= (data_length
- 1)/ 65536 + 1;
1924 DEBUG(10, ("mid %llu, CreditCharge: %d, NeededCharge: %d\n",
1925 (unsigned long long) BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
),
1926 credit_charge
, needed_charge
));
1928 if (needed_charge
> credit_charge
) {
1929 DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
1930 credit_charge
, needed_charge
));
1931 return NT_STATUS_INVALID_PARAMETER
;
1934 return NT_STATUS_OK
;
1937 NTSTATUS
smbd_smb2_request_verify_sizes(struct smbd_smb2_request
*req
,
1938 size_t expected_body_size
)
1940 struct iovec
*inhdr_v
;
1941 const uint8_t *inhdr
;
1943 const uint8_t *inbody
;
1945 size_t min_dyn_size
= expected_body_size
& 0x00000001;
1946 int max_idx
= req
->in
.vector_count
- SMBD_SMB2_NUM_IOV_PER_REQ
;
1949 * The following should be checked already.
1951 if (req
->in
.vector_count
< SMBD_SMB2_NUM_IOV_PER_REQ
) {
1952 return NT_STATUS_INTERNAL_ERROR
;
1954 if (req
->current_idx
> max_idx
) {
1955 return NT_STATUS_INTERNAL_ERROR
;
1958 inhdr_v
= SMBD_SMB2_IN_HDR_IOV(req
);
1959 if (inhdr_v
->iov_len
!= SMB2_HDR_BODY
) {
1960 return NT_STATUS_INTERNAL_ERROR
;
1962 if (SMBD_SMB2_IN_BODY_LEN(req
) < 2) {
1963 return NT_STATUS_INTERNAL_ERROR
;
1966 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1967 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
1971 case SMB2_OP_GETINFO
:
1975 if (req
->smb1req
!= NULL
&& req
->smb1req
->unread_bytes
> 0) {
1976 if (req
->smb1req
->unread_bytes
< min_dyn_size
) {
1977 return NT_STATUS_INVALID_PARAMETER
;
1986 * Now check the expected body size,
1987 * where the last byte might be in the
1990 if (SMBD_SMB2_IN_BODY_LEN(req
) != (expected_body_size
& 0xFFFFFFFE)) {
1991 return NT_STATUS_INVALID_PARAMETER
;
1993 if (SMBD_SMB2_IN_DYN_LEN(req
) < min_dyn_size
) {
1994 return NT_STATUS_INVALID_PARAMETER
;
1997 inbody
= SMBD_SMB2_IN_BODY_PTR(req
);
1999 body_size
= SVAL(inbody
, 0x00);
2000 if (body_size
!= expected_body_size
) {
2001 return NT_STATUS_INVALID_PARAMETER
;
2004 return NT_STATUS_OK
;
2007 NTSTATUS
smbd_smb2_request_dispatch(struct smbd_smb2_request
*req
)
2009 struct smbXsrv_connection
*xconn
= req
->xconn
;
2010 const struct smbd_smb2_dispatch_table
*call
= NULL
;
2011 const struct iovec
*intf_v
= SMBD_SMB2_IN_TF_IOV(req
);
2012 const uint8_t *inhdr
;
2017 NTSTATUS session_status
;
2018 uint32_t allowed_flags
;
2019 NTSTATUS return_value
;
2020 struct smbXsrv_session
*x
= NULL
;
2021 bool signing_required
= false;
2022 bool encryption_desired
= false;
2023 bool encryption_required
= false;
2025 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2027 DO_PROFILE_INC(request
);
2029 /* TODO: verify more things */
2031 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2032 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2033 mid
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
2034 DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2035 smb2_opcode_name(opcode
),
2036 (unsigned long long)mid
));
2038 if (xconn
->protocol
>= PROTOCOL_SMB2_02
) {
2040 * once the protocol is negotiated
2041 * SMB2_OP_NEGPROT is not allowed anymore
2043 if (opcode
== SMB2_OP_NEGPROT
) {
2044 /* drop the connection */
2045 return NT_STATUS_INVALID_PARAMETER
;
2049 * if the protocol is not negotiated yet
2050 * only SMB2_OP_NEGPROT is allowed.
2052 if (opcode
!= SMB2_OP_NEGPROT
) {
2053 /* drop the connection */
2054 return NT_STATUS_INVALID_PARAMETER
;
2059 * Check if the client provided a valid session id,
2060 * if so smbd_smb2_request_check_session() calls
2061 * set_current_user_info().
2063 * As some command don't require a valid session id
2064 * we defer the check of the session_status
2066 session_status
= smbd_smb2_request_check_session(req
);
2069 signing_required
= x
->global
->signing_required
;
2070 encryption_desired
= x
->encryption_desired
;
2071 encryption_required
= x
->global
->encryption_required
;
2074 req
->do_signing
= false;
2075 req
->do_encryption
= false;
2076 req
->was_encrypted
= false;
2077 if (intf_v
->iov_len
== SMB2_TF_HDR_SIZE
) {
2078 const uint8_t *intf
= SMBD_SMB2_IN_TF_PTR(req
);
2079 uint64_t tf_session_id
= BVAL(intf
, SMB2_TF_SESSION_ID
);
2081 if (x
!= NULL
&& x
->global
->session_wire_id
!= tf_session_id
) {
2082 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2083 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2084 (unsigned long long)x
->global
->session_wire_id
,
2085 (unsigned long long)tf_session_id
));
2087 * TODO: windows allows this...
2088 * should we drop the connection?
2090 * For now we just return ACCESS_DENIED
2091 * (Windows clients never trigger this)
2092 * and wait for an update of [MS-SMB2].
2094 return smbd_smb2_request_error(req
,
2095 NT_STATUS_ACCESS_DENIED
);
2098 req
->was_encrypted
= true;
2101 if (encryption_required
&& !req
->was_encrypted
) {
2102 return smbd_smb2_request_error(req
,
2103 NT_STATUS_ACCESS_DENIED
);
2106 call
= smbd_smb2_call(opcode
);
2108 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2111 allowed_flags
= SMB2_HDR_FLAG_CHAINED
|
2112 SMB2_HDR_FLAG_SIGNED
|
2114 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
2115 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
2117 if (opcode
== SMB2_OP_NEGPROT
) {
2118 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11
) {
2119 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
2122 if (opcode
== SMB2_OP_CANCEL
) {
2123 allowed_flags
|= SMB2_HDR_FLAG_ASYNC
;
2125 if ((flags
& ~allowed_flags
) != 0) {
2126 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2129 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
2131 * This check is mostly for giving the correct error code
2132 * for compounded requests.
2134 if (!NT_STATUS_IS_OK(session_status
)) {
2135 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2138 req
->compat_chain_fsp
= NULL
;
2141 if (req
->was_encrypted
) {
2142 signing_required
= false;
2143 } else if (signing_required
|| (flags
& SMB2_HDR_FLAG_SIGNED
)) {
2144 DATA_BLOB signing_key
= data_blob_null
;
2148 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2149 * If the SMB2 header of the SMB2 NEGOTIATE
2150 * request has the SMB2_FLAGS_SIGNED bit set in the
2151 * Flags field, the server MUST fail the request
2152 * with STATUS_INVALID_PARAMETER.
2154 * Microsoft test tool checks this.
2157 if ((opcode
== SMB2_OP_NEGPROT
) &&
2158 (flags
& SMB2_HDR_FLAG_SIGNED
)) {
2159 status
= NT_STATUS_INVALID_PARAMETER
;
2161 status
= NT_STATUS_USER_SESSION_DELETED
;
2163 return smbd_smb2_request_error(req
, status
);
2166 signing_key
= smbd_smb2_signing_key(x
, xconn
);
2169 * If we have a signing key, we should
2172 if (signing_key
.length
> 0) {
2173 req
->do_signing
= true;
2176 status
= smb2_signing_check_pdu(signing_key
,
2178 SMBD_SMB2_IN_HDR_IOV(req
),
2179 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2180 if (!NT_STATUS_IS_OK(status
)) {
2181 return smbd_smb2_request_error(req
, status
);
2185 * Now that we know the request was correctly signed
2186 * we have to sign the response too.
2188 req
->do_signing
= true;
2190 if (!NT_STATUS_IS_OK(session_status
)) {
2191 return smbd_smb2_request_error(req
, session_status
);
2193 } else if (opcode
== SMB2_OP_CANCEL
) {
2194 /* Cancel requests are allowed to skip the signing */
2195 } else if (signing_required
) {
2197 * If signing is required we try to sign
2198 * a possible error response
2200 req
->do_signing
= true;
2201 return smbd_smb2_request_error(req
, NT_STATUS_ACCESS_DENIED
);
2204 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
2205 req
->compound_related
= true;
2208 if (call
->need_session
) {
2209 if (!NT_STATUS_IS_OK(session_status
)) {
2210 return smbd_smb2_request_error(req
, session_status
);
2214 if (call
->need_tcon
) {
2215 SMB_ASSERT(call
->need_session
);
2218 * This call needs to be run as user.
2220 * smbd_smb2_request_check_tcon()
2221 * calls change_to_user() on success.
2223 status
= smbd_smb2_request_check_tcon(req
);
2224 if (!NT_STATUS_IS_OK(status
)) {
2225 return smbd_smb2_request_error(req
, status
);
2227 if (req
->tcon
->encryption_desired
) {
2228 encryption_desired
= true;
2230 if (req
->tcon
->global
->encryption_required
) {
2231 encryption_required
= true;
2233 if (encryption_required
&& !req
->was_encrypted
) {
2234 return smbd_smb2_request_error(req
,
2235 NT_STATUS_ACCESS_DENIED
);
2239 if (req
->was_encrypted
|| encryption_desired
) {
2240 req
->do_encryption
= true;
2243 if (call
->fileid_ofs
!= 0) {
2244 size_t needed
= call
->fileid_ofs
+ 16;
2245 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
2246 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
2247 uint64_t file_id_persistent
;
2248 uint64_t file_id_volatile
;
2249 struct files_struct
*fsp
;
2251 SMB_ASSERT(call
->need_tcon
);
2253 if (needed
> body_size
) {
2254 return smbd_smb2_request_error(req
,
2255 NT_STATUS_INVALID_PARAMETER
);
2258 file_id_persistent
= BVAL(body
, call
->fileid_ofs
+ 0);
2259 file_id_volatile
= BVAL(body
, call
->fileid_ofs
+ 8);
2261 fsp
= file_fsp_smb2(req
, file_id_persistent
, file_id_volatile
);
2263 if (!call
->allow_invalid_fileid
) {
2264 return smbd_smb2_request_error(req
,
2265 NT_STATUS_FILE_CLOSED
);
2268 if (file_id_persistent
!= UINT64_MAX
) {
2269 return smbd_smb2_request_error(req
,
2270 NT_STATUS_FILE_CLOSED
);
2272 if (file_id_volatile
!= UINT64_MAX
) {
2273 return smbd_smb2_request_error(req
,
2274 NT_STATUS_FILE_CLOSED
);
2279 if (call
->as_root
) {
2280 SMB_ASSERT(call
->fileid_ofs
== 0);
2281 /* This call needs to be run as root */
2282 change_to_root_user();
2284 SMB_ASSERT(call
->need_tcon
);
2287 #define _INBYTES(_r) \
2288 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2291 case SMB2_OP_NEGPROT
:
2292 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot
, profile_p
,
2293 req
->profile
, _INBYTES(req
));
2294 return_value
= smbd_smb2_request_process_negprot(req
);
2297 case SMB2_OP_SESSSETUP
:
2298 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup
, profile_p
,
2299 req
->profile
, _INBYTES(req
));
2300 return_value
= smbd_smb2_request_process_sesssetup(req
);
2303 case SMB2_OP_LOGOFF
:
2304 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff
, profile_p
,
2305 req
->profile
, _INBYTES(req
));
2306 return_value
= smbd_smb2_request_process_logoff(req
);
2310 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon
, profile_p
,
2311 req
->profile
, _INBYTES(req
));
2312 return_value
= smbd_smb2_request_process_tcon(req
);
2316 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis
, profile_p
,
2317 req
->profile
, _INBYTES(req
));
2318 return_value
= smbd_smb2_request_process_tdis(req
);
2321 case SMB2_OP_CREATE
:
2322 if (req
->subreq
== NULL
) {
2323 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create
, profile_p
,
2324 req
->profile
, _INBYTES(req
));
2326 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req
->profile
);
2328 return_value
= smbd_smb2_request_process_create(req
);
2332 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close
, profile_p
,
2333 req
->profile
, _INBYTES(req
));
2334 return_value
= smbd_smb2_request_process_close(req
);
2338 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush
, profile_p
,
2339 req
->profile
, _INBYTES(req
));
2340 return_value
= smbd_smb2_request_process_flush(req
);
2344 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read
, profile_p
,
2345 req
->profile
, _INBYTES(req
));
2346 return_value
= smbd_smb2_request_process_read(req
);
2350 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write
, profile_p
,
2351 req
->profile
, _INBYTES(req
));
2352 return_value
= smbd_smb2_request_process_write(req
);
2356 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock
, profile_p
,
2357 req
->profile
, _INBYTES(req
));
2358 return_value
= smbd_smb2_request_process_lock(req
);
2362 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl
, profile_p
,
2363 req
->profile
, _INBYTES(req
));
2364 return_value
= smbd_smb2_request_process_ioctl(req
);
2367 case SMB2_OP_CANCEL
:
2368 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel
, profile_p
,
2369 req
->profile
, _INBYTES(req
));
2370 return_value
= smbd_smb2_request_process_cancel(req
);
2371 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
, 0);
2374 * We don't need the request anymore cancel requests never
2377 * smbd_smb2_request_process_cancel() already called
2378 * DLIST_REMOVE(xconn->smb2.requests, req);
2384 case SMB2_OP_KEEPALIVE
:
2385 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive
, profile_p
,
2386 req
->profile
, _INBYTES(req
));
2387 return_value
= smbd_smb2_request_process_keepalive(req
);
2390 case SMB2_OP_QUERY_DIRECTORY
:
2391 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find
, profile_p
,
2392 req
->profile
, _INBYTES(req
));
2393 return_value
= smbd_smb2_request_process_query_directory(req
);
2396 case SMB2_OP_NOTIFY
:
2397 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify
, profile_p
,
2398 req
->profile
, _INBYTES(req
));
2399 return_value
= smbd_smb2_request_process_notify(req
);
2402 case SMB2_OP_GETINFO
:
2403 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo
, profile_p
,
2404 req
->profile
, _INBYTES(req
));
2405 return_value
= smbd_smb2_request_process_getinfo(req
);
2408 case SMB2_OP_SETINFO
:
2409 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo
, profile_p
,
2410 req
->profile
, _INBYTES(req
));
2411 return_value
= smbd_smb2_request_process_setinfo(req
);
2415 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break
, profile_p
,
2416 req
->profile
, _INBYTES(req
));
2417 return_value
= smbd_smb2_request_process_break(req
);
2421 return_value
= smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2424 return return_value
;
2427 static NTSTATUS
smbd_smb2_request_reply(struct smbd_smb2_request
*req
)
2429 struct smbXsrv_connection
*xconn
= req
->xconn
;
2431 struct iovec
*firsttf
= SMBD_SMB2_IDX_TF_IOV(req
,out
,first_idx
);
2432 struct iovec
*outhdr
= SMBD_SMB2_OUT_HDR_IOV(req
);
2433 struct iovec
*outdyn
= SMBD_SMB2_OUT_DYN_IOV(req
);
2438 TALLOC_FREE(req
->async_te
);
2440 if (req
->do_encryption
&&
2441 (firsttf
->iov_len
== 0) &&
2442 (req
->first_key
.length
== 0) &&
2443 (req
->session
!= NULL
) &&
2444 (req
->session
->global
->encryption_key
.length
!= 0))
2446 DATA_BLOB encryption_key
= req
->session
->global
->encryption_key
;
2448 uint64_t session_id
= req
->session
->global
->session_wire_id
;
2449 uint64_t nonce_high
;
2452 status
= smb2_get_new_nonce(req
->session
,
2455 if (!NT_STATUS_IS_OK(status
)) {
2460 * We need to place the SMB2_TRANSFORM header before the
2465 * we need to remember the encryption key
2466 * and defer the signing/encryption until
2467 * we are sure that we do not change
2470 req
->first_key
= data_blob_dup_talloc(req
, encryption_key
);
2471 if (req
->first_key
.data
== NULL
) {
2472 return NT_STATUS_NO_MEMORY
;
2475 tf
= talloc_zero_array(req
, uint8_t,
2478 return NT_STATUS_NO_MEMORY
;
2481 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2482 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
2483 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
2484 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
2486 firsttf
->iov_base
= (void *)tf
;
2487 firsttf
->iov_len
= SMB2_TF_HDR_SIZE
;
2490 if ((req
->current_idx
> SMBD_SMB2_NUM_IOV_PER_REQ
) &&
2491 (req
->last_key
.length
> 0) &&
2492 (firsttf
->iov_len
== 0))
2494 int last_idx
= req
->current_idx
- SMBD_SMB2_NUM_IOV_PER_REQ
;
2495 struct iovec
*lasthdr
= SMBD_SMB2_IDX_HDR_IOV(req
,out
,last_idx
);
2498 * As we are sure the header of the last request in the
2499 * compound chain will not change, we can to sign here
2500 * with the last signing key we remembered.
2502 status
= smb2_signing_sign_pdu(req
->last_key
,
2505 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2506 if (!NT_STATUS_IS_OK(status
)) {
2510 if (req
->last_key
.length
> 0) {
2511 data_blob_clear_free(&req
->last_key
);
2514 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
,
2515 iov_buflen(outhdr
, SMBD_SMB2_NUM_IOV_PER_REQ
-1));
2517 req
->current_idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
2519 if (req
->current_idx
< req
->out
.vector_count
) {
2521 * We must process the remaining compound
2522 * SMB2 requests before any new incoming SMB2
2523 * requests. This is because incoming SMB2
2524 * requests may include a cancel for a
2525 * compound request we haven't processed
2528 struct tevent_immediate
*im
= tevent_create_immediate(req
);
2530 return NT_STATUS_NO_MEMORY
;
2533 if (req
->do_signing
&& firsttf
->iov_len
== 0) {
2534 struct smbXsrv_session
*x
= req
->session
;
2535 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
2538 * we need to remember the signing key
2539 * and defer the signing until
2540 * we are sure that we do not change
2543 req
->last_key
= data_blob_dup_talloc(req
, signing_key
);
2544 if (req
->last_key
.data
== NULL
) {
2545 return NT_STATUS_NO_MEMORY
;
2549 tevent_schedule_immediate(im
,
2551 smbd_smb2_request_dispatch_immediate
,
2553 return NT_STATUS_OK
;
2556 if (req
->compound_related
) {
2557 req
->compound_related
= false;
2560 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
2562 return NT_STATUS_INVALID_PARAMETER_MIX
;
2565 /* Set credit for these operations (zero credits if this
2566 is a final reply for an async operation). */
2567 smb2_calculate_credits(req
, req
);
2570 * now check if we need to sign the current response
2572 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
2573 status
= smb2_signing_encrypt_pdu(req
->first_key
,
2574 xconn
->smb2
.server
.cipher
,
2576 req
->out
.vector_count
- first_idx
);
2577 if (!NT_STATUS_IS_OK(status
)) {
2580 } else if (req
->do_signing
) {
2581 struct smbXsrv_session
*x
= req
->session
;
2582 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
2584 status
= smb2_signing_sign_pdu(signing_key
,
2587 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2588 if (!NT_STATUS_IS_OK(status
)) {
2592 if (req
->first_key
.length
> 0) {
2593 data_blob_clear_free(&req
->first_key
);
2596 if (req
->preauth
!= NULL
) {
2597 struct hc_sha512state sctx
;
2600 samba_SHA512_Init(&sctx
);
2601 samba_SHA512_Update(&sctx
, req
->preauth
->sha512_value
,
2602 sizeof(req
->preauth
->sha512_value
));
2603 for (i
= 1; i
< req
->in
.vector_count
; i
++) {
2604 samba_SHA512_Update(&sctx
,
2605 req
->in
.vector
[i
].iov_base
,
2606 req
->in
.vector
[i
].iov_len
);
2608 samba_SHA512_Final(req
->preauth
->sha512_value
, &sctx
);
2610 samba_SHA512_Init(&sctx
);
2611 samba_SHA512_Update(&sctx
, req
->preauth
->sha512_value
,
2612 sizeof(req
->preauth
->sha512_value
));
2613 for (i
= 1; i
< req
->out
.vector_count
; i
++) {
2614 samba_SHA512_Update(&sctx
,
2615 req
->out
.vector
[i
].iov_base
,
2616 req
->out
.vector
[i
].iov_len
);
2618 samba_SHA512_Final(req
->preauth
->sha512_value
, &sctx
);
2620 req
->preauth
= NULL
;
2623 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2624 if (req
->out
.vector_count
< (2*SMBD_SMB2_NUM_IOV_PER_REQ
) &&
2625 outdyn
->iov_base
== NULL
&& outdyn
->iov_len
!= 0) {
2626 /* Dynamic part is NULL. Chop it off,
2627 We're going to send it via sendfile. */
2628 req
->out
.vector_count
-= 1;
2632 * We're done with this request -
2633 * move it off the "being processed" queue.
2635 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
2637 req
->queue_entry
.mem_ctx
= req
;
2638 req
->queue_entry
.vector
= req
->out
.vector
;
2639 req
->queue_entry
.count
= req
->out
.vector_count
;
2640 DLIST_ADD_END(xconn
->smb2
.send_queue
, &req
->queue_entry
, NULL
);
2641 xconn
->smb2
.send_queue_len
++;
2643 status
= smbd_smb2_flush_send_queue(xconn
);
2644 if (!NT_STATUS_IS_OK(status
)) {
2648 return NT_STATUS_OK
;
2651 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
);
2653 void smbd_smb2_request_dispatch_immediate(struct tevent_context
*ctx
,
2654 struct tevent_immediate
*im
,
2657 struct smbd_smb2_request
*req
= talloc_get_type_abort(private_data
,
2658 struct smbd_smb2_request
);
2659 struct smbXsrv_connection
*xconn
= req
->xconn
;
2664 if (DEBUGLEVEL
>= 10) {
2665 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2666 req
->current_idx
, req
->in
.vector_count
));
2667 print_req_vectors(req
);
2670 status
= smbd_smb2_request_dispatch(req
);
2671 if (!NT_STATUS_IS_OK(status
)) {
2672 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
2676 status
= smbd_smb2_request_next_incoming(xconn
);
2677 if (!NT_STATUS_IS_OK(status
)) {
2678 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
2683 NTSTATUS
smbd_smb2_request_done_ex(struct smbd_smb2_request
*req
,
2685 DATA_BLOB body
, DATA_BLOB
*dyn
,
2686 const char *location
)
2689 struct iovec
*outbody_v
;
2690 struct iovec
*outdyn_v
;
2691 uint32_t next_command_ofs
;
2693 DEBUG(10,("smbd_smb2_request_done_ex: "
2694 "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
2695 req
->current_idx
, nt_errstr(status
), (unsigned int)body
.length
,
2697 (unsigned int)(dyn
? dyn
->length
: 0),
2700 if (body
.length
< 2) {
2701 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
2704 if ((body
.length
% 2) != 0) {
2705 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
2708 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2709 outbody_v
= SMBD_SMB2_OUT_BODY_IOV(req
);
2710 outdyn_v
= SMBD_SMB2_OUT_DYN_IOV(req
);
2712 next_command_ofs
= IVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
);
2713 SIVAL(outhdr
, SMB2_HDR_STATUS
, NT_STATUS_V(status
));
2715 outbody_v
->iov_base
= (void *)body
.data
;
2716 outbody_v
->iov_len
= body
.length
;
2719 outdyn_v
->iov_base
= (void *)dyn
->data
;
2720 outdyn_v
->iov_len
= dyn
->length
;
2722 outdyn_v
->iov_base
= NULL
;
2723 outdyn_v
->iov_len
= 0;
2727 * See if we need to recalculate the offset to the next response
2729 * Note that all responses may require padding (including the very last
2732 if (req
->out
.vector_count
>= (2 * SMBD_SMB2_NUM_IOV_PER_REQ
)) {
2733 next_command_ofs
= SMB2_HDR_BODY
;
2734 next_command_ofs
+= SMBD_SMB2_OUT_BODY_LEN(req
);
2735 next_command_ofs
+= SMBD_SMB2_OUT_DYN_LEN(req
);
2738 if ((next_command_ofs
% 8) != 0) {
2739 size_t pad_size
= 8 - (next_command_ofs
% 8);
2740 if (SMBD_SMB2_OUT_DYN_LEN(req
) == 0) {
2742 * if the dyn buffer is empty
2743 * we can use it to add padding
2747 pad
= talloc_zero_array(req
,
2750 return smbd_smb2_request_error(req
,
2751 NT_STATUS_NO_MEMORY
);
2754 outdyn_v
->iov_base
= (void *)pad
;
2755 outdyn_v
->iov_len
= pad_size
;
2758 * For now we copy the dynamic buffer
2759 * and add the padding to the new buffer
2766 old_size
= SMBD_SMB2_OUT_DYN_LEN(req
);
2767 old_dyn
= SMBD_SMB2_OUT_DYN_PTR(req
);
2769 new_size
= old_size
+ pad_size
;
2770 new_dyn
= talloc_zero_array(req
,
2772 if (new_dyn
== NULL
) {
2773 return smbd_smb2_request_error(req
,
2774 NT_STATUS_NO_MEMORY
);
2777 memcpy(new_dyn
, old_dyn
, old_size
);
2778 memset(new_dyn
+ old_size
, 0, pad_size
);
2780 outdyn_v
->iov_base
= (void *)new_dyn
;
2781 outdyn_v
->iov_len
= new_size
;
2783 next_command_ofs
+= pad_size
;
2786 if ((req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) >= req
->out
.vector_count
) {
2787 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2789 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
2791 return smbd_smb2_request_reply(req
);
2794 NTSTATUS
smbd_smb2_request_error_ex(struct smbd_smb2_request
*req
,
2797 const char *location
)
2799 struct smbXsrv_connection
*xconn
= req
->xconn
;
2802 uint8_t *outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2803 size_t unread_bytes
= smbd_smb2_unread_bytes(req
);
2805 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
2806 "at %s\n", req
->current_idx
, nt_errstr(status
),
2807 info
? " +info" : "", location
);
2810 /* Recvfile error. Drain incoming socket. */
2814 ret
= drain_socket(xconn
->transport
.sock
, unread_bytes
);
2815 if (ret
!= unread_bytes
) {
2819 error
= NT_STATUS_IO_DEVICE_ERROR
;
2821 error
= map_nt_error_from_unix_common(errno
);
2824 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
2825 "ret[%u] errno[%d] => %s\n",
2826 (unsigned)unread_bytes
,
2827 (unsigned)ret
, errno
, nt_errstr(error
)));
2832 body
.data
= outhdr
+ SMB2_HDR_BODY
;
2834 SSVAL(body
.data
, 0, 9);
2837 SIVAL(body
.data
, 0x04, info
->length
);
2839 /* Allocated size of req->out.vector[i].iov_base
2840 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
2841 * 1 byte without having to do an alloc.
2844 info
->data
= ((uint8_t *)outhdr
) +
2845 OUTVEC_ALLOC_SIZE
- 1;
2847 SCVAL(info
->data
, 0, 0);
2851 * Note: Even if there is an error, continue to process the request.
2855 return smbd_smb2_request_done_ex(req
, status
, body
, info
, __location__
);
2859 struct smbd_smb2_send_break_state
{
2860 struct smbd_smb2_send_queue queue_entry
;
2861 uint8_t nbt_hdr
[NBT_HDR_SIZE
];
2862 uint8_t tf
[SMB2_TF_HDR_SIZE
];
2863 uint8_t hdr
[SMB2_HDR_BODY
];
2864 struct iovec vector
[1+SMBD_SMB2_NUM_IOV_PER_REQ
];
2868 static NTSTATUS
smbd_smb2_send_break(struct smbXsrv_connection
*xconn
,
2869 struct smbXsrv_session
*session
,
2870 struct smbXsrv_tcon
*tcon
,
2871 const uint8_t *body
,
2874 struct smbd_smb2_send_break_state
*state
;
2875 bool do_encryption
= false;
2876 uint64_t session_wire_id
= 0;
2877 uint64_t nonce_high
= 0;
2878 uint64_t nonce_low
= 0;
2883 if (session
!= NULL
) {
2884 session_wire_id
= session
->global
->session_wire_id
;
2885 do_encryption
= session
->encryption_desired
;
2886 if (tcon
->encryption_desired
) {
2887 do_encryption
= true;
2891 statelen
= offsetof(struct smbd_smb2_send_break_state
, body
) +
2894 state
= talloc_zero_size(xconn
, statelen
);
2895 if (state
== NULL
) {
2896 return NT_STATUS_NO_MEMORY
;
2898 talloc_set_name_const(state
, "struct smbd_smb2_send_break_state");
2900 if (do_encryption
) {
2901 status
= smb2_get_new_nonce(session
,
2904 if (!NT_STATUS_IS_OK(status
)) {
2909 SIVAL(state
->tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2910 SBVAL(state
->tf
, SMB2_TF_NONCE
+0, nonce_low
);
2911 SBVAL(state
->tf
, SMB2_TF_NONCE
+8, nonce_high
);
2912 SBVAL(state
->tf
, SMB2_TF_SESSION_ID
, session_wire_id
);
2914 SIVAL(state
->hdr
, 0, SMB2_MAGIC
);
2915 SSVAL(state
->hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
2916 SSVAL(state
->hdr
, SMB2_HDR_EPOCH
, 0);
2917 SIVAL(state
->hdr
, SMB2_HDR_STATUS
, 0);
2918 SSVAL(state
->hdr
, SMB2_HDR_OPCODE
, SMB2_OP_BREAK
);
2919 SSVAL(state
->hdr
, SMB2_HDR_CREDIT
, 0);
2920 SIVAL(state
->hdr
, SMB2_HDR_FLAGS
, SMB2_HDR_FLAG_REDIRECT
);
2921 SIVAL(state
->hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2922 SBVAL(state
->hdr
, SMB2_HDR_MESSAGE_ID
, UINT64_MAX
);
2923 SIVAL(state
->hdr
, SMB2_HDR_PID
, 0);
2924 SIVAL(state
->hdr
, SMB2_HDR_TID
, 0);
2925 SBVAL(state
->hdr
, SMB2_HDR_SESSION_ID
, 0);
2926 memset(state
->hdr
+SMB2_HDR_SIGNATURE
, 0, 16);
2928 state
->vector
[0] = (struct iovec
) {
2929 .iov_base
= state
->nbt_hdr
,
2930 .iov_len
= sizeof(state
->nbt_hdr
)
2933 if (do_encryption
) {
2934 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
2935 .iov_base
= state
->tf
,
2936 .iov_len
= sizeof(state
->tf
)
2939 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
2945 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
] = (struct iovec
) {
2946 .iov_base
= state
->hdr
,
2947 .iov_len
= sizeof(state
->hdr
)
2950 memcpy(state
->body
, body
, body_len
);
2952 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
] = (struct iovec
) {
2953 .iov_base
= state
->body
,
2954 .iov_len
= body_len
/* no sizeof(state->body) .. :-) */
2958 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
2961 ok
= smb2_setup_nbt_length(state
->vector
,
2962 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
2964 return NT_STATUS_INVALID_PARAMETER_MIX
;
2967 if (do_encryption
) {
2968 DATA_BLOB encryption_key
= session
->global
->encryption_key
;
2970 status
= smb2_signing_encrypt_pdu(encryption_key
,
2971 xconn
->smb2
.server
.cipher
,
2972 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
2973 SMBD_SMB2_NUM_IOV_PER_REQ
);
2974 if (!NT_STATUS_IS_OK(status
)) {
2979 state
->queue_entry
.mem_ctx
= state
;
2980 state
->queue_entry
.vector
= state
->vector
;
2981 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
2982 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
, NULL
);
2983 xconn
->smb2
.send_queue_len
++;
2985 status
= smbd_smb2_flush_send_queue(xconn
);
2986 if (!NT_STATUS_IS_OK(status
)) {
2990 return NT_STATUS_OK
;
2993 NTSTATUS
smbd_smb2_send_oplock_break(struct smbXsrv_connection
*xconn
,
2994 struct smbXsrv_session
*session
,
2995 struct smbXsrv_tcon
*tcon
,
2996 struct smbXsrv_open
*op
,
2997 uint8_t oplock_level
)
3001 SSVAL(body
, 0x00, sizeof(body
));
3002 SCVAL(body
, 0x02, oplock_level
);
3003 SCVAL(body
, 0x03, 0); /* reserved */
3004 SIVAL(body
, 0x04, 0); /* reserved */
3005 SBVAL(body
, 0x08, op
->global
->open_persistent_id
);
3006 SBVAL(body
, 0x10, op
->global
->open_volatile_id
);
3008 return smbd_smb2_send_break(xconn
, NULL
, NULL
, body
, sizeof(body
));
3011 NTSTATUS
smbd_smb2_send_lease_break(struct smbXsrv_connection
*xconn
,
3013 uint32_t lease_flags
,
3014 struct smb2_lease_key
*lease_key
,
3015 uint32_t current_lease_state
,
3016 uint32_t new_lease_state
)
3020 SSVAL(body
, 0x00, sizeof(body
));
3021 SSVAL(body
, 0x02, new_epoch
);
3022 SIVAL(body
, 0x04, lease_flags
);
3023 SBVAL(body
, 0x08, lease_key
->data
[0]);
3024 SBVAL(body
, 0x10, lease_key
->data
[1]);
3025 SIVAL(body
, 0x18, current_lease_state
);
3026 SIVAL(body
, 0x1c, new_lease_state
);
3027 SIVAL(body
, 0x20, 0); /* BreakReason, MUST be 0 */
3028 SIVAL(body
, 0x24, 0); /* AccessMaskHint, MUST be 0 */
3029 SIVAL(body
, 0x28, 0); /* ShareMaskHint, MUST be 0 */
3031 return smbd_smb2_send_break(xconn
, NULL
, NULL
, body
, sizeof(body
));
3034 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state
*state
)
3038 uint64_t file_id_persistent
;
3039 uint64_t file_id_volatile
;
3040 struct smbXsrv_open
*op
= NULL
;
3041 struct files_struct
*fsp
= NULL
;
3042 const uint8_t *body
= NULL
;
3045 * This is only called with a pktbuf
3046 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
3050 if (IVAL(state
->pktbuf
, 0) == SMB2_TF_MAGIC
) {
3051 /* Transform header. Cannot recvfile. */
3054 if (IVAL(state
->pktbuf
, 0) != SMB2_MAGIC
) {
3055 /* Not SMB2. Normal error path will cope. */
3058 if (SVAL(state
->pktbuf
, 4) != SMB2_HDR_BODY
) {
3059 /* Not SMB2. Normal error path will cope. */
3062 if (SVAL(state
->pktbuf
, SMB2_HDR_OPCODE
) != SMB2_OP_WRITE
) {
3063 /* Needs to be a WRITE. */
3066 if (IVAL(state
->pktbuf
, SMB2_HDR_NEXT_COMMAND
) != 0) {
3067 /* Chained. Cannot recvfile. */
3070 flags
= IVAL(state
->pktbuf
, SMB2_HDR_FLAGS
);
3071 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3072 /* Chained. Cannot recvfile. */
3075 if (flags
& SMB2_HDR_FLAG_SIGNED
) {
3076 /* Signed. Cannot recvfile. */
3080 body
= &state
->pktbuf
[SMB2_HDR_BODY
];
3082 file_id_persistent
= BVAL(body
, 0x10);
3083 file_id_volatile
= BVAL(body
, 0x18);
3085 status
= smb2srv_open_lookup(state
->req
->xconn
,
3090 if (!NT_STATUS_IS_OK(status
)) {
3098 if (fsp
->conn
== NULL
) {
3102 if (IS_IPC(fsp
->conn
)) {
3105 if (IS_PRINT(fsp
->conn
)) {
3109 DEBUG(10,("Doing recvfile write len = %u\n",
3110 (unsigned int)(state
->pktfull
- state
->pktlen
)));
3115 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
)
3117 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3118 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
3119 size_t max_send_queue_len
;
3120 size_t cur_send_queue_len
;
3122 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
3124 * we're not supposed to do any io
3126 return NT_STATUS_OK
;
3129 if (state
->req
!= NULL
) {
3131 * if there is already a tstream_readv_pdu
3132 * pending, we are done.
3134 return NT_STATUS_OK
;
3137 max_send_queue_len
= MAX(1, xconn
->smb2
.credits
.max
/16);
3138 cur_send_queue_len
= xconn
->smb2
.send_queue_len
;
3140 if (cur_send_queue_len
> max_send_queue_len
) {
3142 * if we have a lot of requests to send,
3143 * we wait until they are on the wire until we
3144 * ask for the next request.
3146 return NT_STATUS_OK
;
3149 /* ask for the next request */
3150 ZERO_STRUCTP(state
);
3151 state
->req
= smbd_smb2_request_allocate(xconn
);
3152 if (state
->req
== NULL
) {
3153 return NT_STATUS_NO_MEMORY
;
3155 state
->req
->sconn
= sconn
;
3156 state
->req
->xconn
= xconn
;
3157 state
->min_recv_size
= lp_min_receive_file_size();
3159 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3161 return NT_STATUS_OK
;
3164 void smbd_smb2_process_negprot(struct smbXsrv_connection
*xconn
,
3165 uint64_t expected_seq_low
,
3166 const uint8_t *inpdu
, size_t size
)
3168 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3170 struct smbd_smb2_request
*req
= NULL
;
3172 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3173 (unsigned int)size
));
3175 status
= smbd_initialize_smb2(xconn
, expected_seq_low
);
3176 if (!NT_STATUS_IS_OK(status
)) {
3177 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3181 status
= smbd_smb2_request_create(xconn
, inpdu
, size
, &req
);
3182 if (!NT_STATUS_IS_OK(status
)) {
3183 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3187 status
= smbd_smb2_request_validate(req
);
3188 if (!NT_STATUS_IS_OK(status
)) {
3189 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3193 status
= smbd_smb2_request_setup_out(req
);
3194 if (!NT_STATUS_IS_OK(status
)) {
3195 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3201 * this was already counted at the SMB1 layer =>
3202 * smbd_smb2_request_dispatch() should not count it twice.
3204 if (profile_p
->values
.request_stats
.count
> 0) {
3205 profile_p
->values
.request_stats
.count
--;
3208 status
= smbd_smb2_request_dispatch(req
);
3209 if (!NT_STATUS_IS_OK(status
)) {
3210 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3214 status
= smbd_smb2_request_next_incoming(xconn
);
3215 if (!NT_STATUS_IS_OK(status
)) {
3216 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3220 sconn
->num_requests
++;
3223 static int socket_error_from_errno(int ret
,
3237 if (sys_errno
== 0) {
3241 if (sys_errno
== EINTR
) {
3246 if (sys_errno
== EINPROGRESS
) {
3251 if (sys_errno
== EAGAIN
) {
3256 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3257 if (sys_errno
== ENOMEM
) {
3263 #if EWOULDBLOCK != EAGAIN
3264 if (sys_errno
== EWOULDBLOCK
) {
3274 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
)
3280 if (xconn
->smb2
.send_queue
== NULL
) {
3281 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
3282 return NT_STATUS_OK
;
3285 while (xconn
->smb2
.send_queue
!= NULL
) {
3286 struct smbd_smb2_send_queue
*e
= xconn
->smb2
.send_queue
;
3289 if (e
->sendfile_header
!= NULL
) {
3290 NTSTATUS status
= NT_STATUS_INTERNAL_ERROR
;
3295 for (i
=0; i
< e
->count
; i
++) {
3296 size
+= e
->vector
[i
].iov_len
;
3299 if (size
<= e
->sendfile_header
->length
) {
3300 buf
= e
->sendfile_header
->data
;
3302 buf
= talloc_array(e
->mem_ctx
, uint8_t, size
);
3304 return NT_STATUS_NO_MEMORY
;
3309 for (i
=0; i
< e
->count
; i
++) {
3311 e
->vector
[i
].iov_base
,
3312 e
->vector
[i
].iov_len
);
3313 size
+= e
->vector
[i
].iov_len
;
3316 e
->sendfile_header
->data
= buf
;
3317 e
->sendfile_header
->length
= size
;
3318 e
->sendfile_status
= &status
;
3321 xconn
->smb2
.send_queue_len
--;
3322 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
3324 * This triggers the sendfile path via
3327 talloc_free(e
->mem_ctx
);
3329 if (!NT_STATUS_IS_OK(status
)) {
3335 ret
= writev(xconn
->transport
.sock
, e
->vector
, e
->count
);
3337 /* propagate end of file */
3338 return NT_STATUS_INTERNAL_ERROR
;
3340 err
= socket_error_from_errno(ret
, errno
, &retry
);
3343 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
3344 return NT_STATUS_OK
;
3347 return map_nt_error_from_unix_common(err
);
3350 ok
= iov_advance(&e
->vector
, &e
->count
, ret
);
3352 return NT_STATUS_INTERNAL_ERROR
;
3356 /* we have more to write */
3357 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
3358 return NT_STATUS_OK
;
3361 xconn
->smb2
.send_queue_len
--;
3362 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
3363 talloc_free(e
->mem_ctx
);
3366 return NT_STATUS_OK
;
3369 static NTSTATUS
smbd_smb2_io_handler(struct smbXsrv_connection
*xconn
,
3372 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3373 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
3374 struct smbd_smb2_request
*req
= NULL
;
3375 size_t min_recvfile_size
= UINT32_MAX
;
3382 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
3384 * we're not supposed to do any io
3386 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
3387 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
3388 return NT_STATUS_OK
;
3391 if (fde_flags
& TEVENT_FD_WRITE
) {
3392 status
= smbd_smb2_flush_send_queue(xconn
);
3393 if (!NT_STATUS_IS_OK(status
)) {
3398 if (!(fde_flags
& TEVENT_FD_READ
)) {
3399 return NT_STATUS_OK
;
3402 if (state
->req
== NULL
) {
3403 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
3404 return NT_STATUS_OK
;
3408 if (!state
->hdr
.done
) {
3409 state
->hdr
.done
= true;
3411 state
->vector
.iov_base
= (void *)state
->hdr
.nbt
;
3412 state
->vector
.iov_len
= NBT_HDR_SIZE
;
3415 ret
= readv(xconn
->transport
.sock
, &state
->vector
, 1);
3417 /* propagate end of file */
3418 return NT_STATUS_END_OF_FILE
;
3420 err
= socket_error_from_errno(ret
, errno
, &retry
);
3423 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3424 return NT_STATUS_OK
;
3427 return map_nt_error_from_unix_common(err
);
3430 if (ret
< state
->vector
.iov_len
) {
3432 base
= (uint8_t *)state
->vector
.iov_base
;
3434 state
->vector
.iov_base
= (void *)base
;
3435 state
->vector
.iov_len
-= ret
;
3436 /* we have more to read */
3437 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3438 return NT_STATUS_OK
;
3441 if (state
->pktlen
> 0) {
3442 if (state
->doing_receivefile
&& !is_smb2_recvfile_write(state
)) {
3444 * Not a possible receivefile write.
3445 * Read the rest of the data.
3447 state
->doing_receivefile
= false;
3449 state
->pktbuf
= talloc_realloc(state
->req
,
3453 if (state
->pktbuf
== NULL
) {
3454 return NT_STATUS_NO_MEMORY
;
3457 state
->vector
.iov_base
= (void *)(state
->pktbuf
+
3459 state
->vector
.iov_len
= (state
->pktfull
-
3462 state
->pktlen
= state
->pktfull
;
3467 * Either this is a receivefile write so we've
3468 * done a short read, or if not we have all the data.
3474 * Now we analyze the NBT header
3476 if (state
->hdr
.nbt
[0] != 0x00) {
3477 state
->min_recv_size
= 0;
3479 state
->pktfull
= smb2_len(state
->hdr
.nbt
);
3480 if (state
->pktfull
== 0) {
3484 if (state
->min_recv_size
!= 0) {
3485 min_recvfile_size
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
3486 min_recvfile_size
+= state
->min_recv_size
;
3489 if (state
->pktfull
> min_recvfile_size
) {
3491 * Might be a receivefile write. Read the SMB2 HEADER +
3492 * SMB2_WRITE header first. Set 'doing_receivefile'
3493 * as we're *attempting* receivefile write. If this
3494 * turns out not to be a SMB2_WRITE request or otherwise
3495 * not suitable then we'll just read the rest of the data
3496 * the next time this function is called.
3498 state
->pktlen
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
3499 state
->doing_receivefile
= true;
3501 state
->pktlen
= state
->pktfull
;
3504 state
->pktbuf
= talloc_array(state
->req
, uint8_t, state
->pktlen
);
3505 if (state
->pktbuf
== NULL
) {
3506 return NT_STATUS_NO_MEMORY
;
3509 state
->vector
.iov_base
= (void *)state
->pktbuf
;
3510 state
->vector
.iov_len
= state
->pktlen
;
3516 if (state
->hdr
.nbt
[0] != 0x00) {
3517 DEBUG(1,("ignore NBT[0x%02X] msg\n",
3518 state
->hdr
.nbt
[0]));
3521 ZERO_STRUCTP(state
);
3523 state
->min_recv_size
= lp_min_receive_file_size();
3531 req
->request_time
= timeval_current();
3532 now
= timeval_to_nttime(&req
->request_time
);
3534 status
= smbd_smb2_inbuf_parse_compound(xconn
,
3540 &req
->in
.vector_count
);
3541 if (!NT_STATUS_IS_OK(status
)) {
3545 if (state
->doing_receivefile
) {
3546 req
->smb1req
= talloc_zero(req
, struct smb_request
);
3547 if (req
->smb1req
== NULL
) {
3548 return NT_STATUS_NO_MEMORY
;
3550 req
->smb1req
->unread_bytes
= state
->pktfull
- state
->pktlen
;
3553 ZERO_STRUCTP(state
);
3555 req
->current_idx
= 1;
3557 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
3558 req
->current_idx
, req
->in
.vector_count
));
3560 status
= smbd_smb2_request_validate(req
);
3561 if (!NT_STATUS_IS_OK(status
)) {
3565 status
= smbd_smb2_request_setup_out(req
);
3566 if (!NT_STATUS_IS_OK(status
)) {
3570 status
= smbd_smb2_request_dispatch(req
);
3571 if (!NT_STATUS_IS_OK(status
)) {
3575 sconn
->num_requests
++;
3577 /* The timeout_processing function isn't run nearly
3578 often enough to implement 'max log size' without
3579 overrunning the size of the file by many megabytes.
3580 This is especially true if we are running at debug
3581 level 10. Checking every 50 SMB2s is a nice
3582 tradeoff of performance vs log file size overrun. */
3584 if ((sconn
->num_requests
% 50) == 0 &&
3585 need_to_check_log_size()) {
3586 change_to_root_user();
3590 status
= smbd_smb2_request_next_incoming(xconn
);
3591 if (!NT_STATUS_IS_OK(status
)) {
3595 return NT_STATUS_OK
;
3598 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
3599 struct tevent_fd
*fde
,
3603 struct smbXsrv_connection
*xconn
=
3604 talloc_get_type_abort(private_data
,
3605 struct smbXsrv_connection
);
3608 status
= smbd_smb2_io_handler(xconn
, flags
);
3609 if (!NT_STATUS_IS_OK(status
)) {
3610 smbd_server_connection_terminate(xconn
, nt_errstr(status
));