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 "../libcli/smb/smb_common.h"
27 #include "../lib/tsocket/tsocket.h"
28 #include "../lib/util/tevent_ntstatus.h"
29 #include "smbprofile.h"
30 #include "../lib/util/bitmap.h"
31 #include "../librpc/gen_ndr/krb5pac.h"
32 #include "lib/util/iov_buf.h"
34 #include "libcli/smb/smbXcli_base.h"
37 /* SIOCOUTQ TIOCOUTQ are the same */
38 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
39 #define __HAVE_TCP_INFO_RTO 1
40 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
41 #elif defined(FREEBSD)
42 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
43 #define __HAVE_TCP_INFO_RTO 1
44 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
47 #include "lib/crypto/gnutls_helpers.h"
48 #include <gnutls/gnutls.h>
49 #include <gnutls/crypto.h>
52 #define DBGC_CLASS DBGC_SMB2
54 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
55 struct tevent_fd
*fde
,
58 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
);
60 static const struct smbd_smb2_dispatch_table
{
67 bool allow_invalid_fileid
;
69 } smbd_smb2_table
[] = {
70 #define _OP(o) .opcode = o, .name = #o
75 _OP(SMB2_OP_SESSSETUP
),
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.
103 .need_session
= true,
108 .need_session
= true,
113 .need_session
= true,
118 .need_session
= true,
124 .need_session
= true,
129 .need_session
= true,
132 .allow_invalid_fileid
= true,
138 _OP(SMB2_OP_KEEPALIVE
),
141 _OP(SMB2_OP_QUERY_DIRECTORY
),
142 .need_session
= true,
147 .need_session
= true,
151 _OP(SMB2_OP_GETINFO
),
152 .need_session
= true,
156 _OP(SMB2_OP_SETINFO
),
157 .need_session
= true,
163 .need_session
= true,
168 * as LEASE breaks does not
174 const char *smb2_opcode_name(uint16_t opcode
)
176 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
177 return "Bad SMB2 opcode";
179 return smbd_smb2_table
[opcode
].name
;
182 static const struct smbd_smb2_dispatch_table
*smbd_smb2_call(uint16_t opcode
)
184 const struct smbd_smb2_dispatch_table
*ret
= NULL
;
186 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
190 ret
= &smbd_smb2_table
[opcode
];
192 SMB_ASSERT(ret
->opcode
== opcode
);
197 static void print_req_vectors(const struct smbd_smb2_request
*req
)
201 for (i
= 0; i
< req
->in
.vector_count
; i
++) {
202 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
204 (unsigned int)req
->in
.vector
[i
].iov_len
);
206 for (i
= 0; i
< req
->out
.vector_count
; i
++) {
207 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
209 (unsigned int)req
->out
.vector
[i
].iov_len
);
213 bool smbd_is_smb2_header(const uint8_t *inbuf
, size_t size
)
215 if (size
< (4 + SMB2_HDR_BODY
)) {
219 if (IVAL(inbuf
, 4) != SMB2_MAGIC
) {
226 bool smbd_smb2_is_compound(const struct smbd_smb2_request
*req
)
228 return req
->in
.vector_count
>= (2*SMBD_SMB2_NUM_IOV_PER_REQ
);
231 static NTSTATUS
smbd_initialize_smb2(struct smbXsrv_connection
*xconn
,
232 uint64_t expected_seq_low
)
236 xconn
->smb2
.credits
.seq_low
= expected_seq_low
;
237 xconn
->smb2
.credits
.seq_range
= 1;
238 xconn
->smb2
.credits
.granted
= 1;
239 xconn
->smb2
.credits
.max
= lp_smb2_max_credits();
240 xconn
->smb2
.credits
.bitmap
= bitmap_talloc(xconn
,
241 xconn
->smb2
.credits
.max
);
242 if (xconn
->smb2
.credits
.bitmap
== NULL
) {
243 return NT_STATUS_NO_MEMORY
;
246 tevent_fd_set_close_fn(xconn
->transport
.fde
, NULL
);
247 TALLOC_FREE(xconn
->transport
.fde
);
249 xconn
->transport
.fde
= tevent_add_fd(
250 xconn
->client
->raw_ev_ctx
,
252 xconn
->transport
.sock
,
254 smbd_smb2_connection_handler
,
256 if (xconn
->transport
.fde
== NULL
) {
257 close(xconn
->transport
.sock
);
258 xconn
->transport
.sock
= -1;
259 return NT_STATUS_NO_MEMORY
;
261 tevent_fd_set_auto_close(xconn
->transport
.fde
);
263 /* Ensure child is set to non-blocking mode */
264 rc
= set_blocking(xconn
->transport
.sock
, false);
266 return NT_STATUS_INTERNAL_ERROR
;
272 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
273 #define _smb2_setlen(_buf,len) do { \
274 uint8_t *buf = (uint8_t *)_buf; \
276 buf[1] = ((len)&0xFF0000)>>16; \
277 buf[2] = ((len)&0xFF00)>>8; \
278 buf[3] = (len)&0xFF; \
281 static bool smb2_setup_nbt_length(struct iovec
*vector
, int count
)
289 len
= iov_buflen(vector
+1, count
-1);
291 if ((len
== -1) || (len
> 0xFFFFFF)) {
295 _smb2_setlen(vector
[0].iov_base
, len
);
299 static int smbd_smb2_request_destructor(struct smbd_smb2_request
*req
)
301 if (req
->first_key
.length
> 0) {
302 data_blob_clear_free(&req
->first_key
);
304 if (req
->last_key
.length
> 0) {
305 data_blob_clear_free(&req
->last_key
);
310 void smb2_request_set_async_internal(struct smbd_smb2_request
*req
,
313 req
->async_internal
= async_internal
;
316 static struct smbd_smb2_request
*smbd_smb2_request_allocate(TALLOC_CTX
*mem_ctx
)
318 TALLOC_CTX
*mem_pool
;
319 struct smbd_smb2_request
*req
;
322 /* Enable this to find subtle valgrind errors. */
323 mem_pool
= talloc_init("smbd_smb2_request_allocate");
325 mem_pool
= talloc_tos();
327 if (mem_pool
== NULL
) {
331 req
= talloc_zero(mem_pool
, struct smbd_smb2_request
);
333 talloc_free(mem_pool
);
336 talloc_reparent(mem_pool
, mem_ctx
, req
);
338 TALLOC_FREE(mem_pool
);
341 req
->last_session_id
= UINT64_MAX
;
342 req
->last_tid
= UINT32_MAX
;
344 talloc_set_destructor(req
, smbd_smb2_request_destructor
);
349 static NTSTATUS
smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection
*xconn
,
353 struct smbd_smb2_request
*req
,
357 TALLOC_CTX
*mem_ctx
= req
;
361 uint8_t *first_hdr
= buf
;
362 size_t verified_buflen
= 0;
367 * Note: index '0' is reserved for the transport protocol
369 iov
= req
->in
._vector
;
371 while (taken
< buflen
) {
372 size_t len
= buflen
- taken
;
373 uint8_t *hdr
= first_hdr
+ taken
;
376 size_t next_command_ofs
;
378 uint8_t *body
= NULL
;
381 struct iovec
*iov_alloc
= NULL
;
383 if (iov
!= req
->in
._vector
) {
387 if (verified_buflen
> taken
) {
388 len
= verified_buflen
- taken
;
395 DEBUG(10, ("%d bytes left, expected at least %d\n",
399 if (IVAL(hdr
, 0) == SMB2_TF_MAGIC
) {
400 struct smbXsrv_session
*s
= NULL
;
402 struct iovec tf_iov
[2];
406 if (xconn
->protocol
< PROTOCOL_SMB2_24
) {
407 DEBUG(10, ("Got SMB2_TRANSFORM header, "
408 "but dialect[0x%04X] is used\n",
409 xconn
->smb2
.server
.dialect
));
413 if (xconn
->smb2
.server
.cipher
== 0) {
414 DEBUG(10, ("Got SMB2_TRANSFORM header, "
415 "but not negotiated "
416 "client[0x%08X] server[0x%08X]\n",
417 xconn
->smb2
.client
.capabilities
,
418 xconn
->smb2
.server
.capabilities
));
422 if (len
< SMB2_TF_HDR_SIZE
) {
423 DEBUG(1, ("%d bytes left, expected at least %d\n",
424 (int)len
, SMB2_TF_HDR_SIZE
));
428 tf_len
= SMB2_TF_HDR_SIZE
;
431 hdr
= first_hdr
+ taken
;
432 enc_len
= IVAL(tf
, SMB2_TF_MSG_SIZE
);
433 uid
= BVAL(tf
, SMB2_TF_SESSION_ID
);
435 if (len
< SMB2_TF_HDR_SIZE
+ enc_len
) {
436 DEBUG(1, ("%d bytes left, expected at least %d\n",
438 (int)(SMB2_TF_HDR_SIZE
+ enc_len
)));
442 status
= smb2srv_session_lookup_conn(xconn
, uid
, now
,
445 DEBUG(1, ("invalid session[%llu] in "
446 "SMB2_TRANSFORM header\n",
447 (unsigned long long)uid
));
448 TALLOC_FREE(iov_alloc
);
449 return NT_STATUS_USER_SESSION_DELETED
;
452 tf_iov
[0].iov_base
= (void *)tf
;
453 tf_iov
[0].iov_len
= tf_len
;
454 tf_iov
[1].iov_base
= (void *)hdr
;
455 tf_iov
[1].iov_len
= enc_len
;
457 status
= smb2_signing_decrypt_pdu(s
->global
->decryption_key
,
458 xconn
->smb2
.server
.cipher
,
460 if (!NT_STATUS_IS_OK(status
)) {
461 TALLOC_FREE(iov_alloc
);
465 verified_buflen
= taken
+ enc_len
;
470 * We need the header plus the body length field
473 if (len
< SMB2_HDR_BODY
+ 2) {
476 (IVAL(hdr
, 0) == SMB_SUICIDE_PACKET
) &&
477 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
478 uint8_t exitcode
= CVAL(hdr
, 4);
479 DBG_WARNING("SUICIDE: Exiting immediately "
480 "with code %"PRIu8
"\n",
485 DEBUG(10, ("%d bytes left, expected at least %d\n",
486 (int)len
, SMB2_HDR_BODY
));
489 if (IVAL(hdr
, 0) != SMB2_MAGIC
) {
490 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
494 if (SVAL(hdr
, 4) != SMB2_HDR_BODY
) {
495 DEBUG(10, ("Got HDR len %d, expected %d\n",
496 SVAL(hdr
, 4), SMB2_HDR_BODY
));
501 next_command_ofs
= IVAL(hdr
, SMB2_HDR_NEXT_COMMAND
);
502 body_size
= SVAL(hdr
, SMB2_HDR_BODY
);
504 if (next_command_ofs
!= 0) {
505 if (next_command_ofs
< (SMB2_HDR_BODY
+ 2)) {
508 if (next_command_ofs
> full_size
) {
511 full_size
= next_command_ofs
;
518 if (body_size
> (full_size
- SMB2_HDR_BODY
)) {
520 * let the caller handle the error
522 body_size
= full_size
- SMB2_HDR_BODY
;
524 body
= hdr
+ SMB2_HDR_BODY
;
525 dyn
= body
+ body_size
;
526 dyn_size
= full_size
- (SMB2_HDR_BODY
+ body_size
);
528 if (num_iov
>= ARRAY_SIZE(req
->in
._vector
)) {
529 struct iovec
*iov_tmp
= NULL
;
531 iov_tmp
= talloc_realloc(mem_ctx
, iov_alloc
,
534 SMBD_SMB2_NUM_IOV_PER_REQ
);
535 if (iov_tmp
== NULL
) {
536 TALLOC_FREE(iov_alloc
);
537 return NT_STATUS_NO_MEMORY
;
540 if (iov_alloc
== NULL
) {
543 sizeof(req
->in
._vector
));
549 num_iov
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
551 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
552 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
553 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
554 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
555 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
556 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= body_size
;
557 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
558 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= dyn_size
;
568 if (iov
!= req
->in
._vector
) {
571 return NT_STATUS_INVALID_PARAMETER
;
574 static NTSTATUS
smbd_smb2_request_create(struct smbXsrv_connection
*xconn
,
575 const uint8_t *_inpdu
, size_t size
,
576 struct smbd_smb2_request
**_req
)
578 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
579 struct smbd_smb2_request
*req
;
580 uint32_t protocol_version
;
581 uint8_t *inpdu
= NULL
;
582 const uint8_t *inhdr
= NULL
;
584 uint32_t next_command_ofs
;
588 if (size
< (SMB2_HDR_BODY
+ 2)) {
589 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size
));
590 return NT_STATUS_INVALID_PARAMETER
;
595 protocol_version
= IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
);
596 if (protocol_version
!= SMB2_MAGIC
) {
597 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
599 return NT_STATUS_INVALID_PARAMETER
;
602 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
603 if (cmd
!= SMB2_OP_NEGPROT
) {
604 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
606 return NT_STATUS_INVALID_PARAMETER
;
609 next_command_ofs
= IVAL(inhdr
, SMB2_HDR_NEXT_COMMAND
);
610 if (next_command_ofs
!= 0) {
611 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
613 return NT_STATUS_INVALID_PARAMETER
;
616 req
= smbd_smb2_request_allocate(xconn
);
618 return NT_STATUS_NO_MEMORY
;
623 inpdu
= talloc_memdup(req
, _inpdu
, size
);
625 return NT_STATUS_NO_MEMORY
;
628 req
->request_time
= timeval_current();
629 now
= timeval_to_nttime(&req
->request_time
);
631 status
= smbd_smb2_inbuf_parse_compound(xconn
,
635 req
, &req
->in
.vector
,
636 &req
->in
.vector_count
);
637 if (!NT_STATUS_IS_OK(status
)) {
642 req
->current_idx
= 1;
648 static bool smb2_validate_sequence_number(struct smbXsrv_connection
*xconn
,
649 uint64_t message_id
, uint64_t seq_id
)
651 struct bitmap
*credits_bm
= xconn
->smb2
.credits
.bitmap
;
655 seq_tmp
= xconn
->smb2
.credits
.seq_low
;
656 if (seq_id
< seq_tmp
) {
657 DBGC_ERR(DBGC_SMB2_CREDITS
,
658 "smb2_validate_sequence_number: bad message_id "
659 "%llu (sequence id %llu) "
660 "(granted = %u, low = %llu, range = %u)\n",
661 (unsigned long long)message_id
,
662 (unsigned long long)seq_id
,
663 (unsigned int)xconn
->smb2
.credits
.granted
,
664 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
665 (unsigned int)xconn
->smb2
.credits
.seq_range
);
669 seq_tmp
+= xconn
->smb2
.credits
.seq_range
;
670 if (seq_id
>= seq_tmp
) {
671 DBGC_ERR(DBGC_SMB2_CREDITS
,
672 "smb2_validate_sequence_number: bad message_id "
673 "%llu (sequence id %llu) "
674 "(granted = %u, low = %llu, range = %u)\n",
675 (unsigned long long)message_id
,
676 (unsigned long long)seq_id
,
677 (unsigned int)xconn
->smb2
.credits
.granted
,
678 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
679 (unsigned int)xconn
->smb2
.credits
.seq_range
);
683 offset
= seq_id
% xconn
->smb2
.credits
.max
;
685 if (bitmap_query(credits_bm
, offset
)) {
686 DBGC_ERR(DBGC_SMB2_CREDITS
,
687 "smb2_validate_sequence_number: duplicate message_id "
688 "%llu (sequence id %llu) "
689 "(granted = %u, low = %llu, range = %u) "
691 (unsigned long long)message_id
,
692 (unsigned long long)seq_id
,
693 (unsigned int)xconn
->smb2
.credits
.granted
,
694 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
695 (unsigned int)xconn
->smb2
.credits
.seq_range
,
700 /* Mark the message_ids as seen in the bitmap. */
701 bitmap_set(credits_bm
, offset
);
703 if (seq_id
!= xconn
->smb2
.credits
.seq_low
) {
708 * Move the window forward by all the message_id's
711 while (bitmap_query(credits_bm
, offset
)) {
712 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
713 "smb2_validate_sequence_number: clearing "
714 "id %llu (position %u) from bitmap\n",
715 (unsigned long long)(xconn
->smb2
.credits
.seq_low
),
717 bitmap_clear(credits_bm
, offset
);
719 xconn
->smb2
.credits
.seq_low
+= 1;
720 xconn
->smb2
.credits
.seq_range
-= 1;
721 offset
= xconn
->smb2
.credits
.seq_low
% xconn
->smb2
.credits
.max
;
727 static bool smb2_validate_message_id(struct smbXsrv_connection
*xconn
,
728 const uint8_t *inhdr
)
730 uint64_t message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
731 uint16_t opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
732 uint16_t credit_charge
= 1;
735 if (opcode
== SMB2_OP_CANCEL
) {
736 /* SMB2_CANCEL requests by definition resend messageids. */
740 if (xconn
->smb2
.credits
.multicredit
) {
741 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
742 credit_charge
= MAX(credit_charge
, 1);
747 ("smb2_validate_message_id: mid %llu (charge %llu), "
748 "credits_granted %llu, "
749 "seqnum low/range: %llu/%llu\n",
750 (unsigned long long) message_id
,
751 (unsigned long long) credit_charge
,
752 (unsigned long long) xconn
->smb2
.credits
.granted
,
753 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
754 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
756 if (xconn
->smb2
.credits
.granted
< credit_charge
) {
757 DBGC_ERR(DBGC_SMB2_CREDITS
,
758 "smb2_validate_message_id: client used more "
759 "credits than granted, mid %llu, charge %llu, "
760 "credits_granted %llu, "
761 "seqnum low/range: %llu/%llu\n",
762 (unsigned long long) message_id
,
763 (unsigned long long) credit_charge
,
764 (unsigned long long) xconn
->smb2
.credits
.granted
,
765 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
766 (unsigned long long) xconn
->smb2
.credits
.seq_range
);
771 * now check the message ids
773 * for multi-credit requests we need to check all current mid plus
774 * the implicit mids caused by the credit charge
775 * e.g. current mid = 15, charge 5 => mark 15-19 as used
778 for (i
= 0; i
<= (credit_charge
-1); i
++) {
779 uint64_t id
= message_id
+ i
;
784 ("Iterating mid %llu charge %u (sequence %llu)\n",
785 (unsigned long long)message_id
,
787 (unsigned long long)id
));
789 ok
= smb2_validate_sequence_number(xconn
, message_id
, id
);
795 /* substract used credits */
796 xconn
->smb2
.credits
.granted
-= credit_charge
;
801 static NTSTATUS
smbd_smb2_request_validate(struct smbd_smb2_request
*req
)
806 count
= req
->in
.vector_count
;
808 if (count
< 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
809 /* It's not a SMB2 request */
810 return NT_STATUS_INVALID_PARAMETER
;
813 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
814 struct iovec
*hdr
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
815 struct iovec
*body
= SMBD_SMB2_IDX_BODY_IOV(req
,in
,idx
);
816 const uint8_t *inhdr
= NULL
;
818 if (hdr
->iov_len
!= SMB2_HDR_BODY
) {
819 return NT_STATUS_INVALID_PARAMETER
;
822 if (body
->iov_len
< 2) {
823 return NT_STATUS_INVALID_PARAMETER
;
826 inhdr
= (const uint8_t *)hdr
->iov_base
;
828 /* Check the SMB2 header */
829 if (IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
) != SMB2_MAGIC
) {
830 return NT_STATUS_INVALID_PARAMETER
;
833 if (!smb2_validate_message_id(req
->xconn
, inhdr
)) {
834 return NT_STATUS_INVALID_PARAMETER
;
841 static void smb2_set_operation_credit(struct smbXsrv_connection
*xconn
,
842 const struct iovec
*in_vector
,
843 struct iovec
*out_vector
)
845 const uint8_t *inhdr
= (const uint8_t *)in_vector
->iov_base
;
846 uint8_t *outhdr
= (uint8_t *)out_vector
->iov_base
;
847 uint16_t credit_charge
= 1;
848 uint16_t credits_requested
;
852 uint16_t credits_granted
= 0;
853 uint64_t credits_possible
;
854 uint16_t current_max_credits
;
857 * first we grant only 1/16th of the max range.
859 * Windows also starts with the 1/16th and then grants
860 * more later. I was only able to trigger higher
861 * values, when using a very high credit charge.
863 * TODO: scale up depending on load, free memory
865 * Maybe also on the relationship between number
866 * of requests and the used sequence number.
867 * Which means we would grant more credits
868 * for client which use multi credit requests.
870 * The above is what Windows Server < 2016 is doing,
871 * but new servers use all credits (8192 by default).
873 current_max_credits
= xconn
->smb2
.credits
.max
;
874 current_max_credits
= MAX(current_max_credits
, 1);
876 if (xconn
->smb2
.credits
.multicredit
) {
877 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
878 credit_charge
= MAX(credit_charge
, 1);
881 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
882 credits_requested
= SVAL(inhdr
, SMB2_HDR_CREDIT
);
883 credits_requested
= MAX(credits_requested
, 1);
884 out_flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
885 out_status
= NT_STATUS(IVAL(outhdr
, SMB2_HDR_STATUS
));
887 SMB_ASSERT(xconn
->smb2
.credits
.max
>= xconn
->smb2
.credits
.granted
);
889 if (xconn
->smb2
.credits
.max
< credit_charge
) {
890 smbd_server_connection_terminate(xconn
,
891 "client error: credit charge > max credits\n");
895 if (out_flags
& SMB2_HDR_FLAG_ASYNC
) {
897 * In case we already send an async interim
898 * response, we should not grant
899 * credits on the final response.
903 uint16_t additional_possible
=
904 xconn
->smb2
.credits
.max
- credit_charge
;
905 uint16_t additional_max
= 0;
906 uint16_t additional_credits
= credits_requested
- 1;
909 case SMB2_OP_NEGPROT
:
911 case SMB2_OP_SESSSETUP
:
913 * Windows 2012 RC1 starts to grant
915 * with a successful session setup
917 if (NT_STATUS_IS_OK(out_status
)) {
918 additional_max
= xconn
->smb2
.credits
.max
;
923 * Windows Server < 2016 and older Samba versions
924 * used to only grant additional credits in
925 * chunks of 32 credits.
927 * But we match Windows Server 2016 and grant
928 * all credits as requested.
930 additional_max
= xconn
->smb2
.credits
.max
;
934 additional_max
= MIN(additional_max
, additional_possible
);
935 additional_credits
= MIN(additional_credits
, additional_max
);
937 credits_granted
= credit_charge
+ additional_credits
;
941 * sequence numbers should not wrap
943 * 1. calculate the possible credits until
944 * the sequence numbers start to wrap on 64-bit.
946 * 2. UINT64_MAX is used for Break Notifications.
948 * 2. truncate the possible credits to the maximum
949 * credits we want to grant to the client in total.
951 * 3. remove the range we'll already granted to the client
952 * this makes sure the client consumes the lowest sequence
953 * number, before we can grant additional credits.
955 credits_possible
= UINT64_MAX
- xconn
->smb2
.credits
.seq_low
;
956 if (credits_possible
> 0) {
957 /* remove UINT64_MAX */
958 credits_possible
-= 1;
960 credits_possible
= MIN(credits_possible
, current_max_credits
);
961 credits_possible
-= xconn
->smb2
.credits
.seq_range
;
963 credits_granted
= MIN(credits_granted
, credits_possible
);
965 SSVAL(outhdr
, SMB2_HDR_CREDIT
, credits_granted
);
966 xconn
->smb2
.credits
.granted
+= credits_granted
;
967 xconn
->smb2
.credits
.seq_range
+= credits_granted
;
969 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
970 "smb2_set_operation_credit: requested %u, charge %u, "
971 "granted %u, current possible/max %u/%u, "
972 "total granted/max/low/range %u/%u/%llu/%u\n",
973 (unsigned int)credits_requested
,
974 (unsigned int)credit_charge
,
975 (unsigned int)credits_granted
,
976 (unsigned int)credits_possible
,
977 (unsigned int)current_max_credits
,
978 (unsigned int)xconn
->smb2
.credits
.granted
,
979 (unsigned int)xconn
->smb2
.credits
.max
,
980 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
981 (unsigned int)xconn
->smb2
.credits
.seq_range
);
984 static void smb2_calculate_credits(const struct smbd_smb2_request
*inreq
,
985 struct smbd_smb2_request
*outreq
)
988 uint16_t total_credits
= 0;
990 count
= outreq
->out
.vector_count
;
992 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
993 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(inreq
,in
,idx
);
994 struct iovec
*outhdr_v
= SMBD_SMB2_IDX_HDR_IOV(outreq
,out
,idx
);
995 uint8_t *outhdr
= (uint8_t *)outhdr_v
->iov_base
;
997 smb2_set_operation_credit(outreq
->xconn
, inhdr_v
, outhdr_v
);
999 /* To match Windows, count up what we
1001 total_credits
+= SVAL(outhdr
, SMB2_HDR_CREDIT
);
1002 /* Set to zero in all but the last reply. */
1003 if (idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
< count
) {
1004 SSVAL(outhdr
, SMB2_HDR_CREDIT
, 0);
1006 SSVAL(outhdr
, SMB2_HDR_CREDIT
, total_credits
);
1011 DATA_BLOB
smbd_smb2_generate_outbody(struct smbd_smb2_request
*req
, size_t size
)
1013 if (req
->current_idx
<= 1) {
1014 if (size
<= sizeof(req
->out
._body
)) {
1015 return data_blob_const(req
->out
._body
, size
);
1019 return data_blob_talloc(req
, NULL
, size
);
1022 static NTSTATUS
smbd_smb2_request_setup_out(struct smbd_smb2_request
*req
)
1024 struct smbXsrv_connection
*xconn
= req
->xconn
;
1025 TALLOC_CTX
*mem_ctx
;
1026 struct iovec
*vector
;
1031 count
= req
->in
.vector_count
;
1032 if (count
<= ARRAY_SIZE(req
->out
._vector
)) {
1034 vector
= req
->out
._vector
;
1036 vector
= talloc_zero_array(req
, struct iovec
, count
);
1037 if (vector
== NULL
) {
1038 return NT_STATUS_NO_MEMORY
;
1043 vector
[0].iov_base
= req
->out
.nbt_hdr
;
1044 vector
[0].iov_len
= 4;
1045 SIVAL(req
->out
.nbt_hdr
, 0, 0);
1047 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1048 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
1049 const uint8_t *inhdr
= (const uint8_t *)inhdr_v
->iov_base
;
1050 uint8_t *outhdr
= NULL
;
1051 uint8_t *outbody
= NULL
;
1052 uint32_t next_command_ofs
= 0;
1053 struct iovec
*current
= &vector
[idx
];
1055 if ((idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) < count
) {
1056 /* we have a next command -
1057 * setup for the error case. */
1058 next_command_ofs
= SMB2_HDR_BODY
+ 9;
1062 outhdr
= req
->out
._hdr
;
1064 outhdr
= talloc_zero_array(mem_ctx
, uint8_t,
1066 if (outhdr
== NULL
) {
1067 return NT_STATUS_NO_MEMORY
;
1071 outbody
= outhdr
+ SMB2_HDR_BODY
;
1074 * SMBD_SMB2_TF_IOV_OFS might be used later
1076 current
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1077 current
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1079 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)outhdr
;
1080 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1082 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)outbody
;
1083 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1085 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= NULL
;
1086 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 0;
1088 /* setup the SMB2 header */
1089 SIVAL(outhdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1090 SSVAL(outhdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1091 SSVAL(outhdr
, SMB2_HDR_CREDIT_CHARGE
,
1092 SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
));
1093 SIVAL(outhdr
, SMB2_HDR_STATUS
,
1094 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR
));
1095 SSVAL(outhdr
, SMB2_HDR_OPCODE
,
1096 SVAL(inhdr
, SMB2_HDR_OPCODE
));
1097 SIVAL(outhdr
, SMB2_HDR_FLAGS
,
1098 IVAL(inhdr
, SMB2_HDR_FLAGS
) | SMB2_HDR_FLAG_REDIRECT
);
1099 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
1100 SBVAL(outhdr
, SMB2_HDR_MESSAGE_ID
,
1101 BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
));
1102 SIVAL(outhdr
, SMB2_HDR_PID
,
1103 IVAL(inhdr
, SMB2_HDR_PID
));
1104 SIVAL(outhdr
, SMB2_HDR_TID
,
1105 IVAL(inhdr
, SMB2_HDR_TID
));
1106 SBVAL(outhdr
, SMB2_HDR_SESSION_ID
,
1107 BVAL(inhdr
, SMB2_HDR_SESSION_ID
));
1108 memcpy(outhdr
+ SMB2_HDR_SIGNATURE
,
1109 inhdr
+ SMB2_HDR_SIGNATURE
, 16);
1111 /* setup error body header */
1112 SSVAL(outbody
, 0x00, 0x08 + 1);
1113 SSVAL(outbody
, 0x02, 0);
1114 SIVAL(outbody
, 0x04, 0);
1117 req
->out
.vector
= vector
;
1118 req
->out
.vector_count
= count
;
1120 /* setup the length of the NBT packet */
1121 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
1123 return NT_STATUS_INVALID_PARAMETER_MIX
;
1126 DLIST_ADD_END(xconn
->smb2
.requests
, req
);
1128 return NT_STATUS_OK
;
1131 bool smbXsrv_server_multi_channel_enabled(void)
1133 bool enabled
= lp_server_multi_channel_support();
1134 #ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1135 bool forced
= false;
1137 * If we don't have support from the kernel
1138 * to ask for the un-acked number of bytes
1139 * in the socket send queue, we better
1140 * don't support multi-channel.
1142 forced
= lp_parm_bool(-1, "force", "server multi channel support", false);
1143 if (enabled
&& !forced
) {
1144 D_NOTICE("'server multi channel support' enabled "
1145 "but not supported on %s (%s)\n",
1146 SYSTEM_UNAME_SYSNAME
, SYSTEM_UNAME_RELEASE
);
1147 DEBUGADD(DBGLVL_NOTICE
, ("Please report this on "
1148 "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1151 #endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1155 static NTSTATUS
smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection
*xconn
,
1156 uint32_t *_rto_usecs
)
1159 * Define an Retransmission Timeout
1160 * of 1 second, if there's no way for the
1161 * kernel to tell us the current value.
1163 uint32_t rto_usecs
= 1000000;
1165 #ifdef __HAVE_TCP_INFO_RTO
1167 struct tcp_info info
;
1168 socklen_t ilen
= sizeof(info
);
1172 ret
= getsockopt(xconn
->transport
.sock
,
1173 IPPROTO_TCP
, TCP_INFO
,
1174 (void *)&info
, &ilen
);
1176 int saved_errno
= errno
;
1177 NTSTATUS status
= map_nt_error_from_unix(errno
);
1178 DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1179 saved_errno
, strerror(saved_errno
),
1184 DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1185 (unsigned)info
.tcpi_rto
,
1186 (unsigned)info
.tcpi_rtt
,
1187 (unsigned)info
.tcpi_rttvar
);
1188 rto_usecs
= info
.tcpi_rto
;
1190 #endif /* __HAVE_TCP_INFO_RTO */
1192 rto_usecs
= MAX(rto_usecs
, 200000); /* at least 0.2s */
1193 rto_usecs
= MIN(rto_usecs
, 1000000); /* at max 1.0s */
1194 *_rto_usecs
= rto_usecs
;
1195 return NT_STATUS_OK
;
1198 static NTSTATUS
smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection
*xconn
,
1199 uint64_t *_acked_bytes
)
1202 * Unless the kernel has an interface
1203 * to reveal the number of un-acked bytes
1204 * in the socket send queue, we'll assume
1205 * everything is already acked.
1207 * But that would mean that we better don't
1208 * pretent to support multi-channel.
1210 uint64_t unacked_bytes
= 0;
1214 if (xconn
->ack
.force_unacked_timeout
) {
1216 * Smbtorture tries to test channel failures...
1217 * Just pretend nothing was acked...
1219 DBG_INFO("Simulating channel failure: "
1220 "xconn->ack.unacked_bytes[%llu]\n",
1221 (unsigned long long)xconn
->ack
.unacked_bytes
);
1222 return NT_STATUS_OK
;
1225 #ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1231 * If we have kernel support to get
1232 * the number of bytes waiting in
1233 * the socket's send queue, we
1234 * use that in order to find out
1235 * the number of unacked bytes.
1237 ret
= ioctl(xconn
->transport
.sock
,
1238 __IOCTL_SEND_QUEUE_SIZE_OPCODE
,
1241 int saved_errno
= errno
;
1242 NTSTATUS status
= map_nt_error_from_unix(saved_errno
);
1243 DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1244 "errno %d (%s) - %s\n",
1245 saved_errno
, strerror(saved_errno
),
1251 DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1252 (unsigned long long)xconn
->ack
.unacked_bytes
,
1254 return NT_STATUS_INTERNAL_ERROR
;
1256 unacked_bytes
= value
;
1259 if (xconn
->ack
.unacked_bytes
== 0) {
1260 xconn
->ack
.unacked_bytes
= unacked_bytes
;
1261 return NT_STATUS_OK
;
1264 if (xconn
->ack
.unacked_bytes
< unacked_bytes
) {
1265 DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1266 (unsigned long long)xconn
->ack
.unacked_bytes
,
1267 (unsigned long long)unacked_bytes
);
1268 return NT_STATUS_INTERNAL_ERROR
;
1271 *_acked_bytes
= xconn
->ack
.unacked_bytes
- unacked_bytes
;
1272 xconn
->ack
.unacked_bytes
= unacked_bytes
;
1273 return NT_STATUS_OK
;
1276 static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue
**queue
,
1279 struct smbd_smb2_send_queue
*e
= NULL
;
1280 struct smbd_smb2_send_queue
*n
= NULL
;
1282 for (e
= *queue
; e
!= NULL
; e
= n
) {
1285 DLIST_REMOVE(*queue
, e
);
1286 if (e
->ack
.req
!= NULL
) {
1287 tevent_req_nterror(e
->ack
.req
, status
);
1292 static NTSTATUS
smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue
**queue
,
1293 uint64_t acked_bytes
)
1295 struct smbd_smb2_send_queue
*e
= NULL
;
1296 struct smbd_smb2_send_queue
*n
= NULL
;
1298 for (e
= *queue
; e
!= NULL
; e
= n
) {
1303 if (e
->ack
.req
== NULL
) {
1307 if (e
->ack
.required_acked_bytes
<= acked_bytes
) {
1308 e
->ack
.required_acked_bytes
= 0;
1309 DLIST_REMOVE(*queue
, e
);
1310 tevent_req_done(e
->ack
.req
);
1313 e
->ack
.required_acked_bytes
-= acked_bytes
;
1315 expired
= timeval_expired(&e
->ack
.timeout
);
1317 return NT_STATUS_IO_TIMEOUT
;
1321 return NT_STATUS_OK
;
1324 static NTSTATUS
smbd_smb2_check_ack_queue(struct smbXsrv_connection
*xconn
)
1326 uint64_t acked_bytes
= 0;
1329 status
= smbXsrv_connection_get_acked_bytes(xconn
, &acked_bytes
);
1330 if (!NT_STATUS_IS_OK(status
)) {
1334 status
= smbd_smb2_send_queue_ack_bytes(&xconn
->ack
.queue
, acked_bytes
);
1335 if (!NT_STATUS_IS_OK(status
)) {
1339 status
= smbd_smb2_send_queue_ack_bytes(&xconn
->smb2
.send_queue
, 0);
1340 if (!NT_STATUS_IS_OK(status
)) {
1344 return NT_STATUS_OK
;
1347 static void smbXsrv_connection_ack_checker(struct tevent_req
*subreq
)
1349 struct smbXsrv_connection
*xconn
=
1350 tevent_req_callback_data(subreq
,
1351 struct smbXsrv_connection
);
1352 struct smbXsrv_client
*client
= xconn
->client
;
1353 struct timeval next_check
;
1357 xconn
->ack
.checker_subreq
= NULL
;
1359 ok
= tevent_wakeup_recv(subreq
);
1360 TALLOC_FREE(subreq
);
1362 smbd_server_connection_terminate(xconn
,
1363 "tevent_wakeup_recv() failed");
1367 status
= smbd_smb2_check_ack_queue(xconn
);
1368 if (!NT_STATUS_IS_OK(status
)) {
1369 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
1373 next_check
= timeval_current_ofs_usec(xconn
->ack
.rto_usecs
);
1374 xconn
->ack
.checker_subreq
= tevent_wakeup_send(xconn
,
1377 if (xconn
->ack
.checker_subreq
== NULL
) {
1378 smbd_server_connection_terminate(xconn
,
1379 "tevent_wakeup_send() failed");
1382 tevent_req_set_callback(xconn
->ack
.checker_subreq
,
1383 smbXsrv_connection_ack_checker
,
1387 static NTSTATUS
smbXsrv_client_pending_breaks_updated(struct smbXsrv_client
*client
)
1389 struct smbXsrv_connection
*xconn
= NULL
;
1391 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
1392 struct timeval next_check
;
1393 uint64_t acked_bytes
= 0;
1397 * A new 'pending break cycle' starts
1398 * with a first pending break and lasts until
1399 * all pending breaks are finished.
1401 * This is typically a very short time,
1402 * the value of one retransmission timeout.
1405 if (client
->pending_breaks
== NULL
) {
1407 * No more pending breaks, remove a pending
1410 TALLOC_FREE(xconn
->ack
.checker_subreq
);
1414 if (xconn
->ack
.checker_subreq
!= NULL
) {
1416 * The cycle already started =>
1423 * Get the current retransmission timeout value.
1425 * It may change over time, but fetching it once
1426 * per 'pending break' cycled should be enough.
1428 status
= smbXsrv_connection_get_rto_usecs(xconn
,
1429 &xconn
->ack
.rto_usecs
);
1430 if (!NT_STATUS_IS_OK(status
)) {
1435 * At the start of the cycle we reset the
1436 * unacked_bytes counter (first to 0 and
1437 * within smbXsrv_connection_get_acked_bytes()
1438 * to the current value in the kernel
1441 xconn
->ack
.unacked_bytes
= 0;
1442 status
= smbXsrv_connection_get_acked_bytes(xconn
, &acked_bytes
);
1443 if (!NT_STATUS_IS_OK(status
)) {
1448 * We setup a timer in order to check for
1449 * acked bytes after one retransmission timeout.
1451 * The code that sets up the send_queue.ack.timeout
1452 * uses a multiple of the retransmission timeout.
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 return NT_STATUS_NO_MEMORY
;
1461 tevent_req_set_callback(xconn
->ack
.checker_subreq
,
1462 smbXsrv_connection_ack_checker
,
1466 return NT_STATUS_OK
;
1469 void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection
*xconn
,
1472 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
1476 xconn
->transport
.status
= status
;
1477 TALLOC_FREE(xconn
->transport
.fde
);
1478 if (xconn
->transport
.sock
!= -1) {
1479 xconn
->transport
.sock
= -1;
1481 smbd_smb2_send_queue_ack_fail(&xconn
->ack
.queue
, status
);
1482 smbd_smb2_send_queue_ack_fail(&xconn
->smb2
.send_queue
, status
);
1483 xconn
->smb2
.send_queue_len
= 0;
1484 DO_PROFILE_INC(disconnect
);
1487 size_t smbXsrv_client_valid_connections(struct smbXsrv_client
*client
)
1489 struct smbXsrv_connection
*xconn
= NULL
;
1492 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
1493 if (NT_STATUS_IS_OK(xconn
->transport
.status
)) {
1501 struct smbXsrv_connection_shutdown_state
{
1502 struct tevent_queue
*wait_queue
;
1503 struct smbXsrv_connection
*xconn
;
1506 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req
*subreq
);
1508 static struct tevent_req
*smbXsrv_connection_shutdown_send(TALLOC_CTX
*mem_ctx
,
1509 struct tevent_context
*ev
,
1510 struct smbXsrv_connection
*xconn
)
1512 struct tevent_req
*req
= NULL
;
1513 struct smbXsrv_connection_shutdown_state
*state
= NULL
;
1514 struct tevent_req
*subreq
= NULL
;
1516 struct smbd_smb2_request
*preq
= NULL
;
1520 * The caller should have called
1521 * smbXsrv_connection_disconnect_transport() before.
1523 SMB_ASSERT(!NT_STATUS_IS_OK(xconn
->transport
.status
));
1524 SMB_ASSERT(xconn
->transport
.terminating
);
1526 req
= tevent_req_create(mem_ctx
, &state
,
1527 struct smbXsrv_connection_shutdown_state
);
1532 state
->xconn
= xconn
;
1533 tevent_req_defer_callback(req
, ev
);
1535 status
= smbXsrv_session_disconnect_xconn(xconn
);
1536 if (tevent_req_nterror(req
, status
)) {
1537 return tevent_req_post(req
, ev
);
1540 state
->wait_queue
= tevent_queue_create(state
, "smbXsrv_connection_shutdown_queue");
1541 if (tevent_req_nomem(state
->wait_queue
, req
)) {
1542 return tevent_req_post(req
, ev
);
1545 for (preq
= xconn
->smb2
.requests
; preq
!= NULL
; preq
= preq
->next
) {
1547 * The connection is gone so we
1548 * don't need to take care of
1551 preq
->session
= NULL
;
1552 preq
->do_signing
= false;
1553 preq
->do_encryption
= false;
1554 preq
->preauth
= NULL
;
1556 if (preq
->subreq
!= NULL
) {
1557 tevent_req_cancel(preq
->subreq
);
1561 * Now wait until the request is finished.
1563 * We don't set a callback, as we just want to block the
1564 * wait queue and the talloc_free() of the request will
1565 * remove the item from the wait queue.
1567 subreq
= tevent_queue_wait_send(preq
, ev
, state
->wait_queue
);
1568 if (tevent_req_nomem(subreq
, req
)) {
1569 return tevent_req_post(req
, ev
);
1573 len
= tevent_queue_length(state
->wait_queue
);
1575 tevent_req_done(req
);
1576 return tevent_req_post(req
, ev
);
1580 * Now we add our own waiter to the end of the queue,
1581 * this way we get notified when all pending requests are finished
1582 * and send to the socket.
1584 subreq
= tevent_queue_wait_send(state
, ev
, state
->wait_queue
);
1585 if (tevent_req_nomem(subreq
, req
)) {
1586 return tevent_req_post(req
, ev
);
1588 tevent_req_set_callback(subreq
, smbXsrv_connection_shutdown_wait_done
, req
);
1593 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req
*subreq
)
1595 struct tevent_req
*req
=
1596 tevent_req_callback_data(subreq
,
1598 struct smbXsrv_connection_shutdown_state
*state
=
1599 tevent_req_data(req
,
1600 struct smbXsrv_connection_shutdown_state
);
1601 struct smbXsrv_connection
*xconn
= state
->xconn
;
1603 tevent_queue_wait_recv(subreq
);
1604 TALLOC_FREE(subreq
);
1606 tevent_req_done(req
);
1608 * make sure the xconn pointer is still valid,
1609 * it should as we used tevent_req_defer_callback()
1611 SMB_ASSERT(xconn
->transport
.terminating
);
1614 static NTSTATUS
smbXsrv_connection_shutdown_recv(struct tevent_req
*req
)
1616 struct smbXsrv_connection_shutdown_state
*state
=
1617 tevent_req_data(req
,
1618 struct smbXsrv_connection_shutdown_state
);
1619 struct smbXsrv_connection
*xconn
= state
->xconn
;
1621 * make sure the xconn pointer is still valid,
1622 * it should as we used tevent_req_defer_callback()
1624 SMB_ASSERT(xconn
->transport
.terminating
);
1625 return tevent_req_simple_recv_ntstatus(req
);
1628 static void smbd_server_connection_terminate_done(struct tevent_req
*subreq
)
1630 struct smbXsrv_connection
*xconn
=
1631 tevent_req_callback_data(subreq
,
1632 struct smbXsrv_connection
);
1633 struct smbXsrv_client
*client
= xconn
->client
;
1636 status
= smbXsrv_connection_shutdown_recv(subreq
);
1637 if (!NT_STATUS_IS_OK(status
)) {
1638 exit_server("smbXsrv_connection_shutdown_recv failed");
1641 DLIST_REMOVE(client
->connections
, xconn
);
1645 void smbd_server_connection_terminate_ex(struct smbXsrv_connection
*xconn
,
1647 const char *location
)
1649 struct smbXsrv_client
*client
= xconn
->client
;
1653 * Make sure that no new request will be able to use this session.
1655 * smbXsrv_connection_disconnect_transport() might be called already,
1656 * but calling it again is a no-op.
1658 smbXsrv_connection_disconnect_transport(xconn
,
1659 NT_STATUS_CONNECTION_DISCONNECTED
);
1661 num_ok
= smbXsrv_client_valid_connections(client
);
1663 if (xconn
->transport
.terminating
) {
1664 DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1665 smbXsrv_connection_dbg(xconn
), num_ok
,
1669 xconn
->transport
.terminating
= true;
1671 DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1672 smbXsrv_connection_dbg(xconn
), num_ok
,
1675 if (xconn
->has_cluster_movable_ip
) {
1677 * If the connection has a movable cluster public address
1678 * we disconnect all client connections,
1679 * as the public address might be moved to
1682 * In future we may recheck which node currently
1683 * holds this address, but for now we keep it simple.
1685 smbd_server_disconnect_client_ex(xconn
->client
,
1692 struct tevent_req
*subreq
= NULL
;
1694 subreq
= smbXsrv_connection_shutdown_send(client
,
1697 if (subreq
== NULL
) {
1698 exit_server("smbXsrv_connection_shutdown_send failed");
1700 tevent_req_set_callback(subreq
,
1701 smbd_server_connection_terminate_done
,
1707 * The last connection was disconnected
1709 exit_server_cleanly(reason
);
1712 void smbd_server_disconnect_client_ex(struct smbXsrv_client
*client
,
1714 const char *location
)
1718 num_ok
= smbXsrv_client_valid_connections(client
);
1720 DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1721 client
->global
->remote_address
, num_ok
,
1725 * Something bad happened we need to disconnect all connections.
1727 exit_server_cleanly(reason
);
1730 static bool dup_smb2_vec4(TALLOC_CTX
*ctx
,
1731 struct iovec
*outvec
,
1732 const struct iovec
*srcvec
)
1734 const uint8_t *srctf
;
1736 const uint8_t *srchdr
;
1738 const uint8_t *srcbody
;
1740 const uint8_t *expected_srcbody
;
1741 const uint8_t *srcdyn
;
1743 const uint8_t *expected_srcdyn
;
1749 srctf
= (const uint8_t *)srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
;
1750 srctf_len
= srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
;
1751 srchdr
= (const uint8_t *)srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
;
1752 srchdr_len
= srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
;
1753 srcbody
= (const uint8_t *)srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
;
1754 srcbody_len
= srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
;
1755 expected_srcbody
= srchdr
+ SMB2_HDR_BODY
;
1756 srcdyn
= (const uint8_t *)srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
;
1757 srcdyn_len
= srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
;
1758 expected_srcdyn
= srcbody
+ 8;
1760 if ((srctf_len
!= SMB2_TF_HDR_SIZE
) && (srctf_len
!= 0)) {
1764 if (srchdr_len
!= SMB2_HDR_BODY
) {
1768 if (srctf_len
== SMB2_TF_HDR_SIZE
) {
1769 dsttf
= talloc_memdup(ctx
, srctf
, SMB2_TF_HDR_SIZE
);
1770 if (dsttf
== NULL
) {
1776 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= (void *)dsttf
;
1777 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= srctf_len
;
1779 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1780 * be allocated with size OUTVEC_ALLOC_SIZE. */
1782 dsthdr
= talloc_memdup(ctx
, srchdr
, OUTVEC_ALLOC_SIZE
);
1783 if (dsthdr
== NULL
) {
1786 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)dsthdr
;
1787 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1790 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1791 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1792 * then duplicate this. Else use talloc_memdup().
1795 if ((srcbody
== expected_srcbody
) && (srcbody_len
== 8)) {
1796 dstbody
= dsthdr
+ SMB2_HDR_BODY
;
1798 dstbody
= talloc_memdup(ctx
, srcbody
, srcbody_len
);
1799 if (dstbody
== NULL
) {
1803 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)dstbody
;
1804 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= srcbody_len
;
1807 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1809 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1810 * then duplicate this. Else use talloc_memdup().
1813 if ((srcdyn
== expected_srcdyn
) && (srcdyn_len
== 1)) {
1814 dstdyn
= dsthdr
+ SMB2_HDR_BODY
+ 8;
1815 } else if (srcdyn
== NULL
) {
1818 dstdyn
= talloc_memdup(ctx
, srcdyn
, srcdyn_len
);
1819 if (dstdyn
== NULL
) {
1823 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= (void *)dstdyn
;
1824 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= srcdyn_len
;
1829 static struct smbd_smb2_request
*dup_smb2_req(const struct smbd_smb2_request
*req
)
1831 struct smbd_smb2_request
*newreq
= NULL
;
1832 struct iovec
*outvec
= NULL
;
1833 int count
= req
->out
.vector_count
;
1837 newreq
= smbd_smb2_request_allocate(req
->xconn
);
1842 newreq
->sconn
= req
->sconn
;
1843 newreq
->xconn
= req
->xconn
;
1844 newreq
->session
= req
->session
;
1845 newreq
->do_encryption
= req
->do_encryption
;
1846 newreq
->do_signing
= req
->do_signing
;
1847 newreq
->current_idx
= req
->current_idx
;
1849 outvec
= talloc_zero_array(newreq
, struct iovec
, count
);
1851 TALLOC_FREE(newreq
);
1854 newreq
->out
.vector
= outvec
;
1855 newreq
->out
.vector_count
= count
;
1857 /* Setup the outvec's identically to req. */
1858 outvec
[0].iov_base
= newreq
->out
.nbt_hdr
;
1859 outvec
[0].iov_len
= 4;
1860 memcpy(newreq
->out
.nbt_hdr
, req
->out
.nbt_hdr
, 4);
1862 /* Setup the vectors identically to the ones in req. */
1863 for (i
= 1; i
< count
; i
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1864 if (!dup_smb2_vec4(outvec
, &outvec
[i
], &req
->out
.vector
[i
])) {
1871 TALLOC_FREE(newreq
);
1875 ok
= smb2_setup_nbt_length(newreq
->out
.vector
,
1876 newreq
->out
.vector_count
);
1878 TALLOC_FREE(newreq
);
1885 static NTSTATUS
smb2_send_async_interim_response(const struct smbd_smb2_request
*req
)
1887 struct smbXsrv_connection
*xconn
= req
->xconn
;
1889 struct iovec
*firsttf
= NULL
;
1890 struct iovec
*outhdr_v
= NULL
;
1891 uint8_t *outhdr
= NULL
;
1892 struct smbd_smb2_request
*nreq
= NULL
;
1896 /* Create a new smb2 request we'll use
1897 for the interim return. */
1898 nreq
= dup_smb2_req(req
);
1900 return NT_STATUS_NO_MEMORY
;
1903 /* Lose the last X out vectors. They're the
1904 ones we'll be using for the async reply. */
1905 nreq
->out
.vector_count
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1907 ok
= smb2_setup_nbt_length(nreq
->out
.vector
,
1908 nreq
->out
.vector_count
);
1910 return NT_STATUS_INVALID_PARAMETER_MIX
;
1913 /* Step back to the previous reply. */
1914 nreq
->current_idx
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1915 firsttf
= SMBD_SMB2_IDX_TF_IOV(nreq
,out
,first_idx
);
1916 outhdr_v
= SMBD_SMB2_OUT_HDR_IOV(nreq
);
1917 outhdr
= SMBD_SMB2_OUT_HDR_PTR(nreq
);
1918 /* And end the chain. */
1919 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
1921 /* Calculate outgoing credits */
1922 smb2_calculate_credits(req
, nreq
);
1924 if (DEBUGLEVEL
>= 10) {
1925 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1926 (unsigned int)nreq
->current_idx
);
1927 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1928 (unsigned int)nreq
->out
.vector_count
);
1929 print_req_vectors(nreq
);
1933 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1934 * we need to sign/encrypt here with the last/first key we remembered
1936 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
1937 struct smb2_signing_key key
= {
1938 .blob
= req
->first_key
,
1940 status
= smb2_signing_encrypt_pdu(&key
,
1941 xconn
->smb2
.server
.cipher
,
1943 nreq
->out
.vector_count
- first_idx
);
1944 smb2_signing_key_destructor(&key
);
1945 if (!NT_STATUS_IS_OK(status
)) {
1948 } else if (req
->last_key
.length
> 0) {
1949 struct smb2_signing_key key
= {
1950 .blob
= req
->last_key
,
1953 status
= smb2_signing_sign_pdu(&key
,
1956 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
1957 smb2_signing_key_destructor(&key
);
1958 if (!NT_STATUS_IS_OK(status
)) {
1963 nreq
->queue_entry
.mem_ctx
= nreq
;
1964 nreq
->queue_entry
.vector
= nreq
->out
.vector
;
1965 nreq
->queue_entry
.count
= nreq
->out
.vector_count
;
1966 DLIST_ADD_END(xconn
->smb2
.send_queue
, &nreq
->queue_entry
);
1967 xconn
->smb2
.send_queue_len
++;
1969 status
= smbd_smb2_flush_send_queue(xconn
);
1970 if (!NT_STATUS_IS_OK(status
)) {
1974 return NT_STATUS_OK
;
1977 struct smbd_smb2_request_pending_state
{
1978 struct smbd_smb2_send_queue queue_entry
;
1979 uint8_t buf
[NBT_HDR_SIZE
+ SMB2_TF_HDR_SIZE
+ SMB2_HDR_BODY
+ 0x08 + 1];
1980 struct iovec vector
[1 + SMBD_SMB2_NUM_IOV_PER_REQ
];
1983 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
1984 struct tevent_timer
*te
,
1985 struct timeval current_time
,
1986 void *private_data
);
1988 NTSTATUS
smbd_smb2_request_pending_queue(struct smbd_smb2_request
*req
,
1989 struct tevent_req
*subreq
,
1990 uint32_t defer_time
)
1993 struct timeval defer_endtime
;
1994 uint8_t *outhdr
= NULL
;
1997 if (!tevent_req_is_in_progress(subreq
)) {
1999 * This is a performance optimization,
2000 * it avoids one tevent_loop iteration,
2001 * which means we avoid one
2002 * talloc_stackframe_pool/talloc_free pair.
2004 tevent_req_notify_callback(subreq
);
2005 return NT_STATUS_OK
;
2008 req
->subreq
= subreq
;
2011 if (req
->async_te
) {
2012 /* We're already async. */
2013 return NT_STATUS_OK
;
2016 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2017 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
2018 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
2019 /* We're already async. */
2020 return NT_STATUS_OK
;
2023 if (req
->async_internal
|| defer_time
== 0) {
2025 * An SMB2 request implementation wants to handle the request
2026 * asynchronously "internally" while keeping synchronous
2027 * behaviour for the SMB2 request. This means we don't send an
2028 * interim response and we can allow processing of compound SMB2
2029 * requests (cf the subsequent check) for all cases.
2031 return NT_STATUS_OK
;
2034 if (req
->in
.vector_count
> req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) {
2036 * We're trying to go async in a compound request
2037 * chain. This is only allowed for opens that cause an
2038 * oplock break or for the last operation in the
2039 * chain, otherwise it is not allowed. See
2040 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2042 const uint8_t *inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2044 if (SVAL(inhdr
, SMB2_HDR_OPCODE
) != SMB2_OP_CREATE
) {
2046 * Cancel the outstanding request.
2048 bool ok
= tevent_req_cancel(req
->subreq
);
2050 return NT_STATUS_OK
;
2052 TALLOC_FREE(req
->subreq
);
2053 return smbd_smb2_request_error(req
,
2054 NT_STATUS_INTERNAL_ERROR
);
2058 if (DEBUGLEVEL
>= 10) {
2059 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2060 (unsigned int)req
->current_idx
);
2061 print_req_vectors(req
);
2064 if (req
->current_idx
> 1) {
2066 * We're going async in a compound
2067 * chain after the first request has
2068 * already been processed. Send an
2069 * interim response containing the
2070 * set of replies already generated.
2072 int idx
= req
->current_idx
;
2074 status
= smb2_send_async_interim_response(req
);
2075 if (!NT_STATUS_IS_OK(status
)) {
2078 if (req
->first_key
.length
> 0) {
2079 data_blob_clear_free(&req
->first_key
);
2082 req
->current_idx
= 1;
2085 * Re-arrange the in.vectors to remove what
2088 memmove(&req
->in
.vector
[1],
2089 &req
->in
.vector
[idx
],
2090 sizeof(req
->in
.vector
[0])*(req
->in
.vector_count
- idx
));
2091 req
->in
.vector_count
= 1 + (req
->in
.vector_count
- idx
);
2093 /* Re-arrange the out.vectors to match. */
2094 memmove(&req
->out
.vector
[1],
2095 &req
->out
.vector
[idx
],
2096 sizeof(req
->out
.vector
[0])*(req
->out
.vector_count
- idx
));
2097 req
->out
.vector_count
= 1 + (req
->out
.vector_count
- idx
);
2099 if (req
->in
.vector_count
== 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
2101 * We only have one remaining request as
2102 * we've processed everything else.
2103 * This is no longer a compound request.
2105 req
->compound_related
= false;
2106 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2107 flags
= (IVAL(outhdr
, SMB2_HDR_FLAGS
) & ~SMB2_HDR_FLAG_CHAINED
);
2108 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
);
2111 if (req
->last_key
.length
> 0) {
2112 data_blob_clear_free(&req
->last_key
);
2116 * smbd_smb2_request_pending_timer() just send a packet
2117 * to the client and doesn't need any impersonation.
2118 * So we use req->xconn->client->raw_ev_ctx instead
2119 * of req->ev_ctx here.
2121 defer_endtime
= timeval_current_ofs_usec(defer_time
);
2122 req
->async_te
= tevent_add_timer(req
->xconn
->client
->raw_ev_ctx
,
2124 smbd_smb2_request_pending_timer
,
2126 if (req
->async_te
== NULL
) {
2127 return NT_STATUS_NO_MEMORY
;
2130 return NT_STATUS_OK
;
2134 struct smb2_signing_key
*smbd_smb2_signing_key(struct smbXsrv_session
*session
,
2135 struct smbXsrv_connection
*xconn
)
2137 struct smbXsrv_channel_global0
*c
= NULL
;
2139 struct smb2_signing_key
*key
= NULL
;
2141 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
2142 if (NT_STATUS_IS_OK(status
)) {
2143 key
= c
->signing_key
;
2146 if (!smb2_signing_key_valid(key
)) {
2147 key
= session
->global
->signing_key
;
2153 static NTSTATUS
smb2_get_new_nonce(struct smbXsrv_session
*session
,
2154 uint64_t *new_nonce_high
,
2155 uint64_t *new_nonce_low
)
2157 uint64_t nonce_high
;
2160 session
->nonce_low
+= 1;
2161 if (session
->nonce_low
== 0) {
2162 session
->nonce_low
+= 1;
2163 session
->nonce_high
+= 1;
2167 * CCM and GCM algorithms must never have their
2168 * nonce wrap, or the security of the whole
2169 * communication and the keys is destroyed.
2170 * We must drop the connection once we have
2171 * transfered too much data.
2173 * NOTE: We assume nonces greater than 8 bytes.
2175 if (session
->nonce_high
>= session
->nonce_high_max
) {
2176 return NT_STATUS_ENCRYPTION_FAILED
;
2179 nonce_high
= session
->nonce_high_random
;
2180 nonce_high
+= session
->nonce_high
;
2181 nonce_low
= session
->nonce_low
;
2183 *new_nonce_high
= nonce_high
;
2184 *new_nonce_low
= nonce_low
;
2185 return NT_STATUS_OK
;
2188 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
2189 struct tevent_timer
*te
,
2190 struct timeval current_time
,
2193 struct smbd_smb2_request
*req
=
2194 talloc_get_type_abort(private_data
,
2195 struct smbd_smb2_request
);
2196 struct smbXsrv_connection
*xconn
= req
->xconn
;
2197 struct smbd_smb2_request_pending_state
*state
= NULL
;
2198 uint8_t *outhdr
= NULL
;
2199 const uint8_t *inhdr
= NULL
;
2201 uint8_t *hdr
= NULL
;
2202 uint8_t *body
= NULL
;
2203 uint8_t *dyn
= NULL
;
2205 uint64_t message_id
= 0;
2206 uint64_t async_id
= 0;
2210 TALLOC_FREE(req
->async_te
);
2212 /* Ensure our final reply matches the interim one. */
2213 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2214 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2215 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
2216 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
2218 async_id
= message_id
; /* keep it simple for now... */
2220 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
2221 SBVAL(outhdr
, SMB2_HDR_ASYNC_ID
, async_id
);
2223 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2225 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
2226 (unsigned long long)async_id
));
2229 * What we send is identical to a smbd_smb2_request_error
2230 * packet with an error status of STATUS_PENDING. Make use
2231 * of this fact sometime when refactoring. JRA.
2234 state
= talloc_zero(req
->xconn
, struct smbd_smb2_request_pending_state
);
2235 if (state
== NULL
) {
2236 smbd_server_connection_terminate(xconn
,
2237 nt_errstr(NT_STATUS_NO_MEMORY
));
2241 tf
= state
->buf
+ NBT_HDR_SIZE
;
2243 hdr
= tf
+ SMB2_TF_HDR_SIZE
;
2244 body
= hdr
+ SMB2_HDR_BODY
;
2247 if (req
->do_encryption
) {
2248 uint64_t nonce_high
= 0;
2249 uint64_t nonce_low
= 0;
2250 uint64_t session_id
= req
->session
->global
->session_wire_id
;
2252 status
= smb2_get_new_nonce(req
->session
,
2255 if (!NT_STATUS_IS_OK(status
)) {
2256 smbd_server_connection_terminate(xconn
,
2261 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2262 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
2263 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
2264 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
2267 SIVAL(hdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
2268 SSVAL(hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
2269 SSVAL(hdr
, SMB2_HDR_EPOCH
, 0);
2270 SIVAL(hdr
, SMB2_HDR_STATUS
, NT_STATUS_V(NT_STATUS_PENDING
));
2271 SSVAL(hdr
, SMB2_HDR_OPCODE
, SVAL(outhdr
, SMB2_HDR_OPCODE
));
2273 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
);
2274 SIVAL(hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2275 SBVAL(hdr
, SMB2_HDR_MESSAGE_ID
, message_id
);
2276 SBVAL(hdr
, SMB2_HDR_PID
, async_id
);
2277 SBVAL(hdr
, SMB2_HDR_SESSION_ID
,
2278 BVAL(outhdr
, SMB2_HDR_SESSION_ID
));
2279 memcpy(hdr
+SMB2_HDR_SIGNATURE
,
2280 outhdr
+SMB2_HDR_SIGNATURE
, 16);
2282 SSVAL(body
, 0x00, 0x08 + 1);
2284 SCVAL(body
, 0x02, 0);
2285 SCVAL(body
, 0x03, 0);
2286 SIVAL(body
, 0x04, 0);
2287 /* Match W2K8R2... */
2288 SCVAL(dyn
, 0x00, 0x21);
2290 state
->vector
[0].iov_base
= (void *)state
->buf
;
2291 state
->vector
[0].iov_len
= NBT_HDR_SIZE
;
2293 if (req
->do_encryption
) {
2294 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
2295 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
=
2298 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
2299 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
2302 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
2303 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
2305 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
2306 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
2308 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
2309 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 1;
2311 ok
= smb2_setup_nbt_length(state
->vector
,
2312 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
2314 smbd_server_connection_terminate(
2315 xconn
, nt_errstr(NT_STATUS_INTERNAL_ERROR
));
2319 /* Ensure we correctly go through crediting. Grant
2320 the credits now, and zero credits on the final
2322 smb2_set_operation_credit(req
->xconn
,
2323 SMBD_SMB2_IN_HDR_IOV(req
),
2324 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
]);
2326 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
2331 for (i
= 0; i
< ARRAY_SIZE(state
->vector
); i
++) {
2332 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2334 (unsigned int)ARRAY_SIZE(state
->vector
),
2335 (unsigned int)state
->vector
[i
].iov_len
);
2339 if (req
->do_encryption
) {
2340 struct smbXsrv_session
*x
= req
->session
;
2341 struct smb2_signing_key
*encryption_key
= x
->global
->encryption_key
;
2343 status
= smb2_signing_encrypt_pdu(encryption_key
,
2344 xconn
->smb2
.server
.cipher
,
2345 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
2346 SMBD_SMB2_NUM_IOV_PER_REQ
);
2347 if (!NT_STATUS_IS_OK(status
)) {
2348 smbd_server_connection_terminate(xconn
,
2352 } else if (req
->do_signing
) {
2353 struct smbXsrv_session
*x
= req
->session
;
2354 struct smb2_signing_key
*signing_key
=
2355 smbd_smb2_signing_key(x
, xconn
);
2357 status
= smb2_signing_sign_pdu(signing_key
,
2359 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
],
2360 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2361 if (!NT_STATUS_IS_OK(status
)) {
2362 smbd_server_connection_terminate(xconn
,
2368 state
->queue_entry
.mem_ctx
= state
;
2369 state
->queue_entry
.vector
= state
->vector
;
2370 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
2371 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
2372 xconn
->smb2
.send_queue_len
++;
2374 status
= smbd_smb2_flush_send_queue(xconn
);
2375 if (!NT_STATUS_IS_OK(status
)) {
2376 smbd_server_connection_terminate(xconn
,
2382 static NTSTATUS
smbd_smb2_request_process_cancel(struct smbd_smb2_request
*req
)
2384 struct smbXsrv_connection
*xconn
= req
->xconn
;
2385 struct smbd_smb2_request
*cur
;
2386 const uint8_t *inhdr
;
2388 uint64_t search_message_id
;
2389 uint64_t search_async_id
;
2392 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2394 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2395 search_message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
2396 search_async_id
= BVAL(inhdr
, SMB2_HDR_PID
);
2399 * We don't need the request anymore cancel requests never
2402 * We defer the TALLOC_FREE(req) to the caller.
2404 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
2406 for (cur
= xconn
->smb2
.requests
; cur
; cur
= cur
->next
) {
2407 const uint8_t *outhdr
;
2408 uint64_t message_id
;
2411 if (cur
->compound_related
) {
2413 * Never cancel anything in a compound request.
2414 * Way too hard to deal with the result.
2419 outhdr
= SMBD_SMB2_OUT_HDR_PTR(cur
);
2421 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
2422 async_id
= BVAL(outhdr
, SMB2_HDR_PID
);
2424 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
2425 if (search_async_id
== async_id
) {
2426 found_id
= async_id
;
2430 if (search_message_id
== message_id
) {
2431 found_id
= message_id
;
2437 if (cur
&& cur
->subreq
) {
2438 inhdr
= SMBD_SMB2_IN_HDR_PTR(cur
);
2439 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2440 "cancel opcode[%s] mid %llu\n",
2441 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
2442 (unsigned long long)found_id
));
2443 tevent_req_cancel(cur
->subreq
);
2446 return NT_STATUS_OK
;
2449 /*************************************************************
2450 Ensure an incoming tid is a valid one for us to access.
2451 Change to the associated uid credentials and chdir to the
2452 valid tid directory.
2453 *************************************************************/
2455 static NTSTATUS
smbd_smb2_request_check_tcon(struct smbd_smb2_request
*req
)
2457 const uint8_t *inhdr
;
2460 struct smbXsrv_tcon
*tcon
;
2462 NTTIME now
= timeval_to_nttime(&req
->request_time
);
2466 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2468 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2469 in_tid
= IVAL(inhdr
, SMB2_HDR_TID
);
2471 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
2472 in_tid
= req
->last_tid
;
2477 status
= smb2srv_tcon_lookup(req
->session
,
2478 in_tid
, now
, &tcon
);
2479 if (!NT_STATUS_IS_OK(status
)) {
2483 if (!change_to_user_and_service(
2485 req
->session
->global
->session_wire_id
))
2487 return NT_STATUS_ACCESS_DENIED
;
2491 req
->last_tid
= in_tid
;
2493 return NT_STATUS_OK
;
2496 /*************************************************************
2497 Ensure an incoming session_id is a valid one for us to access.
2498 *************************************************************/
2500 static NTSTATUS
smbd_smb2_request_check_session(struct smbd_smb2_request
*req
)
2502 const uint8_t *inhdr
;
2505 uint64_t in_session_id
;
2506 struct smbXsrv_session
*session
= NULL
;
2507 struct auth_session_info
*session_info
;
2509 NTTIME now
= timeval_to_nttime(&req
->request_time
);
2511 req
->session
= NULL
;
2514 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2516 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2517 in_opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2518 in_session_id
= BVAL(inhdr
, SMB2_HDR_SESSION_ID
);
2520 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
2521 in_session_id
= req
->last_session_id
;
2524 req
->last_session_id
= 0;
2526 /* look an existing session up */
2527 switch (in_opcode
) {
2528 case SMB2_OP_SESSSETUP
:
2530 * For a session bind request, we don't have the
2531 * channel set up at this point yet, so we defer
2532 * the verification that the connection belongs
2533 * to the session to the session setup code, which
2534 * can look at the session binding flags.
2536 status
= smb2srv_session_lookup_client(req
->xconn
->client
,
2541 status
= smb2srv_session_lookup_conn(req
->xconn
,
2547 req
->session
= session
;
2548 req
->last_session_id
= in_session_id
;
2550 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
2551 switch (in_opcode
) {
2552 case SMB2_OP_SESSSETUP
:
2553 status
= NT_STATUS_OK
;
2555 case SMB2_OP_LOGOFF
:
2558 case SMB2_OP_CANCEL
:
2559 case SMB2_OP_KEEPALIVE
:
2561 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2562 * specifies that LOGOFF, CLOSE and (UN)LOCK
2563 * should always be processed even on expired sessions.
2565 * Also see the logic in
2566 * smbd_smb2_request_process_lock().
2568 * The smb2.session.expire2 test shows that
2569 * CANCEL and KEEPALIVE/ECHO should also
2572 status
= NT_STATUS_OK
;
2578 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2579 switch (in_opcode
) {
2581 case SMB2_OP_CREATE
:
2582 case SMB2_OP_GETINFO
:
2583 case SMB2_OP_SETINFO
:
2584 return NT_STATUS_INVALID_HANDLE
;
2587 * Notice the check for
2588 * (session_info == NULL)
2591 status
= NT_STATUS_OK
;
2595 if (!NT_STATUS_IS_OK(status
)) {
2599 session_info
= session
->global
->auth_session_info
;
2600 if (session_info
== NULL
) {
2601 return NT_STATUS_INVALID_HANDLE
;
2604 return NT_STATUS_OK
;
2607 NTSTATUS
smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request
*req
,
2608 uint32_t data_length
)
2610 struct smbXsrv_connection
*xconn
= req
->xconn
;
2611 uint16_t needed_charge
;
2612 uint16_t credit_charge
= 1;
2613 const uint8_t *inhdr
;
2615 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2617 if (xconn
->smb2
.credits
.multicredit
) {
2618 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
2619 credit_charge
= MAX(credit_charge
, 1);
2622 needed_charge
= (data_length
- 1)/ 65536 + 1;
2624 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
2625 "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2626 (unsigned long long) BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
),
2627 credit_charge
, needed_charge
);
2629 if (needed_charge
> credit_charge
) {
2630 DBGC_WARNING(DBGC_SMB2_CREDITS
,
2631 "CreditCharge too low, given %d, needed %d\n",
2632 credit_charge
, needed_charge
);
2633 return NT_STATUS_INVALID_PARAMETER
;
2636 return NT_STATUS_OK
;
2639 NTSTATUS
smbd_smb2_request_verify_sizes(struct smbd_smb2_request
*req
,
2640 size_t expected_body_size
)
2642 struct iovec
*inhdr_v
;
2643 const uint8_t *inhdr
;
2645 const uint8_t *inbody
;
2647 size_t min_dyn_size
= expected_body_size
& 0x00000001;
2648 int max_idx
= req
->in
.vector_count
- SMBD_SMB2_NUM_IOV_PER_REQ
;
2651 * The following should be checked already.
2653 if (req
->in
.vector_count
< SMBD_SMB2_NUM_IOV_PER_REQ
) {
2654 return NT_STATUS_INTERNAL_ERROR
;
2656 if (req
->current_idx
> max_idx
) {
2657 return NT_STATUS_INTERNAL_ERROR
;
2660 inhdr_v
= SMBD_SMB2_IN_HDR_IOV(req
);
2661 if (inhdr_v
->iov_len
!= SMB2_HDR_BODY
) {
2662 return NT_STATUS_INTERNAL_ERROR
;
2664 if (SMBD_SMB2_IN_BODY_LEN(req
) < 2) {
2665 return NT_STATUS_INTERNAL_ERROR
;
2668 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2669 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2673 case SMB2_OP_GETINFO
:
2680 * Now check the expected body size,
2681 * where the last byte might be in the
2684 if (SMBD_SMB2_IN_BODY_LEN(req
) != (expected_body_size
& 0xFFFFFFFE)) {
2685 return NT_STATUS_INVALID_PARAMETER
;
2687 if (SMBD_SMB2_IN_DYN_LEN(req
) < min_dyn_size
) {
2688 return NT_STATUS_INVALID_PARAMETER
;
2691 inbody
= SMBD_SMB2_IN_BODY_PTR(req
);
2693 body_size
= SVAL(inbody
, 0x00);
2694 if (body_size
!= expected_body_size
) {
2695 return NT_STATUS_INVALID_PARAMETER
;
2698 return NT_STATUS_OK
;
2701 bool smbXsrv_is_encrypted(uint8_t encryption_flags
)
2703 return (!(encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
)
2705 (encryption_flags
& (SMBXSRV_PROCESSED_ENCRYPTED_PACKET
|
2706 SMBXSRV_ENCRYPTION_DESIRED
|
2707 SMBXSRV_ENCRYPTION_REQUIRED
)));
2710 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags
)
2712 return ((encryption_flags
& SMBXSRV_PROCESSED_ENCRYPTED_PACKET
) &&
2713 (encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
));
2716 /* Set a flag if not already set, return true if set */
2717 bool smbXsrv_set_crypto_flag(uint8_t *flags
, uint8_t flag
)
2719 if ((flag
== 0) || (*flags
& flag
)) {
2728 * Update encryption state tracking flags, this can be used to
2729 * determine whether whether the session or tcon is "encrypted".
2731 static void smb2srv_update_crypto_flags(struct smbd_smb2_request
*req
,
2733 bool *update_session_globalp
,
2734 bool *update_tcon_globalp
)
2736 /* Default: assume unecrypted and unsigned */
2737 struct smbXsrv_session
*session
= req
->session
;
2738 struct smbXsrv_tcon
*tcon
= req
->tcon
;
2739 uint8_t encrypt_flag
= SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
;
2740 uint8_t sign_flag
= SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
2741 bool update_session
= false;
2742 bool update_tcon
= false;
2744 if (req
->was_encrypted
&& req
->do_encryption
) {
2745 encrypt_flag
= SMBXSRV_PROCESSED_ENCRYPTED_PACKET
;
2746 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2748 /* Unencrypted packet, can be signed */
2749 if (req
->do_signing
) {
2750 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2751 } else if (opcode
== SMB2_OP_CANCEL
) {
2752 /* Cancel requests are allowed to skip signing */
2753 sign_flag
&= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
2757 update_session
|= smbXsrv_set_crypto_flag(
2758 &session
->global
->encryption_flags
, encrypt_flag
);
2759 update_session
|= smbXsrv_set_crypto_flag(
2760 &session
->global
->signing_flags
, sign_flag
);
2763 update_tcon
|= smbXsrv_set_crypto_flag(
2764 &tcon
->global
->encryption_flags
, encrypt_flag
);
2765 update_tcon
|= smbXsrv_set_crypto_flag(
2766 &tcon
->global
->signing_flags
, sign_flag
);
2769 *update_session_globalp
= update_session
;
2770 *update_tcon_globalp
= update_tcon
;
2774 bool smbXsrv_is_signed(uint8_t signing_flags
)
2777 * Signing is always enabled, so unless we got an unsigned
2778 * packet and at least one signed packet that was not
2779 * encrypted, the session or tcon is "signed".
2781 return (!(signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2782 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2785 bool smbXsrv_is_partially_signed(uint8_t signing_flags
)
2787 return ((signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2788 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2791 static NTSTATUS
smbd_smb2_request_dispatch_update_counts(
2792 struct smbd_smb2_request
*req
,
2795 struct smbXsrv_connection
*xconn
= req
->xconn
;
2796 const uint8_t *inhdr
;
2797 uint16_t channel_sequence
;
2798 uint8_t generation_wrap
= 0;
2801 struct smbXsrv_open
*op
;
2802 bool update_open
= false;
2803 NTSTATUS status
= NT_STATUS_OK
;
2805 SMB_ASSERT(!req
->request_counters_updated
);
2807 if (xconn
->protocol
< PROTOCOL_SMB2_22
) {
2808 return NT_STATUS_OK
;
2811 if (req
->compat_chain_fsp
== NULL
) {
2812 return NT_STATUS_OK
;
2815 op
= req
->compat_chain_fsp
->op
;
2817 return NT_STATUS_OK
;
2820 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2821 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2822 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
2824 cmp
= channel_sequence
- op
->global
->channel_sequence
;
2827 * csn wrap. We need to watch out for long-running
2828 * requests that are still sitting on a previously
2829 * used csn. SMB2_OP_NOTIFY can take VERY long.
2831 generation_wrap
+= 1;
2834 if (abs(cmp
) > INT16_MAX
) {
2836 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2838 * If the channel sequence number of the request and the one
2839 * known to the server are not equal, the channel sequence
2840 * number and outstanding request counts are only updated
2841 * "... if the unsigned difference using 16-bit arithmetic
2842 * between ChannelSequence and Open.ChannelSequence is less than
2843 * or equal to 0x7FFF ...".
2844 * Otherwise, an error is returned for the modifying
2845 * calls write, set_info, and ioctl.
2847 * There are currently two issues with the description:
2849 * * For the other calls, the document seems to imply
2850 * that processing continues without adapting the
2851 * counters (if the sequence numbers are not equal).
2853 * TODO: This needs clarification!
2855 * * Also, the behaviour if the difference is larger
2856 * than 0x7FFF is not clear. The document seems to
2857 * imply that if such a difference is reached,
2858 * the server starts to ignore the counters or
2859 * in the case of the modifying calls, return errors.
2861 * TODO: This needs clarification!
2863 * At this point Samba tries to be a little more
2864 * clever than the description in the MS-SMB2 document
2865 * by heuristically detecting and properly treating
2866 * a 16 bit overflow of the client-submitted sequence
2869 * If the stored channel sequence number is more than
2870 * 0x7FFF larger than the one from the request, then
2871 * the client-provided sequence number has likely
2872 * overflown. We treat this case as valid instead
2875 * The MS-SMB2 behaviour would be setting cmp = -1.
2880 if (flags
& SMB2_HDR_FLAG_REPLAY_OPERATION
) {
2881 if (cmp
== 0 && op
->pre_request_count
== 0) {
2882 op
->request_count
+= 1;
2883 req
->request_counters_updated
= true;
2884 } else if (cmp
> 0 && op
->pre_request_count
== 0) {
2885 op
->pre_request_count
+= op
->request_count
;
2886 op
->request_count
= 1;
2887 op
->global
->channel_sequence
= channel_sequence
;
2888 op
->global
->channel_generation
+= generation_wrap
;
2890 req
->request_counters_updated
= true;
2891 } else if (modify_call
) {
2892 return NT_STATUS_FILE_NOT_AVAILABLE
;
2896 op
->request_count
+= 1;
2897 req
->request_counters_updated
= true;
2898 } else if (cmp
> 0) {
2899 op
->pre_request_count
+= op
->request_count
;
2900 op
->request_count
= 1;
2901 op
->global
->channel_sequence
= channel_sequence
;
2902 op
->global
->channel_generation
+= generation_wrap
;
2904 req
->request_counters_updated
= true;
2905 } else if (modify_call
) {
2906 return NT_STATUS_FILE_NOT_AVAILABLE
;
2909 req
->channel_generation
= op
->global
->channel_generation
;
2912 status
= smbXsrv_open_update(op
);
2918 NTSTATUS
smbd_smb2_request_dispatch(struct smbd_smb2_request
*req
)
2920 struct smbXsrv_connection
*xconn
= req
->xconn
;
2921 const struct smbd_smb2_dispatch_table
*call
= NULL
;
2922 const struct iovec
*intf_v
= SMBD_SMB2_IN_TF_IOV(req
);
2923 const uint8_t *inhdr
;
2928 NTSTATUS session_status
;
2929 uint32_t allowed_flags
;
2930 NTSTATUS return_value
;
2931 struct smbXsrv_session
*x
= NULL
;
2932 bool signing_required
= false;
2933 bool encryption_desired
= false;
2934 bool encryption_required
= false;
2936 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2938 DO_PROFILE_INC(request
);
2940 SMB_ASSERT(!req
->request_counters_updated
);
2942 /* TODO: verify more things */
2944 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2945 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2946 mid
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
2947 DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2948 smb2_opcode_name(opcode
),
2949 (unsigned long long)mid
));
2951 if (xconn
->protocol
>= PROTOCOL_SMB2_02
) {
2953 * once the protocol is negotiated
2954 * SMB2_OP_NEGPROT is not allowed anymore
2956 if (opcode
== SMB2_OP_NEGPROT
) {
2957 /* drop the connection */
2958 return NT_STATUS_INVALID_PARAMETER
;
2962 * if the protocol is not negotiated yet
2963 * only SMB2_OP_NEGPROT is allowed.
2965 if (opcode
!= SMB2_OP_NEGPROT
) {
2966 /* drop the connection */
2967 return NT_STATUS_INVALID_PARAMETER
;
2972 * Check if the client provided a valid session id.
2974 * As some command don't require a valid session id
2975 * we defer the check of the session_status
2977 session_status
= smbd_smb2_request_check_session(req
);
2980 signing_required
= x
->global
->signing_flags
& SMBXSRV_SIGNING_REQUIRED
;
2981 encryption_desired
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
;
2982 encryption_required
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
;
2985 req
->async_internal
= false;
2986 req
->do_signing
= false;
2987 if (opcode
!= SMB2_OP_SESSSETUP
) {
2988 req
->do_encryption
= encryption_desired
;
2990 req
->do_encryption
= false;
2992 req
->was_encrypted
= false;
2993 if (intf_v
->iov_len
== SMB2_TF_HDR_SIZE
) {
2994 const uint8_t *intf
= SMBD_SMB2_IN_TF_PTR(req
);
2995 uint64_t tf_session_id
= BVAL(intf
, SMB2_TF_SESSION_ID
);
2997 if (x
!= NULL
&& x
->global
->session_wire_id
!= tf_session_id
) {
2998 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2999 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
3000 (unsigned long long)x
->global
->session_wire_id
,
3001 (unsigned long long)tf_session_id
));
3003 * TODO: windows allows this...
3004 * should we drop the connection?
3006 * For now we just return ACCESS_DENIED
3007 * (Windows clients never trigger this)
3008 * and wait for an update of [MS-SMB2].
3010 return smbd_smb2_request_error(req
,
3011 NT_STATUS_ACCESS_DENIED
);
3014 req
->was_encrypted
= true;
3015 req
->do_encryption
= true;
3018 if (encryption_required
&& !req
->was_encrypted
) {
3019 req
->do_encryption
= true;
3020 return smbd_smb2_request_error(req
,
3021 NT_STATUS_ACCESS_DENIED
);
3024 call
= smbd_smb2_call(opcode
);
3026 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3029 allowed_flags
= SMB2_HDR_FLAG_CHAINED
|
3030 SMB2_HDR_FLAG_SIGNED
|
3032 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
3033 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
3035 if (opcode
== SMB2_OP_NEGPROT
) {
3036 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11
) {
3037 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
3040 if (opcode
== SMB2_OP_CANCEL
) {
3041 allowed_flags
|= SMB2_HDR_FLAG_ASYNC
;
3043 if (xconn
->protocol
>= PROTOCOL_SMB2_22
) {
3044 allowed_flags
|= SMB2_HDR_FLAG_REPLAY_OPERATION
;
3046 if ((flags
& ~allowed_flags
) != 0) {
3047 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3050 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3052 * This check is mostly for giving the correct error code
3053 * for compounded requests.
3055 if (!NT_STATUS_IS_OK(session_status
)) {
3056 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3059 req
->compat_chain_fsp
= NULL
;
3062 if (req
->was_encrypted
) {
3063 signing_required
= false;
3064 } else if (signing_required
|| (flags
& SMB2_HDR_FLAG_SIGNED
)) {
3065 struct smb2_signing_key
*signing_key
= NULL
;
3069 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3070 * If the SMB2 header of the SMB2 NEGOTIATE
3071 * request has the SMB2_FLAGS_SIGNED bit set in the
3072 * Flags field, the server MUST fail the request
3073 * with STATUS_INVALID_PARAMETER.
3075 * Microsoft test tool checks this.
3078 if ((opcode
== SMB2_OP_NEGPROT
) &&
3079 (flags
& SMB2_HDR_FLAG_SIGNED
)) {
3080 status
= NT_STATUS_INVALID_PARAMETER
;
3082 status
= NT_STATUS_USER_SESSION_DELETED
;
3084 return smbd_smb2_request_error(req
, status
);
3087 signing_key
= smbd_smb2_signing_key(x
, xconn
);
3090 * If we have a signing key, we should
3093 if (smb2_signing_key_valid(signing_key
)) {
3094 req
->do_signing
= true;
3097 status
= smb2_signing_check_pdu(signing_key
,
3099 SMBD_SMB2_IN_HDR_IOV(req
),
3100 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3101 if (!NT_STATUS_IS_OK(status
)) {
3102 return smbd_smb2_request_error(req
, status
);
3106 * Now that we know the request was correctly signed
3107 * we have to sign the response too.
3109 req
->do_signing
= true;
3111 if (!NT_STATUS_IS_OK(session_status
)) {
3112 return smbd_smb2_request_error(req
, session_status
);
3114 } else if (opcode
== SMB2_OP_CANCEL
) {
3115 /* Cancel requests are allowed to skip the signing */
3116 } else if (opcode
== SMB2_OP_IOCTL
) {
3118 * Some special IOCTL calls don't require
3119 * file, tcon nor session.
3121 * They typically don't do any real action
3122 * on behalf of the client.
3124 * They are mainly used to alter the behavior
3125 * of the connection for testing. So we can
3126 * run as root and skip all file, tcon and session
3129 static const struct smbd_smb2_dispatch_table _root_ioctl_call
= {
3133 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
3134 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
3135 uint32_t in_ctl_code
;
3138 if (needed
> body_size
) {
3139 return smbd_smb2_request_error(req
,
3140 NT_STATUS_INVALID_PARAMETER
);
3143 in_ctl_code
= IVAL(body
, 0x04);
3145 * Only add trusted IOCTL codes here!
3147 switch (in_ctl_code
) {
3148 case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT
:
3149 call
= &_root_ioctl_call
;
3152 } else if (signing_required
) {
3154 * If signing is required we try to sign
3155 * a possible error response
3157 req
->do_signing
= true;
3158 return smbd_smb2_request_error(req
, NT_STATUS_ACCESS_DENIED
);
3161 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3162 req
->compound_related
= true;
3165 if (call
->need_session
) {
3166 if (!NT_STATUS_IS_OK(session_status
)) {
3167 return smbd_smb2_request_error(req
, session_status
);
3171 if (call
->need_tcon
) {
3172 SMB_ASSERT(call
->need_session
);
3175 * This call needs to be run as user.
3177 * smbd_smb2_request_check_tcon()
3178 * calls change_to_user() on success.
3179 * Which implies set_current_user_info()
3180 * and chdir_current_service().
3182 status
= smbd_smb2_request_check_tcon(req
);
3183 if (!NT_STATUS_IS_OK(status
)) {
3184 return smbd_smb2_request_error(req
, status
);
3186 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
) {
3187 encryption_desired
= true;
3189 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
) {
3190 encryption_required
= true;
3192 if (encryption_required
&& !req
->was_encrypted
) {
3193 req
->do_encryption
= true;
3194 return smbd_smb2_request_error(req
,
3195 NT_STATUS_ACCESS_DENIED
);
3196 } else if (encryption_desired
) {
3197 req
->do_encryption
= true;
3199 } else if (call
->need_session
) {
3200 struct auth_session_info
*session_info
= NULL
;
3203 * Unless we also have need_tcon (see above),
3204 * we still need to call set_current_user_info().
3207 session_info
= req
->session
->global
->auth_session_info
;
3208 if (session_info
== NULL
) {
3209 return NT_STATUS_INVALID_HANDLE
;
3212 set_current_user_info(session_info
->unix_info
->sanitized_username
,
3213 session_info
->unix_info
->unix_name
,
3214 session_info
->info
->domain_name
);
3218 bool update_session_global
= false;
3219 bool update_tcon_global
= false;
3221 smb2srv_update_crypto_flags(req
, opcode
,
3222 &update_session_global
,
3223 &update_tcon_global
);
3225 if (update_session_global
) {
3226 status
= smbXsrv_session_update(x
);
3227 if (!NT_STATUS_IS_OK(status
)) {
3228 return smbd_smb2_request_error(req
, status
);
3231 if (update_tcon_global
) {
3232 status
= smbXsrv_tcon_update(req
->tcon
);
3233 if (!NT_STATUS_IS_OK(status
)) {
3234 return smbd_smb2_request_error(req
, status
);
3239 if (call
->fileid_ofs
!= 0) {
3240 size_t needed
= call
->fileid_ofs
+ 16;
3241 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
3242 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
3243 uint64_t file_id_persistent
;
3244 uint64_t file_id_volatile
;
3245 struct files_struct
*fsp
;
3247 SMB_ASSERT(call
->need_tcon
);
3249 if (needed
> body_size
) {
3250 return smbd_smb2_request_error(req
,
3251 NT_STATUS_INVALID_PARAMETER
);
3254 file_id_persistent
= BVAL(body
, call
->fileid_ofs
+ 0);
3255 file_id_volatile
= BVAL(body
, call
->fileid_ofs
+ 8);
3257 fsp
= file_fsp_smb2(req
, file_id_persistent
, file_id_volatile
);
3259 if (!call
->allow_invalid_fileid
) {
3260 return smbd_smb2_request_error(req
,
3261 NT_STATUS_FILE_CLOSED
);
3264 if (file_id_persistent
!= UINT64_MAX
) {
3265 return smbd_smb2_request_error(req
,
3266 NT_STATUS_FILE_CLOSED
);
3268 if (file_id_volatile
!= UINT64_MAX
) {
3269 return smbd_smb2_request_error(req
,
3270 NT_STATUS_FILE_CLOSED
);
3273 if (fsp
->fsp_flags
.encryption_required
&& !req
->was_encrypted
) {
3274 return smbd_smb2_request_error(req
,
3275 NT_STATUS_ACCESS_DENIED
);
3280 status
= smbd_smb2_request_dispatch_update_counts(req
, call
->modify
);
3281 if (!NT_STATUS_IS_OK(status
)) {
3282 return smbd_smb2_request_error(req
, status
);
3285 if (call
->as_root
) {
3286 SMB_ASSERT(call
->fileid_ofs
== 0);
3287 /* This call needs to be run as root */
3288 change_to_root_user();
3290 SMB_ASSERT(call
->need_tcon
);
3293 #define _INBYTES(_r) \
3294 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3297 case SMB2_OP_NEGPROT
:
3298 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot
, profile_p
,
3299 req
->profile
, _INBYTES(req
));
3300 return_value
= smbd_smb2_request_process_negprot(req
);
3303 case SMB2_OP_SESSSETUP
:
3304 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup
, profile_p
,
3305 req
->profile
, _INBYTES(req
));
3306 return_value
= smbd_smb2_request_process_sesssetup(req
);
3309 case SMB2_OP_LOGOFF
:
3310 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff
, profile_p
,
3311 req
->profile
, _INBYTES(req
));
3312 return_value
= smbd_smb2_request_process_logoff(req
);
3316 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon
, profile_p
,
3317 req
->profile
, _INBYTES(req
));
3318 return_value
= smbd_smb2_request_process_tcon(req
);
3322 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis
, profile_p
,
3323 req
->profile
, _INBYTES(req
));
3324 return_value
= smbd_smb2_request_process_tdis(req
);
3327 case SMB2_OP_CREATE
:
3328 if (req
->subreq
== NULL
) {
3329 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create
, profile_p
,
3330 req
->profile
, _INBYTES(req
));
3332 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req
->profile
);
3334 return_value
= smbd_smb2_request_process_create(req
);
3338 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close
, profile_p
,
3339 req
->profile
, _INBYTES(req
));
3340 return_value
= smbd_smb2_request_process_close(req
);
3344 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush
, profile_p
,
3345 req
->profile
, _INBYTES(req
));
3346 return_value
= smbd_smb2_request_process_flush(req
);
3350 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read
, profile_p
,
3351 req
->profile
, _INBYTES(req
));
3352 return_value
= smbd_smb2_request_process_read(req
);
3356 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write
, profile_p
,
3357 req
->profile
, _INBYTES(req
));
3358 return_value
= smbd_smb2_request_process_write(req
);
3362 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock
, profile_p
,
3363 req
->profile
, _INBYTES(req
));
3364 return_value
= smbd_smb2_request_process_lock(req
);
3368 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl
, profile_p
,
3369 req
->profile
, _INBYTES(req
));
3370 return_value
= smbd_smb2_request_process_ioctl(req
);
3373 case SMB2_OP_CANCEL
:
3374 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel
, profile_p
,
3375 req
->profile
, _INBYTES(req
));
3376 return_value
= smbd_smb2_request_process_cancel(req
);
3377 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
, 0);
3380 * We don't need the request anymore cancel requests never
3383 * smbd_smb2_request_process_cancel() already called
3384 * DLIST_REMOVE(xconn->smb2.requests, req);
3390 case SMB2_OP_KEEPALIVE
:
3391 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive
, profile_p
,
3392 req
->profile
, _INBYTES(req
));
3393 return_value
= smbd_smb2_request_process_keepalive(req
);
3396 case SMB2_OP_QUERY_DIRECTORY
:
3397 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find
, profile_p
,
3398 req
->profile
, _INBYTES(req
));
3399 return_value
= smbd_smb2_request_process_query_directory(req
);
3402 case SMB2_OP_NOTIFY
:
3403 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify
, profile_p
,
3404 req
->profile
, _INBYTES(req
));
3405 return_value
= smbd_smb2_request_process_notify(req
);
3408 case SMB2_OP_GETINFO
:
3409 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo
, profile_p
,
3410 req
->profile
, _INBYTES(req
));
3411 return_value
= smbd_smb2_request_process_getinfo(req
);
3414 case SMB2_OP_SETINFO
:
3415 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo
, profile_p
,
3416 req
->profile
, _INBYTES(req
));
3417 return_value
= smbd_smb2_request_process_setinfo(req
);
3421 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break
, profile_p
,
3422 req
->profile
, _INBYTES(req
));
3423 return_value
= smbd_smb2_request_process_break(req
);
3427 return_value
= smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3430 return return_value
;
3433 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request
*req
)
3435 struct smbXsrv_connection
*xconn
= req
->xconn
;
3436 const uint8_t *inhdr
;
3437 uint16_t channel_sequence
;
3438 struct smbXsrv_open
*op
;
3440 if (!req
->request_counters_updated
) {
3444 req
->request_counters_updated
= false;
3446 if (xconn
->protocol
< PROTOCOL_SMB2_22
) {
3450 if (req
->compat_chain_fsp
== NULL
) {
3454 op
= req
->compat_chain_fsp
->op
;
3459 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
3460 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
3462 if ((op
->global
->channel_sequence
== channel_sequence
) &&
3463 (op
->global
->channel_generation
== req
->channel_generation
)) {
3464 SMB_ASSERT(op
->request_count
> 0);
3465 op
->request_count
-= 1;
3467 SMB_ASSERT(op
->pre_request_count
> 0);
3468 op
->pre_request_count
-= 1;
3472 static NTSTATUS
smbd_smb2_request_reply(struct smbd_smb2_request
*req
)
3474 struct smbXsrv_connection
*xconn
= req
->xconn
;
3476 struct iovec
*firsttf
= SMBD_SMB2_IDX_TF_IOV(req
,out
,first_idx
);
3477 struct iovec
*outhdr
= SMBD_SMB2_OUT_HDR_IOV(req
);
3478 struct iovec
*outdyn
= SMBD_SMB2_OUT_DYN_IOV(req
);
3483 TALLOC_FREE(req
->async_te
);
3485 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3486 smbd_smb2_request_reply_update_counts(req
);
3488 if (req
->do_encryption
&&
3489 (firsttf
->iov_len
== 0) &&
3490 (req
->first_key
.length
== 0) &&
3491 (req
->session
!= NULL
) &&
3492 smb2_signing_key_valid(req
->session
->global
->encryption_key
))
3494 struct smb2_signing_key
*encryption_key
=
3495 req
->session
->global
->encryption_key
;
3497 uint64_t session_id
= req
->session
->global
->session_wire_id
;
3498 uint64_t nonce_high
;
3501 status
= smb2_get_new_nonce(req
->session
,
3504 if (!NT_STATUS_IS_OK(status
)) {
3509 * We need to place the SMB2_TRANSFORM header before the
3514 * we need to remember the encryption key
3515 * and defer the signing/encryption until
3516 * we are sure that we do not change
3519 req
->first_key
= data_blob_dup_talloc(req
,
3520 encryption_key
->blob
);
3521 if (req
->first_key
.data
== NULL
) {
3522 return NT_STATUS_NO_MEMORY
;
3525 tf
= talloc_zero_array(req
, uint8_t,
3528 return NT_STATUS_NO_MEMORY
;
3531 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
3532 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
3533 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
3534 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
3536 firsttf
->iov_base
= (void *)tf
;
3537 firsttf
->iov_len
= SMB2_TF_HDR_SIZE
;
3540 if ((req
->current_idx
> SMBD_SMB2_NUM_IOV_PER_REQ
) &&
3541 (req
->last_key
.length
> 0) &&
3542 (firsttf
->iov_len
== 0))
3544 int last_idx
= req
->current_idx
- SMBD_SMB2_NUM_IOV_PER_REQ
;
3545 struct iovec
*lasthdr
= SMBD_SMB2_IDX_HDR_IOV(req
,out
,last_idx
);
3546 struct smb2_signing_key key
= {
3547 .blob
= req
->last_key
,
3551 * As we are sure the header of the last request in the
3552 * compound chain will not change, we can to sign here
3553 * with the last signing key we remembered.
3555 status
= smb2_signing_sign_pdu(&key
,
3558 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3559 smb2_signing_key_destructor(&key
);
3560 if (!NT_STATUS_IS_OK(status
)) {
3564 if (req
->last_key
.length
> 0) {
3565 data_blob_clear_free(&req
->last_key
);
3568 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
,
3569 iov_buflen(outhdr
, SMBD_SMB2_NUM_IOV_PER_REQ
-1));
3571 req
->current_idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
3573 if (req
->current_idx
< req
->out
.vector_count
) {
3575 * We must process the remaining compound
3576 * SMB2 requests before any new incoming SMB2
3577 * requests. This is because incoming SMB2
3578 * requests may include a cancel for a
3579 * compound request we haven't processed
3582 struct tevent_immediate
*im
= tevent_create_immediate(req
);
3584 return NT_STATUS_NO_MEMORY
;
3587 if (req
->do_signing
&& firsttf
->iov_len
== 0) {
3588 struct smbXsrv_session
*x
= req
->session
;
3589 struct smb2_signing_key
*signing_key
=
3590 smbd_smb2_signing_key(x
, xconn
);
3593 * we need to remember the signing key
3594 * and defer the signing until
3595 * we are sure that we do not change
3598 req
->last_key
= data_blob_dup_talloc(req
,
3600 if (req
->last_key
.data
== NULL
) {
3601 return NT_STATUS_NO_MEMORY
;
3606 * smbd_smb2_request_dispatch() will redo the impersonation.
3607 * So we use req->xconn->client->raw_ev_ctx instead
3608 * of req->ev_ctx here.
3610 tevent_schedule_immediate(im
,
3611 req
->xconn
->client
->raw_ev_ctx
,
3612 smbd_smb2_request_dispatch_immediate
,
3614 return NT_STATUS_OK
;
3617 if (req
->compound_related
) {
3618 req
->compound_related
= false;
3621 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
3623 return NT_STATUS_INVALID_PARAMETER_MIX
;
3626 /* Set credit for these operations (zero credits if this
3627 is a final reply for an async operation). */
3628 smb2_calculate_credits(req
, req
);
3631 * now check if we need to sign the current response
3633 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
3634 struct smb2_signing_key key
= {
3635 .blob
= req
->first_key
,
3637 status
= smb2_signing_encrypt_pdu(&key
,
3638 xconn
->smb2
.server
.cipher
,
3640 req
->out
.vector_count
- first_idx
);
3641 smb2_signing_key_destructor(&key
);
3642 if (!NT_STATUS_IS_OK(status
)) {
3645 } else if (req
->do_signing
) {
3646 struct smbXsrv_session
*x
= req
->session
;
3647 struct smb2_signing_key
*signing_key
=
3648 smbd_smb2_signing_key(x
, xconn
);
3650 status
= smb2_signing_sign_pdu(signing_key
,
3653 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3654 if (!NT_STATUS_IS_OK(status
)) {
3658 if (req
->first_key
.length
> 0) {
3659 data_blob_clear_free(&req
->first_key
);
3662 if (req
->preauth
!= NULL
) {
3663 gnutls_hash_hd_t hash_hnd
= NULL
;
3667 rc
= gnutls_hash_init(&hash_hnd
, GNUTLS_DIG_SHA512
);
3669 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3671 rc
= gnutls_hash(hash_hnd
,
3672 req
->preauth
->sha512_value
,
3673 sizeof(req
->preauth
->sha512_value
));
3675 gnutls_hash_deinit(hash_hnd
, NULL
);
3676 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3678 for (i
= 1; i
< req
->in
.vector_count
; i
++) {
3679 rc
= gnutls_hash(hash_hnd
,
3680 req
->in
.vector
[i
].iov_base
,
3681 req
->in
.vector
[i
].iov_len
);
3683 gnutls_hash_deinit(hash_hnd
, NULL
);
3684 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3688 gnutls_hash_deinit(hash_hnd
, NULL
);
3689 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3691 gnutls_hash_output(hash_hnd
, req
->preauth
->sha512_value
);
3693 rc
= gnutls_hash(hash_hnd
,
3694 req
->preauth
->sha512_value
,
3695 sizeof(req
->preauth
->sha512_value
));
3697 gnutls_hash_deinit(hash_hnd
, NULL
);
3698 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3700 for (i
= 1; i
< req
->out
.vector_count
; i
++) {
3701 rc
= gnutls_hash(hash_hnd
,
3702 req
->out
.vector
[i
].iov_base
,
3703 req
->out
.vector
[i
].iov_len
);
3705 gnutls_hash_deinit(hash_hnd
, NULL
);
3706 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3710 gnutls_hash_deinit(hash_hnd
, req
->preauth
->sha512_value
);
3712 req
->preauth
= NULL
;
3715 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3716 if (req
->out
.vector_count
< (2*SMBD_SMB2_NUM_IOV_PER_REQ
) &&
3717 outdyn
->iov_base
== NULL
&& outdyn
->iov_len
!= 0) {
3718 /* Dynamic part is NULL. Chop it off,
3719 We're going to send it via sendfile. */
3720 req
->out
.vector_count
-= 1;
3724 * We're done with this request -
3725 * move it off the "being processed" queue.
3727 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
3729 req
->queue_entry
.mem_ctx
= req
;
3730 req
->queue_entry
.vector
= req
->out
.vector
;
3731 req
->queue_entry
.count
= req
->out
.vector_count
;
3732 DLIST_ADD_END(xconn
->smb2
.send_queue
, &req
->queue_entry
);
3733 xconn
->smb2
.send_queue_len
++;
3735 status
= smbd_smb2_flush_send_queue(xconn
);
3736 if (!NT_STATUS_IS_OK(status
)) {
3740 return NT_STATUS_OK
;
3743 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
);
3745 void smbd_smb2_request_dispatch_immediate(struct tevent_context
*ctx
,
3746 struct tevent_immediate
*im
,
3749 struct smbd_smb2_request
*req
= talloc_get_type_abort(private_data
,
3750 struct smbd_smb2_request
);
3751 struct smbXsrv_connection
*xconn
= req
->xconn
;
3756 if (DEBUGLEVEL
>= 10) {
3757 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3758 req
->current_idx
, req
->in
.vector_count
));
3759 print_req_vectors(req
);
3762 status
= smbd_smb2_request_dispatch(req
);
3763 if (!NT_STATUS_IS_OK(status
)) {
3764 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3768 status
= smbd_smb2_request_next_incoming(xconn
);
3769 if (!NT_STATUS_IS_OK(status
)) {
3770 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3775 NTSTATUS
smbd_smb2_request_done_ex(struct smbd_smb2_request
*req
,
3777 DATA_BLOB body
, DATA_BLOB
*dyn
,
3778 const char *location
)
3781 struct iovec
*outbody_v
;
3782 struct iovec
*outdyn_v
;
3783 uint32_t next_command_ofs
;
3786 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
3787 mid
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
3789 DBG_DEBUG("mid [%"PRIu64
"] idx[%d] status[%s] "
3790 "body[%u] dyn[%s:%u] at %s\n",
3794 (unsigned int)body
.length
,
3796 (unsigned int)(dyn
? dyn
->length
: 0),
3799 if (body
.length
< 2) {
3800 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
3803 if ((body
.length
% 2) != 0) {
3804 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
3807 outbody_v
= SMBD_SMB2_OUT_BODY_IOV(req
);
3808 outdyn_v
= SMBD_SMB2_OUT_DYN_IOV(req
);
3810 next_command_ofs
= IVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
);
3811 SIVAL(outhdr
, SMB2_HDR_STATUS
, NT_STATUS_V(status
));
3813 outbody_v
->iov_base
= (void *)body
.data
;
3814 outbody_v
->iov_len
= body
.length
;
3817 outdyn_v
->iov_base
= (void *)dyn
->data
;
3818 outdyn_v
->iov_len
= dyn
->length
;
3820 outdyn_v
->iov_base
= NULL
;
3821 outdyn_v
->iov_len
= 0;
3825 * See if we need to recalculate the offset to the next response
3827 * Note that all responses may require padding (including the very last
3830 if (req
->out
.vector_count
>= (2 * SMBD_SMB2_NUM_IOV_PER_REQ
)) {
3831 next_command_ofs
= SMB2_HDR_BODY
;
3832 next_command_ofs
+= SMBD_SMB2_OUT_BODY_LEN(req
);
3833 next_command_ofs
+= SMBD_SMB2_OUT_DYN_LEN(req
);
3836 if ((next_command_ofs
% 8) != 0) {
3837 size_t pad_size
= 8 - (next_command_ofs
% 8);
3838 if (SMBD_SMB2_OUT_DYN_LEN(req
) == 0) {
3840 * if the dyn buffer is empty
3841 * we can use it to add padding
3845 pad
= talloc_zero_array(req
,
3848 return smbd_smb2_request_error(req
,
3849 NT_STATUS_NO_MEMORY
);
3852 outdyn_v
->iov_base
= (void *)pad
;
3853 outdyn_v
->iov_len
= pad_size
;
3856 * For now we copy the dynamic buffer
3857 * and add the padding to the new buffer
3864 old_size
= SMBD_SMB2_OUT_DYN_LEN(req
);
3865 old_dyn
= SMBD_SMB2_OUT_DYN_PTR(req
);
3867 new_size
= old_size
+ pad_size
;
3868 new_dyn
= talloc_zero_array(req
,
3870 if (new_dyn
== NULL
) {
3871 return smbd_smb2_request_error(req
,
3872 NT_STATUS_NO_MEMORY
);
3875 memcpy(new_dyn
, old_dyn
, old_size
);
3876 memset(new_dyn
+ old_size
, 0, pad_size
);
3878 outdyn_v
->iov_base
= (void *)new_dyn
;
3879 outdyn_v
->iov_len
= new_size
;
3881 next_command_ofs
+= pad_size
;
3884 if ((req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) >= req
->out
.vector_count
) {
3885 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
3887 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
3889 return smbd_smb2_request_reply(req
);
3892 NTSTATUS
smbd_smb2_request_error_ex(struct smbd_smb2_request
*req
,
3895 const char *location
)
3897 struct smbXsrv_connection
*xconn
= req
->xconn
;
3900 uint8_t *outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
3901 size_t unread_bytes
= smbd_smb2_unread_bytes(req
);
3903 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3904 "at %s\n", req
->current_idx
, nt_errstr(status
),
3905 info
? " +info" : "", location
);
3908 /* Recvfile error. Drain incoming socket. */
3912 ret
= drain_socket(xconn
->transport
.sock
, unread_bytes
);
3913 if (ret
!= unread_bytes
) {
3917 error
= NT_STATUS_IO_DEVICE_ERROR
;
3919 error
= map_nt_error_from_unix_common(errno
);
3922 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3923 "ret[%u] errno[%d] => %s\n",
3924 (unsigned)unread_bytes
,
3925 (unsigned)ret
, errno
, nt_errstr(error
)));
3930 body
.data
= outhdr
+ SMB2_HDR_BODY
;
3932 SSVAL(body
.data
, 0, 9);
3935 SIVAL(body
.data
, 0x04, info
->length
);
3937 /* Allocated size of req->out.vector[i].iov_base
3938 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3939 * 1 byte without having to do an alloc.
3942 info
->data
= ((uint8_t *)outhdr
) +
3943 OUTVEC_ALLOC_SIZE
- 1;
3945 SCVAL(info
->data
, 0, 0);
3949 * Note: Even if there is an error, continue to process the request.
3953 return smbd_smb2_request_done_ex(req
, status
, body
, info
, __location__
);
3956 struct smbd_smb2_break_state
{
3957 struct tevent_req
*req
;
3958 struct smbd_smb2_send_queue queue_entry
;
3959 uint8_t nbt_hdr
[NBT_HDR_SIZE
];
3960 uint8_t hdr
[SMB2_HDR_BODY
];
3961 struct iovec vector
[1+SMBD_SMB2_NUM_IOV_PER_REQ
];
3964 static struct tevent_req
*smbd_smb2_break_send(TALLOC_CTX
*mem_ctx
,
3965 struct tevent_context
*ev
,
3966 struct smbXsrv_connection
*xconn
,
3967 uint64_t session_id
,
3968 const uint8_t *body
,
3971 struct tevent_req
*req
= NULL
;
3972 struct smbd_smb2_break_state
*state
= NULL
;
3976 req
= tevent_req_create(mem_ctx
, &state
,
3977 struct smbd_smb2_break_state
);
3983 tevent_req_defer_callback(req
, ev
);
3985 SIVAL(state
->hdr
, 0, SMB2_MAGIC
);
3986 SSVAL(state
->hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
3987 SSVAL(state
->hdr
, SMB2_HDR_EPOCH
, 0);
3988 SIVAL(state
->hdr
, SMB2_HDR_STATUS
, 0);
3989 SSVAL(state
->hdr
, SMB2_HDR_OPCODE
, SMB2_OP_BREAK
);
3990 SSVAL(state
->hdr
, SMB2_HDR_CREDIT
, 0);
3991 SIVAL(state
->hdr
, SMB2_HDR_FLAGS
, SMB2_HDR_FLAG_REDIRECT
);
3992 SIVAL(state
->hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
3993 SBVAL(state
->hdr
, SMB2_HDR_MESSAGE_ID
, UINT64_MAX
);
3994 SIVAL(state
->hdr
, SMB2_HDR_PID
, 0);
3995 SIVAL(state
->hdr
, SMB2_HDR_TID
, 0);
3996 SBVAL(state
->hdr
, SMB2_HDR_SESSION_ID
, session_id
);
3997 memset(state
->hdr
+SMB2_HDR_SIGNATURE
, 0, 16);
3999 state
->vector
[0] = (struct iovec
) {
4000 .iov_base
= state
->nbt_hdr
,
4001 .iov_len
= sizeof(state
->nbt_hdr
)
4004 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
4009 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
] = (struct iovec
) {
4010 .iov_base
= state
->hdr
,
4011 .iov_len
= sizeof(state
->hdr
)
4014 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
] = (struct iovec
) {
4015 .iov_base
= discard_const_p(uint8_t, body
),
4016 .iov_len
= body_len
,
4020 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4023 ok
= smb2_setup_nbt_length(state
->vector
,
4024 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
4026 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
4027 return tevent_req_post(req
, ev
);
4031 * We require TCP acks for this PDU to the client!
4032 * We want 5 retransmissions and timeout when the
4033 * retransmission timeout (rto) passed 6 times.
4035 * required_acked_bytes gets a dummy value of
4036 * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4037 * it'll get the real value when it's moved to
4040 * state->queue_entry.ack.req gets completed with
4041 * 1. tevent_req_done(), when all bytes are acked.
4042 * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4043 * the timeout expired before all bytes were acked.
4044 * 2b. tevent_req_nterror(transport_error), when the
4045 * connection got a disconnect from the kernel.
4047 state
->queue_entry
.ack
.timeout
=
4048 timeval_current_ofs_usec(xconn
->ack
.rto_usecs
* 6);
4049 state
->queue_entry
.ack
.required_acked_bytes
= UINT64_MAX
;
4050 state
->queue_entry
.ack
.req
= req
;
4051 state
->queue_entry
.mem_ctx
= state
;
4052 state
->queue_entry
.vector
= state
->vector
;
4053 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
4054 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
4055 xconn
->smb2
.send_queue_len
++;
4057 status
= smbd_smb2_flush_send_queue(xconn
);
4058 if (tevent_req_nterror(req
, status
)) {
4059 return tevent_req_post(req
, ev
);
4065 static NTSTATUS
smbd_smb2_break_recv(struct tevent_req
*req
)
4067 return tevent_req_simple_recv_ntstatus(req
);
4070 struct smbXsrv_pending_break
{
4071 struct smbXsrv_pending_break
*prev
, *next
;
4072 struct smbXsrv_client
*client
;
4073 bool disable_oplock_break_retries
;
4074 uint64_t session_id
;
4075 uint64_t last_channel_id
;
4078 uint8_t oplock
[0x18];
4079 uint8_t lease
[0x2c];
4084 static void smbXsrv_pending_break_done(struct tevent_req
*subreq
);
4086 static struct smbXsrv_pending_break
*smbXsrv_pending_break_create(
4087 struct smbXsrv_client
*client
,
4088 uint64_t session_id
)
4090 struct smbXsrv_pending_break
*pb
= NULL
;
4092 pb
= talloc_zero(client
, struct smbXsrv_pending_break
);
4096 pb
->client
= client
;
4097 pb
->session_id
= session_id
;
4098 pb
->disable_oplock_break_retries
= lp_smb2_disable_oplock_break_retry();
4103 static NTSTATUS
smbXsrv_pending_break_submit(struct smbXsrv_pending_break
*pb
);
4105 static NTSTATUS
smbXsrv_pending_break_schedule(struct smbXsrv_pending_break
*pb
)
4107 struct smbXsrv_client
*client
= pb
->client
;
4110 DLIST_ADD_END(client
->pending_breaks
, pb
);
4111 status
= smbXsrv_client_pending_breaks_updated(client
);
4112 if (!NT_STATUS_IS_OK(status
)) {
4116 status
= smbXsrv_pending_break_submit(pb
);
4117 if (!NT_STATUS_IS_OK(status
)) {
4121 return NT_STATUS_OK
;
4124 static NTSTATUS
smbXsrv_pending_break_submit(struct smbXsrv_pending_break
*pb
)
4126 struct smbXsrv_client
*client
= pb
->client
;
4127 struct smbXsrv_session
*session
= NULL
;
4128 struct smbXsrv_connection
*xconn
= NULL
;
4129 struct smbXsrv_connection
*oplock_xconn
= NULL
;
4130 struct tevent_req
*subreq
= NULL
;
4133 if (pb
->session_id
!= 0) {
4134 status
= get_valid_smbXsrv_session(client
,
4137 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
4138 return NT_STATUS_ABANDONED
;
4140 if (!NT_STATUS_IS_OK(status
)) {
4144 if (pb
->last_channel_id
!= 0) {
4146 * This is what current Windows servers
4147 * do, they don't retry on all available
4148 * channels. They only use the last channel.
4150 * But it doesn't match the specification in
4151 * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4154 * Per default disable_oplock_break_retries is false
4155 * and we behave like the specification.
4157 if (pb
->disable_oplock_break_retries
) {
4158 return NT_STATUS_ABANDONED
;
4163 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
4164 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4168 if (xconn
->channel_id
== 0) {
4170 * non-multichannel case
4175 if (session
!= NULL
) {
4176 struct smbXsrv_channel_global0
*c
= NULL
;
4179 * Having a session means we're handling
4180 * an oplock break and we only need to
4181 * use channels available on the
4184 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
4185 if (!NT_STATUS_IS_OK(status
)) {
4190 * This is what current Windows servers
4191 * do, they don't retry on all available
4192 * channels. They only use the last channel.
4194 * But it doesn't match the specification
4195 * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4198 * Per default disable_oplock_break_retries is false
4199 * and we behave like the specification.
4201 if (pb
->disable_oplock_break_retries
) {
4202 oplock_xconn
= xconn
;
4207 if (xconn
->channel_id
> pb
->last_channel_id
) {
4215 if (xconn
== NULL
) {
4216 xconn
= oplock_xconn
;
4219 if (xconn
== NULL
) {
4221 * If there's no remaining connection available
4222 * tell the caller to stop...
4224 return NT_STATUS_ABANDONED
;
4227 pb
->last_channel_id
= xconn
->channel_id
;
4229 subreq
= smbd_smb2_break_send(pb
,
4235 if (subreq
== NULL
) {
4236 return NT_STATUS_NO_MEMORY
;
4238 tevent_req_set_callback(subreq
,
4239 smbXsrv_pending_break_done
,
4242 return NT_STATUS_OK
;
4245 static void smbXsrv_pending_break_done(struct tevent_req
*subreq
)
4247 struct smbXsrv_pending_break
*pb
=
4248 tevent_req_callback_data(subreq
,
4249 struct smbXsrv_pending_break
);
4250 struct smbXsrv_client
*client
= pb
->client
;
4253 status
= smbd_smb2_break_recv(subreq
);
4254 TALLOC_FREE(subreq
);
4255 if (!NT_STATUS_IS_OK(status
)) {
4256 status
= smbXsrv_pending_break_submit(pb
);
4257 if (NT_STATUS_EQUAL(status
, NT_STATUS_ABANDONED
)) {
4259 * If there's no remaing connection
4260 * there's no need to send a break again.
4264 if (!NT_STATUS_IS_OK(status
)) {
4265 smbd_server_disconnect_client(client
, nt_errstr(status
));
4272 DLIST_REMOVE(client
->pending_breaks
, pb
);
4275 status
= smbXsrv_client_pending_breaks_updated(client
);
4276 if (!NT_STATUS_IS_OK(status
)) {
4277 smbd_server_disconnect_client(client
, nt_errstr(status
));
4282 NTSTATUS
smbd_smb2_send_oplock_break(struct smbXsrv_client
*client
,
4283 struct smbXsrv_open
*op
,
4284 uint8_t oplock_level
)
4286 struct smbXsrv_pending_break
*pb
= NULL
;
4287 uint8_t *body
= NULL
;
4289 pb
= smbXsrv_pending_break_create(client
,
4292 return NT_STATUS_NO_MEMORY
;
4294 pb
->body_len
= sizeof(pb
->body
.oplock
);
4295 body
= pb
->body
.oplock
;
4297 SSVAL(body
, 0x00, pb
->body_len
);
4298 SCVAL(body
, 0x02, oplock_level
);
4299 SCVAL(body
, 0x03, 0); /* reserved */
4300 SIVAL(body
, 0x04, 0); /* reserved */
4301 SBVAL(body
, 0x08, op
->global
->open_persistent_id
);
4302 SBVAL(body
, 0x10, op
->global
->open_volatile_id
);
4304 return smbXsrv_pending_break_schedule(pb
);
4307 NTSTATUS
smbd_smb2_send_lease_break(struct smbXsrv_client
*client
,
4309 uint32_t lease_flags
,
4310 struct smb2_lease_key
*lease_key
,
4311 uint32_t current_lease_state
,
4312 uint32_t new_lease_state
)
4314 struct smbXsrv_pending_break
*pb
= NULL
;
4315 uint8_t *body
= NULL
;
4317 pb
= smbXsrv_pending_break_create(client
,
4318 0); /* no session_id */
4320 return NT_STATUS_NO_MEMORY
;
4322 pb
->body_len
= sizeof(pb
->body
.lease
);
4323 body
= pb
->body
.lease
;
4325 SSVAL(body
, 0x00, pb
->body_len
);
4326 SSVAL(body
, 0x02, new_epoch
);
4327 SIVAL(body
, 0x04, lease_flags
);
4328 SBVAL(body
, 0x08, lease_key
->data
[0]);
4329 SBVAL(body
, 0x10, lease_key
->data
[1]);
4330 SIVAL(body
, 0x18, current_lease_state
);
4331 SIVAL(body
, 0x1c, new_lease_state
);
4332 SIVAL(body
, 0x20, 0); /* BreakReason, MUST be 0 */
4333 SIVAL(body
, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4334 SIVAL(body
, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4336 return smbXsrv_pending_break_schedule(pb
);
4339 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state
*state
)
4343 uint64_t file_id_persistent
;
4344 uint64_t file_id_volatile
;
4345 struct smbXsrv_open
*op
= NULL
;
4346 struct files_struct
*fsp
= NULL
;
4347 const uint8_t *body
= NULL
;
4350 * This is only called with a pktbuf
4351 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4355 if (IVAL(state
->pktbuf
, 0) == SMB2_TF_MAGIC
) {
4356 /* Transform header. Cannot recvfile. */
4359 if (IVAL(state
->pktbuf
, 0) != SMB2_MAGIC
) {
4360 /* Not SMB2. Normal error path will cope. */
4363 if (SVAL(state
->pktbuf
, 4) != SMB2_HDR_BODY
) {
4364 /* Not SMB2. Normal error path will cope. */
4367 if (SVAL(state
->pktbuf
, SMB2_HDR_OPCODE
) != SMB2_OP_WRITE
) {
4368 /* Needs to be a WRITE. */
4371 if (IVAL(state
->pktbuf
, SMB2_HDR_NEXT_COMMAND
) != 0) {
4372 /* Chained. Cannot recvfile. */
4375 flags
= IVAL(state
->pktbuf
, SMB2_HDR_FLAGS
);
4376 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
4377 /* Chained. Cannot recvfile. */
4380 if (flags
& SMB2_HDR_FLAG_SIGNED
) {
4381 /* Signed. Cannot recvfile. */
4385 body
= &state
->pktbuf
[SMB2_HDR_BODY
];
4387 file_id_persistent
= BVAL(body
, 0x10);
4388 file_id_volatile
= BVAL(body
, 0x18);
4390 status
= smb2srv_open_lookup(state
->req
->xconn
,
4395 if (!NT_STATUS_IS_OK(status
)) {
4403 if (fsp
->conn
== NULL
) {
4407 if (IS_IPC(fsp
->conn
)) {
4410 if (IS_PRINT(fsp
->conn
)) {
4413 if (fsp
->base_fsp
!= NULL
) {
4417 DEBUG(10,("Doing recvfile write len = %u\n",
4418 (unsigned int)(state
->pktfull
- state
->pktlen
)));
4423 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
)
4425 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
4426 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
4427 size_t max_send_queue_len
;
4428 size_t cur_send_queue_len
;
4430 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4432 * we're not supposed to do any io
4434 return NT_STATUS_OK
;
4437 if (state
->req
!= NULL
) {
4439 * if there is already a tstream_readv_pdu
4440 * pending, we are done.
4442 return NT_STATUS_OK
;
4445 max_send_queue_len
= MAX(1, xconn
->smb2
.credits
.max
/16);
4446 cur_send_queue_len
= xconn
->smb2
.send_queue_len
;
4448 if (cur_send_queue_len
> max_send_queue_len
) {
4450 * if we have a lot of requests to send,
4451 * we wait until they are on the wire until we
4452 * ask for the next request.
4454 return NT_STATUS_OK
;
4457 /* ask for the next request */
4458 ZERO_STRUCTP(state
);
4459 state
->req
= smbd_smb2_request_allocate(xconn
);
4460 if (state
->req
== NULL
) {
4461 return NT_STATUS_NO_MEMORY
;
4463 state
->req
->sconn
= sconn
;
4464 state
->req
->xconn
= xconn
;
4465 state
->min_recv_size
= lp_min_receive_file_size();
4467 TEVENT_FD_READABLE(xconn
->transport
.fde
);
4469 return NT_STATUS_OK
;
4472 NTSTATUS
smbd_smb2_process_negprot(struct smbXsrv_connection
*xconn
,
4473 uint64_t expected_seq_low
,
4474 const uint8_t *inpdu
, size_t size
)
4476 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
4478 struct smbd_smb2_request
*req
= NULL
;
4480 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4481 (unsigned int)size
));
4483 status
= smbd_initialize_smb2(xconn
, expected_seq_low
);
4484 if (!NT_STATUS_IS_OK(status
)) {
4485 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4490 * If a new connection joins the process, when we're
4491 * already in a "pending break cycle", we need to
4492 * turn on the ack checker on the new connection.
4494 status
= smbXsrv_client_pending_breaks_updated(xconn
->client
);
4495 if (!NT_STATUS_IS_OK(status
)) {
4497 * If there's a problem, we disconnect the whole
4498 * client with all connections here!
4500 * Instead of just the new connection.
4502 smbd_server_disconnect_client(xconn
->client
, nt_errstr(status
));
4506 status
= smbd_smb2_request_create(xconn
, inpdu
, size
, &req
);
4507 if (!NT_STATUS_IS_OK(status
)) {
4508 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4512 status
= smbd_smb2_request_validate(req
);
4513 if (!NT_STATUS_IS_OK(status
)) {
4514 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4518 status
= smbd_smb2_request_setup_out(req
);
4519 if (!NT_STATUS_IS_OK(status
)) {
4520 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4526 * this was already counted at the SMB1 layer =>
4527 * smbd_smb2_request_dispatch() should not count it twice.
4529 if (profile_p
->values
.request_stats
.count
> 0) {
4530 profile_p
->values
.request_stats
.count
--;
4533 status
= smbd_smb2_request_dispatch(req
);
4534 if (!NT_STATUS_IS_OK(status
)) {
4535 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4539 status
= smbd_smb2_request_next_incoming(xconn
);
4540 if (!NT_STATUS_IS_OK(status
)) {
4541 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4545 sconn
->num_requests
++;
4546 return NT_STATUS_OK
;
4549 static int socket_error_from_errno(int ret
,
4563 if (sys_errno
== 0) {
4567 if (sys_errno
== EINTR
) {
4572 if (sys_errno
== EINPROGRESS
) {
4577 if (sys_errno
== EAGAIN
) {
4582 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4583 if (sys_errno
== ENOMEM
) {
4589 #if EWOULDBLOCK != EAGAIN
4590 if (sys_errno
== EWOULDBLOCK
) {
4600 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
)
4607 if (xconn
->smb2
.send_queue
== NULL
) {
4608 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
4609 return NT_STATUS_OK
;
4612 while (xconn
->smb2
.send_queue
!= NULL
) {
4613 struct smbd_smb2_send_queue
*e
= xconn
->smb2
.send_queue
;
4617 if (e
->sendfile_header
!= NULL
) {
4622 status
= NT_STATUS_INTERNAL_ERROR
;
4624 for (i
=0; i
< e
->count
; i
++) {
4625 size
+= e
->vector
[i
].iov_len
;
4628 if (size
<= e
->sendfile_header
->length
) {
4629 buf
= e
->sendfile_header
->data
;
4631 buf
= talloc_array(e
->mem_ctx
, uint8_t, size
);
4633 return NT_STATUS_NO_MEMORY
;
4638 for (i
=0; i
< e
->count
; i
++) {
4640 e
->vector
[i
].iov_base
,
4641 e
->vector
[i
].iov_len
);
4642 size
+= e
->vector
[i
].iov_len
;
4645 e
->sendfile_header
->data
= buf
;
4646 e
->sendfile_header
->length
= size
;
4647 e
->sendfile_status
= &status
;
4650 xconn
->smb2
.send_queue_len
--;
4651 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4653 size
+= e
->sendfile_body_size
;
4656 * This triggers the sendfile path via
4659 talloc_free(e
->mem_ctx
);
4661 if (!NT_STATUS_IS_OK(status
)) {
4662 smbXsrv_connection_disconnect_transport(xconn
,
4666 xconn
->ack
.unacked_bytes
+= size
;
4670 msg
= (struct msghdr
) {
4671 .msg_iov
= e
->vector
,
4672 .msg_iovlen
= e
->count
,
4675 ret
= sendmsg(xconn
->transport
.sock
, &msg
, 0);
4677 /* propagate end of file */
4678 return NT_STATUS_INTERNAL_ERROR
;
4680 err
= socket_error_from_errno(ret
, errno
, &retry
);
4683 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
4684 return NT_STATUS_OK
;
4687 status
= map_nt_error_from_unix_common(err
);
4688 smbXsrv_connection_disconnect_transport(xconn
,
4693 xconn
->ack
.unacked_bytes
+= ret
;
4695 ok
= iov_advance(&e
->vector
, &e
->count
, ret
);
4697 return NT_STATUS_INTERNAL_ERROR
;
4701 /* we have more to write */
4702 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
4703 return NT_STATUS_OK
;
4706 xconn
->smb2
.send_queue_len
--;
4707 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4709 if (e
->ack
.req
== NULL
) {
4710 talloc_free(e
->mem_ctx
);
4714 e
->ack
.required_acked_bytes
= xconn
->ack
.unacked_bytes
;
4715 DLIST_ADD_END(xconn
->ack
.queue
, e
);
4719 * Restart reads if we were blocked on
4720 * draining the send queue.
4723 status
= smbd_smb2_request_next_incoming(xconn
);
4724 if (!NT_STATUS_IS_OK(status
)) {
4728 return NT_STATUS_OK
;
4731 static NTSTATUS
smbd_smb2_io_handler(struct smbXsrv_connection
*xconn
,
4734 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
4735 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
4736 struct smbd_smb2_request
*req
= NULL
;
4737 size_t min_recvfile_size
= UINT32_MAX
;
4745 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4747 * we're not supposed to do any io
4749 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
4750 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
4751 return NT_STATUS_OK
;
4754 if (fde_flags
& TEVENT_FD_WRITE
) {
4755 status
= smbd_smb2_flush_send_queue(xconn
);
4756 if (!NT_STATUS_IS_OK(status
)) {
4761 if (!(fde_flags
& TEVENT_FD_READ
)) {
4762 return NT_STATUS_OK
;
4765 if (state
->req
== NULL
) {
4766 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
4767 return NT_STATUS_OK
;
4771 if (!state
->hdr
.done
) {
4772 state
->hdr
.done
= true;
4774 state
->vector
.iov_base
= (void *)state
->hdr
.nbt
;
4775 state
->vector
.iov_len
= NBT_HDR_SIZE
;
4778 msg
= (struct msghdr
) {
4779 .msg_iov
= &state
->vector
,
4783 ret
= recvmsg(xconn
->transport
.sock
, &msg
, 0);
4785 /* propagate end of file */
4786 status
= NT_STATUS_END_OF_FILE
;
4787 smbXsrv_connection_disconnect_transport(xconn
,
4791 err
= socket_error_from_errno(ret
, errno
, &retry
);
4794 TEVENT_FD_READABLE(xconn
->transport
.fde
);
4795 return NT_STATUS_OK
;
4798 status
= map_nt_error_from_unix_common(err
);
4799 smbXsrv_connection_disconnect_transport(xconn
,
4804 if (ret
< state
->vector
.iov_len
) {
4806 base
= (uint8_t *)state
->vector
.iov_base
;
4808 state
->vector
.iov_base
= (void *)base
;
4809 state
->vector
.iov_len
-= ret
;
4810 /* we have more to read */
4811 TEVENT_FD_READABLE(xconn
->transport
.fde
);
4812 return NT_STATUS_OK
;
4815 if (state
->pktlen
> 0) {
4816 if (state
->doing_receivefile
&& !is_smb2_recvfile_write(state
)) {
4818 * Not a possible receivefile write.
4819 * Read the rest of the data.
4821 state
->doing_receivefile
= false;
4823 state
->pktbuf
= talloc_realloc(state
->req
,
4827 if (state
->pktbuf
== NULL
) {
4828 return NT_STATUS_NO_MEMORY
;
4831 state
->vector
.iov_base
= (void *)(state
->pktbuf
+
4833 state
->vector
.iov_len
= (state
->pktfull
-
4836 state
->pktlen
= state
->pktfull
;
4841 * Either this is a receivefile write so we've
4842 * done a short read, or if not we have all the data.
4848 * Now we analyze the NBT header
4850 if (state
->hdr
.nbt
[0] != 0x00) {
4851 state
->min_recv_size
= 0;
4853 state
->pktfull
= smb2_len(state
->hdr
.nbt
);
4854 if (state
->pktfull
== 0) {
4858 if (state
->min_recv_size
!= 0) {
4859 min_recvfile_size
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
4860 min_recvfile_size
+= state
->min_recv_size
;
4863 if (state
->pktfull
> min_recvfile_size
) {
4865 * Might be a receivefile write. Read the SMB2 HEADER +
4866 * SMB2_WRITE header first. Set 'doing_receivefile'
4867 * as we're *attempting* receivefile write. If this
4868 * turns out not to be a SMB2_WRITE request or otherwise
4869 * not suitable then we'll just read the rest of the data
4870 * the next time this function is called.
4872 state
->pktlen
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
4873 state
->doing_receivefile
= true;
4875 state
->pktlen
= state
->pktfull
;
4878 state
->pktbuf
= talloc_array(state
->req
, uint8_t, state
->pktlen
);
4879 if (state
->pktbuf
== NULL
) {
4880 return NT_STATUS_NO_MEMORY
;
4883 state
->vector
.iov_base
= (void *)state
->pktbuf
;
4884 state
->vector
.iov_len
= state
->pktlen
;
4890 if (state
->hdr
.nbt
[0] != 0x00) {
4891 DEBUG(1,("ignore NBT[0x%02X] msg\n",
4892 state
->hdr
.nbt
[0]));
4895 ZERO_STRUCTP(state
);
4897 state
->min_recv_size
= lp_min_receive_file_size();
4905 req
->request_time
= timeval_current();
4906 now
= timeval_to_nttime(&req
->request_time
);
4908 status
= smbd_smb2_inbuf_parse_compound(xconn
,
4914 &req
->in
.vector_count
);
4915 if (!NT_STATUS_IS_OK(status
)) {
4919 if (state
->doing_receivefile
) {
4920 req
->smb1req
= talloc_zero(req
, struct smb_request
);
4921 if (req
->smb1req
== NULL
) {
4922 return NT_STATUS_NO_MEMORY
;
4924 req
->smb1req
->unread_bytes
= state
->pktfull
- state
->pktlen
;
4927 ZERO_STRUCTP(state
);
4929 req
->current_idx
= 1;
4931 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
4932 req
->current_idx
, req
->in
.vector_count
));
4934 status
= smbd_smb2_request_validate(req
);
4935 if (!NT_STATUS_IS_OK(status
)) {
4939 status
= smbd_smb2_request_setup_out(req
);
4940 if (!NT_STATUS_IS_OK(status
)) {
4944 status
= smbd_smb2_request_dispatch(req
);
4945 if (!NT_STATUS_IS_OK(status
)) {
4949 sconn
->num_requests
++;
4951 /* The timeout_processing function isn't run nearly
4952 often enough to implement 'max log size' without
4953 overrunning the size of the file by many megabytes.
4954 This is especially true if we are running at debug
4955 level 10. Checking every 50 SMB2s is a nice
4956 tradeoff of performance vs log file size overrun. */
4958 if ((sconn
->num_requests
% 50) == 0 &&
4959 need_to_check_log_size()) {
4960 change_to_root_user();
4964 status
= smbd_smb2_request_next_incoming(xconn
);
4965 if (!NT_STATUS_IS_OK(status
)) {
4969 return NT_STATUS_OK
;
4972 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
4973 struct tevent_fd
*fde
,
4977 struct smbXsrv_connection
*xconn
=
4978 talloc_get_type_abort(private_data
,
4979 struct smbXsrv_connection
);
4982 status
= smbd_smb2_io_handler(xconn
, flags
);
4983 if (!NT_STATUS_IS_OK(status
)) {
4984 smbd_server_connection_terminate(xconn
, nt_errstr(status
));