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 "system/network.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "smbd/smbXsrv_open.h"
27 #include "lib/param/param.h"
28 #include "../libcli/smb/smb_common.h"
29 #include "../lib/tsocket/tsocket.h"
30 #include "../lib/util/tevent_ntstatus.h"
31 #include "smbprofile.h"
32 #include "../lib/util/bitmap.h"
33 #include "../librpc/gen_ndr/krb5pac.h"
34 #include "lib/util/iov_buf.h"
36 #include "libcli/smb/smbXcli_base.h"
37 #include "source3/lib/substitute.h"
40 /* SIOCOUTQ TIOCOUTQ are the same */
41 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
42 #define __HAVE_TCP_INFO_RTO 1
43 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
44 #elif defined(FREEBSD)
45 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
46 #define __HAVE_TCP_INFO_RTO 1
47 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
50 #include "lib/crypto/gnutls_helpers.h"
51 #include <gnutls/gnutls.h>
52 #include <gnutls/crypto.h>
55 #define DBGC_CLASS DBGC_SMB2
57 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
58 struct tevent_fd
*fde
,
61 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
);
63 static const struct smbd_smb2_dispatch_table
{
66 bool need_session
: 1;
70 } smbd_smb2_table
[] = {
72 .opcode
= SMB2_OP_NEGPROT
,
75 .opcode
= SMB2_OP_SESSSETUP
,
78 .opcode
= SMB2_OP_LOGOFF
,
82 .opcode
= SMB2_OP_TCON
,
85 * This call needs to be run as root.
87 * smbd_smb2_request_process_tcon()
88 * calls make_connection_snum(), which will call
89 * change_to_user(), when needed.
93 .opcode
= SMB2_OP_TDIS
,
98 .opcode
= SMB2_OP_CREATE
,
102 .opcode
= SMB2_OP_CLOSE
,
103 .need_session
= true,
107 .opcode
= SMB2_OP_FLUSH
,
108 .need_session
= true,
112 .opcode
= SMB2_OP_READ
,
113 .need_session
= true,
117 .opcode
= SMB2_OP_WRITE
,
118 .need_session
= true,
123 .opcode
= SMB2_OP_LOCK
,
124 .need_session
= true,
128 .opcode
= SMB2_OP_IOCTL
,
129 .need_session
= true,
134 .opcode
= SMB2_OP_CANCEL
,
137 .opcode
= SMB2_OP_KEEPALIVE
,
139 .opcode
= SMB2_OP_QUERY_DIRECTORY
,
140 .need_session
= true,
144 .opcode
= SMB2_OP_NOTIFY
,
145 .need_session
= true,
149 .opcode
= SMB2_OP_GETINFO
,
150 .need_session
= true,
154 .opcode
= SMB2_OP_SETINFO
,
155 .need_session
= true,
160 .opcode
= SMB2_OP_BREAK
,
161 .need_session
= true,
166 * as LEASE breaks does not
172 const char *smb2_opcode_name(uint16_t opcode
)
174 const char *result
= "Bad SMB2 opcode";
177 case SMB2_OP_NEGPROT
:
178 result
= "SMB2_OP_NEGPROT";
180 case SMB2_OP_SESSSETUP
:
181 result
= "SMB2_OP_SESSSETUP";
184 result
= "SMB2_OP_LOGOFF";
187 result
= "SMB2_OP_TCON";
190 result
= "SMB2_OP_TDIS";
193 result
= "SMB2_OP_CREATE";
196 result
= "SMB2_OP_CLOSE";
199 result
= "SMB2_OP_FLUSH";
202 result
= "SMB2_OP_READ";
205 result
= "SMB2_OP_WRITE";
208 result
= "SMB2_OP_LOCK";
211 result
= "SMB2_OP_IOCTL";
214 result
= "SMB2_OP_CANCEL";
216 case SMB2_OP_KEEPALIVE
:
217 result
= "SMB2_OP_KEEPALIVE";
219 case SMB2_OP_QUERY_DIRECTORY
:
220 result
= "SMB2_OP_QUERY_DIRECTORY";
223 result
= "SMB2_OP_NOTIFY";
225 case SMB2_OP_GETINFO
:
226 result
= "SMB2_OP_GETINFO";
228 case SMB2_OP_SETINFO
:
229 result
= "SMB2_OP_SETINFO";
232 result
= "SMB2_OP_BREAK";
240 static const struct smbd_smb2_dispatch_table
*smbd_smb2_call(uint16_t opcode
)
242 const struct smbd_smb2_dispatch_table
*ret
= NULL
;
244 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
248 ret
= &smbd_smb2_table
[opcode
];
250 SMB_ASSERT(ret
->opcode
== opcode
);
255 static void print_req_vectors(const struct smbd_smb2_request
*req
)
259 for (i
= 0; i
< req
->in
.vector_count
; i
++) {
260 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
262 (unsigned int)req
->in
.vector
[i
].iov_len
);
264 for (i
= 0; i
< req
->out
.vector_count
; i
++) {
265 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
267 (unsigned int)req
->out
.vector
[i
].iov_len
);
271 bool smbd_is_smb2_header(const uint8_t *inbuf
, size_t size
)
273 if (size
< (4 + SMB2_HDR_BODY
)) {
277 if (IVAL(inbuf
, 4) != SMB2_MAGIC
) {
284 bool smbd_smb2_is_compound(const struct smbd_smb2_request
*req
)
286 return req
->in
.vector_count
>= (2*SMBD_SMB2_NUM_IOV_PER_REQ
);
289 bool smbd_smb2_is_last_in_compound(const struct smbd_smb2_request
*req
)
291 return (req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
==
292 req
->in
.vector_count
);
295 static NTSTATUS
smbd_initialize_smb2(struct smbXsrv_connection
*xconn
,
296 uint64_t expected_seq_low
)
300 xconn
->smb2
.credits
.seq_low
= expected_seq_low
;
301 xconn
->smb2
.credits
.seq_range
= 1;
302 xconn
->smb2
.credits
.granted
= 1;
303 xconn
->smb2
.credits
.max
= lp_smb2_max_credits();
304 xconn
->smb2
.credits
.bitmap
= bitmap_talloc(xconn
,
305 xconn
->smb2
.credits
.max
);
306 if (xconn
->smb2
.credits
.bitmap
== NULL
) {
307 return NT_STATUS_NO_MEMORY
;
310 tevent_fd_set_close_fn(xconn
->transport
.fde
, NULL
);
311 TALLOC_FREE(xconn
->transport
.fde
);
313 xconn
->transport
.fde
= tevent_add_fd(
314 xconn
->client
->raw_ev_ctx
,
316 xconn
->transport
.sock
,
318 smbd_smb2_connection_handler
,
320 if (xconn
->transport
.fde
== NULL
) {
321 close(xconn
->transport
.sock
);
322 xconn
->transport
.sock
= -1;
323 return NT_STATUS_NO_MEMORY
;
325 tevent_fd_set_auto_close(xconn
->transport
.fde
);
328 * Ensure child is set to non-blocking mode,
329 * unless the system supports MSG_DONTWAIT,
330 * if MSG_DONTWAIT is available we should force
334 rc
= set_blocking(xconn
->transport
.sock
, true);
336 return NT_STATUS_INTERNAL_ERROR
;
339 rc
= set_blocking(xconn
->transport
.sock
, false);
341 return NT_STATUS_INTERNAL_ERROR
;
348 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
349 #define _smb2_setlen(_buf,len) do { \
350 uint8_t *buf = (uint8_t *)_buf; \
352 buf[1] = ((len)&0xFF0000)>>16; \
353 buf[2] = ((len)&0xFF00)>>8; \
354 buf[3] = (len)&0xFF; \
357 static bool smb2_setup_nbt_length(struct iovec
*vector
, int count
)
365 len
= iov_buflen(vector
+1, count
-1);
367 if ((len
== -1) || (len
> 0xFFFFFF)) {
371 _smb2_setlen(vector
[0].iov_base
, len
);
375 static int smbd_smb2_request_destructor(struct smbd_smb2_request
*req
)
377 TALLOC_FREE(req
->first_enc_key
);
378 TALLOC_FREE(req
->last_sign_key
);
382 void smb2_request_set_async_internal(struct smbd_smb2_request
*req
,
385 req
->async_internal
= async_internal
;
388 static struct smbd_smb2_request
*smbd_smb2_request_allocate(struct smbXsrv_connection
*xconn
)
390 TALLOC_CTX
*mem_pool
;
391 struct smbd_smb2_request
*req
;
394 /* Enable this to find subtle valgrind errors. */
395 mem_pool
= talloc_init("smbd_smb2_request_allocate");
397 mem_pool
= talloc_tos();
399 if (mem_pool
== NULL
) {
403 req
= talloc(mem_pool
, struct smbd_smb2_request
);
405 talloc_free(mem_pool
);
408 talloc_reparent(mem_pool
, xconn
, req
);
410 TALLOC_FREE(mem_pool
);
412 *req
= (struct smbd_smb2_request
) {
413 .sconn
= xconn
->client
->sconn
,
415 .last_session_id
= UINT64_MAX
,
416 .last_tid
= UINT32_MAX
,
419 talloc_set_destructor(req
, smbd_smb2_request_destructor
);
424 static NTSTATUS
smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection
*xconn
,
428 struct smbd_smb2_request
*req
,
432 TALLOC_CTX
*mem_ctx
= req
;
436 uint8_t *first_hdr
= buf
;
437 size_t verified_buflen
= 0;
442 * Note: index '0' is reserved for the transport protocol
444 iov
= req
->in
._vector
;
446 while (taken
< buflen
) {
447 size_t len
= buflen
- taken
;
448 uint8_t *hdr
= first_hdr
+ taken
;
451 size_t next_command_ofs
;
453 uint8_t *body
= NULL
;
456 struct iovec
*iov_alloc
= NULL
;
458 if (iov
!= req
->in
._vector
) {
462 if (verified_buflen
> taken
) {
463 len
= verified_buflen
- taken
;
470 DEBUG(10, ("%d bytes left, expected at least %d\n",
474 if (IVAL(hdr
, 0) == SMB2_TF_MAGIC
) {
475 struct smbXsrv_session
*s
= NULL
;
477 struct iovec tf_iov
[2];
481 if (xconn
->protocol
< PROTOCOL_SMB3_00
) {
482 DEBUG(10, ("Got SMB2_TRANSFORM header, "
483 "but dialect[0x%04X] is used\n",
484 xconn
->smb2
.server
.dialect
));
488 if (xconn
->smb2
.server
.cipher
== 0) {
489 DEBUG(10, ("Got SMB2_TRANSFORM header, "
490 "but not negotiated "
491 "client[0x%08X] server[0x%08X]\n",
492 xconn
->smb2
.client
.capabilities
,
493 xconn
->smb2
.server
.capabilities
));
497 if (len
< SMB2_TF_HDR_SIZE
) {
498 DEBUG(1, ("%d bytes left, expected at least %d\n",
499 (int)len
, SMB2_TF_HDR_SIZE
));
503 tf_len
= SMB2_TF_HDR_SIZE
;
506 hdr
= first_hdr
+ taken
;
507 enc_len
= IVAL(tf
, SMB2_TF_MSG_SIZE
);
508 uid
= BVAL(tf
, SMB2_TF_SESSION_ID
);
510 if (len
< SMB2_TF_HDR_SIZE
+ enc_len
) {
511 DEBUG(1, ("%d bytes left, expected at least %d\n",
513 (int)(SMB2_TF_HDR_SIZE
+ enc_len
)));
517 status
= smb2srv_session_lookup_conn(xconn
, uid
, now
,
520 status
= smb2srv_session_lookup_global(xconn
->client
,
524 DEBUG(1, ("invalid session[%llu] in "
525 "SMB2_TRANSFORM header\n",
526 (unsigned long long)uid
));
527 TALLOC_FREE(iov_alloc
);
528 return NT_STATUS_USER_SESSION_DELETED
;
531 tf_iov
[0].iov_base
= (void *)tf
;
532 tf_iov
[0].iov_len
= tf_len
;
533 tf_iov
[1].iov_base
= (void *)hdr
;
534 tf_iov
[1].iov_len
= enc_len
;
536 status
= smb2_signing_decrypt_pdu(s
->global
->decryption_key
,
538 if (!NT_STATUS_IS_OK(status
)) {
539 TALLOC_FREE(iov_alloc
);
543 verified_buflen
= taken
+ enc_len
;
548 * We need the header plus the body length field
551 if (len
< SMB2_HDR_BODY
+ 2) {
554 (IVAL(hdr
, 0) == SMB_SUICIDE_PACKET
) &&
555 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
556 uint8_t exitcode
= CVAL(hdr
, 4);
557 DBG_WARNING("SUICIDE: Exiting immediately "
558 "with code %"PRIu8
"\n",
563 DEBUG(10, ("%d bytes left, expected at least %d\n",
564 (int)len
, SMB2_HDR_BODY
));
567 if (IVAL(hdr
, 0) != SMB2_MAGIC
) {
568 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
572 if (SVAL(hdr
, 4) != SMB2_HDR_BODY
) {
573 DEBUG(10, ("Got HDR len %d, expected %d\n",
574 SVAL(hdr
, 4), SMB2_HDR_BODY
));
579 next_command_ofs
= IVAL(hdr
, SMB2_HDR_NEXT_COMMAND
);
580 body_size
= SVAL(hdr
, SMB2_HDR_BODY
);
582 if (next_command_ofs
!= 0) {
583 if (next_command_ofs
< (SMB2_HDR_BODY
+ 2)) {
586 if (next_command_ofs
> full_size
) {
589 full_size
= next_command_ofs
;
596 if (body_size
> (full_size
- SMB2_HDR_BODY
)) {
598 * let the caller handle the error
600 body_size
= full_size
- SMB2_HDR_BODY
;
602 body
= hdr
+ SMB2_HDR_BODY
;
603 dyn
= body
+ body_size
;
604 dyn_size
= full_size
- (SMB2_HDR_BODY
+ body_size
);
606 if (num_iov
>= ARRAY_SIZE(req
->in
._vector
)) {
607 struct iovec
*iov_tmp
= NULL
;
609 iov_tmp
= talloc_realloc(mem_ctx
, iov_alloc
,
612 SMBD_SMB2_NUM_IOV_PER_REQ
);
613 if (iov_tmp
== NULL
) {
614 TALLOC_FREE(iov_alloc
);
615 return NT_STATUS_NO_MEMORY
;
618 if (iov_alloc
== NULL
) {
621 sizeof(req
->in
._vector
));
627 num_iov
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
629 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
630 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
631 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
632 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
633 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
634 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= body_size
;
635 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
636 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= dyn_size
;
646 if (iov
!= req
->in
._vector
) {
649 return NT_STATUS_INVALID_PARAMETER
;
652 static NTSTATUS
smbd_smb2_request_create(struct smbXsrv_connection
*xconn
,
653 const uint8_t *_inpdu
, size_t size
,
654 struct smbd_smb2_request
**_req
)
656 struct smbd_smb2_request
*req
;
657 uint32_t protocol_version
;
658 uint8_t *inpdu
= NULL
;
659 const uint8_t *inhdr
= NULL
;
661 uint32_t next_command_ofs
;
665 if (size
< (SMB2_HDR_BODY
+ 2)) {
666 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size
));
667 return NT_STATUS_INVALID_PARAMETER
;
672 protocol_version
= IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
);
673 if (protocol_version
!= SMB2_MAGIC
) {
674 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
676 return NT_STATUS_INVALID_PARAMETER
;
679 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
680 if (cmd
!= SMB2_OP_NEGPROT
) {
681 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
683 return NT_STATUS_INVALID_PARAMETER
;
686 next_command_ofs
= IVAL(inhdr
, SMB2_HDR_NEXT_COMMAND
);
687 if (next_command_ofs
!= 0) {
688 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
690 return NT_STATUS_INVALID_PARAMETER
;
693 req
= smbd_smb2_request_allocate(xconn
);
695 return NT_STATUS_NO_MEMORY
;
698 inpdu
= talloc_memdup(req
, _inpdu
, size
);
700 return NT_STATUS_NO_MEMORY
;
703 req
->request_time
= timeval_current();
704 now
= timeval_to_nttime(&req
->request_time
);
706 status
= smbd_smb2_inbuf_parse_compound(xconn
,
710 req
, &req
->in
.vector
,
711 &req
->in
.vector_count
);
712 if (!NT_STATUS_IS_OK(status
)) {
717 req
->current_idx
= 1;
723 static bool smb2_validate_sequence_number(struct smbXsrv_connection
*xconn
,
724 uint64_t message_id
, uint64_t seq_id
)
726 struct bitmap
*credits_bm
= xconn
->smb2
.credits
.bitmap
;
730 seq_tmp
= xconn
->smb2
.credits
.seq_low
;
731 if (seq_id
< seq_tmp
) {
732 DBGC_ERR(DBGC_SMB2_CREDITS
,
733 "smb2_validate_sequence_number: bad message_id "
734 "%llu (sequence id %llu) "
735 "(granted = %u, low = %llu, range = %u)\n",
736 (unsigned long long)message_id
,
737 (unsigned long long)seq_id
,
738 (unsigned int)xconn
->smb2
.credits
.granted
,
739 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
740 (unsigned int)xconn
->smb2
.credits
.seq_range
);
744 seq_tmp
+= xconn
->smb2
.credits
.seq_range
;
745 if (seq_id
>= seq_tmp
) {
746 DBGC_ERR(DBGC_SMB2_CREDITS
,
747 "smb2_validate_sequence_number: bad message_id "
748 "%llu (sequence id %llu) "
749 "(granted = %u, low = %llu, range = %u)\n",
750 (unsigned long long)message_id
,
751 (unsigned long long)seq_id
,
752 (unsigned int)xconn
->smb2
.credits
.granted
,
753 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
754 (unsigned int)xconn
->smb2
.credits
.seq_range
);
758 offset
= seq_id
% xconn
->smb2
.credits
.max
;
760 if (bitmap_query(credits_bm
, offset
)) {
761 DBGC_ERR(DBGC_SMB2_CREDITS
,
762 "smb2_validate_sequence_number: duplicate message_id "
763 "%llu (sequence id %llu) "
764 "(granted = %u, low = %llu, range = %u) "
766 (unsigned long long)message_id
,
767 (unsigned long long)seq_id
,
768 (unsigned int)xconn
->smb2
.credits
.granted
,
769 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
770 (unsigned int)xconn
->smb2
.credits
.seq_range
,
775 /* Mark the message_ids as seen in the bitmap. */
776 bitmap_set(credits_bm
, offset
);
778 if (seq_id
!= xconn
->smb2
.credits
.seq_low
) {
783 * Move the window forward by all the message_id's
786 while (bitmap_query(credits_bm
, offset
)) {
787 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
788 "smb2_validate_sequence_number: clearing "
789 "id %llu (position %u) from bitmap\n",
790 (unsigned long long)(xconn
->smb2
.credits
.seq_low
),
792 bitmap_clear(credits_bm
, offset
);
794 xconn
->smb2
.credits
.seq_low
+= 1;
795 xconn
->smb2
.credits
.seq_range
-= 1;
796 offset
= xconn
->smb2
.credits
.seq_low
% xconn
->smb2
.credits
.max
;
802 static bool smb2_validate_message_id(struct smbXsrv_connection
*xconn
,
803 const uint8_t *inhdr
)
805 uint64_t message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
806 uint16_t opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
807 uint16_t credit_charge
= 1;
810 if (opcode
== SMB2_OP_CANCEL
) {
811 /* SMB2_CANCEL requests by definition resend messageids. */
815 if (xconn
->smb2
.credits
.multicredit
) {
816 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
817 credit_charge
= MAX(credit_charge
, 1);
822 ("smb2_validate_message_id: mid %llu (charge %llu), "
823 "credits_granted %llu, "
824 "seqnum low/range: %llu/%llu\n",
825 (unsigned long long) message_id
,
826 (unsigned long long) credit_charge
,
827 (unsigned long long) xconn
->smb2
.credits
.granted
,
828 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
829 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
831 if (xconn
->smb2
.credits
.granted
< credit_charge
) {
832 DBGC_ERR(DBGC_SMB2_CREDITS
,
833 "smb2_validate_message_id: client used more "
834 "credits than granted, mid %llu, charge %llu, "
835 "credits_granted %llu, "
836 "seqnum low/range: %llu/%llu\n",
837 (unsigned long long) message_id
,
838 (unsigned long long) credit_charge
,
839 (unsigned long long) xconn
->smb2
.credits
.granted
,
840 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
841 (unsigned long long) xconn
->smb2
.credits
.seq_range
);
846 * now check the message ids
848 * for multi-credit requests we need to check all current mid plus
849 * the implicit mids caused by the credit charge
850 * e.g. current mid = 15, charge 5 => mark 15-19 as used
853 for (i
= 0; i
<= (credit_charge
-1); i
++) {
854 uint64_t id
= message_id
+ i
;
859 ("Iterating mid %llu charge %u (sequence %llu)\n",
860 (unsigned long long)message_id
,
862 (unsigned long long)id
));
864 ok
= smb2_validate_sequence_number(xconn
, message_id
, id
);
870 /* subtract used credits */
871 xconn
->smb2
.credits
.granted
-= credit_charge
;
876 static NTSTATUS
smbd_smb2_request_validate(struct smbd_smb2_request
*req
)
881 count
= req
->in
.vector_count
;
883 if (count
< 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
884 /* It's not a SMB2 request */
885 return NT_STATUS_INVALID_PARAMETER
;
888 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
889 struct iovec
*hdr
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
890 struct iovec
*body
= SMBD_SMB2_IDX_BODY_IOV(req
,in
,idx
);
891 const uint8_t *inhdr
= NULL
;
893 if (hdr
->iov_len
!= SMB2_HDR_BODY
) {
894 return NT_STATUS_INVALID_PARAMETER
;
897 if (body
->iov_len
< 2) {
898 return NT_STATUS_INVALID_PARAMETER
;
901 inhdr
= (const uint8_t *)hdr
->iov_base
;
903 /* Check the SMB2 header */
904 if (IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
) != SMB2_MAGIC
) {
905 return NT_STATUS_INVALID_PARAMETER
;
908 if (!smb2_validate_message_id(req
->xconn
, inhdr
)) {
909 return NT_STATUS_INVALID_PARAMETER
;
916 static void smb2_set_operation_credit(struct smbXsrv_connection
*xconn
,
917 const struct iovec
*in_vector
,
918 struct iovec
*out_vector
)
920 const uint8_t *inhdr
= (const uint8_t *)in_vector
->iov_base
;
921 uint8_t *outhdr
= (uint8_t *)out_vector
->iov_base
;
922 uint16_t credit_charge
= 1;
923 uint16_t credits_requested
;
927 uint16_t credits_granted
= 0;
928 uint64_t credits_possible
;
929 uint16_t current_max_credits
;
932 * first we grant only 1/16th of the max range.
934 * Windows also starts with the 1/16th and then grants
935 * more later. I was only able to trigger higher
936 * values, when using a very high credit charge.
938 * TODO: scale up depending on load, free memory
940 * Maybe also on the relationship between number
941 * of requests and the used sequence number.
942 * Which means we would grant more credits
943 * for client which use multi credit requests.
945 * The above is what Windows Server < 2016 is doing,
946 * but new servers use all credits (8192 by default).
948 current_max_credits
= xconn
->smb2
.credits
.max
;
949 current_max_credits
= MAX(current_max_credits
, 1);
951 if (xconn
->smb2
.credits
.multicredit
) {
952 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
953 credit_charge
= MAX(credit_charge
, 1);
956 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
957 credits_requested
= SVAL(inhdr
, SMB2_HDR_CREDIT
);
958 credits_requested
= MAX(credits_requested
, 1);
959 out_flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
960 out_status
= NT_STATUS(IVAL(outhdr
, SMB2_HDR_STATUS
));
962 SMB_ASSERT(xconn
->smb2
.credits
.max
>= xconn
->smb2
.credits
.granted
);
964 if (xconn
->smb2
.credits
.max
< credit_charge
) {
965 smbd_server_connection_terminate(xconn
,
966 "client error: credit charge > max credits\n");
970 if (out_flags
& SMB2_HDR_FLAG_ASYNC
) {
972 * In case we already send an async interim
973 * response, we should not grant
974 * credits on the final response.
978 uint16_t additional_possible
=
979 xconn
->smb2
.credits
.max
- credit_charge
;
980 uint16_t additional_max
= 0;
981 uint16_t additional_credits
= credits_requested
- 1;
984 case SMB2_OP_NEGPROT
:
986 case SMB2_OP_SESSSETUP
:
988 * Windows 2012 RC1 starts to grant
990 * with a successful session setup
992 if (NT_STATUS_IS_OK(out_status
)) {
993 additional_max
= xconn
->smb2
.credits
.max
;
998 * Windows Server < 2016 and older Samba versions
999 * used to only grant additional credits in
1000 * chunks of 32 credits.
1002 * But we match Windows Server 2016 and grant
1003 * all credits as requested.
1005 additional_max
= xconn
->smb2
.credits
.max
;
1009 additional_max
= MIN(additional_max
, additional_possible
);
1010 additional_credits
= MIN(additional_credits
, additional_max
);
1012 credits_granted
= credit_charge
+ additional_credits
;
1016 * sequence numbers should not wrap
1018 * 1. calculate the possible credits until
1019 * the sequence numbers start to wrap on 64-bit.
1021 * 2. UINT64_MAX is used for Break Notifications.
1023 * 2. truncate the possible credits to the maximum
1024 * credits we want to grant to the client in total.
1026 * 3. remove the range we'll already granted to the client
1027 * this makes sure the client consumes the lowest sequence
1028 * number, before we can grant additional credits.
1030 credits_possible
= UINT64_MAX
- xconn
->smb2
.credits
.seq_low
;
1031 if (credits_possible
> 0) {
1032 /* remove UINT64_MAX */
1033 credits_possible
-= 1;
1035 credits_possible
= MIN(credits_possible
, current_max_credits
);
1036 credits_possible
-= xconn
->smb2
.credits
.seq_range
;
1038 credits_granted
= MIN(credits_granted
, credits_possible
);
1040 SSVAL(outhdr
, SMB2_HDR_CREDIT
, credits_granted
);
1041 xconn
->smb2
.credits
.granted
+= credits_granted
;
1042 xconn
->smb2
.credits
.seq_range
+= credits_granted
;
1044 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
1045 "smb2_set_operation_credit: requested %u, charge %u, "
1046 "granted %u, current possible/max %u/%u, "
1047 "total granted/max/low/range %u/%u/%llu/%u\n",
1048 (unsigned int)credits_requested
,
1049 (unsigned int)credit_charge
,
1050 (unsigned int)credits_granted
,
1051 (unsigned int)credits_possible
,
1052 (unsigned int)current_max_credits
,
1053 (unsigned int)xconn
->smb2
.credits
.granted
,
1054 (unsigned int)xconn
->smb2
.credits
.max
,
1055 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
1056 (unsigned int)xconn
->smb2
.credits
.seq_range
);
1059 static void smb2_calculate_credits(const struct smbd_smb2_request
*inreq
,
1060 struct smbd_smb2_request
*outreq
)
1063 uint16_t total_credits
= 0;
1065 count
= outreq
->out
.vector_count
;
1067 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1068 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(inreq
,in
,idx
);
1069 struct iovec
*outhdr_v
= SMBD_SMB2_IDX_HDR_IOV(outreq
,out
,idx
);
1070 uint8_t *outhdr
= (uint8_t *)outhdr_v
->iov_base
;
1072 smb2_set_operation_credit(outreq
->xconn
, inhdr_v
, outhdr_v
);
1074 /* To match Windows, count up what we
1076 total_credits
+= SVAL(outhdr
, SMB2_HDR_CREDIT
);
1077 /* Set to zero in all but the last reply. */
1078 if (idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
< count
) {
1079 SSVAL(outhdr
, SMB2_HDR_CREDIT
, 0);
1081 SSVAL(outhdr
, SMB2_HDR_CREDIT
, total_credits
);
1086 DATA_BLOB
smbd_smb2_generate_outbody(struct smbd_smb2_request
*req
, size_t size
)
1088 if (req
->current_idx
<= 1) {
1089 if (size
<= sizeof(req
->out
._body
)) {
1090 return data_blob_const(req
->out
._body
, size
);
1094 return data_blob_talloc(req
, NULL
, size
);
1097 static NTSTATUS
smbd_smb2_request_setup_out(struct smbd_smb2_request
*req
)
1099 struct smbXsrv_connection
*xconn
= req
->xconn
;
1100 TALLOC_CTX
*mem_ctx
;
1101 struct iovec
*vector
;
1106 count
= req
->in
.vector_count
;
1107 if (count
<= ARRAY_SIZE(req
->out
._vector
)) {
1109 vector
= req
->out
._vector
;
1111 vector
= talloc_zero_array(req
, struct iovec
, count
);
1112 if (vector
== NULL
) {
1113 return NT_STATUS_NO_MEMORY
;
1118 vector
[0].iov_base
= req
->out
.nbt_hdr
;
1119 vector
[0].iov_len
= 4;
1120 SIVAL(req
->out
.nbt_hdr
, 0, 0);
1122 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1123 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
1124 const uint8_t *inhdr
= (const uint8_t *)inhdr_v
->iov_base
;
1125 uint8_t *outhdr
= NULL
;
1126 uint8_t *outbody
= NULL
;
1127 uint32_t next_command_ofs
= 0;
1128 struct iovec
*current
= &vector
[idx
];
1130 if ((idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) < count
) {
1131 /* we have a next command -
1132 * setup for the error case. */
1133 next_command_ofs
= SMB2_HDR_BODY
+ 9;
1137 outhdr
= req
->out
._hdr
;
1139 outhdr
= talloc_zero_array(mem_ctx
, uint8_t,
1141 if (outhdr
== NULL
) {
1142 return NT_STATUS_NO_MEMORY
;
1146 outbody
= outhdr
+ SMB2_HDR_BODY
;
1149 * SMBD_SMB2_TF_IOV_OFS might be used later
1151 current
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1152 current
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1154 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)outhdr
;
1155 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1157 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)outbody
;
1158 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1160 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= NULL
;
1161 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 0;
1163 /* setup the SMB2 header */
1164 SIVAL(outhdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1165 SSVAL(outhdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1166 SSVAL(outhdr
, SMB2_HDR_CREDIT_CHARGE
,
1167 SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
));
1168 SIVAL(outhdr
, SMB2_HDR_STATUS
,
1169 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR
));
1170 SSVAL(outhdr
, SMB2_HDR_OPCODE
,
1171 SVAL(inhdr
, SMB2_HDR_OPCODE
));
1172 SIVAL(outhdr
, SMB2_HDR_FLAGS
,
1173 IVAL(inhdr
, SMB2_HDR_FLAGS
) | SMB2_HDR_FLAG_REDIRECT
);
1174 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
1175 SBVAL(outhdr
, SMB2_HDR_MESSAGE_ID
,
1176 BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
));
1177 SIVAL(outhdr
, SMB2_HDR_PID
,
1178 IVAL(inhdr
, SMB2_HDR_PID
));
1179 SIVAL(outhdr
, SMB2_HDR_TID
,
1180 IVAL(inhdr
, SMB2_HDR_TID
));
1181 SBVAL(outhdr
, SMB2_HDR_SESSION_ID
,
1182 BVAL(inhdr
, SMB2_HDR_SESSION_ID
));
1183 memcpy(outhdr
+ SMB2_HDR_SIGNATURE
,
1184 inhdr
+ SMB2_HDR_SIGNATURE
, 16);
1186 /* setup error body header */
1187 SSVAL(outbody
, 0x00, 0x08 + 1);
1188 SSVAL(outbody
, 0x02, 0);
1189 SIVAL(outbody
, 0x04, 0);
1192 req
->out
.vector
= vector
;
1193 req
->out
.vector_count
= count
;
1195 /* setup the length of the NBT packet */
1196 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
1198 return NT_STATUS_INVALID_PARAMETER_MIX
;
1201 DLIST_ADD_END(xconn
->smb2
.requests
, req
);
1203 return NT_STATUS_OK
;
1206 bool smbXsrv_server_multi_channel_enabled(void)
1208 bool enabled
= lp_server_multi_channel_support();
1209 #ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1210 bool forced
= false;
1211 struct loadparm_context
*lp_ctx
= loadparm_init_s3(NULL
, loadparm_s3_helpers());
1212 bool unspecified
= lpcfg_parm_is_unspecified(lp_ctx
, "server multi channel support");
1217 * If we don't have support from the kernel
1218 * to ask for the un-acked number of bytes
1219 * in the socket send queue, we better
1220 * don't support multi-channel.
1222 forced
= lp_parm_bool(-1, "force", "server multi channel support", false);
1223 if (enabled
&& !forced
) {
1224 D_NOTICE("'server multi channel support' enabled "
1225 "but not supported on %s (%s)\n",
1226 SYSTEM_UNAME_SYSNAME
, SYSTEM_UNAME_RELEASE
);
1227 DEBUGADD(DBGLVL_NOTICE
, ("Please report this on "
1228 "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1231 TALLOC_FREE(lp_ctx
);
1232 #endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1236 static NTSTATUS
smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection
*xconn
,
1237 uint32_t *_rto_usecs
)
1240 * Define an Retransmission Timeout
1241 * of 1 second, if there's no way for the
1242 * kernel to tell us the current value.
1244 uint32_t rto_usecs
= 1000000;
1246 #ifdef __HAVE_TCP_INFO_RTO
1248 struct tcp_info info
;
1249 socklen_t ilen
= sizeof(info
);
1253 ret
= getsockopt(xconn
->transport
.sock
,
1254 IPPROTO_TCP
, TCP_INFO
,
1255 (void *)&info
, &ilen
);
1257 int saved_errno
= errno
;
1258 NTSTATUS status
= map_nt_error_from_unix(errno
);
1259 DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1260 saved_errno
, strerror(saved_errno
),
1265 DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1266 (unsigned)info
.tcpi_rto
,
1267 (unsigned)info
.tcpi_rtt
,
1268 (unsigned)info
.tcpi_rttvar
);
1269 rto_usecs
= info
.tcpi_rto
;
1271 #endif /* __HAVE_TCP_INFO_RTO */
1273 rto_usecs
= MAX(rto_usecs
, 200000); /* at least 0.2s */
1274 rto_usecs
= MIN(rto_usecs
, 1000000); /* at max 1.0s */
1275 *_rto_usecs
= rto_usecs
;
1276 return NT_STATUS_OK
;
1279 static NTSTATUS
smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection
*xconn
,
1280 uint64_t *_acked_bytes
)
1283 * Unless the kernel has an interface
1284 * to reveal the number of un-acked bytes
1285 * in the socket send queue, we'll assume
1286 * everything is already acked.
1288 * But that would mean that we better don't
1289 * pretent to support multi-channel.
1291 uint64_t unacked_bytes
= 0;
1295 if (xconn
->ack
.force_unacked_timeout
) {
1297 * Smbtorture tries to test channel failures...
1298 * Just pretend nothing was acked...
1300 DBG_INFO("Simulating channel failure: "
1301 "xconn->ack.unacked_bytes[%llu]\n",
1302 (unsigned long long)xconn
->ack
.unacked_bytes
);
1303 return NT_STATUS_OK
;
1306 #ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1312 * If we have kernel support to get
1313 * the number of bytes waiting in
1314 * the socket's send queue, we
1315 * use that in order to find out
1316 * the number of unacked bytes.
1318 ret
= ioctl(xconn
->transport
.sock
,
1319 __IOCTL_SEND_QUEUE_SIZE_OPCODE
,
1322 int saved_errno
= errno
;
1323 NTSTATUS status
= map_nt_error_from_unix(saved_errno
);
1324 DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1325 "errno %d (%s) - %s\n",
1326 saved_errno
, strerror(saved_errno
),
1332 DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1333 (unsigned long long)xconn
->ack
.unacked_bytes
,
1335 return NT_STATUS_INTERNAL_ERROR
;
1337 unacked_bytes
= value
;
1340 if (xconn
->ack
.unacked_bytes
== 0) {
1341 xconn
->ack
.unacked_bytes
= unacked_bytes
;
1342 return NT_STATUS_OK
;
1345 if (xconn
->ack
.unacked_bytes
< unacked_bytes
) {
1346 DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1347 (unsigned long long)xconn
->ack
.unacked_bytes
,
1348 (unsigned long long)unacked_bytes
);
1349 return NT_STATUS_INTERNAL_ERROR
;
1352 *_acked_bytes
= xconn
->ack
.unacked_bytes
- unacked_bytes
;
1353 xconn
->ack
.unacked_bytes
= unacked_bytes
;
1354 return NT_STATUS_OK
;
1357 static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue
**queue
,
1360 struct smbd_smb2_send_queue
*e
= NULL
;
1361 struct smbd_smb2_send_queue
*n
= NULL
;
1363 for (e
= *queue
; e
!= NULL
; e
= n
) {
1366 DLIST_REMOVE(*queue
, e
);
1367 if (e
->ack
.req
!= NULL
) {
1368 tevent_req_nterror(e
->ack
.req
, status
);
1373 static NTSTATUS
smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue
**queue
,
1374 uint64_t acked_bytes
)
1376 struct smbd_smb2_send_queue
*e
= NULL
;
1377 struct smbd_smb2_send_queue
*n
= NULL
;
1379 for (e
= *queue
; e
!= NULL
; e
= n
) {
1384 if (e
->ack
.req
== NULL
) {
1388 if (e
->ack
.required_acked_bytes
<= acked_bytes
) {
1389 e
->ack
.required_acked_bytes
= 0;
1390 DLIST_REMOVE(*queue
, e
);
1391 tevent_req_done(e
->ack
.req
);
1394 e
->ack
.required_acked_bytes
-= acked_bytes
;
1396 expired
= timeval_expired(&e
->ack
.timeout
);
1398 return NT_STATUS_IO_TIMEOUT
;
1402 return NT_STATUS_OK
;
1405 static NTSTATUS
smbd_smb2_check_ack_queue(struct smbXsrv_connection
*xconn
)
1407 uint64_t acked_bytes
= 0;
1410 status
= smbXsrv_connection_get_acked_bytes(xconn
, &acked_bytes
);
1411 if (!NT_STATUS_IS_OK(status
)) {
1415 status
= smbd_smb2_send_queue_ack_bytes(&xconn
->ack
.queue
, acked_bytes
);
1416 if (!NT_STATUS_IS_OK(status
)) {
1420 status
= smbd_smb2_send_queue_ack_bytes(&xconn
->smb2
.send_queue
, 0);
1421 if (!NT_STATUS_IS_OK(status
)) {
1425 return NT_STATUS_OK
;
1428 static void smbXsrv_connection_ack_checker(struct tevent_req
*subreq
)
1430 struct smbXsrv_connection
*xconn
=
1431 tevent_req_callback_data(subreq
,
1432 struct smbXsrv_connection
);
1433 struct smbXsrv_client
*client
= xconn
->client
;
1434 struct timeval next_check
;
1438 xconn
->ack
.checker_subreq
= NULL
;
1440 ok
= tevent_wakeup_recv(subreq
);
1441 TALLOC_FREE(subreq
);
1443 smbd_server_connection_terminate(xconn
,
1444 "tevent_wakeup_recv() failed");
1448 status
= smbd_smb2_check_ack_queue(xconn
);
1449 if (!NT_STATUS_IS_OK(status
)) {
1450 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
1454 next_check
= timeval_current_ofs_usec(xconn
->ack
.rto_usecs
);
1455 xconn
->ack
.checker_subreq
= tevent_wakeup_send(xconn
,
1458 if (xconn
->ack
.checker_subreq
== NULL
) {
1459 smbd_server_connection_terminate(xconn
,
1460 "tevent_wakeup_send() failed");
1463 tevent_req_set_callback(xconn
->ack
.checker_subreq
,
1464 smbXsrv_connection_ack_checker
,
1468 static NTSTATUS
smbXsrv_client_pending_breaks_updated(struct smbXsrv_client
*client
)
1470 struct smbXsrv_connection
*xconn
= NULL
;
1472 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
1473 struct timeval next_check
;
1474 uint64_t acked_bytes
= 0;
1478 * A new 'pending break cycle' starts
1479 * with a first pending break and lasts until
1480 * all pending breaks are finished.
1482 * This is typically a very short time,
1483 * the value of one retransmission timeout.
1486 if (client
->pending_breaks
== NULL
) {
1488 * No more pending breaks, remove a pending
1491 TALLOC_FREE(xconn
->ack
.checker_subreq
);
1495 if (xconn
->ack
.checker_subreq
!= NULL
) {
1497 * The cycle already started =>
1504 * Get the current retransmission timeout value.
1506 * It may change over time, but fetching it once
1507 * per 'pending break' cycled should be enough.
1509 status
= smbXsrv_connection_get_rto_usecs(xconn
,
1510 &xconn
->ack
.rto_usecs
);
1511 if (!NT_STATUS_IS_OK(status
)) {
1516 * At the start of the cycle we reset the
1517 * unacked_bytes counter (first to 0 and
1518 * within smbXsrv_connection_get_acked_bytes()
1519 * to the current value in the kernel
1522 xconn
->ack
.unacked_bytes
= 0;
1523 status
= smbXsrv_connection_get_acked_bytes(xconn
, &acked_bytes
);
1524 if (!NT_STATUS_IS_OK(status
)) {
1529 * We setup a timer in order to check for
1530 * acked bytes after one retransmission timeout.
1532 * The code that sets up the send_queue.ack.timeout
1533 * uses a multiple of the retransmission timeout.
1535 next_check
= timeval_current_ofs_usec(xconn
->ack
.rto_usecs
);
1536 xconn
->ack
.checker_subreq
= tevent_wakeup_send(xconn
,
1539 if (xconn
->ack
.checker_subreq
== NULL
) {
1540 return NT_STATUS_NO_MEMORY
;
1542 tevent_req_set_callback(xconn
->ack
.checker_subreq
,
1543 smbXsrv_connection_ack_checker
,
1547 return NT_STATUS_OK
;
1550 void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection
*xconn
,
1553 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
1557 xconn
->transport
.status
= status
;
1558 TALLOC_FREE(xconn
->transport
.fde
);
1559 if (xconn
->transport
.sock
!= -1) {
1560 xconn
->transport
.sock
= -1;
1562 smbd_smb2_send_queue_ack_fail(&xconn
->ack
.queue
, status
);
1563 smbd_smb2_send_queue_ack_fail(&xconn
->smb2
.send_queue
, status
);
1564 xconn
->smb2
.send_queue_len
= 0;
1565 DO_PROFILE_INC(disconnect
);
1568 size_t smbXsrv_client_valid_connections(struct smbXsrv_client
*client
)
1570 struct smbXsrv_connection
*xconn
= NULL
;
1573 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
1574 if (NT_STATUS_IS_OK(xconn
->transport
.status
)) {
1582 struct smbXsrv_connection_shutdown_state
{
1583 struct smbXsrv_connection
*xconn
;
1586 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req
*subreq
);
1588 static struct tevent_req
*smbXsrv_connection_shutdown_send(TALLOC_CTX
*mem_ctx
,
1589 struct tevent_context
*ev
,
1590 struct smbXsrv_connection
*xconn
)
1592 struct tevent_req
*req
= NULL
;
1593 struct smbXsrv_connection_shutdown_state
*state
= NULL
;
1594 struct tevent_req
*subreq
= NULL
;
1596 struct smbd_smb2_request
*preq
= NULL
;
1600 * The caller should have called
1601 * smbXsrv_connection_disconnect_transport() before.
1603 SMB_ASSERT(!NT_STATUS_IS_OK(xconn
->transport
.status
));
1604 SMB_ASSERT(xconn
->transport
.terminating
);
1605 SMB_ASSERT(xconn
->transport
.shutdown_wait_queue
== NULL
);
1607 req
= tevent_req_create(mem_ctx
, &state
,
1608 struct smbXsrv_connection_shutdown_state
);
1613 state
->xconn
= xconn
;
1614 tevent_req_defer_callback(req
, ev
);
1616 xconn
->transport
.shutdown_wait_queue
=
1617 tevent_queue_create(state
, "smbXsrv_connection_shutdown_queue");
1618 if (tevent_req_nomem(xconn
->transport
.shutdown_wait_queue
, req
)) {
1619 return tevent_req_post(req
, ev
);
1622 for (preq
= xconn
->smb2
.requests
; preq
!= NULL
; preq
= preq
->next
) {
1624 * Now wait until the request is finished.
1626 * We don't set a callback, as we just want to block the
1627 * wait queue and the talloc_free() of the request will
1628 * remove the item from the wait queue.
1630 * Note that we don't cancel the requests here
1631 * in order to keep the replay detection logic correct.
1633 * However if we teardown the last channel of
1634 * a connection, we'll call some logic via
1635 * smbXsrv_session_disconnect_xconn()
1636 * -> smbXsrv_session_disconnect_xconn_callback()
1637 * -> smbXsrv_session_remove_channel()
1638 * -> smb2srv_session_shutdown_send()
1639 * will indeed cancel the request.
1641 subreq
= tevent_queue_wait_send(preq
, ev
,
1642 xconn
->transport
.shutdown_wait_queue
);
1643 if (tevent_req_nomem(subreq
, req
)) {
1644 return tevent_req_post(req
, ev
);
1649 * This may attach sessions with num_channels == 0
1650 * to xconn->transport.shutdown_wait_queue.
1652 status
= smbXsrv_session_disconnect_xconn(xconn
);
1653 if (tevent_req_nterror(req
, status
)) {
1654 return tevent_req_post(req
, ev
);
1657 len
= tevent_queue_length(xconn
->transport
.shutdown_wait_queue
);
1659 tevent_req_done(req
);
1660 return tevent_req_post(req
, ev
);
1664 * Now we add our own waiter to the end of the queue,
1665 * this way we get notified when all pending requests are finished
1666 * and send to the socket.
1668 subreq
= tevent_queue_wait_send(state
, ev
, xconn
->transport
.shutdown_wait_queue
);
1669 if (tevent_req_nomem(subreq
, req
)) {
1670 return tevent_req_post(req
, ev
);
1672 tevent_req_set_callback(subreq
, smbXsrv_connection_shutdown_wait_done
, req
);
1677 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req
*subreq
)
1679 struct tevent_req
*req
=
1680 tevent_req_callback_data(subreq
,
1682 struct smbXsrv_connection_shutdown_state
*state
=
1683 tevent_req_data(req
,
1684 struct smbXsrv_connection_shutdown_state
);
1685 struct smbXsrv_connection
*xconn
= state
->xconn
;
1687 tevent_queue_wait_recv(subreq
);
1688 TALLOC_FREE(subreq
);
1690 tevent_req_done(req
);
1692 * make sure the xconn pointer is still valid,
1693 * it should as we used tevent_req_defer_callback()
1695 SMB_ASSERT(xconn
->transport
.terminating
);
1698 static NTSTATUS
smbXsrv_connection_shutdown_recv(struct tevent_req
*req
)
1700 struct smbXsrv_connection_shutdown_state
*state
=
1701 tevent_req_data(req
,
1702 struct smbXsrv_connection_shutdown_state
);
1703 struct smbXsrv_connection
*xconn
= state
->xconn
;
1705 * make sure the xconn pointer is still valid,
1706 * it should as we used tevent_req_defer_callback()
1708 SMB_ASSERT(xconn
->transport
.terminating
);
1709 return tevent_req_simple_recv_ntstatus(req
);
1712 static void smbd_server_connection_terminate_done(struct tevent_req
*subreq
)
1714 struct smbXsrv_connection
*xconn
=
1715 tevent_req_callback_data(subreq
,
1716 struct smbXsrv_connection
);
1717 struct smbXsrv_client
*client
= xconn
->client
;
1720 status
= smbXsrv_connection_shutdown_recv(subreq
);
1721 TALLOC_FREE(subreq
);
1722 if (!NT_STATUS_IS_OK(status
)) {
1723 exit_server("smbXsrv_connection_shutdown_recv failed");
1726 DLIST_REMOVE(client
->connections
, xconn
);
1730 void smbd_server_connection_terminate_ex(struct smbXsrv_connection
*xconn
,
1732 const char *location
)
1734 struct smbXsrv_client
*client
= xconn
->client
;
1738 * Make sure that no new request will be able to use this session.
1740 * smbXsrv_connection_disconnect_transport() might be called already,
1741 * but calling it again is a no-op.
1743 smbXsrv_connection_disconnect_transport(xconn
,
1744 NT_STATUS_CONNECTION_DISCONNECTED
);
1746 num_ok
= smbXsrv_client_valid_connections(client
);
1748 if (xconn
->transport
.terminating
) {
1749 DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1750 smbXsrv_connection_dbg(xconn
), num_ok
,
1754 xconn
->transport
.terminating
= true;
1756 DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1757 smbXsrv_connection_dbg(xconn
), num_ok
,
1760 if (xconn
->has_cluster_movable_ip
) {
1762 * If the connection has a movable cluster public address
1763 * we disconnect all client connections,
1764 * as the public address might be moved to
1767 * In future we may recheck which node currently
1768 * holds this address, but for now we keep it simple.
1770 smbd_server_disconnect_client_ex(xconn
->client
,
1777 struct tevent_req
*subreq
= NULL
;
1779 subreq
= smbXsrv_connection_shutdown_send(client
,
1782 if (subreq
== NULL
) {
1783 exit_server("smbXsrv_connection_shutdown_send failed");
1785 tevent_req_set_callback(subreq
,
1786 smbd_server_connection_terminate_done
,
1792 * The last connection was disconnected
1794 exit_server_cleanly(reason
);
1797 void smbd_server_disconnect_client_ex(struct smbXsrv_client
*client
,
1799 const char *location
)
1803 num_ok
= smbXsrv_client_valid_connections(client
);
1805 DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1806 client
->global
->remote_address
, num_ok
,
1810 * Something bad happened we need to disconnect all connections.
1812 exit_server_cleanly(reason
);
1815 static bool dup_smb2_vec4(TALLOC_CTX
*ctx
,
1816 struct iovec
*outvec
,
1817 const struct iovec
*srcvec
)
1819 const uint8_t *srctf
;
1821 const uint8_t *srchdr
;
1823 const uint8_t *srcbody
;
1825 const uint8_t *expected_srcbody
;
1826 const uint8_t *srcdyn
;
1828 const uint8_t *expected_srcdyn
;
1834 srctf
= (const uint8_t *)srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
;
1835 srctf_len
= srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
;
1836 srchdr
= (const uint8_t *)srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
;
1837 srchdr_len
= srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
;
1838 srcbody
= (const uint8_t *)srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
;
1839 srcbody_len
= srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
;
1840 expected_srcbody
= srchdr
+ SMB2_HDR_BODY
;
1841 srcdyn
= (const uint8_t *)srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
;
1842 srcdyn_len
= srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
;
1843 expected_srcdyn
= srcbody
+ 8;
1845 if ((srctf_len
!= SMB2_TF_HDR_SIZE
) && (srctf_len
!= 0)) {
1849 if (srchdr_len
!= SMB2_HDR_BODY
) {
1853 if (srctf_len
== SMB2_TF_HDR_SIZE
) {
1854 dsttf
= talloc_memdup(ctx
, srctf
, SMB2_TF_HDR_SIZE
);
1855 if (dsttf
== NULL
) {
1861 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= (void *)dsttf
;
1862 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= srctf_len
;
1864 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1865 * be allocated with size OUTVEC_ALLOC_SIZE. */
1867 dsthdr
= talloc_memdup(ctx
, srchdr
, OUTVEC_ALLOC_SIZE
);
1868 if (dsthdr
== NULL
) {
1871 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)dsthdr
;
1872 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1875 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1876 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1877 * then duplicate this. Else use talloc_memdup().
1880 if ((srcbody
== expected_srcbody
) && (srcbody_len
== 8)) {
1881 dstbody
= dsthdr
+ SMB2_HDR_BODY
;
1883 dstbody
= talloc_memdup(ctx
, srcbody
, srcbody_len
);
1884 if (dstbody
== NULL
) {
1888 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)dstbody
;
1889 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= srcbody_len
;
1892 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1894 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1895 * then duplicate this. Else use talloc_memdup().
1898 if ((srcdyn
== expected_srcdyn
) && (srcdyn_len
== 1)) {
1899 dstdyn
= dsthdr
+ SMB2_HDR_BODY
+ 8;
1900 } else if (srcdyn
== NULL
) {
1903 dstdyn
= talloc_memdup(ctx
, srcdyn
, srcdyn_len
);
1904 if (dstdyn
== NULL
) {
1908 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= (void *)dstdyn
;
1909 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= srcdyn_len
;
1914 static struct smbd_smb2_request
*dup_smb2_req(const struct smbd_smb2_request
*req
)
1916 struct smbd_smb2_request
*newreq
= NULL
;
1917 struct iovec
*outvec
= NULL
;
1918 int count
= req
->out
.vector_count
;
1922 newreq
= smbd_smb2_request_allocate(req
->xconn
);
1927 newreq
->session
= req
->session
;
1928 newreq
->do_encryption
= req
->do_encryption
;
1929 newreq
->do_signing
= req
->do_signing
;
1930 newreq
->current_idx
= req
->current_idx
;
1932 outvec
= talloc_zero_array(newreq
, struct iovec
, count
);
1934 TALLOC_FREE(newreq
);
1937 newreq
->out
.vector
= outvec
;
1938 newreq
->out
.vector_count
= count
;
1940 /* Setup the outvec's identically to req. */
1941 outvec
[0].iov_base
= newreq
->out
.nbt_hdr
;
1942 outvec
[0].iov_len
= 4;
1943 memcpy(newreq
->out
.nbt_hdr
, req
->out
.nbt_hdr
, 4);
1945 /* Setup the vectors identically to the ones in req. */
1946 for (i
= 1; i
< count
; i
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1947 if (!dup_smb2_vec4(outvec
, &outvec
[i
], &req
->out
.vector
[i
])) {
1954 TALLOC_FREE(newreq
);
1958 ok
= smb2_setup_nbt_length(newreq
->out
.vector
,
1959 newreq
->out
.vector_count
);
1961 TALLOC_FREE(newreq
);
1968 static NTSTATUS
smb2_send_async_interim_response(const struct smbd_smb2_request
*req
)
1970 struct smbXsrv_connection
*xconn
= req
->xconn
;
1972 struct iovec
*firsttf
= NULL
;
1973 struct iovec
*outhdr_v
= NULL
;
1974 uint8_t *outhdr
= NULL
;
1975 struct smbd_smb2_request
*nreq
= NULL
;
1979 /* Create a new smb2 request we'll use
1980 for the interim return. */
1981 nreq
= dup_smb2_req(req
);
1983 return NT_STATUS_NO_MEMORY
;
1986 /* Lose the last X out vectors. They're the
1987 ones we'll be using for the async reply. */
1988 nreq
->out
.vector_count
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1990 ok
= smb2_setup_nbt_length(nreq
->out
.vector
,
1991 nreq
->out
.vector_count
);
1993 return NT_STATUS_INVALID_PARAMETER_MIX
;
1996 /* Step back to the previous reply. */
1997 nreq
->current_idx
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1998 firsttf
= SMBD_SMB2_IDX_TF_IOV(nreq
,out
,first_idx
);
1999 outhdr_v
= SMBD_SMB2_OUT_HDR_IOV(nreq
);
2000 outhdr
= SMBD_SMB2_OUT_HDR_PTR(nreq
);
2001 /* And end the chain. */
2002 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2004 /* Calculate outgoing credits */
2005 smb2_calculate_credits(req
, nreq
);
2007 if (DEBUGLEVEL
>= 10) {
2008 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
2009 (unsigned int)nreq
->current_idx
);
2010 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
2011 (unsigned int)nreq
->out
.vector_count
);
2012 print_req_vectors(nreq
);
2016 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
2017 * we need to sign/encrypt here with the last/first key we remembered
2019 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
2020 status
= smb2_signing_encrypt_pdu(req
->first_enc_key
,
2022 nreq
->out
.vector_count
- first_idx
);
2023 if (!NT_STATUS_IS_OK(status
)) {
2026 } else if (smb2_signing_key_valid(req
->last_sign_key
)) {
2027 status
= smb2_signing_sign_pdu(req
->last_sign_key
,
2029 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2030 if (!NT_STATUS_IS_OK(status
)) {
2035 nreq
->queue_entry
.mem_ctx
= nreq
;
2036 nreq
->queue_entry
.vector
= nreq
->out
.vector
;
2037 nreq
->queue_entry
.count
= nreq
->out
.vector_count
;
2038 DLIST_ADD_END(xconn
->smb2
.send_queue
, &nreq
->queue_entry
);
2039 xconn
->smb2
.send_queue_len
++;
2041 status
= smbd_smb2_flush_send_queue(xconn
);
2042 if (!NT_STATUS_IS_OK(status
)) {
2046 return NT_STATUS_OK
;
2049 struct smbd_smb2_request_pending_state
{
2050 struct smbd_smb2_send_queue queue_entry
;
2051 uint8_t buf
[NBT_HDR_SIZE
+ SMB2_TF_HDR_SIZE
+ SMB2_HDR_BODY
+ 0x08 + 1];
2052 struct iovec vector
[1 + SMBD_SMB2_NUM_IOV_PER_REQ
];
2055 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
2056 struct tevent_timer
*te
,
2057 struct timeval current_time
,
2058 void *private_data
);
2060 NTSTATUS
smbd_smb2_request_pending_queue(struct smbd_smb2_request
*req
,
2061 struct tevent_req
*subreq
,
2062 uint32_t defer_time
)
2065 struct timeval defer_endtime
;
2066 uint8_t *outhdr
= NULL
;
2069 if (!tevent_req_is_in_progress(subreq
)) {
2071 * This is a performance optimization,
2072 * it avoids one tevent_loop iteration,
2073 * which means we avoid one
2074 * talloc_stackframe_pool/talloc_free pair.
2076 tevent_req_notify_callback(subreq
);
2077 return NT_STATUS_OK
;
2080 req
->subreq
= subreq
;
2083 if (req
->async_te
) {
2084 /* We're already async. */
2085 return NT_STATUS_OK
;
2088 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2089 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
2090 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
2091 /* We're already async. */
2092 return NT_STATUS_OK
;
2095 if (req
->async_internal
|| defer_time
== 0) {
2097 * An SMB2 request implementation wants to handle the request
2098 * asynchronously "internally" while keeping synchronous
2099 * behaviour for the SMB2 request. This means we don't send an
2100 * interim response and we can allow processing of compound SMB2
2101 * requests (cf the subsequent check) for all cases.
2103 return NT_STATUS_OK
;
2106 if (req
->in
.vector_count
> req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) {
2108 * We're trying to go async in a compound request
2109 * chain. This is only allowed for opens that cause an
2110 * oplock break or for the last operation in the
2111 * chain, otherwise it is not allowed. See
2112 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2114 const uint8_t *inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2116 if (SVAL(inhdr
, SMB2_HDR_OPCODE
) != SMB2_OP_CREATE
) {
2118 * Cancel the outstanding request.
2120 bool ok
= tevent_req_cancel(req
->subreq
);
2122 return NT_STATUS_OK
;
2124 TALLOC_FREE(req
->subreq
);
2125 return smbd_smb2_request_error(req
,
2126 NT_STATUS_INTERNAL_ERROR
);
2130 if (DEBUGLEVEL
>= 10) {
2131 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2132 (unsigned int)req
->current_idx
);
2133 print_req_vectors(req
);
2136 if (req
->current_idx
> 1) {
2138 * We're going async in a compound
2139 * chain after the first request has
2140 * already been processed. Send an
2141 * interim response containing the
2142 * set of replies already generated.
2144 int idx
= req
->current_idx
;
2146 status
= smb2_send_async_interim_response(req
);
2147 if (!NT_STATUS_IS_OK(status
)) {
2150 TALLOC_FREE(req
->first_enc_key
);
2152 req
->current_idx
= 1;
2155 * Re-arrange the in.vectors to remove what
2158 memmove(&req
->in
.vector
[1],
2159 &req
->in
.vector
[idx
],
2160 sizeof(req
->in
.vector
[0])*(req
->in
.vector_count
- idx
));
2161 req
->in
.vector_count
= 1 + (req
->in
.vector_count
- idx
);
2163 /* Re-arrange the out.vectors to match. */
2164 memmove(&req
->out
.vector
[1],
2165 &req
->out
.vector
[idx
],
2166 sizeof(req
->out
.vector
[0])*(req
->out
.vector_count
- idx
));
2167 req
->out
.vector_count
= 1 + (req
->out
.vector_count
- idx
);
2169 if (req
->in
.vector_count
== 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
2171 * We only have one remaining request as
2172 * we've processed everything else.
2173 * This is no longer a compound request.
2175 req
->compound_related
= false;
2176 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2177 flags
= (IVAL(outhdr
, SMB2_HDR_FLAGS
) & ~SMB2_HDR_FLAG_CHAINED
);
2178 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
);
2181 TALLOC_FREE(req
->last_sign_key
);
2184 * smbd_smb2_request_pending_timer() just send a packet
2185 * to the client and doesn't need any impersonation.
2186 * So we use req->xconn->client->raw_ev_ctx instead
2187 * of req->ev_ctx here.
2189 defer_endtime
= timeval_current_ofs_usec(defer_time
);
2190 req
->async_te
= tevent_add_timer(req
->xconn
->client
->raw_ev_ctx
,
2192 smbd_smb2_request_pending_timer
,
2194 if (req
->async_te
== NULL
) {
2195 return NT_STATUS_NO_MEMORY
;
2198 return NT_STATUS_OK
;
2202 struct smb2_signing_key
*smbd_smb2_signing_key(struct smbXsrv_session
*session
,
2203 struct smbXsrv_connection
*xconn
,
2206 struct smbXsrv_channel_global0
*c
= NULL
;
2208 struct smb2_signing_key
*key
= NULL
;
2209 bool has_channel
= false;
2211 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
2212 if (NT_STATUS_IS_OK(status
)) {
2213 key
= c
->signing_key
;
2217 if (!smb2_signing_key_valid(key
)) {
2218 key
= session
->global
->signing_key
;
2219 has_channel
= false;
2222 if (_has_channel
!= NULL
) {
2223 *_has_channel
= has_channel
;
2229 static NTSTATUS
smb2_get_new_nonce(struct smbXsrv_session
*session
,
2230 uint64_t *new_nonce_high
,
2231 uint64_t *new_nonce_low
)
2233 uint64_t nonce_high
;
2236 session
->nonce_low
+= 1;
2237 if (session
->nonce_low
== 0) {
2238 session
->nonce_low
+= 1;
2239 session
->nonce_high
+= 1;
2243 * CCM and GCM algorithms must never have their
2244 * nonce wrap, or the security of the whole
2245 * communication and the keys is destroyed.
2246 * We must drop the connection once we have
2247 * transferred too much data.
2249 * NOTE: We assume nonces greater than 8 bytes.
2251 if (session
->nonce_high
>= session
->nonce_high_max
) {
2252 return NT_STATUS_ENCRYPTION_FAILED
;
2255 nonce_high
= session
->nonce_high_random
;
2256 nonce_high
+= session
->nonce_high
;
2257 nonce_low
= session
->nonce_low
;
2259 *new_nonce_high
= nonce_high
;
2260 *new_nonce_low
= nonce_low
;
2261 return NT_STATUS_OK
;
2264 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
2265 struct tevent_timer
*te
,
2266 struct timeval current_time
,
2269 struct smbd_smb2_request
*req
=
2270 talloc_get_type_abort(private_data
,
2271 struct smbd_smb2_request
);
2272 struct smbXsrv_connection
*xconn
= req
->xconn
;
2273 struct smbd_smb2_request_pending_state
*state
= NULL
;
2274 uint8_t *outhdr
= NULL
;
2275 const uint8_t *inhdr
= NULL
;
2277 uint8_t *hdr
= NULL
;
2278 uint8_t *body
= NULL
;
2279 uint8_t *dyn
= NULL
;
2281 uint64_t message_id
= 0;
2282 uint64_t async_id
= 0;
2286 TALLOC_FREE(req
->async_te
);
2288 /* Ensure our final reply matches the interim one. */
2289 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2290 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2291 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
2292 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
2294 async_id
= message_id
; /* keep it simple for now... */
2296 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
2297 SBVAL(outhdr
, SMB2_HDR_ASYNC_ID
, async_id
);
2299 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2301 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
2302 (unsigned long long)async_id
));
2305 * What we send is identical to a smbd_smb2_request_error
2306 * packet with an error status of STATUS_PENDING. Make use
2307 * of this fact sometime when refactoring. JRA.
2310 state
= talloc_zero(req
->xconn
, struct smbd_smb2_request_pending_state
);
2311 if (state
== NULL
) {
2312 smbd_server_connection_terminate(xconn
,
2313 nt_errstr(NT_STATUS_NO_MEMORY
));
2317 tf
= state
->buf
+ NBT_HDR_SIZE
;
2319 hdr
= tf
+ SMB2_TF_HDR_SIZE
;
2320 body
= hdr
+ SMB2_HDR_BODY
;
2323 if (req
->do_encryption
) {
2324 uint64_t nonce_high
= 0;
2325 uint64_t nonce_low
= 0;
2326 uint64_t session_id
= req
->session
->global
->session_wire_id
;
2328 status
= smb2_get_new_nonce(req
->session
,
2331 if (!NT_STATUS_IS_OK(status
)) {
2332 smbd_server_connection_terminate(xconn
,
2337 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2338 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
2339 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
2340 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
2343 SIVAL(hdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
2344 SSVAL(hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
2345 SSVAL(hdr
, SMB2_HDR_EPOCH
, 0);
2346 SIVAL(hdr
, SMB2_HDR_STATUS
, NT_STATUS_V(NT_STATUS_PENDING
));
2347 SSVAL(hdr
, SMB2_HDR_OPCODE
, SVAL(outhdr
, SMB2_HDR_OPCODE
));
2350 * The STATUS_PENDING response has SMB2_HDR_FLAG_SIGNED
2351 * clearedm, but echoes the signature field.
2353 flags
&= ~SMB2_HDR_FLAG_SIGNED
;
2354 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
);
2355 SIVAL(hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2356 SBVAL(hdr
, SMB2_HDR_MESSAGE_ID
, message_id
);
2357 SBVAL(hdr
, SMB2_HDR_PID
, async_id
);
2358 SBVAL(hdr
, SMB2_HDR_SESSION_ID
,
2359 BVAL(outhdr
, SMB2_HDR_SESSION_ID
));
2360 memcpy(hdr
+SMB2_HDR_SIGNATURE
,
2361 outhdr
+SMB2_HDR_SIGNATURE
, 16);
2363 SSVAL(body
, 0x00, 0x08 + 1);
2365 SCVAL(body
, 0x02, 0);
2366 SCVAL(body
, 0x03, 0);
2367 SIVAL(body
, 0x04, 0);
2368 /* Match W2K8R2... */
2369 SCVAL(dyn
, 0x00, 0x21);
2371 state
->vector
[0].iov_base
= (void *)state
->buf
;
2372 state
->vector
[0].iov_len
= NBT_HDR_SIZE
;
2374 if (req
->do_encryption
) {
2375 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
2376 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
=
2379 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
2380 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
2383 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
2384 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
2386 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
2387 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
2389 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
2390 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 1;
2392 ok
= smb2_setup_nbt_length(state
->vector
,
2393 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
2395 smbd_server_connection_terminate(
2396 xconn
, nt_errstr(NT_STATUS_INTERNAL_ERROR
));
2400 /* Ensure we correctly go through crediting. Grant
2401 the credits now, and zero credits on the final
2403 smb2_set_operation_credit(req
->xconn
,
2404 SMBD_SMB2_IN_HDR_IOV(req
),
2405 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
]);
2408 * We add SMB2_HDR_FLAG_ASYNC after smb2_set_operation_credit()
2409 * as it reacts on it
2411 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
2416 for (i
= 0; i
< ARRAY_SIZE(state
->vector
); i
++) {
2417 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2419 (unsigned int)ARRAY_SIZE(state
->vector
),
2420 (unsigned int)state
->vector
[i
].iov_len
);
2424 if (req
->do_encryption
) {
2425 struct smbXsrv_session
*x
= req
->session
;
2426 struct smb2_signing_key
*encryption_key
= x
->global
->encryption_key
;
2428 status
= smb2_signing_encrypt_pdu(encryption_key
,
2429 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
2430 SMBD_SMB2_NUM_IOV_PER_REQ
);
2431 if (!NT_STATUS_IS_OK(status
)) {
2432 smbd_server_connection_terminate(xconn
,
2438 state
->queue_entry
.mem_ctx
= state
;
2439 state
->queue_entry
.vector
= state
->vector
;
2440 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
2441 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
2442 xconn
->smb2
.send_queue_len
++;
2444 status
= smbd_smb2_flush_send_queue(xconn
);
2445 if (!NT_STATUS_IS_OK(status
)) {
2446 smbd_server_connection_terminate(xconn
,
2452 static NTSTATUS
smbd_smb2_request_process_cancel(struct smbd_smb2_request
*req
)
2454 struct smbXsrv_connection
*xconn
= req
->xconn
;
2455 struct smbd_smb2_request
*cur
;
2456 const uint8_t *inhdr
;
2458 uint64_t search_message_id
;
2459 uint64_t search_async_id
;
2462 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2464 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2465 search_message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
2466 search_async_id
= BVAL(inhdr
, SMB2_HDR_PID
);
2469 * We don't need the request anymore cancel requests never
2472 * We defer the TALLOC_FREE(req) to the caller.
2474 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
2476 for (cur
= xconn
->smb2
.requests
; cur
; cur
= cur
->next
) {
2477 const uint8_t *outhdr
;
2478 uint64_t message_id
;
2481 if (cur
->session
!= req
->session
) {
2485 if (cur
->compound_related
) {
2487 * Never cancel anything in a compound request.
2488 * Way too hard to deal with the result.
2493 outhdr
= SMBD_SMB2_OUT_HDR_PTR(cur
);
2495 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
2496 async_id
= BVAL(outhdr
, SMB2_HDR_PID
);
2498 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
2499 if (search_async_id
== async_id
) {
2500 found_id
= async_id
;
2504 if (search_message_id
== message_id
) {
2505 found_id
= message_id
;
2511 if (cur
&& cur
->subreq
) {
2512 inhdr
= SMBD_SMB2_IN_HDR_PTR(cur
);
2513 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2514 "cancel opcode[%s] mid %llu\n",
2515 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
2516 (unsigned long long)found_id
));
2517 tevent_req_cancel(cur
->subreq
);
2520 return NT_STATUS_OK
;
2523 /*************************************************************
2524 Ensure an incoming tid is a valid one for us to access.
2525 Change to the associated uid credentials and chdir to the
2526 valid tid directory.
2527 *************************************************************/
2529 static NTSTATUS
smbd_smb2_request_check_tcon(struct smbd_smb2_request
*req
)
2531 const uint8_t *inhdr
;
2534 struct smbXsrv_tcon
*tcon
;
2536 NTTIME now
= timeval_to_nttime(&req
->request_time
);
2540 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2542 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2543 in_tid
= IVAL(inhdr
, SMB2_HDR_TID
);
2545 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
2546 in_tid
= req
->last_tid
;
2551 status
= smb2srv_tcon_lookup(req
->session
,
2552 in_tid
, now
, &tcon
);
2553 if (!NT_STATUS_IS_OK(status
)) {
2557 if (!change_to_user_and_service(
2559 req
->session
->global
->session_wire_id
))
2561 return NT_STATUS_ACCESS_DENIED
;
2565 req
->last_tid
= in_tid
;
2567 return NT_STATUS_OK
;
2570 /*************************************************************
2571 Ensure an incoming session_id is a valid one for us to access.
2572 *************************************************************/
2574 static NTSTATUS
smbd_smb2_request_check_session(struct smbd_smb2_request
*req
)
2576 const uint8_t *inhdr
;
2579 uint64_t in_session_id
;
2580 struct smbXsrv_session
*session
= NULL
;
2581 struct auth_session_info
*session_info
;
2583 NTTIME now
= timeval_to_nttime(&req
->request_time
);
2585 req
->session
= NULL
;
2588 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2590 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2591 in_opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2592 in_session_id
= BVAL(inhdr
, SMB2_HDR_SESSION_ID
);
2594 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
2595 in_session_id
= req
->last_session_id
;
2598 req
->last_session_id
= 0;
2600 /* look an existing session up */
2601 switch (in_opcode
) {
2602 case SMB2_OP_SESSSETUP
:
2604 * For a session bind request, we don't have the
2605 * channel set up at this point yet, so we defer
2606 * the verification that the connection belongs
2607 * to the session to the session setup code, which
2608 * can look at the session binding flags.
2610 status
= smb2srv_session_lookup_client(req
->xconn
->client
,
2615 status
= smb2srv_session_lookup_conn(req
->xconn
,
2621 req
->session
= session
;
2622 req
->last_session_id
= in_session_id
;
2624 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
2625 switch (in_opcode
) {
2626 case SMB2_OP_SESSSETUP
:
2627 status
= smb2srv_session_lookup_global(req
->xconn
->client
,
2631 if (NT_STATUS_IS_OK(status
)) {
2633 * We fallback to a session of
2634 * another process in order to
2635 * get the signing correct.
2637 * We don't set req->last_session_id here.
2639 req
->session
= session
;
2646 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
2647 switch (in_opcode
) {
2648 case SMB2_OP_SESSSETUP
:
2649 status
= NT_STATUS_OK
;
2651 case SMB2_OP_LOGOFF
:
2654 case SMB2_OP_CANCEL
:
2655 case SMB2_OP_KEEPALIVE
:
2657 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2658 * specifies that LOGOFF, CLOSE and (UN)LOCK
2659 * should always be processed even on expired sessions.
2661 * Also see the logic in
2662 * smbd_smb2_request_process_lock().
2664 * The smb2.session.expire2 test shows that
2665 * CANCEL and KEEPALIVE/ECHO should also
2668 status
= NT_STATUS_OK
;
2674 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2675 switch (in_opcode
) {
2677 case SMB2_OP_CREATE
:
2678 case SMB2_OP_GETINFO
:
2679 case SMB2_OP_SETINFO
:
2680 return NT_STATUS_INVALID_HANDLE
;
2683 * Notice the check for
2684 * (session_info == NULL)
2687 status
= NT_STATUS_OK
;
2691 if (!NT_STATUS_IS_OK(status
)) {
2695 session_info
= session
->global
->auth_session_info
;
2696 if (session_info
== NULL
) {
2697 return NT_STATUS_INVALID_HANDLE
;
2700 return NT_STATUS_OK
;
2703 NTSTATUS
smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request
*req
,
2704 uint32_t data_length
)
2706 struct smbXsrv_connection
*xconn
= req
->xconn
;
2707 uint16_t needed_charge
;
2708 uint16_t credit_charge
= 1;
2709 const uint8_t *inhdr
;
2711 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2713 if (xconn
->smb2
.credits
.multicredit
) {
2714 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
2715 credit_charge
= MAX(credit_charge
, 1);
2718 needed_charge
= (data_length
- 1)/ 65536 + 1;
2720 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
2721 "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2722 (unsigned long long) BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
),
2723 credit_charge
, needed_charge
);
2725 if (needed_charge
> credit_charge
) {
2726 DBGC_WARNING(DBGC_SMB2_CREDITS
,
2727 "CreditCharge too low, given %d, needed %d\n",
2728 credit_charge
, needed_charge
);
2729 return NT_STATUS_INVALID_PARAMETER
;
2732 return NT_STATUS_OK
;
2735 NTSTATUS
smbd_smb2_request_verify_sizes(struct smbd_smb2_request
*req
,
2736 size_t expected_body_size
)
2738 struct iovec
*inhdr_v
;
2739 const uint8_t *inhdr
;
2741 const uint8_t *inbody
;
2743 size_t min_dyn_size
= expected_body_size
& 0x00000001;
2744 int max_idx
= req
->in
.vector_count
- SMBD_SMB2_NUM_IOV_PER_REQ
;
2747 * The following should be checked already.
2749 if (req
->in
.vector_count
< SMBD_SMB2_NUM_IOV_PER_REQ
) {
2750 return NT_STATUS_INTERNAL_ERROR
;
2752 if (req
->current_idx
> max_idx
) {
2753 return NT_STATUS_INTERNAL_ERROR
;
2756 inhdr_v
= SMBD_SMB2_IN_HDR_IOV(req
);
2757 if (inhdr_v
->iov_len
!= SMB2_HDR_BODY
) {
2758 return NT_STATUS_INTERNAL_ERROR
;
2760 if (SMBD_SMB2_IN_BODY_LEN(req
) < 2) {
2761 return NT_STATUS_INTERNAL_ERROR
;
2764 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2765 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2769 case SMB2_OP_GETINFO
:
2776 * Now check the expected body size,
2777 * where the last byte might be in the
2780 if (SMBD_SMB2_IN_BODY_LEN(req
) != (expected_body_size
& 0xFFFFFFFE)) {
2781 return NT_STATUS_INVALID_PARAMETER
;
2783 if (SMBD_SMB2_IN_DYN_LEN(req
) < min_dyn_size
) {
2784 return NT_STATUS_INVALID_PARAMETER
;
2787 inbody
= SMBD_SMB2_IN_BODY_PTR(req
);
2789 body_size
= SVAL(inbody
, 0x00);
2790 if (body_size
!= expected_body_size
) {
2791 return NT_STATUS_INVALID_PARAMETER
;
2794 return NT_STATUS_OK
;
2797 bool smbXsrv_is_encrypted(uint8_t encryption_flags
)
2799 return (!(encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
)
2801 (encryption_flags
& (SMBXSRV_PROCESSED_ENCRYPTED_PACKET
|
2802 SMBXSRV_ENCRYPTION_DESIRED
|
2803 SMBXSRV_ENCRYPTION_REQUIRED
)));
2806 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags
)
2808 return ((encryption_flags
& SMBXSRV_PROCESSED_ENCRYPTED_PACKET
) &&
2809 (encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
));
2812 /* Set a flag if not already set, return true if set */
2813 bool smbXsrv_set_crypto_flag(uint8_t *flags
, uint8_t flag
)
2815 if ((flag
== 0) || (*flags
& flag
)) {
2824 * Update encryption state tracking flags, this can be used to
2825 * determine whether whether the session or tcon is "encrypted".
2827 static void smb2srv_update_crypto_flags(struct smbd_smb2_request
*req
,
2829 bool *update_session_globalp
,
2830 bool *update_tcon_globalp
)
2832 /* Default: assume unecrypted and unsigned */
2833 struct smbXsrv_session
*session
= req
->session
;
2834 struct smbXsrv_tcon
*tcon
= req
->tcon
;
2835 uint8_t encrypt_flag
= SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
;
2836 uint8_t sign_flag
= SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
2837 bool update_session
= false;
2838 bool update_tcon
= false;
2840 if (session
->table
== NULL
) {
2842 * sessions from smb2srv_session_lookup_global()
2843 * have NT_STATUS_BAD_LOGON_SESSION_STATE
2844 * and session->table == NULL.
2846 * They only used to give the correct error
2847 * status, we should not update any state.
2852 if (req
->was_encrypted
&& req
->do_encryption
) {
2853 encrypt_flag
= SMBXSRV_PROCESSED_ENCRYPTED_PACKET
;
2854 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2856 /* Unencrypted packet, can be signed */
2857 if (req
->do_signing
) {
2858 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2862 update_session
|= smbXsrv_set_crypto_flag(
2863 &session
->global
->encryption_flags
, encrypt_flag
);
2864 update_session
|= smbXsrv_set_crypto_flag(
2865 &session
->global
->signing_flags
, sign_flag
);
2868 update_tcon
|= smbXsrv_set_crypto_flag(
2869 &tcon
->global
->encryption_flags
, encrypt_flag
);
2870 update_tcon
|= smbXsrv_set_crypto_flag(
2871 &tcon
->global
->signing_flags
, sign_flag
);
2875 *update_session_globalp
= update_session
;
2876 *update_tcon_globalp
= update_tcon
;
2880 bool smbXsrv_is_signed(uint8_t signing_flags
)
2883 * Signing is always enabled, so unless we got an unsigned
2884 * packet and at least one signed packet that was not
2885 * encrypted, the session or tcon is "signed".
2887 return (!(signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2888 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2891 bool smbXsrv_is_partially_signed(uint8_t signing_flags
)
2893 return ((signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2894 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2897 static NTSTATUS
smbd_smb2_request_dispatch_update_counts(
2898 struct smbd_smb2_request
*req
,
2901 struct smbXsrv_connection
*xconn
= req
->xconn
;
2902 const uint8_t *inhdr
;
2903 uint16_t channel_sequence
;
2904 uint8_t generation_wrap
= 0;
2907 struct smbXsrv_open
*op
;
2908 bool update_open
= false;
2909 NTSTATUS status
= NT_STATUS_OK
;
2911 SMB_ASSERT(!req
->request_counters_updated
);
2913 if (xconn
->protocol
< PROTOCOL_SMB3_00
) {
2914 return NT_STATUS_OK
;
2917 if (req
->compat_chain_fsp
== NULL
) {
2918 return NT_STATUS_OK
;
2921 op
= req
->compat_chain_fsp
->op
;
2923 return NT_STATUS_OK
;
2926 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2927 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2928 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
2930 cmp
= channel_sequence
- op
->global
->channel_sequence
;
2933 * csn wrap. We need to watch out for long-running
2934 * requests that are still sitting on a previously
2935 * used csn. SMB2_OP_NOTIFY can take VERY long.
2937 generation_wrap
+= 1;
2940 if (abs(cmp
) > INT16_MAX
) {
2942 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2944 * If the channel sequence number of the request and the one
2945 * known to the server are not equal, the channel sequence
2946 * number and outstanding request counts are only updated
2947 * "... if the unsigned difference using 16-bit arithmetic
2948 * between ChannelSequence and Open.ChannelSequence is less than
2949 * or equal to 0x7FFF ...".
2950 * Otherwise, an error is returned for the modifying
2951 * calls write, set_info, and ioctl.
2953 * There are currently two issues with the description:
2955 * * For the other calls, the document seems to imply
2956 * that processing continues without adapting the
2957 * counters (if the sequence numbers are not equal).
2959 * TODO: This needs clarification!
2961 * * Also, the behaviour if the difference is larger
2962 * than 0x7FFF is not clear. The document seems to
2963 * imply that if such a difference is reached,
2964 * the server starts to ignore the counters or
2965 * in the case of the modifying calls, return errors.
2967 * TODO: This needs clarification!
2969 * At this point Samba tries to be a little more
2970 * clever than the description in the MS-SMB2 document
2971 * by heuristically detecting and properly treating
2972 * a 16 bit overflow of the client-submitted sequence
2975 * If the stored channel sequence number is more than
2976 * 0x7FFF larger than the one from the request, then
2977 * the client-provided sequence number has likely
2978 * overflown. We treat this case as valid instead
2981 * The MS-SMB2 behaviour would be setting cmp = -1.
2986 if (flags
& SMB2_HDR_FLAG_REPLAY_OPERATION
) {
2987 if (cmp
== 0 && op
->pre_request_count
== 0) {
2988 op
->request_count
+= 1;
2989 req
->request_counters_updated
= true;
2990 } else if (cmp
> 0 && op
->pre_request_count
== 0) {
2991 op
->pre_request_count
+= op
->request_count
;
2992 op
->request_count
= 1;
2993 op
->global
->channel_sequence
= channel_sequence
;
2994 op
->global
->channel_generation
+= generation_wrap
;
2996 req
->request_counters_updated
= true;
2997 } else if (modify_call
) {
2998 return NT_STATUS_FILE_NOT_AVAILABLE
;
3002 op
->request_count
+= 1;
3003 req
->request_counters_updated
= true;
3004 } else if (cmp
> 0) {
3005 op
->pre_request_count
+= op
->request_count
;
3006 op
->request_count
= 1;
3007 op
->global
->channel_sequence
= channel_sequence
;
3008 op
->global
->channel_generation
+= generation_wrap
;
3010 req
->request_counters_updated
= true;
3011 } else if (modify_call
) {
3012 return NT_STATUS_FILE_NOT_AVAILABLE
;
3015 req
->channel_generation
= op
->global
->channel_generation
;
3018 status
= smbXsrv_open_update(op
);
3024 NTSTATUS
smbd_smb2_request_dispatch(struct smbd_smb2_request
*req
)
3026 struct smbXsrv_connection
*xconn
= req
->xconn
;
3027 const struct smbd_smb2_dispatch_table
*call
= NULL
;
3028 const struct iovec
*intf_v
= SMBD_SMB2_IN_TF_IOV(req
);
3029 const uint8_t *inhdr
;
3034 NTSTATUS session_status
;
3035 uint32_t allowed_flags
;
3036 NTSTATUS return_value
;
3037 struct smbXsrv_session
*x
= NULL
;
3038 bool signing_required
= false;
3039 bool encryption_desired
= false;
3040 bool encryption_required
= false;
3042 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
3044 DO_PROFILE_INC(request
);
3046 SMB_ASSERT(!req
->request_counters_updated
);
3048 /* TODO: verify more things */
3050 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
3051 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
3052 mid
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
3053 DBG_DEBUG("opcode[%s] mid = %"PRIu64
"\n",
3054 smb2_opcode_name(opcode
),
3057 if (xconn
->protocol
>= PROTOCOL_SMB2_02
) {
3059 * once the protocol is negotiated
3060 * SMB2_OP_NEGPROT is not allowed anymore
3062 if (opcode
== SMB2_OP_NEGPROT
) {
3063 /* drop the connection */
3064 return NT_STATUS_INVALID_PARAMETER
;
3068 * if the protocol is not negotiated yet
3069 * only SMB2_OP_NEGPROT is allowed.
3071 if (opcode
!= SMB2_OP_NEGPROT
) {
3072 /* drop the connection */
3073 return NT_STATUS_INVALID_PARAMETER
;
3078 * Check if the client provided a valid session id.
3080 * As some command don't require a valid session id
3081 * we defer the check of the session_status
3083 session_status
= smbd_smb2_request_check_session(req
);
3086 signing_required
= x
->global
->signing_flags
& SMBXSRV_SIGNING_REQUIRED
;
3087 encryption_desired
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
;
3088 encryption_required
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
;
3091 req
->async_internal
= false;
3092 req
->do_signing
= false;
3093 if (opcode
!= SMB2_OP_SESSSETUP
) {
3094 req
->do_encryption
= encryption_desired
;
3096 req
->do_encryption
= false;
3098 req
->was_encrypted
= false;
3099 if (intf_v
->iov_len
== SMB2_TF_HDR_SIZE
) {
3100 const uint8_t *intf
= SMBD_SMB2_IN_TF_PTR(req
);
3101 uint64_t tf_session_id
= BVAL(intf
, SMB2_TF_SESSION_ID
);
3103 if (x
!= NULL
&& x
->global
->session_wire_id
!= tf_session_id
) {
3104 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
3105 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
3106 (unsigned long long)x
->global
->session_wire_id
,
3107 (unsigned long long)tf_session_id
));
3109 * TODO: windows allows this...
3110 * should we drop the connection?
3112 * For now we just return ACCESS_DENIED
3113 * (Windows clients never trigger this)
3114 * and wait for an update of [MS-SMB2].
3116 return smbd_smb2_request_error(req
,
3117 NT_STATUS_ACCESS_DENIED
);
3120 req
->was_encrypted
= true;
3121 req
->do_encryption
= true;
3124 if (encryption_required
&& !req
->was_encrypted
) {
3125 req
->do_encryption
= true;
3126 return smbd_smb2_request_error(req
,
3127 NT_STATUS_ACCESS_DENIED
);
3130 call
= smbd_smb2_call(opcode
);
3132 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3135 allowed_flags
= SMB2_HDR_FLAG_CHAINED
|
3136 SMB2_HDR_FLAG_SIGNED
|
3138 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
3139 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
3141 if (opcode
== SMB2_OP_NEGPROT
) {
3142 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11
) {
3143 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
3146 if (opcode
== SMB2_OP_CANCEL
) {
3147 allowed_flags
|= SMB2_HDR_FLAG_ASYNC
;
3149 if (xconn
->protocol
>= PROTOCOL_SMB3_00
) {
3150 allowed_flags
|= SMB2_HDR_FLAG_REPLAY_OPERATION
;
3152 if ((flags
& ~allowed_flags
) != 0) {
3153 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3156 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3158 * This check is mostly for giving the correct error code
3159 * for compounded requests.
3161 if (!NT_STATUS_IS_OK(session_status
)) {
3162 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3165 req
->compat_chain_fsp
= NULL
;
3168 if (req
->was_encrypted
) {
3169 signing_required
= false;
3170 } else if (signing_required
|| (flags
& SMB2_HDR_FLAG_SIGNED
)) {
3171 struct smb2_signing_key
*signing_key
= NULL
;
3172 bool has_channel
= false;
3176 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3177 * If the SMB2 header of the SMB2 NEGOTIATE
3178 * request has the SMB2_FLAGS_SIGNED bit set in the
3179 * Flags field, the server MUST fail the request
3180 * with STATUS_INVALID_PARAMETER.
3182 * Microsoft test tool checks this.
3185 if ((opcode
== SMB2_OP_NEGPROT
) &&
3186 (flags
& SMB2_HDR_FLAG_SIGNED
)) {
3187 status
= NT_STATUS_INVALID_PARAMETER
;
3189 status
= NT_STATUS_USER_SESSION_DELETED
;
3191 return smbd_smb2_request_error(req
, status
);
3194 signing_key
= smbd_smb2_signing_key(x
, xconn
, &has_channel
);
3197 * If we have a signing key, we should
3200 if (smb2_signing_key_valid(signing_key
) && opcode
!= SMB2_OP_CANCEL
) {
3201 req
->do_signing
= true;
3204 status
= smb2_signing_check_pdu(signing_key
,
3205 SMBD_SMB2_IN_HDR_IOV(req
),
3206 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3207 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) &&
3208 opcode
== SMB2_OP_SESSSETUP
&& !has_channel
&&
3209 NT_STATUS_IS_OK(session_status
))
3211 if (!NT_STATUS_EQUAL(x
->status
, NT_STATUS_BAD_LOGON_SESSION_STATE
)) {
3212 struct smbXsrv_session
*session
= NULL
;
3215 error
= smb2srv_session_lookup_global(req
->xconn
->client
,
3216 x
->global
->session_wire_id
,
3219 if (!NT_STATUS_IS_OK(error
)) {
3220 return smbd_smb2_request_error(req
, error
);
3224 * We fallback to a session of
3225 * another process in order to
3226 * get the signing correct.
3228 * We don't set req->last_session_id here.
3230 req
->session
= x
= session
;
3232 goto skipped_signing
;
3234 if (!NT_STATUS_IS_OK(status
)) {
3235 return smbd_smb2_request_error(req
, status
);
3239 * Now that we know the request was correctly signed
3240 * we have to sign the response too.
3242 if (opcode
!= SMB2_OP_CANCEL
) {
3243 req
->do_signing
= true;
3246 if (!NT_STATUS_IS_OK(session_status
)) {
3247 return smbd_smb2_request_error(req
, session_status
);
3251 if (opcode
== SMB2_OP_IOCTL
) {
3253 * Some special IOCTL calls don't require
3254 * file, tcon nor session.
3256 * They typically don't do any real action
3257 * on behalf of the client.
3259 * They are mainly used to alter the behavior
3260 * of the connection for testing. So we can
3261 * run as root and skip all file, tcon and session
3264 static const struct smbd_smb2_dispatch_table _root_ioctl_call
= {
3265 .opcode
= SMB2_OP_IOCTL
,
3268 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
3269 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
3270 uint32_t in_ctl_code
;
3273 if (needed
> body_size
) {
3274 return smbd_smb2_request_error(req
,
3275 NT_STATUS_INVALID_PARAMETER
);
3278 in_ctl_code
= IVAL(body
, 0x04);
3280 * Only add trusted IOCTL codes here!
3282 switch (in_ctl_code
) {
3283 case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT
:
3284 call
= &_root_ioctl_call
;
3286 case FSCTL_VALIDATE_NEGOTIATE_INFO
:
3287 call
= &_root_ioctl_call
;
3289 case FSCTL_QUERY_NETWORK_INTERFACE_INFO
:
3290 call
= &_root_ioctl_call
;
3297 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3298 req
->compound_related
= true;
3301 if (call
->need_session
) {
3302 if (!NT_STATUS_IS_OK(session_status
)) {
3303 return smbd_smb2_request_error(req
, session_status
);
3307 if (call
->need_tcon
) {
3308 SMB_ASSERT(call
->need_session
);
3311 * This call needs to be run as user.
3313 * smbd_smb2_request_check_tcon()
3314 * calls change_to_user() on success.
3315 * Which implies set_current_user_info()
3316 * and chdir_current_service().
3318 status
= smbd_smb2_request_check_tcon(req
);
3319 if (!NT_STATUS_IS_OK(status
)) {
3320 return smbd_smb2_request_error(req
, status
);
3322 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
) {
3323 encryption_desired
= true;
3325 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
) {
3326 encryption_required
= true;
3328 if (encryption_required
&& !req
->was_encrypted
) {
3329 req
->do_encryption
= true;
3330 return smbd_smb2_request_error(req
,
3331 NT_STATUS_ACCESS_DENIED
);
3332 } else if (encryption_desired
) {
3333 req
->do_encryption
= true;
3335 } else if (call
->need_session
) {
3336 struct auth_session_info
*session_info
= NULL
;
3339 * Unless we also have need_tcon (see above),
3340 * we still need to call set_current_user_info().
3343 session_info
= req
->session
->global
->auth_session_info
;
3344 if (session_info
== NULL
) {
3345 return NT_STATUS_INVALID_HANDLE
;
3348 set_current_user_info(session_info
->unix_info
->sanitized_username
,
3349 session_info
->unix_info
->unix_name
,
3350 session_info
->info
->domain_name
);
3354 bool update_session_global
= false;
3355 bool update_tcon_global
= false;
3357 smb2srv_update_crypto_flags(req
, opcode
,
3358 &update_session_global
,
3359 &update_tcon_global
);
3361 if (update_session_global
) {
3362 status
= smbXsrv_session_update(x
);
3363 if (!NT_STATUS_IS_OK(status
)) {
3364 return smbd_smb2_request_error(req
, status
);
3367 if (update_tcon_global
) {
3368 status
= smbXsrv_tcon_update(req
->tcon
);
3369 if (!NT_STATUS_IS_OK(status
)) {
3370 return smbd_smb2_request_error(req
, status
);
3375 if (call
->fileid_ofs
!= 0) {
3376 size_t needed
= call
->fileid_ofs
+ 16;
3377 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
3378 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
3379 uint64_t file_id_persistent
;
3380 uint64_t file_id_volatile
;
3381 struct files_struct
*fsp
;
3383 SMB_ASSERT(call
->need_tcon
);
3385 if (needed
> body_size
) {
3386 return smbd_smb2_request_error(req
,
3387 NT_STATUS_INVALID_PARAMETER
);
3390 file_id_persistent
= BVAL(body
, call
->fileid_ofs
+ 0);
3391 file_id_volatile
= BVAL(body
, call
->fileid_ofs
+ 8);
3393 fsp
= file_fsp_smb2(req
, file_id_persistent
, file_id_volatile
);
3395 if (req
->compound_related
&&
3396 !NT_STATUS_IS_OK(req
->compound_create_err
))
3398 return smbd_smb2_request_error(req
,
3399 req
->compound_create_err
);
3402 * smbd_smb2_request_process_ioctl()
3403 * has more checks in order to return more
3404 * detailed error codes...
3406 if (opcode
!= SMB2_OP_IOCTL
) {
3407 return smbd_smb2_request_error(req
,
3408 NT_STATUS_FILE_CLOSED
);
3411 if (fsp
->fsp_flags
.encryption_required
&& !req
->was_encrypted
) {
3412 return smbd_smb2_request_error(req
,
3413 NT_STATUS_ACCESS_DENIED
);
3418 status
= smbd_smb2_request_dispatch_update_counts(req
, call
->modify
);
3419 if (!NT_STATUS_IS_OK(status
)) {
3420 return smbd_smb2_request_error(req
, status
);
3423 if (call
->as_root
) {
3424 SMB_ASSERT(call
->fileid_ofs
== 0);
3425 /* This call needs to be run as root */
3426 change_to_root_user();
3427 } else if (opcode
!= SMB2_OP_KEEPALIVE
) {
3428 SMB_ASSERT(call
->need_tcon
);
3431 #define _INBYTES(_r) \
3432 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3435 case SMB2_OP_NEGPROT
:
3436 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot
, profile_p
,
3437 req
->profile
, _INBYTES(req
));
3438 return_value
= smbd_smb2_request_process_negprot(req
);
3441 case SMB2_OP_SESSSETUP
:
3442 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup
, profile_p
,
3443 req
->profile
, _INBYTES(req
));
3444 return_value
= smbd_smb2_request_process_sesssetup(req
);
3447 case SMB2_OP_LOGOFF
:
3448 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff
, profile_p
,
3449 req
->profile
, _INBYTES(req
));
3450 return_value
= smbd_smb2_request_process_logoff(req
);
3454 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon
, profile_p
,
3455 req
->profile
, _INBYTES(req
));
3456 return_value
= smbd_smb2_request_process_tcon(req
);
3460 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis
, profile_p
,
3461 req
->profile
, _INBYTES(req
));
3462 return_value
= smbd_smb2_request_process_tdis(req
);
3465 case SMB2_OP_CREATE
:
3466 if (req
->subreq
== NULL
) {
3467 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create
, profile_p
,
3468 req
->profile
, _INBYTES(req
));
3470 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req
->profile
);
3472 return_value
= smbd_smb2_request_process_create(req
);
3476 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close
, profile_p
,
3477 req
->profile
, _INBYTES(req
));
3478 return_value
= smbd_smb2_request_process_close(req
);
3482 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush
, profile_p
,
3483 req
->profile
, _INBYTES(req
));
3484 return_value
= smbd_smb2_request_process_flush(req
);
3488 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read
, profile_p
,
3489 req
->profile
, _INBYTES(req
));
3490 return_value
= smbd_smb2_request_process_read(req
);
3494 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write
, profile_p
,
3495 req
->profile
, _INBYTES(req
));
3496 return_value
= smbd_smb2_request_process_write(req
);
3500 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock
, profile_p
,
3501 req
->profile
, _INBYTES(req
));
3502 return_value
= smbd_smb2_request_process_lock(req
);
3506 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl
, profile_p
,
3507 req
->profile
, _INBYTES(req
));
3508 return_value
= smbd_smb2_request_process_ioctl(req
);
3511 case SMB2_OP_CANCEL
:
3512 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel
, profile_p
,
3513 req
->profile
, _INBYTES(req
));
3514 return_value
= smbd_smb2_request_process_cancel(req
);
3515 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
, 0);
3518 * We don't need the request anymore cancel requests never
3521 * smbd_smb2_request_process_cancel() already called
3522 * DLIST_REMOVE(xconn->smb2.requests, req);
3528 case SMB2_OP_KEEPALIVE
:
3529 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive
, profile_p
,
3530 req
->profile
, _INBYTES(req
));
3531 return_value
= smbd_smb2_request_process_keepalive(req
);
3534 case SMB2_OP_QUERY_DIRECTORY
:
3535 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find
, profile_p
,
3536 req
->profile
, _INBYTES(req
));
3537 return_value
= smbd_smb2_request_process_query_directory(req
);
3540 case SMB2_OP_NOTIFY
:
3541 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify
, profile_p
,
3542 req
->profile
, _INBYTES(req
));
3543 return_value
= smbd_smb2_request_process_notify(req
);
3546 case SMB2_OP_GETINFO
:
3547 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo
, profile_p
,
3548 req
->profile
, _INBYTES(req
));
3549 return_value
= smbd_smb2_request_process_getinfo(req
);
3552 case SMB2_OP_SETINFO
:
3553 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo
, profile_p
,
3554 req
->profile
, _INBYTES(req
));
3555 return_value
= smbd_smb2_request_process_setinfo(req
);
3559 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break
, profile_p
,
3560 req
->profile
, _INBYTES(req
));
3561 return_value
= smbd_smb2_request_process_break(req
);
3565 return_value
= smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3568 return return_value
;
3571 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request
*req
)
3573 struct smbXsrv_connection
*xconn
= req
->xconn
;
3574 const uint8_t *inhdr
;
3575 uint16_t channel_sequence
;
3576 struct smbXsrv_open
*op
;
3578 if (!req
->request_counters_updated
) {
3582 req
->request_counters_updated
= false;
3584 if (xconn
->protocol
< PROTOCOL_SMB3_00
) {
3588 if (req
->compat_chain_fsp
== NULL
) {
3592 op
= req
->compat_chain_fsp
->op
;
3597 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
3598 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
3600 if ((op
->global
->channel_sequence
== channel_sequence
) &&
3601 (op
->global
->channel_generation
== req
->channel_generation
)) {
3602 SMB_ASSERT(op
->request_count
> 0);
3603 op
->request_count
-= 1;
3605 SMB_ASSERT(op
->pre_request_count
> 0);
3606 op
->pre_request_count
-= 1;
3610 static NTSTATUS
smbd_smb2_request_reply(struct smbd_smb2_request
*req
)
3612 struct smbXsrv_connection
*xconn
= req
->xconn
;
3614 struct iovec
*firsttf
= SMBD_SMB2_IDX_TF_IOV(req
,out
,first_idx
);
3615 struct iovec
*outhdr
= SMBD_SMB2_OUT_HDR_IOV(req
);
3616 struct iovec
*outdyn
= SMBD_SMB2_OUT_DYN_IOV(req
);
3621 TALLOC_FREE(req
->async_te
);
3623 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3624 smbd_smb2_request_reply_update_counts(req
);
3626 if (req
->do_encryption
&&
3627 (firsttf
->iov_len
== 0) &&
3628 (!smb2_signing_key_valid(req
->first_enc_key
)) &&
3629 (req
->session
!= NULL
) &&
3630 smb2_signing_key_valid(req
->session
->global
->encryption_key
))
3632 struct smb2_signing_key
*encryption_key
=
3633 req
->session
->global
->encryption_key
;
3635 uint64_t session_id
= req
->session
->global
->session_wire_id
;
3636 uint64_t nonce_high
;
3639 status
= smb2_get_new_nonce(req
->session
,
3642 if (!NT_STATUS_IS_OK(status
)) {
3647 * We need to place the SMB2_TRANSFORM header before the
3652 * we need to remember the encryption key
3653 * and defer the signing/encryption until
3654 * we are sure that we do not change
3657 status
= smb2_signing_key_copy(req
,
3659 &req
->first_enc_key
);
3660 if (!NT_STATUS_IS_OK(status
)) {
3664 tf
= talloc_zero_array(req
, uint8_t,
3667 return NT_STATUS_NO_MEMORY
;
3670 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
3671 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
3672 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
3673 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
3675 firsttf
->iov_base
= (void *)tf
;
3676 firsttf
->iov_len
= SMB2_TF_HDR_SIZE
;
3679 if ((req
->current_idx
> SMBD_SMB2_NUM_IOV_PER_REQ
) &&
3680 (smb2_signing_key_valid(req
->last_sign_key
)) &&
3681 (firsttf
->iov_len
== 0))
3683 int last_idx
= req
->current_idx
- SMBD_SMB2_NUM_IOV_PER_REQ
;
3684 struct iovec
*lasthdr
= SMBD_SMB2_IDX_HDR_IOV(req
,out
,last_idx
);
3687 * As we are sure the header of the last request in the
3688 * compound chain will not change, we can to sign here
3689 * with the last signing key we remembered.
3691 status
= smb2_signing_sign_pdu(req
->last_sign_key
,
3693 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3694 if (!NT_STATUS_IS_OK(status
)) {
3698 TALLOC_FREE(req
->last_sign_key
);
3700 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
,
3701 iov_buflen(outhdr
, SMBD_SMB2_NUM_IOV_PER_REQ
-1));
3703 req
->current_idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
3705 if (req
->current_idx
< req
->out
.vector_count
) {
3707 * We must process the remaining compound
3708 * SMB2 requests before any new incoming SMB2
3709 * requests. This is because incoming SMB2
3710 * requests may include a cancel for a
3711 * compound request we haven't processed
3714 struct tevent_immediate
*im
= tevent_create_immediate(req
);
3716 return NT_STATUS_NO_MEMORY
;
3719 if (req
->do_signing
&& firsttf
->iov_len
== 0) {
3720 struct smbXsrv_session
*x
= req
->session
;
3721 struct smb2_signing_key
*signing_key
=
3722 smbd_smb2_signing_key(x
, xconn
, NULL
);
3725 * we need to remember the signing key
3726 * and defer the signing until
3727 * we are sure that we do not change
3730 status
= smb2_signing_key_copy(req
,
3732 &req
->last_sign_key
);
3733 if (!NT_STATUS_IS_OK(status
)) {
3739 * smbd_smb2_request_dispatch() will redo the impersonation.
3740 * So we use req->xconn->client->raw_ev_ctx instead
3741 * of req->ev_ctx here.
3743 tevent_schedule_immediate(im
,
3744 req
->xconn
->client
->raw_ev_ctx
,
3745 smbd_smb2_request_dispatch_immediate
,
3747 return NT_STATUS_OK
;
3750 if (req
->compound_related
) {
3751 req
->compound_related
= false;
3754 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
3756 return NT_STATUS_INVALID_PARAMETER_MIX
;
3759 /* Set credit for these operations (zero credits if this
3760 is a final reply for an async operation). */
3761 smb2_calculate_credits(req
, req
);
3764 * now check if we need to sign the current response
3766 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
3767 status
= smb2_signing_encrypt_pdu(req
->first_enc_key
,
3769 req
->out
.vector_count
- first_idx
);
3770 if (!NT_STATUS_IS_OK(status
)) {
3773 } else if (req
->do_signing
) {
3774 struct smbXsrv_session
*x
= req
->session
;
3775 struct smb2_signing_key
*signing_key
=
3776 smbd_smb2_signing_key(x
, xconn
, NULL
);
3778 status
= smb2_signing_sign_pdu(signing_key
,
3780 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3781 if (!NT_STATUS_IS_OK(status
)) {
3785 TALLOC_FREE(req
->first_enc_key
);
3787 if (req
->preauth
!= NULL
) {
3788 gnutls_hash_hd_t hash_hnd
= NULL
;
3792 rc
= gnutls_hash_init(&hash_hnd
, GNUTLS_DIG_SHA512
);
3794 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3796 rc
= gnutls_hash(hash_hnd
,
3797 req
->preauth
->sha512_value
,
3798 sizeof(req
->preauth
->sha512_value
));
3800 gnutls_hash_deinit(hash_hnd
, NULL
);
3801 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3803 for (i
= 1; i
< req
->in
.vector_count
; i
++) {
3804 rc
= gnutls_hash(hash_hnd
,
3805 req
->in
.vector
[i
].iov_base
,
3806 req
->in
.vector
[i
].iov_len
);
3808 gnutls_hash_deinit(hash_hnd
, NULL
);
3809 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3813 gnutls_hash_deinit(hash_hnd
, NULL
);
3814 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3816 gnutls_hash_output(hash_hnd
, req
->preauth
->sha512_value
);
3818 rc
= gnutls_hash(hash_hnd
,
3819 req
->preauth
->sha512_value
,
3820 sizeof(req
->preauth
->sha512_value
));
3822 gnutls_hash_deinit(hash_hnd
, NULL
);
3823 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3825 for (i
= 1; i
< req
->out
.vector_count
; i
++) {
3826 rc
= gnutls_hash(hash_hnd
,
3827 req
->out
.vector
[i
].iov_base
,
3828 req
->out
.vector
[i
].iov_len
);
3830 gnutls_hash_deinit(hash_hnd
, NULL
);
3831 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3835 gnutls_hash_deinit(hash_hnd
, req
->preauth
->sha512_value
);
3837 req
->preauth
= NULL
;
3840 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3841 if (req
->out
.vector_count
< (2*SMBD_SMB2_NUM_IOV_PER_REQ
) &&
3842 outdyn
->iov_base
== NULL
&& outdyn
->iov_len
!= 0) {
3843 /* Dynamic part is NULL. Chop it off,
3844 We're going to send it via sendfile. */
3845 req
->out
.vector_count
-= 1;
3849 * We're done with this request -
3850 * move it off the "being processed" queue.
3852 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
3854 req
->queue_entry
.mem_ctx
= req
;
3855 req
->queue_entry
.vector
= req
->out
.vector
;
3856 req
->queue_entry
.count
= req
->out
.vector_count
;
3857 DLIST_ADD_END(xconn
->smb2
.send_queue
, &req
->queue_entry
);
3858 xconn
->smb2
.send_queue_len
++;
3860 status
= smbd_smb2_flush_send_queue(xconn
);
3861 if (!NT_STATUS_IS_OK(status
)) {
3865 return NT_STATUS_OK
;
3868 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
);
3870 void smbd_smb2_request_dispatch_immediate(struct tevent_context
*ctx
,
3871 struct tevent_immediate
*im
,
3874 struct smbd_smb2_request
*req
= talloc_get_type_abort(private_data
,
3875 struct smbd_smb2_request
);
3876 struct smbXsrv_connection
*xconn
= req
->xconn
;
3881 if (DEBUGLEVEL
>= 10) {
3882 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3883 req
->current_idx
, req
->in
.vector_count
));
3884 print_req_vectors(req
);
3887 status
= smbd_smb2_request_dispatch(req
);
3888 if (!NT_STATUS_IS_OK(status
)) {
3889 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3893 status
= smbd_smb2_request_next_incoming(xconn
);
3894 if (!NT_STATUS_IS_OK(status
)) {
3895 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3900 NTSTATUS
smbd_smb2_request_done_ex(struct smbd_smb2_request
*req
,
3902 DATA_BLOB body
, DATA_BLOB
*dyn
,
3903 const char *location
)
3906 struct iovec
*outbody_v
;
3907 struct iovec
*outdyn_v
;
3908 uint32_t next_command_ofs
;
3911 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
3912 mid
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
3914 DBG_DEBUG("mid [%"PRIu64
"] idx[%d] status[%s] "
3915 "body[%u] dyn[%s:%u] at %s\n",
3919 (unsigned int)body
.length
,
3921 (unsigned int)(dyn
? dyn
->length
: 0),
3924 if (body
.length
< 2) {
3925 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
3928 if ((body
.length
% 2) != 0) {
3929 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
3932 outbody_v
= SMBD_SMB2_OUT_BODY_IOV(req
);
3933 outdyn_v
= SMBD_SMB2_OUT_DYN_IOV(req
);
3935 next_command_ofs
= IVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
);
3936 SIVAL(outhdr
, SMB2_HDR_STATUS
, NT_STATUS_V(status
));
3938 outbody_v
->iov_base
= (void *)body
.data
;
3939 outbody_v
->iov_len
= body
.length
;
3942 outdyn_v
->iov_base
= (void *)dyn
->data
;
3943 outdyn_v
->iov_len
= dyn
->length
;
3945 outdyn_v
->iov_base
= NULL
;
3946 outdyn_v
->iov_len
= 0;
3950 * See if we need to recalculate the offset to the next response
3952 * Note that all responses may require padding (including the very last
3955 if (req
->out
.vector_count
>= (2 * SMBD_SMB2_NUM_IOV_PER_REQ
)) {
3956 next_command_ofs
= SMB2_HDR_BODY
;
3957 next_command_ofs
+= SMBD_SMB2_OUT_BODY_LEN(req
);
3958 next_command_ofs
+= SMBD_SMB2_OUT_DYN_LEN(req
);
3961 if ((next_command_ofs
% 8) != 0) {
3962 size_t pad_size
= 8 - (next_command_ofs
% 8);
3963 if (SMBD_SMB2_OUT_DYN_LEN(req
) == 0) {
3965 * if the dyn buffer is empty
3966 * we can use it to add padding
3970 pad
= talloc_zero_array(req
,
3973 return smbd_smb2_request_error(req
,
3974 NT_STATUS_NO_MEMORY
);
3977 outdyn_v
->iov_base
= (void *)pad
;
3978 outdyn_v
->iov_len
= pad_size
;
3981 * For now we copy the dynamic buffer
3982 * and add the padding to the new buffer
3989 old_size
= SMBD_SMB2_OUT_DYN_LEN(req
);
3990 old_dyn
= SMBD_SMB2_OUT_DYN_PTR(req
);
3992 new_size
= old_size
+ pad_size
;
3993 new_dyn
= talloc_zero_array(req
,
3995 if (new_dyn
== NULL
) {
3996 return smbd_smb2_request_error(req
,
3997 NT_STATUS_NO_MEMORY
);
4000 memcpy(new_dyn
, old_dyn
, old_size
);
4001 memset(new_dyn
+ old_size
, 0, pad_size
);
4003 outdyn_v
->iov_base
= (void *)new_dyn
;
4004 outdyn_v
->iov_len
= new_size
;
4006 next_command_ofs
+= pad_size
;
4009 if ((req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) >= req
->out
.vector_count
) {
4010 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
4012 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
4014 return smbd_smb2_request_reply(req
);
4017 NTSTATUS
smbd_smb2_request_error_ex(struct smbd_smb2_request
*req
,
4019 uint8_t error_context_count
,
4021 const char *location
)
4023 struct smbXsrv_connection
*xconn
= req
->xconn
;
4026 uint8_t *outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
4027 size_t unread_bytes
= smbd_smb2_unread_bytes(req
);
4029 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
4030 "at %s\n", req
->current_idx
, nt_errstr(status
),
4031 info
? " +info" : "", location
);
4034 /* Recvfile error. Drain incoming socket. */
4038 ret
= drain_socket(xconn
->transport
.sock
, unread_bytes
);
4039 if (ret
!= unread_bytes
) {
4043 error
= NT_STATUS_IO_DEVICE_ERROR
;
4045 error
= map_nt_error_from_unix_common(errno
);
4048 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
4049 "ret[%u] errno[%d] => %s\n",
4050 (unsigned)unread_bytes
,
4051 (unsigned)ret
, errno
, nt_errstr(error
)));
4056 body
.data
= outhdr
+ SMB2_HDR_BODY
;
4058 SSVAL(body
.data
, 0, 9);
4059 SCVAL(body
.data
, 2, error_context_count
);
4062 SIVAL(body
.data
, 0x04, info
->length
);
4064 /* Allocated size of req->out.vector[i].iov_base
4065 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
4066 * 1 byte without having to do an alloc.
4069 info
->data
= ((uint8_t *)outhdr
) +
4070 OUTVEC_ALLOC_SIZE
- 1;
4072 SCVAL(info
->data
, 0, 0);
4076 * Note: Even if there is an error, continue to process the request.
4080 return smbd_smb2_request_done_ex(req
, status
, body
, info
, __location__
);
4083 struct smbd_smb2_break_state
{
4084 struct tevent_req
*req
;
4085 struct smbd_smb2_send_queue queue_entry
;
4086 uint8_t nbt_hdr
[NBT_HDR_SIZE
];
4087 uint8_t hdr
[SMB2_HDR_BODY
];
4088 struct iovec vector
[1+SMBD_SMB2_NUM_IOV_PER_REQ
];
4091 static struct tevent_req
*smbd_smb2_break_send(TALLOC_CTX
*mem_ctx
,
4092 struct tevent_context
*ev
,
4093 struct smbXsrv_connection
*xconn
,
4094 uint64_t session_id
,
4095 const uint8_t *body
,
4098 struct tevent_req
*req
= NULL
;
4099 struct smbd_smb2_break_state
*state
= NULL
;
4103 req
= tevent_req_create(mem_ctx
, &state
,
4104 struct smbd_smb2_break_state
);
4110 tevent_req_defer_callback(req
, ev
);
4112 SIVAL(state
->hdr
, 0, SMB2_MAGIC
);
4113 SSVAL(state
->hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
4114 SSVAL(state
->hdr
, SMB2_HDR_EPOCH
, 0);
4115 SIVAL(state
->hdr
, SMB2_HDR_STATUS
, 0);
4116 SSVAL(state
->hdr
, SMB2_HDR_OPCODE
, SMB2_OP_BREAK
);
4117 SSVAL(state
->hdr
, SMB2_HDR_CREDIT
, 0);
4118 SIVAL(state
->hdr
, SMB2_HDR_FLAGS
, SMB2_HDR_FLAG_REDIRECT
);
4119 SIVAL(state
->hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
4120 SBVAL(state
->hdr
, SMB2_HDR_MESSAGE_ID
, UINT64_MAX
);
4121 SIVAL(state
->hdr
, SMB2_HDR_PID
, 0);
4122 SIVAL(state
->hdr
, SMB2_HDR_TID
, 0);
4123 SBVAL(state
->hdr
, SMB2_HDR_SESSION_ID
, session_id
);
4124 memset(state
->hdr
+SMB2_HDR_SIGNATURE
, 0, 16);
4126 state
->vector
[0] = (struct iovec
) {
4127 .iov_base
= state
->nbt_hdr
,
4128 .iov_len
= sizeof(state
->nbt_hdr
)
4131 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
4136 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
] = (struct iovec
) {
4137 .iov_base
= state
->hdr
,
4138 .iov_len
= sizeof(state
->hdr
)
4141 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
] = (struct iovec
) {
4142 .iov_base
= discard_const_p(uint8_t, body
),
4143 .iov_len
= body_len
,
4147 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4150 ok
= smb2_setup_nbt_length(state
->vector
,
4151 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
4153 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
4154 return tevent_req_post(req
, ev
);
4158 * We require TCP acks for this PDU to the client!
4159 * We want 5 retransmissions and timeout when the
4160 * retransmission timeout (rto) passed 6 times.
4162 * required_acked_bytes gets a dummy value of
4163 * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4164 * it'll get the real value when it's moved to
4167 * state->queue_entry.ack.req gets completed with
4168 * 1. tevent_req_done(), when all bytes are acked.
4169 * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4170 * the timeout expired before all bytes were acked.
4171 * 2b. tevent_req_nterror(transport_error), when the
4172 * connection got a disconnect from the kernel.
4174 state
->queue_entry
.ack
.timeout
=
4175 timeval_current_ofs_usec(xconn
->ack
.rto_usecs
* 6);
4176 state
->queue_entry
.ack
.required_acked_bytes
= UINT64_MAX
;
4177 state
->queue_entry
.ack
.req
= req
;
4178 state
->queue_entry
.mem_ctx
= state
;
4179 state
->queue_entry
.vector
= state
->vector
;
4180 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
4181 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
4182 xconn
->smb2
.send_queue_len
++;
4184 status
= smbd_smb2_flush_send_queue(xconn
);
4185 if (tevent_req_nterror(req
, status
)) {
4186 return tevent_req_post(req
, ev
);
4192 static NTSTATUS
smbd_smb2_break_recv(struct tevent_req
*req
)
4194 return tevent_req_simple_recv_ntstatus(req
);
4197 struct smbXsrv_pending_break
{
4198 struct smbXsrv_pending_break
*prev
, *next
;
4199 struct smbXsrv_client
*client
;
4200 bool disable_oplock_break_retries
;
4201 uint64_t session_id
;
4202 uint64_t last_channel_id
;
4205 uint8_t oplock
[0x18];
4206 uint8_t lease
[0x2c];
4211 static void smbXsrv_pending_break_done(struct tevent_req
*subreq
);
4213 static struct smbXsrv_pending_break
*smbXsrv_pending_break_create(
4214 struct smbXsrv_client
*client
,
4215 uint64_t session_id
)
4217 struct smbXsrv_pending_break
*pb
= NULL
;
4219 pb
= talloc_zero(client
, struct smbXsrv_pending_break
);
4223 pb
->client
= client
;
4224 pb
->session_id
= session_id
;
4225 pb
->disable_oplock_break_retries
= lp_smb2_disable_oplock_break_retry();
4230 static NTSTATUS
smbXsrv_pending_break_submit(struct smbXsrv_pending_break
*pb
);
4232 static NTSTATUS
smbXsrv_pending_break_schedule(struct smbXsrv_pending_break
*pb
)
4234 struct smbXsrv_client
*client
= pb
->client
;
4237 DLIST_ADD_END(client
->pending_breaks
, pb
);
4238 status
= smbXsrv_client_pending_breaks_updated(client
);
4239 if (!NT_STATUS_IS_OK(status
)) {
4243 status
= smbXsrv_pending_break_submit(pb
);
4244 if (!NT_STATUS_IS_OK(status
)) {
4248 return NT_STATUS_OK
;
4251 static NTSTATUS
smbXsrv_pending_break_submit(struct smbXsrv_pending_break
*pb
)
4253 struct smbXsrv_client
*client
= pb
->client
;
4254 struct smbXsrv_session
*session
= NULL
;
4255 struct smbXsrv_connection
*xconn
= NULL
;
4256 struct smbXsrv_connection
*oplock_xconn
= NULL
;
4257 struct tevent_req
*subreq
= NULL
;
4260 if (pb
->session_id
!= 0) {
4261 status
= get_valid_smbXsrv_session(client
,
4264 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
4265 return NT_STATUS_ABANDONED
;
4267 if (!NT_STATUS_IS_OK(status
)) {
4271 if (pb
->last_channel_id
!= 0) {
4273 * This is what current Windows servers
4274 * do, they don't retry on all available
4275 * channels. They only use the last channel.
4277 * But it doesn't match the specification in
4278 * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4281 * Per default disable_oplock_break_retries is false
4282 * and we behave like the specification.
4284 if (pb
->disable_oplock_break_retries
) {
4285 return NT_STATUS_ABANDONED
;
4290 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
4291 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4295 if (xconn
->channel_id
== 0) {
4297 * non-multichannel case
4302 if (session
!= NULL
) {
4303 struct smbXsrv_channel_global0
*c
= NULL
;
4306 * Having a session means we're handling
4307 * an oplock break and we only need to
4308 * use channels available on the
4311 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
4312 if (!NT_STATUS_IS_OK(status
)) {
4317 * This is what current Windows servers
4318 * do, they don't retry on all available
4319 * channels. They only use the last channel.
4321 * But it doesn't match the specification
4322 * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4325 * Per default disable_oplock_break_retries is false
4326 * and we behave like the specification.
4328 if (pb
->disable_oplock_break_retries
) {
4329 oplock_xconn
= xconn
;
4334 if (xconn
->channel_id
> pb
->last_channel_id
) {
4342 if (xconn
== NULL
) {
4343 xconn
= oplock_xconn
;
4346 if (xconn
== NULL
) {
4348 * If there's no remaining connection available
4349 * tell the caller to stop...
4351 return NT_STATUS_ABANDONED
;
4354 pb
->last_channel_id
= xconn
->channel_id
;
4356 subreq
= smbd_smb2_break_send(pb
,
4362 if (subreq
== NULL
) {
4363 return NT_STATUS_NO_MEMORY
;
4365 tevent_req_set_callback(subreq
,
4366 smbXsrv_pending_break_done
,
4369 return NT_STATUS_OK
;
4372 static void smbXsrv_pending_break_done(struct tevent_req
*subreq
)
4374 struct smbXsrv_pending_break
*pb
=
4375 tevent_req_callback_data(subreq
,
4376 struct smbXsrv_pending_break
);
4377 struct smbXsrv_client
*client
= pb
->client
;
4380 status
= smbd_smb2_break_recv(subreq
);
4381 TALLOC_FREE(subreq
);
4382 if (!NT_STATUS_IS_OK(status
)) {
4383 status
= smbXsrv_pending_break_submit(pb
);
4384 if (NT_STATUS_EQUAL(status
, NT_STATUS_ABANDONED
)) {
4386 * If there's no remaining connection
4387 * there's no need to send a break again.
4391 if (!NT_STATUS_IS_OK(status
)) {
4392 smbd_server_disconnect_client(client
, nt_errstr(status
));
4399 DLIST_REMOVE(client
->pending_breaks
, pb
);
4402 status
= smbXsrv_client_pending_breaks_updated(client
);
4403 if (!NT_STATUS_IS_OK(status
)) {
4404 smbd_server_disconnect_client(client
, nt_errstr(status
));
4409 NTSTATUS
smbd_smb2_send_oplock_break(struct smbXsrv_client
*client
,
4410 struct smbXsrv_open
*op
,
4411 uint8_t oplock_level
)
4413 struct smbXsrv_pending_break
*pb
= NULL
;
4414 uint8_t *body
= NULL
;
4416 pb
= smbXsrv_pending_break_create(client
,
4419 return NT_STATUS_NO_MEMORY
;
4421 pb
->body_len
= sizeof(pb
->body
.oplock
);
4422 body
= pb
->body
.oplock
;
4424 SSVAL(body
, 0x00, pb
->body_len
);
4425 SCVAL(body
, 0x02, oplock_level
);
4426 SCVAL(body
, 0x03, 0); /* reserved */
4427 SIVAL(body
, 0x04, 0); /* reserved */
4428 SBVAL(body
, 0x08, op
->global
->open_persistent_id
);
4429 SBVAL(body
, 0x10, op
->global
->open_volatile_id
);
4431 return smbXsrv_pending_break_schedule(pb
);
4434 NTSTATUS
smbd_smb2_send_lease_break(struct smbXsrv_client
*client
,
4436 uint32_t lease_flags
,
4437 struct smb2_lease_key
*lease_key
,
4438 uint32_t current_lease_state
,
4439 uint32_t new_lease_state
)
4441 struct smbXsrv_pending_break
*pb
= NULL
;
4442 uint8_t *body
= NULL
;
4444 pb
= smbXsrv_pending_break_create(client
,
4445 0); /* no session_id */
4447 return NT_STATUS_NO_MEMORY
;
4449 pb
->body_len
= sizeof(pb
->body
.lease
);
4450 body
= pb
->body
.lease
;
4452 SSVAL(body
, 0x00, pb
->body_len
);
4453 SSVAL(body
, 0x02, new_epoch
);
4454 SIVAL(body
, 0x04, lease_flags
);
4455 SBVAL(body
, 0x08, lease_key
->data
[0]);
4456 SBVAL(body
, 0x10, lease_key
->data
[1]);
4457 SIVAL(body
, 0x18, current_lease_state
);
4458 SIVAL(body
, 0x1c, new_lease_state
);
4459 SIVAL(body
, 0x20, 0); /* BreakReason, MUST be 0 */
4460 SIVAL(body
, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4461 SIVAL(body
, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4463 return smbXsrv_pending_break_schedule(pb
);
4466 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state
*state
)
4470 uint64_t file_id_persistent
;
4471 uint64_t file_id_volatile
;
4472 struct smbXsrv_open
*op
= NULL
;
4473 struct files_struct
*fsp
= NULL
;
4474 const uint8_t *body
= NULL
;
4477 * This is only called with a pktbuf
4478 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4482 if (IVAL(state
->pktbuf
, 0) == SMB2_TF_MAGIC
) {
4483 /* Transform header. Cannot recvfile. */
4486 if (IVAL(state
->pktbuf
, 0) != SMB2_MAGIC
) {
4487 /* Not SMB2. Normal error path will cope. */
4490 if (SVAL(state
->pktbuf
, 4) != SMB2_HDR_BODY
) {
4491 /* Not SMB2. Normal error path will cope. */
4494 if (SVAL(state
->pktbuf
, SMB2_HDR_OPCODE
) != SMB2_OP_WRITE
) {
4495 /* Needs to be a WRITE. */
4498 if (IVAL(state
->pktbuf
, SMB2_HDR_NEXT_COMMAND
) != 0) {
4499 /* Chained. Cannot recvfile. */
4502 flags
= IVAL(state
->pktbuf
, SMB2_HDR_FLAGS
);
4503 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
4504 /* Chained. Cannot recvfile. */
4507 if (flags
& SMB2_HDR_FLAG_SIGNED
) {
4508 /* Signed. Cannot recvfile. */
4512 body
= &state
->pktbuf
[SMB2_HDR_BODY
];
4514 file_id_persistent
= BVAL(body
, 0x10);
4515 file_id_volatile
= BVAL(body
, 0x18);
4517 status
= smb2srv_open_lookup(state
->req
->xconn
,
4522 if (!NT_STATUS_IS_OK(status
)) {
4530 if (fsp
->conn
== NULL
) {
4534 if (IS_IPC(fsp
->conn
)) {
4537 if (IS_PRINT(fsp
->conn
)) {
4540 if (fsp_is_alternate_stream(fsp
)) {
4544 DEBUG(10,("Doing recvfile write len = %u\n",
4545 (unsigned int)(state
->pktfull
- state
->pktlen
)));
4550 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
)
4552 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
4553 struct smbd_smb2_request
*req
= NULL
;
4554 size_t max_send_queue_len
;
4555 size_t cur_send_queue_len
;
4557 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4559 * we're not supposed to do any io
4561 return NT_STATUS_OK
;
4564 if (state
->req
!= NULL
) {
4566 * if there is already a tstream_readv_pdu
4567 * pending, we are done.
4569 return NT_STATUS_OK
;
4572 max_send_queue_len
= MAX(1, xconn
->smb2
.credits
.max
/16);
4573 cur_send_queue_len
= xconn
->smb2
.send_queue_len
;
4575 if (cur_send_queue_len
> max_send_queue_len
) {
4577 * if we have a lot of requests to send,
4578 * we wait until they are on the wire until we
4579 * ask for the next request.
4581 return NT_STATUS_OK
;
4584 /* ask for the next request */
4585 req
= smbd_smb2_request_allocate(xconn
);
4587 return NT_STATUS_NO_MEMORY
;
4589 *state
= (struct smbd_smb2_request_read_state
) {
4591 .min_recv_size
= lp_min_receive_file_size(),
4593 [0] = (struct iovec
) {
4594 .iov_base
= (void *)state
->hdr
.nbt
,
4595 .iov_len
= NBT_HDR_SIZE
,
4598 .vector
= state
->_vector
,
4602 TEVENT_FD_READABLE(xconn
->transport
.fde
);
4604 return NT_STATUS_OK
;
4607 NTSTATUS
smbd_smb2_process_negprot(struct smbXsrv_connection
*xconn
,
4608 uint64_t expected_seq_low
,
4609 const uint8_t *inpdu
, size_t size
)
4611 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
4613 struct smbd_smb2_request
*req
= NULL
;
4615 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4616 (unsigned int)size
));
4618 status
= smbd_initialize_smb2(xconn
, expected_seq_low
);
4619 if (!NT_STATUS_IS_OK(status
)) {
4620 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4625 * If a new connection joins the process, when we're
4626 * already in a "pending break cycle", we need to
4627 * turn on the ack checker on the new connection.
4629 status
= smbXsrv_client_pending_breaks_updated(xconn
->client
);
4630 if (!NT_STATUS_IS_OK(status
)) {
4632 * If there's a problem, we disconnect the whole
4633 * client with all connections here!
4635 * Instead of just the new connection.
4637 smbd_server_disconnect_client(xconn
->client
, nt_errstr(status
));
4641 status
= smbd_smb2_request_create(xconn
, inpdu
, size
, &req
);
4642 if (!NT_STATUS_IS_OK(status
)) {
4643 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4647 status
= smbd_smb2_request_validate(req
);
4648 if (!NT_STATUS_IS_OK(status
)) {
4649 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4653 status
= smbd_smb2_request_setup_out(req
);
4654 if (!NT_STATUS_IS_OK(status
)) {
4655 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4661 * this was already counted at the SMB1 layer =>
4662 * smbd_smb2_request_dispatch() should not count it twice.
4664 if (profile_p
->values
.request_stats
.count
> 0) {
4665 profile_p
->values
.request_stats
.count
--;
4668 status
= smbd_smb2_request_dispatch(req
);
4669 if (!NT_STATUS_IS_OK(status
)) {
4670 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4674 status
= smbd_smb2_request_next_incoming(xconn
);
4675 if (!NT_STATUS_IS_OK(status
)) {
4676 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4680 sconn
->num_requests
++;
4681 return NT_STATUS_OK
;
4684 static int socket_error_from_errno(int ret
,
4698 if (sys_errno
== 0) {
4702 if (sys_errno
== EINTR
) {
4707 if (sys_errno
== EINPROGRESS
) {
4712 if (sys_errno
== EAGAIN
) {
4717 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4718 if (sys_errno
== ENOMEM
) {
4724 #if EWOULDBLOCK != EAGAIN
4725 if (sys_errno
== EWOULDBLOCK
) {
4735 static NTSTATUS
smbd_smb2_advance_send_queue(struct smbXsrv_connection
*xconn
,
4736 struct smbd_smb2_send_queue
**_e
,
4739 struct smbd_smb2_send_queue
*e
= *_e
;
4742 xconn
->ack
.unacked_bytes
+= n
;
4744 ok
= iov_advance(&e
->vector
, &e
->count
, n
);
4746 return NT_STATUS_INTERNAL_ERROR
;
4750 return NT_STATUS_RETRY
;
4753 xconn
->smb2
.send_queue_len
--;
4754 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4756 if (e
->ack
.req
== NULL
) {
4758 talloc_free(e
->mem_ctx
);
4759 return NT_STATUS_OK
;
4762 e
->ack
.required_acked_bytes
= xconn
->ack
.unacked_bytes
;
4763 DLIST_ADD_END(xconn
->ack
.queue
, e
);
4765 return NT_STATUS_OK
;
4768 static NTSTATUS
smbd_smb2_flush_with_sendmsg(struct smbXsrv_connection
*xconn
)
4775 if (xconn
->smb2
.send_queue
== NULL
) {
4776 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
4777 return NT_STATUS_OK
;
4780 while (xconn
->smb2
.send_queue
!= NULL
) {
4781 struct smbd_smb2_send_queue
*e
= xconn
->smb2
.send_queue
;
4782 unsigned sendmsg_flags
= 0;
4784 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4786 * we're not supposed to do any io
4787 * just flush all pending stuff.
4789 xconn
->smb2
.send_queue_len
--;
4790 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4792 talloc_free(e
->mem_ctx
);
4796 if (e
->sendfile_header
!= NULL
) {
4801 status
= NT_STATUS_INTERNAL_ERROR
;
4803 for (i
=0; i
< e
->count
; i
++) {
4804 size
+= e
->vector
[i
].iov_len
;
4807 if (size
<= e
->sendfile_header
->length
) {
4808 buf
= e
->sendfile_header
->data
;
4810 buf
= talloc_array(e
->mem_ctx
, uint8_t, size
);
4812 return NT_STATUS_NO_MEMORY
;
4817 for (i
=0; i
< e
->count
; i
++) {
4819 e
->vector
[i
].iov_base
,
4820 e
->vector
[i
].iov_len
);
4821 size
+= e
->vector
[i
].iov_len
;
4824 e
->sendfile_header
->data
= buf
;
4825 e
->sendfile_header
->length
= size
;
4826 e
->sendfile_status
= &status
;
4829 xconn
->smb2
.send_queue_len
--;
4830 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4832 size
+= e
->sendfile_body_size
;
4835 * This triggers the sendfile path via
4838 talloc_free(e
->mem_ctx
);
4840 if (!NT_STATUS_IS_OK(status
)) {
4841 smbXsrv_connection_disconnect_transport(xconn
,
4845 xconn
->ack
.unacked_bytes
+= size
;
4849 e
->msg
= (struct msghdr
) {
4850 .msg_iov
= e
->vector
,
4851 .msg_iovlen
= e
->count
,
4855 sendmsg_flags
|= MSG_NOSIGNAL
;
4858 sendmsg_flags
|= MSG_DONTWAIT
;
4861 ret
= sendmsg(xconn
->transport
.sock
, &e
->msg
, sendmsg_flags
);
4863 /* propagate end of file */
4864 return NT_STATUS_INTERNAL_ERROR
;
4866 err
= socket_error_from_errno(ret
, errno
, &retry
);
4869 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
4870 return NT_STATUS_OK
;
4873 status
= map_nt_error_from_unix_common(err
);
4874 smbXsrv_connection_disconnect_transport(xconn
,
4879 status
= smbd_smb2_advance_send_queue(xconn
, &e
, ret
);
4880 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
4882 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
4883 return NT_STATUS_OK
;
4885 if (!NT_STATUS_IS_OK(status
)) {
4886 smbXsrv_connection_disconnect_transport(xconn
,
4892 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
4895 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
)
4899 status
= smbd_smb2_flush_with_sendmsg(xconn
);
4900 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
4905 * Restart reads if we were blocked on
4906 * draining the send queue.
4909 status
= smbd_smb2_request_next_incoming(xconn
);
4910 if (!NT_STATUS_IS_OK(status
)) {
4914 return NT_STATUS_OK
;
4917 static NTSTATUS
smbd_smb2_advance_incoming(struct smbXsrv_connection
*xconn
, size_t n
)
4919 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
4920 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
4921 struct smbd_smb2_request
*req
= NULL
;
4922 size_t min_recvfile_size
= UINT32_MAX
;
4927 ok
= iov_advance(&state
->vector
, &state
->count
, n
);
4929 return NT_STATUS_INTERNAL_ERROR
;
4932 if (state
->count
> 0) {
4933 return NT_STATUS_PENDING
;
4936 if (state
->pktlen
> 0) {
4937 if (!state
->doing_receivefile
) {
4939 * we have all the data.
4944 if (!is_smb2_recvfile_write(state
)) {
4945 size_t ofs
= state
->pktlen
;
4948 * Not a possible receivefile write.
4949 * Read the rest of the data.
4951 state
->doing_receivefile
= false;
4953 state
->pktbuf
= talloc_realloc(state
->req
,
4957 if (state
->pktbuf
== NULL
) {
4958 return NT_STATUS_NO_MEMORY
;
4961 state
->_vector
[0] = (struct iovec
) {
4962 .iov_base
= (void *)(state
->pktbuf
+ ofs
),
4963 .iov_len
= (state
->pktfull
- ofs
),
4965 state
->vector
= state
->_vector
;
4968 state
->pktlen
= state
->pktfull
;
4969 return NT_STATUS_RETRY
;
4973 * This is a receivefile write so we've
4974 * done a short read.
4980 * Now we analyze the NBT header
4982 if (state
->hdr
.nbt
[0] != 0x00) {
4983 state
->min_recv_size
= 0;
4985 state
->pktfull
= smb2_len(state
->hdr
.nbt
);
4986 if (state
->pktfull
== 0) {
4990 if (state
->min_recv_size
!= 0) {
4991 min_recvfile_size
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
4992 min_recvfile_size
+= state
->min_recv_size
;
4995 if (state
->pktfull
> min_recvfile_size
) {
4997 * Might be a receivefile write. Read the SMB2 HEADER +
4998 * SMB2_WRITE header first. Set 'doing_receivefile'
4999 * as we're *attempting* receivefile write. If this
5000 * turns out not to be a SMB2_WRITE request or otherwise
5001 * not suitable then we'll just read the rest of the data
5002 * the next time this function is called.
5004 state
->pktlen
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
5005 state
->doing_receivefile
= true;
5007 state
->pktlen
= state
->pktfull
;
5010 state
->pktbuf
= talloc_array(state
->req
, uint8_t, state
->pktlen
);
5011 if (state
->pktbuf
== NULL
) {
5012 return NT_STATUS_NO_MEMORY
;
5015 state
->_vector
[0] = (struct iovec
) {
5016 .iov_base
= (void *)state
->pktbuf
,
5017 .iov_len
= state
->pktlen
,
5019 state
->vector
= state
->_vector
;
5022 return NT_STATUS_RETRY
;
5026 if (state
->hdr
.nbt
[0] != 0x00) {
5027 DEBUG(1,("ignore NBT[0x%02X] msg\n",
5028 state
->hdr
.nbt
[0]));
5031 *state
= (struct smbd_smb2_request_read_state
) {
5033 .min_recv_size
= lp_min_receive_file_size(),
5035 [0] = (struct iovec
) {
5036 .iov_base
= (void *)state
->hdr
.nbt
,
5037 .iov_len
= NBT_HDR_SIZE
,
5040 .vector
= state
->_vector
,
5043 return NT_STATUS_RETRY
;
5048 req
->request_time
= timeval_current();
5049 now
= timeval_to_nttime(&req
->request_time
);
5051 status
= smbd_smb2_inbuf_parse_compound(xconn
,
5057 &req
->in
.vector_count
);
5058 if (!NT_STATUS_IS_OK(status
)) {
5062 if (state
->doing_receivefile
) {
5063 req
->smb1req
= talloc_zero(req
, struct smb_request
);
5064 if (req
->smb1req
== NULL
) {
5065 return NT_STATUS_NO_MEMORY
;
5067 req
->smb1req
->unread_bytes
= state
->pktfull
- state
->pktlen
;
5070 *state
= (struct smbd_smb2_request_read_state
) {
5074 req
->current_idx
= 1;
5076 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
5077 req
->current_idx
, req
->in
.vector_count
));
5079 status
= smbd_smb2_request_validate(req
);
5080 if (!NT_STATUS_IS_OK(status
)) {
5084 status
= smbd_smb2_request_setup_out(req
);
5085 if (!NT_STATUS_IS_OK(status
)) {
5089 status
= smbd_smb2_request_dispatch(req
);
5090 if (!NT_STATUS_IS_OK(status
)) {
5094 sconn
->num_requests
++;
5096 /* The timeout_processing function isn't run nearly
5097 often enough to implement 'max log size' without
5098 overrunning the size of the file by many megabytes.
5099 This is especially true if we are running at debug
5100 level 10. Checking every 50 SMB2s is a nice
5101 tradeoff of performance vs log file size overrun. */
5103 if ((sconn
->num_requests
% 50) == 0 &&
5104 need_to_check_log_size()) {
5105 change_to_root_user();
5109 status
= smbd_smb2_request_next_incoming(xconn
);
5110 if (!NT_STATUS_IS_OK(status
)) {
5114 return NT_STATUS_OK
;
5117 static NTSTATUS
smbd_smb2_io_handler(struct smbXsrv_connection
*xconn
,
5120 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
5121 unsigned recvmsg_flags
= 0;
5127 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
5129 * we're not supposed to do any io
5131 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
5132 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
5133 return NT_STATUS_OK
;
5136 if (fde_flags
& TEVENT_FD_WRITE
) {
5137 status
= smbd_smb2_flush_send_queue(xconn
);
5138 if (!NT_STATUS_IS_OK(status
)) {
5143 if (!(fde_flags
& TEVENT_FD_READ
)) {
5144 return NT_STATUS_OK
;
5147 if (state
->req
== NULL
) {
5148 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
5149 return NT_STATUS_OK
;
5154 state
->msg
= (struct msghdr
) {
5155 .msg_iov
= state
->vector
,
5156 .msg_iovlen
= state
->count
,
5160 recvmsg_flags
|= MSG_NOSIGNAL
;
5163 recvmsg_flags
|= MSG_DONTWAIT
;
5166 ret
= recvmsg(xconn
->transport
.sock
, &state
->msg
, recvmsg_flags
);
5168 /* propagate end of file */
5169 status
= NT_STATUS_END_OF_FILE
;
5170 smbXsrv_connection_disconnect_transport(xconn
,
5174 err
= socket_error_from_errno(ret
, errno
, &retry
);
5177 TEVENT_FD_READABLE(xconn
->transport
.fde
);
5178 return NT_STATUS_OK
;
5181 status
= map_nt_error_from_unix_common(err
);
5182 smbXsrv_connection_disconnect_transport(xconn
,
5187 status
= smbd_smb2_advance_incoming(xconn
, ret
);
5188 if (NT_STATUS_EQUAL(status
, NT_STATUS_PENDING
)) {
5189 /* we have more to read */
5190 TEVENT_FD_READABLE(xconn
->transport
.fde
);
5191 return NT_STATUS_OK
;
5193 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
5195 * smbd_smb2_advance_incoming setup a new vector
5196 * that we should try to read immediately.
5200 if (!NT_STATUS_IS_OK(status
)) {
5204 return NT_STATUS_OK
;
5207 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
5208 struct tevent_fd
*fde
,
5212 struct smbXsrv_connection
*xconn
=
5213 talloc_get_type_abort(private_data
,
5214 struct smbXsrv_connection
);
5217 status
= smbd_smb2_io_handler(xconn
, flags
);
5218 if (!NT_STATUS_IS_OK(status
)) {
5219 smbd_server_connection_terminate(xconn
, nt_errstr(status
));