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 "source3/smbd/smbXsrv_session.h"
27 #include "smbd/smbXsrv_open.h"
28 #include "lib/param/param.h"
29 #include "../libcli/smb/smb_common.h"
30 #include "../lib/tsocket/tsocket.h"
31 #include "../lib/util/tevent_ntstatus.h"
32 #include "smbprofile.h"
33 #include "../lib/util/bitmap.h"
34 #include "../librpc/gen_ndr/krb5pac.h"
35 #include "lib/util/iov_buf.h"
37 #include "libcli/smb/smbXcli_base.h"
38 #include "source3/lib/substitute.h"
41 /* SIOCOUTQ TIOCOUTQ are the same */
42 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
43 #define __HAVE_TCP_INFO_RTO 1
44 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
45 #elif defined(FREEBSD)
46 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
47 #define __HAVE_TCP_INFO_RTO 1
48 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
51 #include "lib/crypto/gnutls_helpers.h"
52 #include <gnutls/gnutls.h>
53 #include <gnutls/crypto.h>
56 #define DBGC_CLASS DBGC_SMB2
58 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
59 struct tevent_fd
*fde
,
62 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
);
64 static const struct smbd_smb2_dispatch_table
{
67 bool need_session
: 1;
71 } smbd_smb2_table
[] = {
73 .opcode
= SMB2_OP_NEGPROT
,
76 .opcode
= SMB2_OP_SESSSETUP
,
79 .opcode
= SMB2_OP_LOGOFF
,
83 .opcode
= SMB2_OP_TCON
,
86 * This call needs to be run as root.
88 * smbd_smb2_request_process_tcon()
89 * calls make_connection_snum(), which will call
90 * change_to_user(), when needed.
94 .opcode
= SMB2_OP_TDIS
,
99 .opcode
= SMB2_OP_CREATE
,
100 .need_session
= true,
103 .opcode
= SMB2_OP_CLOSE
,
104 .need_session
= true,
108 .opcode
= SMB2_OP_FLUSH
,
109 .need_session
= true,
113 .opcode
= SMB2_OP_READ
,
114 .need_session
= true,
118 .opcode
= SMB2_OP_WRITE
,
119 .need_session
= true,
124 .opcode
= SMB2_OP_LOCK
,
125 .need_session
= true,
129 .opcode
= SMB2_OP_IOCTL
,
130 .need_session
= true,
135 .opcode
= SMB2_OP_CANCEL
,
138 .opcode
= SMB2_OP_KEEPALIVE
,
140 .opcode
= SMB2_OP_QUERY_DIRECTORY
,
141 .need_session
= true,
145 .opcode
= SMB2_OP_NOTIFY
,
146 .need_session
= true,
150 .opcode
= SMB2_OP_GETINFO
,
151 .need_session
= true,
155 .opcode
= SMB2_OP_SETINFO
,
156 .need_session
= true,
161 .opcode
= SMB2_OP_BREAK
,
162 .need_session
= true,
167 * as LEASE breaks does not
173 const char *smb2_opcode_name(uint16_t opcode
)
175 const char *result
= "Bad SMB2 opcode";
178 case SMB2_OP_NEGPROT
:
179 result
= "SMB2_OP_NEGPROT";
181 case SMB2_OP_SESSSETUP
:
182 result
= "SMB2_OP_SESSSETUP";
185 result
= "SMB2_OP_LOGOFF";
188 result
= "SMB2_OP_TCON";
191 result
= "SMB2_OP_TDIS";
194 result
= "SMB2_OP_CREATE";
197 result
= "SMB2_OP_CLOSE";
200 result
= "SMB2_OP_FLUSH";
203 result
= "SMB2_OP_READ";
206 result
= "SMB2_OP_WRITE";
209 result
= "SMB2_OP_LOCK";
212 result
= "SMB2_OP_IOCTL";
215 result
= "SMB2_OP_CANCEL";
217 case SMB2_OP_KEEPALIVE
:
218 result
= "SMB2_OP_KEEPALIVE";
220 case SMB2_OP_QUERY_DIRECTORY
:
221 result
= "SMB2_OP_QUERY_DIRECTORY";
224 result
= "SMB2_OP_NOTIFY";
226 case SMB2_OP_GETINFO
:
227 result
= "SMB2_OP_GETINFO";
229 case SMB2_OP_SETINFO
:
230 result
= "SMB2_OP_SETINFO";
233 result
= "SMB2_OP_BREAK";
241 static const struct smbd_smb2_dispatch_table
*smbd_smb2_call(uint16_t opcode
)
243 const struct smbd_smb2_dispatch_table
*ret
= NULL
;
245 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
249 ret
= &smbd_smb2_table
[opcode
];
251 SMB_ASSERT(ret
->opcode
== opcode
);
256 static void print_req_vectors(const struct smbd_smb2_request
*req
)
260 for (i
= 0; i
< req
->in
.vector_count
; i
++) {
261 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
263 (unsigned int)req
->in
.vector
[i
].iov_len
);
265 for (i
= 0; i
< req
->out
.vector_count
; i
++) {
266 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
268 (unsigned int)req
->out
.vector
[i
].iov_len
);
272 bool smbd_is_smb2_header(const uint8_t *inbuf
, size_t size
)
274 if (size
< (4 + SMB2_HDR_BODY
)) {
278 if (IVAL(inbuf
, 4) != SMB2_MAGIC
) {
285 bool smbd_smb2_is_compound(const struct smbd_smb2_request
*req
)
287 return req
->in
.vector_count
>= (2*SMBD_SMB2_NUM_IOV_PER_REQ
);
290 bool smbd_smb2_is_last_in_compound(const struct smbd_smb2_request
*req
)
292 return (req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
==
293 req
->in
.vector_count
);
296 static NTSTATUS
smbd_initialize_smb2(struct smbXsrv_connection
*xconn
,
297 uint64_t expected_seq_low
)
301 xconn
->smb2
.credits
.seq_low
= expected_seq_low
;
302 xconn
->smb2
.credits
.seq_range
= 1;
303 xconn
->smb2
.credits
.granted
= 1;
304 xconn
->smb2
.credits
.max
= lp_smb2_max_credits();
305 xconn
->smb2
.credits
.bitmap
= bitmap_talloc(xconn
,
306 xconn
->smb2
.credits
.max
);
307 if (xconn
->smb2
.credits
.bitmap
== NULL
) {
308 return NT_STATUS_NO_MEMORY
;
311 tevent_fd_set_close_fn(xconn
->transport
.fde
, NULL
);
312 TALLOC_FREE(xconn
->transport
.fde
);
314 xconn
->transport
.fde
= tevent_add_fd(
315 xconn
->client
->raw_ev_ctx
,
317 xconn
->transport
.sock
,
318 TEVENT_FD_ERROR
| TEVENT_FD_READ
,
319 smbd_smb2_connection_handler
,
321 if (xconn
->transport
.fde
== NULL
) {
322 close(xconn
->transport
.sock
);
323 xconn
->transport
.sock
= -1;
324 return NT_STATUS_NO_MEMORY
;
326 tevent_fd_set_auto_close(xconn
->transport
.fde
);
329 * Ensure child is set to non-blocking mode,
330 * unless the system supports MSG_DONTWAIT,
331 * if MSG_DONTWAIT is available we should force
335 rc
= set_blocking(xconn
->transport
.sock
, true);
337 return NT_STATUS_INTERNAL_ERROR
;
340 rc
= set_blocking(xconn
->transport
.sock
, false);
342 return NT_STATUS_INTERNAL_ERROR
;
349 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
350 #define _smb2_setlen(_buf,len) do { \
351 uint8_t *buf = (uint8_t *)_buf; \
353 buf[1] = ((len)&0xFF0000)>>16; \
354 buf[2] = ((len)&0xFF00)>>8; \
355 buf[3] = (len)&0xFF; \
358 static bool smb2_setup_nbt_length(struct iovec
*vector
, int count
)
366 len
= iov_buflen(vector
+1, count
-1);
368 if ((len
== -1) || (len
> 0xFFFFFF)) {
372 _smb2_setlen(vector
[0].iov_base
, len
);
376 static int smbd_smb2_request_destructor(struct smbd_smb2_request
*req
)
378 TALLOC_FREE(req
->first_enc_key
);
379 TALLOC_FREE(req
->last_sign_key
);
383 void smb2_request_set_async_internal(struct smbd_smb2_request
*req
,
386 req
->async_internal
= async_internal
;
389 static struct smbd_smb2_request
*smbd_smb2_request_allocate(struct smbXsrv_connection
*xconn
)
391 TALLOC_CTX
*mem_pool
;
392 struct smbd_smb2_request
*req
;
395 /* Enable this to find subtle valgrind errors. */
396 mem_pool
= talloc_init("smbd_smb2_request_allocate");
398 mem_pool
= talloc_tos();
400 if (mem_pool
== NULL
) {
404 req
= talloc(mem_pool
, struct smbd_smb2_request
);
406 talloc_free(mem_pool
);
409 talloc_reparent(mem_pool
, xconn
, req
);
411 TALLOC_FREE(mem_pool
);
413 *req
= (struct smbd_smb2_request
) {
414 .sconn
= xconn
->client
->sconn
,
416 .last_session_id
= UINT64_MAX
,
417 .last_tid
= UINT32_MAX
,
420 talloc_set_destructor(req
, smbd_smb2_request_destructor
);
425 static NTSTATUS
smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection
*xconn
,
429 struct smbd_smb2_request
*req
,
433 TALLOC_CTX
*mem_ctx
= req
;
437 uint8_t *first_hdr
= buf
;
438 size_t verified_buflen
= 0;
443 * Note: index '0' is reserved for the transport protocol
445 iov
= req
->in
._vector
;
447 while (taken
< buflen
) {
448 size_t len
= buflen
- taken
;
449 uint8_t *hdr
= first_hdr
+ taken
;
452 size_t next_command_ofs
;
454 uint8_t *body
= NULL
;
457 struct iovec
*iov_alloc
= NULL
;
459 if (iov
!= req
->in
._vector
) {
463 if (verified_buflen
> taken
) {
464 len
= verified_buflen
- taken
;
471 DEBUG(10, ("%d bytes left, expected at least %d\n",
475 if (IVAL(hdr
, 0) == SMB2_TF_MAGIC
) {
476 struct smbXsrv_session
*s
= NULL
;
478 struct iovec tf_iov
[2];
482 if (xconn
->protocol
< PROTOCOL_SMB3_00
) {
483 DEBUG(10, ("Got SMB2_TRANSFORM header, "
484 "but dialect[0x%04X] is used\n",
485 xconn
->smb2
.server
.dialect
));
489 if (xconn
->smb2
.server
.cipher
== 0) {
490 DEBUG(10, ("Got SMB2_TRANSFORM header, "
491 "but not negotiated "
492 "client[0x%08X] server[0x%08X]\n",
493 xconn
->smb2
.client
.capabilities
,
494 xconn
->smb2
.server
.capabilities
));
498 if (len
< SMB2_TF_HDR_SIZE
) {
499 DEBUG(1, ("%d bytes left, expected at least %d\n",
500 (int)len
, SMB2_TF_HDR_SIZE
));
504 tf_len
= SMB2_TF_HDR_SIZE
;
507 hdr
= first_hdr
+ taken
;
508 enc_len
= IVAL(tf
, SMB2_TF_MSG_SIZE
);
509 uid
= BVAL(tf
, SMB2_TF_SESSION_ID
);
511 if (len
< SMB2_TF_HDR_SIZE
+ enc_len
) {
512 DEBUG(1, ("%d bytes left, expected at least %d\n",
514 (int)(SMB2_TF_HDR_SIZE
+ enc_len
)));
518 status
= smb2srv_session_lookup_conn(xconn
, uid
, now
,
520 if (!NT_STATUS_IS_OK(status
)) {
521 status
= smb2srv_session_lookup_global(xconn
->client
,
524 if (!NT_STATUS_IS_OK(status
)) {
525 DBG_WARNING("invalid session[%" PRIu64
"] in "
526 "SMB2_TRANSFORM header\n",
528 TALLOC_FREE(iov_alloc
);
529 return NT_STATUS_USER_SESSION_DELETED
;
532 tf_iov
[0].iov_base
= (void *)tf
;
533 tf_iov
[0].iov_len
= tf_len
;
534 tf_iov
[1].iov_base
= (void *)hdr
;
535 tf_iov
[1].iov_len
= enc_len
;
537 status
= smb2_signing_decrypt_pdu(s
->global
->decryption_key
,
539 if (!NT_STATUS_IS_OK(status
)) {
540 TALLOC_FREE(iov_alloc
);
544 verified_buflen
= taken
+ enc_len
;
549 * We need the header plus the body length field
552 if (len
< SMB2_HDR_BODY
+ 2) {
555 (IVAL(hdr
, 0) == SMB_SUICIDE_PACKET
) &&
556 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
557 uint8_t exitcode
= CVAL(hdr
, 4);
558 DBG_WARNING("SUICIDE: Exiting immediately "
559 "with code %"PRIu8
"\n",
564 DEBUG(10, ("%d bytes left, expected at least %d\n",
565 (int)len
, SMB2_HDR_BODY
));
568 if (IVAL(hdr
, 0) != SMB2_MAGIC
) {
569 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
573 if (SVAL(hdr
, 4) != SMB2_HDR_BODY
) {
574 DEBUG(10, ("Got HDR len %d, expected %d\n",
575 SVAL(hdr
, 4), SMB2_HDR_BODY
));
580 next_command_ofs
= IVAL(hdr
, SMB2_HDR_NEXT_COMMAND
);
581 body_size
= SVAL(hdr
, SMB2_HDR_BODY
);
583 if (next_command_ofs
!= 0) {
584 if (next_command_ofs
< (SMB2_HDR_BODY
+ 2)) {
587 if (next_command_ofs
> full_size
) {
590 full_size
= next_command_ofs
;
597 if (body_size
> (full_size
- SMB2_HDR_BODY
)) {
599 * let the caller handle the error
601 body_size
= full_size
- SMB2_HDR_BODY
;
603 body
= hdr
+ SMB2_HDR_BODY
;
604 dyn
= body
+ body_size
;
605 dyn_size
= full_size
- (SMB2_HDR_BODY
+ body_size
);
607 if (num_iov
>= ARRAY_SIZE(req
->in
._vector
)) {
608 struct iovec
*iov_tmp
= NULL
;
610 iov_tmp
= talloc_realloc(mem_ctx
, iov_alloc
,
613 SMBD_SMB2_NUM_IOV_PER_REQ
);
614 if (iov_tmp
== NULL
) {
615 TALLOC_FREE(iov_alloc
);
616 return NT_STATUS_NO_MEMORY
;
619 if (iov_alloc
== NULL
) {
622 sizeof(req
->in
._vector
));
628 num_iov
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
630 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
631 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
632 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
633 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
634 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
635 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= body_size
;
636 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
637 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= dyn_size
;
647 if (iov
!= req
->in
._vector
) {
650 return NT_STATUS_INVALID_PARAMETER
;
653 static NTSTATUS
smbd_smb2_request_create(struct smbXsrv_connection
*xconn
,
654 const uint8_t *_inpdu
, size_t size
,
655 struct smbd_smb2_request
**_req
)
657 struct smbd_smb2_request
*req
;
658 uint32_t protocol_version
;
659 uint8_t *inpdu
= NULL
;
660 const uint8_t *inhdr
= NULL
;
662 uint32_t next_command_ofs
;
666 if (size
< (SMB2_HDR_BODY
+ 2)) {
667 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size
));
668 return NT_STATUS_INVALID_PARAMETER
;
673 protocol_version
= IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
);
674 if (protocol_version
!= SMB2_MAGIC
) {
675 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
677 return NT_STATUS_INVALID_PARAMETER
;
680 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
681 if (cmd
!= SMB2_OP_NEGPROT
) {
682 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
684 return NT_STATUS_INVALID_PARAMETER
;
687 next_command_ofs
= IVAL(inhdr
, SMB2_HDR_NEXT_COMMAND
);
688 if (next_command_ofs
!= 0) {
689 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
691 return NT_STATUS_INVALID_PARAMETER
;
694 req
= smbd_smb2_request_allocate(xconn
);
696 return NT_STATUS_NO_MEMORY
;
699 inpdu
= talloc_memdup(req
, _inpdu
, size
);
701 return NT_STATUS_NO_MEMORY
;
704 req
->request_time
= timeval_current();
705 now
= timeval_to_nttime(&req
->request_time
);
707 status
= smbd_smb2_inbuf_parse_compound(xconn
,
711 req
, &req
->in
.vector
,
712 &req
->in
.vector_count
);
713 if (!NT_STATUS_IS_OK(status
)) {
718 req
->current_idx
= 1;
724 static bool smb2_validate_sequence_number(struct smbXsrv_connection
*xconn
,
725 uint64_t message_id
, uint64_t seq_id
)
727 struct bitmap
*credits_bm
= xconn
->smb2
.credits
.bitmap
;
731 seq_tmp
= xconn
->smb2
.credits
.seq_low
;
732 if (seq_id
< seq_tmp
) {
733 DBGC_ERR(DBGC_SMB2_CREDITS
,
734 "smb2_validate_sequence_number: bad message_id "
735 "%llu (sequence id %llu) "
736 "(granted = %u, low = %llu, range = %u)\n",
737 (unsigned long long)message_id
,
738 (unsigned long long)seq_id
,
739 (unsigned int)xconn
->smb2
.credits
.granted
,
740 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
741 (unsigned int)xconn
->smb2
.credits
.seq_range
);
745 seq_tmp
+= xconn
->smb2
.credits
.seq_range
;
746 if (seq_id
>= seq_tmp
) {
747 DBGC_ERR(DBGC_SMB2_CREDITS
,
748 "smb2_validate_sequence_number: bad message_id "
749 "%llu (sequence id %llu) "
750 "(granted = %u, low = %llu, range = %u)\n",
751 (unsigned long long)message_id
,
752 (unsigned long long)seq_id
,
753 (unsigned int)xconn
->smb2
.credits
.granted
,
754 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
755 (unsigned int)xconn
->smb2
.credits
.seq_range
);
759 offset
= seq_id
% xconn
->smb2
.credits
.max
;
761 if (bitmap_query(credits_bm
, offset
)) {
762 DBGC_ERR(DBGC_SMB2_CREDITS
,
763 "smb2_validate_sequence_number: duplicate message_id "
764 "%llu (sequence id %llu) "
765 "(granted = %u, low = %llu, range = %u) "
767 (unsigned long long)message_id
,
768 (unsigned long long)seq_id
,
769 (unsigned int)xconn
->smb2
.credits
.granted
,
770 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
771 (unsigned int)xconn
->smb2
.credits
.seq_range
,
776 /* Mark the message_ids as seen in the bitmap. */
777 bitmap_set(credits_bm
, offset
);
779 if (seq_id
!= xconn
->smb2
.credits
.seq_low
) {
784 * Move the window forward by all the message_id's
787 while (bitmap_query(credits_bm
, offset
)) {
788 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
789 "smb2_validate_sequence_number: clearing "
790 "id %llu (position %u) from bitmap\n",
791 (unsigned long long)(xconn
->smb2
.credits
.seq_low
),
793 bitmap_clear(credits_bm
, offset
);
795 xconn
->smb2
.credits
.seq_low
+= 1;
796 xconn
->smb2
.credits
.seq_range
-= 1;
797 offset
= xconn
->smb2
.credits
.seq_low
% xconn
->smb2
.credits
.max
;
803 static bool smb2_validate_message_id(struct smbXsrv_connection
*xconn
,
804 const uint8_t *inhdr
)
806 uint64_t message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
807 uint16_t opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
808 uint16_t credit_charge
= 1;
811 if (opcode
== SMB2_OP_CANCEL
) {
812 /* SMB2_CANCEL requests by definition resend messageids. */
816 if (xconn
->smb2
.credits
.multicredit
) {
817 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
818 credit_charge
= MAX(credit_charge
, 1);
823 ("smb2_validate_message_id: mid %llu (charge %llu), "
824 "credits_granted %llu, "
825 "seqnum low/range: %llu/%llu\n",
826 (unsigned long long) message_id
,
827 (unsigned long long) credit_charge
,
828 (unsigned long long) xconn
->smb2
.credits
.granted
,
829 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
830 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
832 if (xconn
->smb2
.credits
.granted
< credit_charge
) {
833 DBGC_ERR(DBGC_SMB2_CREDITS
,
834 "smb2_validate_message_id: client used more "
835 "credits than granted, mid %llu, charge %llu, "
836 "credits_granted %llu, "
837 "seqnum low/range: %llu/%llu\n",
838 (unsigned long long) message_id
,
839 (unsigned long long) credit_charge
,
840 (unsigned long long) xconn
->smb2
.credits
.granted
,
841 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
842 (unsigned long long) xconn
->smb2
.credits
.seq_range
);
847 * now check the message ids
849 * for multi-credit requests we need to check all current mid plus
850 * the implicit mids caused by the credit charge
851 * e.g. current mid = 15, charge 5 => mark 15-19 as used
854 for (i
= 0; i
<= (credit_charge
-1); i
++) {
855 uint64_t id
= message_id
+ i
;
860 ("Iterating mid %llu charge %u (sequence %llu)\n",
861 (unsigned long long)message_id
,
863 (unsigned long long)id
));
865 ok
= smb2_validate_sequence_number(xconn
, message_id
, id
);
871 /* subtract used credits */
872 xconn
->smb2
.credits
.granted
-= credit_charge
;
877 static NTSTATUS
smbd_smb2_request_validate(struct smbd_smb2_request
*req
)
882 count
= req
->in
.vector_count
;
884 if (count
< 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
885 /* It's not a SMB2 request */
886 return NT_STATUS_INVALID_PARAMETER
;
889 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
890 struct iovec
*hdr
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
891 struct iovec
*body
= SMBD_SMB2_IDX_BODY_IOV(req
,in
,idx
);
892 const uint8_t *inhdr
= NULL
;
894 if (hdr
->iov_len
!= SMB2_HDR_BODY
) {
895 return NT_STATUS_INVALID_PARAMETER
;
898 if (body
->iov_len
< 2) {
899 return NT_STATUS_INVALID_PARAMETER
;
902 inhdr
= (const uint8_t *)hdr
->iov_base
;
904 /* Check the SMB2 header */
905 if (IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
) != SMB2_MAGIC
) {
906 return NT_STATUS_INVALID_PARAMETER
;
909 if (!smb2_validate_message_id(req
->xconn
, inhdr
)) {
910 return NT_STATUS_INVALID_PARAMETER
;
917 static void smb2_set_operation_credit(struct smbXsrv_connection
*xconn
,
918 const struct iovec
*in_vector
,
919 struct iovec
*out_vector
)
921 const uint8_t *inhdr
= (const uint8_t *)in_vector
->iov_base
;
922 uint8_t *outhdr
= (uint8_t *)out_vector
->iov_base
;
923 uint16_t credit_charge
= 1;
924 uint16_t credits_requested
;
928 uint16_t credits_granted
= 0;
929 uint64_t credits_possible
;
930 uint16_t current_max_credits
;
933 * first we grant only 1/16th of the max range.
935 * Windows also starts with the 1/16th and then grants
936 * more later. I was only able to trigger higher
937 * values, when using a very high credit charge.
939 * TODO: scale up depending on load, free memory
941 * Maybe also on the relationship between number
942 * of requests and the used sequence number.
943 * Which means we would grant more credits
944 * for client which use multi credit requests.
946 * The above is what Windows Server < 2016 is doing,
947 * but new servers use all credits (8192 by default).
949 current_max_credits
= xconn
->smb2
.credits
.max
;
950 current_max_credits
= MAX(current_max_credits
, 1);
952 if (xconn
->smb2
.credits
.multicredit
) {
953 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
954 credit_charge
= MAX(credit_charge
, 1);
957 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
958 credits_requested
= SVAL(inhdr
, SMB2_HDR_CREDIT
);
959 credits_requested
= MAX(credits_requested
, 1);
960 out_flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
961 out_status
= NT_STATUS(IVAL(outhdr
, SMB2_HDR_STATUS
));
963 SMB_ASSERT(xconn
->smb2
.credits
.max
>= xconn
->smb2
.credits
.granted
);
965 if (xconn
->smb2
.credits
.max
< credit_charge
) {
966 smbd_server_connection_terminate(xconn
,
967 "client error: credit charge > max credits\n");
971 if (out_flags
& SMB2_HDR_FLAG_ASYNC
) {
973 * In case we already send an async interim
974 * response, we should not grant
975 * credits on the final response.
979 uint16_t additional_possible
=
980 xconn
->smb2
.credits
.max
- credit_charge
;
981 uint16_t additional_max
= 0;
982 uint16_t additional_credits
= credits_requested
- 1;
985 case SMB2_OP_NEGPROT
:
987 case SMB2_OP_SESSSETUP
:
989 * Windows 2012 RC1 starts to grant
991 * with a successful session setup
993 if (NT_STATUS_IS_OK(out_status
)) {
994 additional_max
= xconn
->smb2
.credits
.max
;
999 * Windows Server < 2016 and older Samba versions
1000 * used to only grant additional credits in
1001 * chunks of 32 credits.
1003 * But we match Windows Server 2016 and grant
1004 * all credits as requested.
1006 additional_max
= xconn
->smb2
.credits
.max
;
1010 additional_max
= MIN(additional_max
, additional_possible
);
1011 additional_credits
= MIN(additional_credits
, additional_max
);
1013 credits_granted
= credit_charge
+ additional_credits
;
1017 * sequence numbers should not wrap
1019 * 1. calculate the possible credits until
1020 * the sequence numbers start to wrap on 64-bit.
1022 * 2. UINT64_MAX is used for Break Notifications.
1024 * 2. truncate the possible credits to the maximum
1025 * credits we want to grant to the client in total.
1027 * 3. remove the range we'll already granted to the client
1028 * this makes sure the client consumes the lowest sequence
1029 * number, before we can grant additional credits.
1031 credits_possible
= UINT64_MAX
- xconn
->smb2
.credits
.seq_low
;
1032 if (credits_possible
> 0) {
1033 /* remove UINT64_MAX */
1034 credits_possible
-= 1;
1036 credits_possible
= MIN(credits_possible
, current_max_credits
);
1037 credits_possible
-= xconn
->smb2
.credits
.seq_range
;
1039 credits_granted
= MIN(credits_granted
, credits_possible
);
1041 SSVAL(outhdr
, SMB2_HDR_CREDIT
, credits_granted
);
1042 xconn
->smb2
.credits
.granted
+= credits_granted
;
1043 xconn
->smb2
.credits
.seq_range
+= credits_granted
;
1045 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
1046 "smb2_set_operation_credit: requested %u, charge %u, "
1047 "granted %u, current possible/max %u/%u, "
1048 "total granted/max/low/range %u/%u/%llu/%u\n",
1049 (unsigned int)credits_requested
,
1050 (unsigned int)credit_charge
,
1051 (unsigned int)credits_granted
,
1052 (unsigned int)credits_possible
,
1053 (unsigned int)current_max_credits
,
1054 (unsigned int)xconn
->smb2
.credits
.granted
,
1055 (unsigned int)xconn
->smb2
.credits
.max
,
1056 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
1057 (unsigned int)xconn
->smb2
.credits
.seq_range
);
1060 static void smb2_calculate_credits(const struct smbd_smb2_request
*inreq
,
1061 struct smbd_smb2_request
*outreq
)
1064 uint16_t total_credits
= 0;
1066 count
= outreq
->out
.vector_count
;
1068 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1069 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(inreq
,in
,idx
);
1070 struct iovec
*outhdr_v
= SMBD_SMB2_IDX_HDR_IOV(outreq
,out
,idx
);
1071 uint8_t *outhdr
= (uint8_t *)outhdr_v
->iov_base
;
1073 smb2_set_operation_credit(outreq
->xconn
, inhdr_v
, outhdr_v
);
1075 /* To match Windows, count up what we
1077 total_credits
+= SVAL(outhdr
, SMB2_HDR_CREDIT
);
1078 /* Set to zero in all but the last reply. */
1079 if (idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
< count
) {
1080 SSVAL(outhdr
, SMB2_HDR_CREDIT
, 0);
1082 SSVAL(outhdr
, SMB2_HDR_CREDIT
, total_credits
);
1087 DATA_BLOB
smbd_smb2_generate_outbody(struct smbd_smb2_request
*req
, size_t size
)
1089 if (req
->current_idx
<= 1) {
1090 if (size
<= sizeof(req
->out
._body
)) {
1091 return data_blob_const(req
->out
._body
, size
);
1095 return data_blob_talloc(req
, NULL
, size
);
1098 static NTSTATUS
smbd_smb2_request_setup_out(struct smbd_smb2_request
*req
)
1100 struct smbXsrv_connection
*xconn
= req
->xconn
;
1101 TALLOC_CTX
*mem_ctx
;
1102 struct iovec
*vector
;
1107 count
= req
->in
.vector_count
;
1108 if (count
<= ARRAY_SIZE(req
->out
._vector
)) {
1110 vector
= req
->out
._vector
;
1112 vector
= talloc_zero_array(req
, struct iovec
, count
);
1113 if (vector
== NULL
) {
1114 return NT_STATUS_NO_MEMORY
;
1119 vector
[0].iov_base
= req
->out
.nbt_hdr
;
1120 vector
[0].iov_len
= 4;
1121 SIVAL(req
->out
.nbt_hdr
, 0, 0);
1123 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1124 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
1125 const uint8_t *inhdr
= (const uint8_t *)inhdr_v
->iov_base
;
1126 uint8_t *outhdr
= NULL
;
1127 uint8_t *outbody
= NULL
;
1128 uint32_t next_command_ofs
= 0;
1129 struct iovec
*current
= &vector
[idx
];
1131 if ((idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) < count
) {
1132 /* we have a next command -
1133 * setup for the error case. */
1134 next_command_ofs
= SMB2_HDR_BODY
+ 9;
1138 outhdr
= req
->out
._hdr
;
1140 outhdr
= talloc_zero_array(mem_ctx
, uint8_t,
1142 if (outhdr
== NULL
) {
1143 return NT_STATUS_NO_MEMORY
;
1147 outbody
= outhdr
+ SMB2_HDR_BODY
;
1150 * SMBD_SMB2_TF_IOV_OFS might be used later
1152 current
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1153 current
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1155 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)outhdr
;
1156 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1158 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)outbody
;
1159 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1161 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= NULL
;
1162 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 0;
1164 /* setup the SMB2 header */
1165 SIVAL(outhdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1166 SSVAL(outhdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1167 SSVAL(outhdr
, SMB2_HDR_CREDIT_CHARGE
,
1168 SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
));
1169 SIVAL(outhdr
, SMB2_HDR_STATUS
,
1170 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR
));
1171 SSVAL(outhdr
, SMB2_HDR_OPCODE
,
1172 SVAL(inhdr
, SMB2_HDR_OPCODE
));
1173 SIVAL(outhdr
, SMB2_HDR_FLAGS
,
1174 IVAL(inhdr
, SMB2_HDR_FLAGS
) | SMB2_HDR_FLAG_REDIRECT
);
1175 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
1176 SBVAL(outhdr
, SMB2_HDR_MESSAGE_ID
,
1177 BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
));
1178 SIVAL(outhdr
, SMB2_HDR_PID
,
1179 IVAL(inhdr
, SMB2_HDR_PID
));
1180 SIVAL(outhdr
, SMB2_HDR_TID
,
1181 IVAL(inhdr
, SMB2_HDR_TID
));
1182 SBVAL(outhdr
, SMB2_HDR_SESSION_ID
,
1183 BVAL(inhdr
, SMB2_HDR_SESSION_ID
));
1184 memcpy(outhdr
+ SMB2_HDR_SIGNATURE
,
1185 inhdr
+ SMB2_HDR_SIGNATURE
, 16);
1187 /* setup error body header */
1188 SSVAL(outbody
, 0x00, 0x08 + 1);
1189 SSVAL(outbody
, 0x02, 0);
1190 SIVAL(outbody
, 0x04, 0);
1193 req
->out
.vector
= vector
;
1194 req
->out
.vector_count
= count
;
1196 /* setup the length of the NBT packet */
1197 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
1199 return NT_STATUS_INVALID_PARAMETER_MIX
;
1202 DLIST_ADD_END(xconn
->smb2
.requests
, req
);
1204 return NT_STATUS_OK
;
1207 bool smbXsrv_server_multi_channel_enabled(void)
1209 bool enabled
= lp_server_multi_channel_support();
1210 #ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1211 bool forced
= false;
1212 struct loadparm_context
*lp_ctx
= loadparm_init_s3(NULL
, loadparm_s3_helpers());
1213 bool unspecified
= lpcfg_parm_is_unspecified(lp_ctx
, "server multi channel support");
1218 * If we don't have support from the kernel
1219 * to ask for the un-acked number of bytes
1220 * in the socket send queue, we better
1221 * don't support multi-channel.
1223 forced
= lp_parm_bool(-1, "force", "server multi channel support", false);
1224 if (enabled
&& !forced
) {
1225 D_NOTICE("'server multi channel support' enabled "
1226 "but not supported on %s (%s)\n",
1227 SYSTEM_UNAME_SYSNAME
, SYSTEM_UNAME_RELEASE
);
1228 DEBUGADD(DBGLVL_NOTICE
, ("Please report this on "
1229 "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1232 TALLOC_FREE(lp_ctx
);
1233 #endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1237 static NTSTATUS
smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection
*xconn
,
1238 uint32_t *_rto_usecs
)
1241 * Define an Retransmission Timeout
1242 * of 1 second, if there's no way for the
1243 * kernel to tell us the current value.
1245 uint32_t rto_usecs
= 1000000;
1247 #ifdef __HAVE_TCP_INFO_RTO
1249 struct tcp_info info
;
1250 socklen_t ilen
= sizeof(info
);
1254 ret
= getsockopt(xconn
->transport
.sock
,
1255 IPPROTO_TCP
, TCP_INFO
,
1256 (void *)&info
, &ilen
);
1258 int saved_errno
= errno
;
1259 NTSTATUS status
= map_nt_error_from_unix(errno
);
1260 DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1261 saved_errno
, strerror(saved_errno
),
1266 DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1267 (unsigned)info
.tcpi_rto
,
1268 (unsigned)info
.tcpi_rtt
,
1269 (unsigned)info
.tcpi_rttvar
);
1270 rto_usecs
= info
.tcpi_rto
;
1272 #endif /* __HAVE_TCP_INFO_RTO */
1274 rto_usecs
= MAX(rto_usecs
, 200000); /* at least 0.2s */
1275 rto_usecs
= MIN(rto_usecs
, 1000000); /* at max 1.0s */
1276 *_rto_usecs
= rto_usecs
;
1277 return NT_STATUS_OK
;
1280 static NTSTATUS
smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection
*xconn
,
1281 uint64_t *_acked_bytes
)
1284 * Unless the kernel has an interface
1285 * to reveal the number of un-acked bytes
1286 * in the socket send queue, we'll assume
1287 * everything is already acked.
1289 * But that would mean that we better don't
1290 * pretent to support multi-channel.
1292 uint64_t unacked_bytes
= 0;
1296 if (xconn
->ack
.force_unacked_timeout
) {
1298 * Smbtorture tries to test channel failures...
1299 * Just pretend nothing was acked...
1301 DBG_INFO("Simulating channel failure: "
1302 "xconn->ack.unacked_bytes[%llu]\n",
1303 (unsigned long long)xconn
->ack
.unacked_bytes
);
1304 return NT_STATUS_OK
;
1307 #ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1313 * If we have kernel support to get
1314 * the number of bytes waiting in
1315 * the socket's send queue, we
1316 * use that in order to find out
1317 * the number of unacked bytes.
1319 ret
= ioctl(xconn
->transport
.sock
,
1320 __IOCTL_SEND_QUEUE_SIZE_OPCODE
,
1323 int saved_errno
= errno
;
1324 NTSTATUS status
= map_nt_error_from_unix(saved_errno
);
1325 DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1326 "errno %d (%s) - %s\n",
1327 saved_errno
, strerror(saved_errno
),
1333 DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1334 (unsigned long long)xconn
->ack
.unacked_bytes
,
1336 return NT_STATUS_INTERNAL_ERROR
;
1338 unacked_bytes
= value
;
1341 if (xconn
->ack
.unacked_bytes
== 0) {
1342 xconn
->ack
.unacked_bytes
= unacked_bytes
;
1343 return NT_STATUS_OK
;
1346 if (xconn
->ack
.unacked_bytes
< unacked_bytes
) {
1347 DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1348 (unsigned long long)xconn
->ack
.unacked_bytes
,
1349 (unsigned long long)unacked_bytes
);
1350 return NT_STATUS_INTERNAL_ERROR
;
1353 *_acked_bytes
= xconn
->ack
.unacked_bytes
- unacked_bytes
;
1354 xconn
->ack
.unacked_bytes
= unacked_bytes
;
1355 return NT_STATUS_OK
;
1358 static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue
**queue
,
1361 struct smbd_smb2_send_queue
*e
= NULL
;
1362 struct smbd_smb2_send_queue
*n
= NULL
;
1364 for (e
= *queue
; e
!= NULL
; e
= n
) {
1367 DLIST_REMOVE(*queue
, e
);
1368 if (e
->ack
.req
!= NULL
) {
1369 tevent_req_nterror(e
->ack
.req
, status
);
1374 static NTSTATUS
smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue
**queue
,
1375 uint64_t acked_bytes
)
1377 struct smbd_smb2_send_queue
*e
= NULL
;
1378 struct smbd_smb2_send_queue
*n
= NULL
;
1380 for (e
= *queue
; e
!= NULL
; e
= n
) {
1385 if (e
->ack
.req
== NULL
) {
1389 if (e
->ack
.required_acked_bytes
<= acked_bytes
) {
1390 e
->ack
.required_acked_bytes
= 0;
1391 DLIST_REMOVE(*queue
, e
);
1392 tevent_req_done(e
->ack
.req
);
1395 e
->ack
.required_acked_bytes
-= acked_bytes
;
1397 expired
= timeval_expired(&e
->ack
.timeout
);
1399 return NT_STATUS_IO_TIMEOUT
;
1403 return NT_STATUS_OK
;
1406 static NTSTATUS
smbd_smb2_check_ack_queue(struct smbXsrv_connection
*xconn
)
1408 uint64_t acked_bytes
= 0;
1411 status
= smbXsrv_connection_get_acked_bytes(xconn
, &acked_bytes
);
1412 if (!NT_STATUS_IS_OK(status
)) {
1416 status
= smbd_smb2_send_queue_ack_bytes(&xconn
->ack
.queue
, acked_bytes
);
1417 if (!NT_STATUS_IS_OK(status
)) {
1421 status
= smbd_smb2_send_queue_ack_bytes(&xconn
->smb2
.send_queue
, 0);
1422 if (!NT_STATUS_IS_OK(status
)) {
1426 return NT_STATUS_OK
;
1429 static void smbXsrv_connection_ack_checker(struct tevent_req
*subreq
)
1431 struct smbXsrv_connection
*xconn
=
1432 tevent_req_callback_data(subreq
,
1433 struct smbXsrv_connection
);
1434 struct smbXsrv_client
*client
= xconn
->client
;
1435 struct timeval next_check
;
1439 xconn
->ack
.checker_subreq
= NULL
;
1441 ok
= tevent_wakeup_recv(subreq
);
1442 TALLOC_FREE(subreq
);
1444 smbd_server_connection_terminate(xconn
,
1445 "tevent_wakeup_recv() failed");
1449 status
= smbd_smb2_check_ack_queue(xconn
);
1450 if (!NT_STATUS_IS_OK(status
)) {
1451 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
1455 next_check
= timeval_current_ofs_usec(xconn
->ack
.rto_usecs
);
1456 xconn
->ack
.checker_subreq
= tevent_wakeup_send(xconn
,
1459 if (xconn
->ack
.checker_subreq
== NULL
) {
1460 smbd_server_connection_terminate(xconn
,
1461 "tevent_wakeup_send() failed");
1464 tevent_req_set_callback(xconn
->ack
.checker_subreq
,
1465 smbXsrv_connection_ack_checker
,
1469 static NTSTATUS
smbXsrv_client_pending_breaks_updated(struct smbXsrv_client
*client
)
1471 struct smbXsrv_connection
*xconn
= NULL
;
1473 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
1474 struct timeval next_check
;
1475 uint64_t acked_bytes
= 0;
1479 * A new 'pending break cycle' starts
1480 * with a first pending break and lasts until
1481 * all pending breaks are finished.
1483 * This is typically a very short time,
1484 * the value of one retransmission timeout.
1487 if (client
->pending_breaks
== NULL
) {
1489 * No more pending breaks, remove a pending
1492 TALLOC_FREE(xconn
->ack
.checker_subreq
);
1496 if (xconn
->ack
.checker_subreq
!= NULL
) {
1498 * The cycle already started =>
1505 * Get the current retransmission timeout value.
1507 * It may change over time, but fetching it once
1508 * per 'pending break' cycled should be enough.
1510 status
= smbXsrv_connection_get_rto_usecs(xconn
,
1511 &xconn
->ack
.rto_usecs
);
1512 if (!NT_STATUS_IS_OK(status
)) {
1517 * At the start of the cycle we reset the
1518 * unacked_bytes counter (first to 0 and
1519 * within smbXsrv_connection_get_acked_bytes()
1520 * to the current value in the kernel
1523 xconn
->ack
.unacked_bytes
= 0;
1524 status
= smbXsrv_connection_get_acked_bytes(xconn
, &acked_bytes
);
1525 if (!NT_STATUS_IS_OK(status
)) {
1530 * We setup a timer in order to check for
1531 * acked bytes after one retransmission timeout.
1533 * The code that sets up the send_queue.ack.timeout
1534 * uses a multiple of the retransmission timeout.
1536 next_check
= timeval_current_ofs_usec(xconn
->ack
.rto_usecs
);
1537 xconn
->ack
.checker_subreq
= tevent_wakeup_send(xconn
,
1540 if (xconn
->ack
.checker_subreq
== NULL
) {
1541 return NT_STATUS_NO_MEMORY
;
1543 tevent_req_set_callback(xconn
->ack
.checker_subreq
,
1544 smbXsrv_connection_ack_checker
,
1548 return NT_STATUS_OK
;
1551 void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection
*xconn
,
1554 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
1558 xconn
->transport
.status
= status
;
1559 TALLOC_FREE(xconn
->transport
.fde
);
1560 if (xconn
->transport
.sock
!= -1) {
1561 xconn
->transport
.sock
= -1;
1563 smbd_smb2_send_queue_ack_fail(&xconn
->ack
.queue
, status
);
1564 smbd_smb2_send_queue_ack_fail(&xconn
->smb2
.send_queue
, status
);
1565 xconn
->smb2
.send_queue_len
= 0;
1566 DO_PROFILE_INC(disconnect
);
1569 size_t smbXsrv_client_valid_connections(struct smbXsrv_client
*client
)
1571 struct smbXsrv_connection
*xconn
= NULL
;
1574 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
1575 if (NT_STATUS_IS_OK(xconn
->transport
.status
)) {
1583 struct smbXsrv_connection_shutdown_state
{
1584 struct smbXsrv_connection
*xconn
;
1587 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req
*subreq
);
1589 static struct tevent_req
*smbXsrv_connection_shutdown_send(TALLOC_CTX
*mem_ctx
,
1590 struct tevent_context
*ev
,
1591 struct smbXsrv_connection
*xconn
)
1593 struct tevent_req
*req
= NULL
;
1594 struct smbXsrv_connection_shutdown_state
*state
= NULL
;
1595 struct tevent_req
*subreq
= NULL
;
1597 struct smbd_smb2_request
*preq
= NULL
;
1601 * The caller should have called
1602 * smbXsrv_connection_disconnect_transport() before.
1604 SMB_ASSERT(!NT_STATUS_IS_OK(xconn
->transport
.status
));
1605 SMB_ASSERT(xconn
->transport
.terminating
);
1606 SMB_ASSERT(xconn
->transport
.shutdown_wait_queue
== NULL
);
1608 req
= tevent_req_create(mem_ctx
, &state
,
1609 struct smbXsrv_connection_shutdown_state
);
1614 state
->xconn
= xconn
;
1615 tevent_req_defer_callback(req
, ev
);
1617 xconn
->transport
.shutdown_wait_queue
=
1618 tevent_queue_create(state
, "smbXsrv_connection_shutdown_queue");
1619 if (tevent_req_nomem(xconn
->transport
.shutdown_wait_queue
, req
)) {
1620 return tevent_req_post(req
, ev
);
1623 for (preq
= xconn
->smb2
.requests
; preq
!= NULL
; preq
= preq
->next
) {
1625 * Now wait until the request is finished.
1627 * We don't set a callback, as we just want to block the
1628 * wait queue and the talloc_free() of the request will
1629 * remove the item from the wait queue.
1631 * Note that we don't cancel the requests here
1632 * in order to keep the replay detection logic correct.
1634 * However if we teardown the last channel of
1635 * a connection, we'll call some logic via
1636 * smbXsrv_session_disconnect_xconn()
1637 * -> smbXsrv_session_disconnect_xconn_callback()
1638 * -> smbXsrv_session_remove_channel()
1639 * -> smb2srv_session_shutdown_send()
1640 * will indeed cancel the request.
1642 subreq
= tevent_queue_wait_send(preq
, ev
,
1643 xconn
->transport
.shutdown_wait_queue
);
1644 if (tevent_req_nomem(subreq
, req
)) {
1645 return tevent_req_post(req
, ev
);
1650 * This may attach sessions with num_channels == 0
1651 * to xconn->transport.shutdown_wait_queue.
1653 status
= smbXsrv_session_disconnect_xconn(xconn
);
1654 if (tevent_req_nterror(req
, status
)) {
1655 return tevent_req_post(req
, ev
);
1658 len
= tevent_queue_length(xconn
->transport
.shutdown_wait_queue
);
1660 tevent_req_done(req
);
1661 return tevent_req_post(req
, ev
);
1665 * Now we add our own waiter to the end of the queue,
1666 * this way we get notified when all pending requests are finished
1667 * and send to the socket.
1669 subreq
= tevent_queue_wait_send(state
, ev
, xconn
->transport
.shutdown_wait_queue
);
1670 if (tevent_req_nomem(subreq
, req
)) {
1671 return tevent_req_post(req
, ev
);
1673 tevent_req_set_callback(subreq
, smbXsrv_connection_shutdown_wait_done
, req
);
1678 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req
*subreq
)
1680 struct tevent_req
*req
=
1681 tevent_req_callback_data(subreq
,
1683 struct smbXsrv_connection_shutdown_state
*state
=
1684 tevent_req_data(req
,
1685 struct smbXsrv_connection_shutdown_state
);
1686 struct smbXsrv_connection
*xconn
= state
->xconn
;
1688 tevent_queue_wait_recv(subreq
);
1689 TALLOC_FREE(subreq
);
1691 tevent_req_done(req
);
1693 * make sure the xconn pointer is still valid,
1694 * it should as we used tevent_req_defer_callback()
1696 SMB_ASSERT(xconn
->transport
.terminating
);
1699 static NTSTATUS
smbXsrv_connection_shutdown_recv(struct tevent_req
*req
)
1701 struct smbXsrv_connection_shutdown_state
*state
=
1702 tevent_req_data(req
,
1703 struct smbXsrv_connection_shutdown_state
);
1704 struct smbXsrv_connection
*xconn
= state
->xconn
;
1706 * make sure the xconn pointer is still valid,
1707 * it should as we used tevent_req_defer_callback()
1709 SMB_ASSERT(xconn
->transport
.terminating
);
1710 return tevent_req_simple_recv_ntstatus(req
);
1713 static void smbd_server_connection_terminate_done(struct tevent_req
*subreq
)
1715 struct smbXsrv_connection
*xconn
=
1716 tevent_req_callback_data(subreq
,
1717 struct smbXsrv_connection
);
1718 struct smbXsrv_client
*client
= xconn
->client
;
1721 status
= smbXsrv_connection_shutdown_recv(subreq
);
1722 TALLOC_FREE(subreq
);
1723 if (!NT_STATUS_IS_OK(status
)) {
1724 exit_server("smbXsrv_connection_shutdown_recv failed");
1727 DLIST_REMOVE(client
->connections
, xconn
);
1731 void smbd_server_connection_terminate_ex(struct smbXsrv_connection
*xconn
,
1733 const char *location
)
1735 struct smbXsrv_client
*client
= xconn
->client
;
1739 * Make sure that no new request will be able to use this session.
1741 * smbXsrv_connection_disconnect_transport() might be called already,
1742 * but calling it again is a no-op.
1744 smbXsrv_connection_disconnect_transport(xconn
,
1745 NT_STATUS_CONNECTION_DISCONNECTED
);
1747 num_ok
= smbXsrv_client_valid_connections(client
);
1749 if (xconn
->transport
.terminating
) {
1750 DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1751 smbXsrv_connection_dbg(xconn
), num_ok
,
1755 xconn
->transport
.terminating
= true;
1757 DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1758 smbXsrv_connection_dbg(xconn
), num_ok
,
1761 if (xconn
->has_cluster_movable_ip
) {
1763 * If the connection has a movable cluster public address
1764 * we disconnect all client connections,
1765 * as the public address might be moved to
1768 * In future we may recheck which node currently
1769 * holds this address, but for now we keep it simple.
1771 smbd_server_disconnect_client_ex(xconn
->client
,
1778 struct tevent_req
*subreq
= NULL
;
1780 subreq
= smbXsrv_connection_shutdown_send(client
,
1783 if (subreq
== NULL
) {
1784 exit_server("smbXsrv_connection_shutdown_send failed");
1786 tevent_req_set_callback(subreq
,
1787 smbd_server_connection_terminate_done
,
1793 * The last connection was disconnected
1795 exit_server_cleanly(reason
);
1798 void smbd_server_disconnect_client_ex(struct smbXsrv_client
*client
,
1800 const char *location
)
1804 num_ok
= smbXsrv_client_valid_connections(client
);
1806 DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1807 client
->global
->remote_address
, num_ok
,
1811 * Something bad happened we need to disconnect all connections.
1813 exit_server_cleanly(reason
);
1816 static bool dup_smb2_vec4(TALLOC_CTX
*ctx
,
1817 struct iovec
*outvec
,
1818 const struct iovec
*srcvec
)
1820 const uint8_t *srctf
;
1822 const uint8_t *srchdr
;
1824 const uint8_t *srcbody
;
1826 const uint8_t *expected_srcbody
;
1827 const uint8_t *srcdyn
;
1829 const uint8_t *expected_srcdyn
;
1835 srctf
= (const uint8_t *)srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
;
1836 srctf_len
= srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
;
1837 srchdr
= (const uint8_t *)srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
;
1838 srchdr_len
= srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
;
1839 srcbody
= (const uint8_t *)srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
;
1840 srcbody_len
= srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
;
1841 expected_srcbody
= srchdr
+ SMB2_HDR_BODY
;
1842 srcdyn
= (const uint8_t *)srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
;
1843 srcdyn_len
= srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
;
1844 expected_srcdyn
= srcbody
+ 8;
1846 if ((srctf_len
!= SMB2_TF_HDR_SIZE
) && (srctf_len
!= 0)) {
1850 if (srchdr_len
!= SMB2_HDR_BODY
) {
1854 if (srctf_len
== SMB2_TF_HDR_SIZE
) {
1855 dsttf
= talloc_memdup(ctx
, srctf
, SMB2_TF_HDR_SIZE
);
1856 if (dsttf
== NULL
) {
1862 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= (void *)dsttf
;
1863 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= srctf_len
;
1865 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1866 * be allocated with size OUTVEC_ALLOC_SIZE. */
1868 dsthdr
= talloc_memdup(ctx
, srchdr
, OUTVEC_ALLOC_SIZE
);
1869 if (dsthdr
== NULL
) {
1872 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)dsthdr
;
1873 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1876 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1877 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1878 * then duplicate this. Else use talloc_memdup().
1881 if ((srcbody
== expected_srcbody
) && (srcbody_len
== 8)) {
1882 dstbody
= dsthdr
+ SMB2_HDR_BODY
;
1884 dstbody
= talloc_memdup(ctx
, srcbody
, srcbody_len
);
1885 if (dstbody
== NULL
) {
1889 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)dstbody
;
1890 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= srcbody_len
;
1893 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1895 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1896 * then duplicate this. Else use talloc_memdup().
1899 if ((srcdyn
== expected_srcdyn
) && (srcdyn_len
== 1)) {
1900 dstdyn
= dsthdr
+ SMB2_HDR_BODY
+ 8;
1901 } else if (srcdyn
== NULL
) {
1904 dstdyn
= talloc_memdup(ctx
, srcdyn
, srcdyn_len
);
1905 if (dstdyn
== NULL
) {
1909 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= (void *)dstdyn
;
1910 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= srcdyn_len
;
1915 static struct smbd_smb2_request
*dup_smb2_req(const struct smbd_smb2_request
*req
)
1917 struct smbd_smb2_request
*newreq
= NULL
;
1918 struct iovec
*outvec
= NULL
;
1919 int count
= req
->out
.vector_count
;
1923 newreq
= smbd_smb2_request_allocate(req
->xconn
);
1928 newreq
->session
= req
->session
;
1929 newreq
->do_encryption
= req
->do_encryption
;
1930 newreq
->do_signing
= req
->do_signing
;
1931 newreq
->current_idx
= req
->current_idx
;
1933 outvec
= talloc_zero_array(newreq
, struct iovec
, count
);
1935 TALLOC_FREE(newreq
);
1938 newreq
->out
.vector
= outvec
;
1939 newreq
->out
.vector_count
= count
;
1941 /* Setup the outvec's identically to req. */
1942 outvec
[0].iov_base
= newreq
->out
.nbt_hdr
;
1943 outvec
[0].iov_len
= 4;
1944 memcpy(newreq
->out
.nbt_hdr
, req
->out
.nbt_hdr
, 4);
1946 /* Setup the vectors identically to the ones in req. */
1947 for (i
= 1; i
< count
; i
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1948 if (!dup_smb2_vec4(outvec
, &outvec
[i
], &req
->out
.vector
[i
])) {
1955 TALLOC_FREE(newreq
);
1959 ok
= smb2_setup_nbt_length(newreq
->out
.vector
,
1960 newreq
->out
.vector_count
);
1962 TALLOC_FREE(newreq
);
1969 static NTSTATUS
smb2_send_async_interim_response(const struct smbd_smb2_request
*req
)
1971 struct smbXsrv_connection
*xconn
= req
->xconn
;
1973 struct iovec
*firsttf
= NULL
;
1974 struct iovec
*outhdr_v
= NULL
;
1975 uint8_t *outhdr
= NULL
;
1976 struct smbd_smb2_request
*nreq
= NULL
;
1980 /* Create a new smb2 request we'll use
1981 for the interim return. */
1982 nreq
= dup_smb2_req(req
);
1984 return NT_STATUS_NO_MEMORY
;
1987 /* Lose the last X out vectors. They're the
1988 ones we'll be using for the async reply. */
1989 nreq
->out
.vector_count
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1991 ok
= smb2_setup_nbt_length(nreq
->out
.vector
,
1992 nreq
->out
.vector_count
);
1994 return NT_STATUS_INVALID_PARAMETER_MIX
;
1997 /* Step back to the previous reply. */
1998 nreq
->current_idx
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1999 firsttf
= SMBD_SMB2_IDX_TF_IOV(nreq
,out
,first_idx
);
2000 outhdr_v
= SMBD_SMB2_OUT_HDR_IOV(nreq
);
2001 outhdr
= SMBD_SMB2_OUT_HDR_PTR(nreq
);
2002 /* And end the chain. */
2003 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2005 /* Calculate outgoing credits */
2006 smb2_calculate_credits(req
, nreq
);
2008 if (DEBUGLEVEL
>= 10) {
2009 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
2010 (unsigned int)nreq
->current_idx
);
2011 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
2012 (unsigned int)nreq
->out
.vector_count
);
2013 print_req_vectors(nreq
);
2017 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
2018 * we need to sign/encrypt here with the last/first key we remembered
2020 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
2021 status
= smb2_signing_encrypt_pdu(req
->first_enc_key
,
2023 nreq
->out
.vector_count
- first_idx
);
2024 if (!NT_STATUS_IS_OK(status
)) {
2027 } else if (smb2_signing_key_valid(req
->last_sign_key
)) {
2028 status
= smb2_signing_sign_pdu(req
->last_sign_key
,
2030 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2031 if (!NT_STATUS_IS_OK(status
)) {
2036 nreq
->queue_entry
.mem_ctx
= nreq
;
2037 nreq
->queue_entry
.vector
= nreq
->out
.vector
;
2038 nreq
->queue_entry
.count
= nreq
->out
.vector_count
;
2039 DLIST_ADD_END(xconn
->smb2
.send_queue
, &nreq
->queue_entry
);
2040 xconn
->smb2
.send_queue_len
++;
2042 status
= smbd_smb2_flush_send_queue(xconn
);
2043 if (!NT_STATUS_IS_OK(status
)) {
2047 return NT_STATUS_OK
;
2050 struct smbd_smb2_request_pending_state
{
2051 struct smbd_smb2_send_queue queue_entry
;
2052 uint8_t buf
[NBT_HDR_SIZE
+ SMB2_TF_HDR_SIZE
+ SMB2_HDR_BODY
+ 0x08 + 1];
2053 struct iovec vector
[1 + SMBD_SMB2_NUM_IOV_PER_REQ
];
2056 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
2057 struct tevent_timer
*te
,
2058 struct timeval current_time
,
2059 void *private_data
);
2061 NTSTATUS
smbd_smb2_request_pending_queue(struct smbd_smb2_request
*req
,
2062 struct tevent_req
*subreq
,
2063 uint32_t defer_time
)
2066 struct timeval defer_endtime
;
2067 uint8_t *outhdr
= NULL
;
2070 if (!tevent_req_is_in_progress(subreq
)) {
2072 * This is a performance optimization,
2073 * it avoids one tevent_loop iteration,
2074 * which means we avoid one
2075 * talloc_stackframe_pool/talloc_free pair.
2077 tevent_req_notify_callback(subreq
);
2078 return NT_STATUS_OK
;
2081 req
->subreq
= subreq
;
2084 if (req
->async_te
) {
2085 /* We're already async. */
2086 return NT_STATUS_OK
;
2089 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2090 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
2091 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
2092 /* We're already async. */
2093 return NT_STATUS_OK
;
2096 if (req
->async_internal
|| defer_time
== 0) {
2098 * An SMB2 request implementation wants to handle the request
2099 * asynchronously "internally" while keeping synchronous
2100 * behaviour for the SMB2 request. This means we don't send an
2101 * interim response and we can allow processing of compound SMB2
2102 * requests (cf the subsequent check) for all cases.
2104 return NT_STATUS_OK
;
2107 if (req
->in
.vector_count
> req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) {
2109 * We're trying to go async in a compound request
2110 * chain. This is only allowed for opens that cause an
2111 * oplock break or for the last operation in the
2112 * chain, otherwise it is not allowed. See
2113 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2115 const uint8_t *inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2117 if (SVAL(inhdr
, SMB2_HDR_OPCODE
) != SMB2_OP_CREATE
) {
2119 * Cancel the outstanding request.
2121 bool ok
= tevent_req_cancel(req
->subreq
);
2123 return NT_STATUS_OK
;
2125 TALLOC_FREE(req
->subreq
);
2126 return smbd_smb2_request_error(req
,
2127 NT_STATUS_INTERNAL_ERROR
);
2131 if (DEBUGLEVEL
>= 10) {
2132 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2133 (unsigned int)req
->current_idx
);
2134 print_req_vectors(req
);
2137 if (req
->current_idx
> 1) {
2139 * We're going async in a compound
2140 * chain after the first request has
2141 * already been processed. Send an
2142 * interim response containing the
2143 * set of replies already generated.
2145 int idx
= req
->current_idx
;
2147 status
= smb2_send_async_interim_response(req
);
2148 if (!NT_STATUS_IS_OK(status
)) {
2151 TALLOC_FREE(req
->first_enc_key
);
2153 req
->current_idx
= 1;
2156 * Re-arrange the in.vectors to remove what
2159 memmove(&req
->in
.vector
[1],
2160 &req
->in
.vector
[idx
],
2161 sizeof(req
->in
.vector
[0])*(req
->in
.vector_count
- idx
));
2162 req
->in
.vector_count
= 1 + (req
->in
.vector_count
- idx
);
2164 /* Re-arrange the out.vectors to match. */
2165 memmove(&req
->out
.vector
[1],
2166 &req
->out
.vector
[idx
],
2167 sizeof(req
->out
.vector
[0])*(req
->out
.vector_count
- idx
));
2168 req
->out
.vector_count
= 1 + (req
->out
.vector_count
- idx
);
2170 if (req
->in
.vector_count
== 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
2172 * We only have one remaining request as
2173 * we've processed everything else.
2174 * This is no longer a compound request.
2176 req
->compound_related
= false;
2177 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2178 flags
= (IVAL(outhdr
, SMB2_HDR_FLAGS
) & ~SMB2_HDR_FLAG_CHAINED
);
2179 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
);
2182 TALLOC_FREE(req
->last_sign_key
);
2185 * smbd_smb2_request_pending_timer() just send a packet
2186 * to the client and doesn't need any impersonation.
2187 * So we use req->xconn->client->raw_ev_ctx instead
2188 * of req->ev_ctx here.
2190 defer_endtime
= timeval_current_ofs_usec(defer_time
);
2191 req
->async_te
= tevent_add_timer(req
->xconn
->client
->raw_ev_ctx
,
2193 smbd_smb2_request_pending_timer
,
2195 if (req
->async_te
== NULL
) {
2196 return NT_STATUS_NO_MEMORY
;
2199 return NT_STATUS_OK
;
2203 struct smb2_signing_key
*smbd_smb2_signing_key(struct smbXsrv_session
*session
,
2204 struct smbXsrv_connection
*xconn
,
2207 struct smbXsrv_channel_global0
*c
= NULL
;
2209 struct smb2_signing_key
*key
= NULL
;
2210 bool has_channel
= false;
2212 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
2213 if (NT_STATUS_IS_OK(status
)) {
2214 key
= c
->signing_key
;
2218 if (!smb2_signing_key_valid(key
)) {
2219 key
= session
->global
->signing_key
;
2220 has_channel
= false;
2223 if (_has_channel
!= NULL
) {
2224 *_has_channel
= has_channel
;
2230 static NTSTATUS
smb2_get_new_nonce(struct smbXsrv_session
*session
,
2231 uint64_t *new_nonce_high
,
2232 uint64_t *new_nonce_low
)
2234 uint64_t nonce_high
;
2237 session
->nonce_low
+= 1;
2238 if (session
->nonce_low
== 0) {
2239 session
->nonce_low
+= 1;
2240 session
->nonce_high
+= 1;
2244 * CCM and GCM algorithms must never have their
2245 * nonce wrap, or the security of the whole
2246 * communication and the keys is destroyed.
2247 * We must drop the connection once we have
2248 * transferred too much data.
2250 * NOTE: We assume nonces greater than 8 bytes.
2252 if (session
->nonce_high
>= session
->nonce_high_max
) {
2253 return NT_STATUS_ENCRYPTION_FAILED
;
2256 nonce_high
= session
->nonce_high_random
;
2257 nonce_high
+= session
->nonce_high
;
2258 nonce_low
= session
->nonce_low
;
2260 *new_nonce_high
= nonce_high
;
2261 *new_nonce_low
= nonce_low
;
2262 return NT_STATUS_OK
;
2265 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
2266 struct tevent_timer
*te
,
2267 struct timeval current_time
,
2270 struct smbd_smb2_request
*req
=
2271 talloc_get_type_abort(private_data
,
2272 struct smbd_smb2_request
);
2273 struct smbXsrv_connection
*xconn
= req
->xconn
;
2274 struct smbd_smb2_request_pending_state
*state
= NULL
;
2275 uint8_t *outhdr
= NULL
;
2276 const uint8_t *inhdr
= NULL
;
2278 uint8_t *hdr
= NULL
;
2279 uint8_t *body
= NULL
;
2280 uint8_t *dyn
= NULL
;
2282 uint64_t message_id
= 0;
2283 uint64_t async_id
= 0;
2287 TALLOC_FREE(req
->async_te
);
2289 /* Ensure our final reply matches the interim one. */
2290 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2291 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2292 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
2293 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
2295 async_id
= message_id
; /* keep it simple for now... */
2297 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
2298 SBVAL(outhdr
, SMB2_HDR_ASYNC_ID
, async_id
);
2300 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2302 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
2303 (unsigned long long)async_id
));
2306 * What we send is identical to a smbd_smb2_request_error
2307 * packet with an error status of STATUS_PENDING. Make use
2308 * of this fact sometime when refactoring. JRA.
2311 state
= talloc_zero(req
->xconn
, struct smbd_smb2_request_pending_state
);
2312 if (state
== NULL
) {
2313 smbd_server_connection_terminate(xconn
,
2314 nt_errstr(NT_STATUS_NO_MEMORY
));
2318 tf
= state
->buf
+ NBT_HDR_SIZE
;
2320 hdr
= tf
+ SMB2_TF_HDR_SIZE
;
2321 body
= hdr
+ SMB2_HDR_BODY
;
2324 if (req
->do_encryption
) {
2325 uint64_t nonce_high
= 0;
2326 uint64_t nonce_low
= 0;
2327 uint64_t session_id
= req
->session
->global
->session_wire_id
;
2329 status
= smb2_get_new_nonce(req
->session
,
2332 if (!NT_STATUS_IS_OK(status
)) {
2333 smbd_server_connection_terminate(xconn
,
2338 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2339 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
2340 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
2341 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
2344 SIVAL(hdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
2345 SSVAL(hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
2346 SSVAL(hdr
, SMB2_HDR_EPOCH
, 0);
2347 SIVAL(hdr
, SMB2_HDR_STATUS
, NT_STATUS_V(NT_STATUS_PENDING
));
2348 SSVAL(hdr
, SMB2_HDR_OPCODE
, SVAL(outhdr
, SMB2_HDR_OPCODE
));
2351 * The STATUS_PENDING response has SMB2_HDR_FLAG_SIGNED
2352 * clearedm, but echoes the signature field.
2354 flags
&= ~SMB2_HDR_FLAG_SIGNED
;
2355 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
);
2356 SIVAL(hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2357 SBVAL(hdr
, SMB2_HDR_MESSAGE_ID
, message_id
);
2358 SBVAL(hdr
, SMB2_HDR_PID
, async_id
);
2359 SBVAL(hdr
, SMB2_HDR_SESSION_ID
,
2360 BVAL(outhdr
, SMB2_HDR_SESSION_ID
));
2361 memcpy(hdr
+SMB2_HDR_SIGNATURE
,
2362 outhdr
+SMB2_HDR_SIGNATURE
, 16);
2364 SSVAL(body
, 0x00, 0x08 + 1);
2366 SCVAL(body
, 0x02, 0);
2367 SCVAL(body
, 0x03, 0);
2368 SIVAL(body
, 0x04, 0);
2369 /* Match W2K8R2... */
2370 SCVAL(dyn
, 0x00, 0x21);
2372 state
->vector
[0].iov_base
= (void *)state
->buf
;
2373 state
->vector
[0].iov_len
= NBT_HDR_SIZE
;
2375 if (req
->do_encryption
) {
2376 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
2377 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
=
2380 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
2381 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
2384 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
2385 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
2387 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
2388 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
2390 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
2391 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 1;
2393 ok
= smb2_setup_nbt_length(state
->vector
,
2394 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
2396 smbd_server_connection_terminate(
2397 xconn
, nt_errstr(NT_STATUS_INTERNAL_ERROR
));
2401 /* Ensure we correctly go through crediting. Grant
2402 the credits now, and zero credits on the final
2404 smb2_set_operation_credit(req
->xconn
,
2405 SMBD_SMB2_IN_HDR_IOV(req
),
2406 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
]);
2409 * We add SMB2_HDR_FLAG_ASYNC after smb2_set_operation_credit()
2410 * as it reacts on it
2412 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
2417 for (i
= 0; i
< ARRAY_SIZE(state
->vector
); i
++) {
2418 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2420 (unsigned int)ARRAY_SIZE(state
->vector
),
2421 (unsigned int)state
->vector
[i
].iov_len
);
2425 if (req
->do_encryption
) {
2426 struct smbXsrv_session
*x
= req
->session
;
2427 struct smb2_signing_key
*encryption_key
= x
->global
->encryption_key
;
2429 status
= smb2_signing_encrypt_pdu(encryption_key
,
2430 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
2431 SMBD_SMB2_NUM_IOV_PER_REQ
);
2432 if (!NT_STATUS_IS_OK(status
)) {
2433 smbd_server_connection_terminate(xconn
,
2439 state
->queue_entry
.mem_ctx
= state
;
2440 state
->queue_entry
.vector
= state
->vector
;
2441 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
2442 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
2443 xconn
->smb2
.send_queue_len
++;
2445 status
= smbd_smb2_flush_send_queue(xconn
);
2446 if (!NT_STATUS_IS_OK(status
)) {
2447 smbd_server_connection_terminate(xconn
,
2453 static NTSTATUS
smbd_smb2_request_process_cancel(struct smbd_smb2_request
*req
)
2455 struct smbXsrv_connection
*xconn
= req
->xconn
;
2456 struct smbd_smb2_request
*cur
;
2457 const uint8_t *inhdr
;
2459 uint64_t search_message_id
;
2460 uint64_t search_async_id
;
2461 uint64_t found_id
= 0;
2463 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2465 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2466 search_message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
2467 search_async_id
= BVAL(inhdr
, SMB2_HDR_PID
);
2470 * We don't need the request anymore cancel requests never
2473 * We defer the TALLOC_FREE(req) to the caller.
2475 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
2477 for (cur
= xconn
->smb2
.requests
; cur
; cur
= cur
->next
) {
2478 const uint8_t *outhdr
;
2479 uint64_t message_id
;
2482 if (cur
->session
!= req
->session
) {
2486 if (cur
->compound_related
) {
2488 * Never cancel anything in a compound request.
2489 * Way too hard to deal with the result.
2494 outhdr
= SMBD_SMB2_OUT_HDR_PTR(cur
);
2496 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
2497 async_id
= BVAL(outhdr
, SMB2_HDR_PID
);
2499 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
2500 if (search_async_id
== async_id
) {
2501 found_id
= async_id
;
2505 if (search_message_id
== message_id
) {
2506 found_id
= message_id
;
2512 if (cur
&& cur
->subreq
) {
2513 inhdr
= SMBD_SMB2_IN_HDR_PTR(cur
);
2514 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2515 "cancel opcode[%s] mid %llu\n",
2516 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
2517 (unsigned long long)found_id
));
2518 tevent_req_cancel(cur
->subreq
);
2521 return NT_STATUS_OK
;
2524 /*************************************************************
2525 Ensure an incoming tid is a valid one for us to access.
2526 Change to the associated uid credentials and chdir to the
2527 valid tid directory.
2528 *************************************************************/
2530 static NTSTATUS
smbd_smb2_request_check_tcon(struct smbd_smb2_request
*req
)
2532 const uint8_t *inhdr
;
2535 struct smbXsrv_tcon
*tcon
;
2537 NTTIME now
= timeval_to_nttime(&req
->request_time
);
2541 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2543 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2544 in_tid
= IVAL(inhdr
, SMB2_HDR_TID
);
2546 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
2547 in_tid
= req
->last_tid
;
2552 status
= smb2srv_tcon_lookup(req
->session
,
2553 in_tid
, now
, &tcon
);
2554 if (!NT_STATUS_IS_OK(status
)) {
2558 if (!change_to_user_and_service(
2560 req
->session
->global
->session_wire_id
))
2562 return NT_STATUS_ACCESS_DENIED
;
2566 req
->last_tid
= in_tid
;
2568 return NT_STATUS_OK
;
2571 /*************************************************************
2572 Ensure an incoming session_id is a valid one for us to access.
2573 *************************************************************/
2575 static NTSTATUS
smbd_smb2_request_check_session(struct smbd_smb2_request
*req
)
2577 const uint8_t *inhdr
;
2580 uint64_t in_session_id
;
2581 struct smbXsrv_session
*session
= NULL
;
2582 struct auth_session_info
*session_info
;
2584 NTTIME now
= timeval_to_nttime(&req
->request_time
);
2586 req
->session
= NULL
;
2589 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2591 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2592 in_opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2593 in_session_id
= BVAL(inhdr
, SMB2_HDR_SESSION_ID
);
2595 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
2596 in_session_id
= req
->last_session_id
;
2599 req
->last_session_id
= 0;
2601 /* look an existing session up */
2602 switch (in_opcode
) {
2603 case SMB2_OP_SESSSETUP
:
2605 * For a session bind request, we don't have the
2606 * channel set up at this point yet, so we defer
2607 * the verification that the connection belongs
2608 * to the session to the session setup code, which
2609 * can look at the session binding flags.
2611 status
= smb2srv_session_lookup_client(req
->xconn
->client
,
2616 status
= smb2srv_session_lookup_conn(req
->xconn
,
2622 req
->session
= session
;
2623 req
->last_session_id
= in_session_id
;
2625 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
2626 switch (in_opcode
) {
2627 case SMB2_OP_SESSSETUP
:
2628 status
= smb2srv_session_lookup_global(req
->xconn
->client
,
2632 if (NT_STATUS_IS_OK(status
)) {
2634 * We fallback to a session of
2635 * another process in order to
2636 * get the signing correct.
2638 * We don't set req->last_session_id here.
2640 req
->session
= session
;
2647 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
2648 switch (in_opcode
) {
2649 case SMB2_OP_SESSSETUP
:
2650 status
= NT_STATUS_OK
;
2652 case SMB2_OP_LOGOFF
:
2655 case SMB2_OP_CANCEL
:
2656 case SMB2_OP_KEEPALIVE
:
2658 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2659 * specifies that LOGOFF, CLOSE and (UN)LOCK
2660 * should always be processed even on expired sessions.
2662 * Also see the logic in
2663 * smbd_smb2_request_process_lock().
2665 * The smb2.session.expire2 test shows that
2666 * CANCEL and KEEPALIVE/ECHO should also
2669 status
= NT_STATUS_OK
;
2675 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2676 switch (in_opcode
) {
2678 case SMB2_OP_CREATE
:
2679 case SMB2_OP_GETINFO
:
2680 case SMB2_OP_SETINFO
:
2681 return NT_STATUS_INVALID_HANDLE
;
2684 * Notice the check for
2685 * (session_info == NULL)
2688 status
= NT_STATUS_OK
;
2692 if (!NT_STATUS_IS_OK(status
)) {
2696 session_info
= session
->global
->auth_session_info
;
2697 if (session_info
== NULL
) {
2698 return NT_STATUS_INVALID_HANDLE
;
2701 return NT_STATUS_OK
;
2704 NTSTATUS
smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request
*req
,
2705 uint32_t data_length
)
2707 struct smbXsrv_connection
*xconn
= req
->xconn
;
2708 uint16_t needed_charge
;
2709 uint16_t credit_charge
= 1;
2710 const uint8_t *inhdr
;
2712 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2714 if (xconn
->smb2
.credits
.multicredit
) {
2715 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
2716 credit_charge
= MAX(credit_charge
, 1);
2719 needed_charge
= (data_length
- 1)/ 65536 + 1;
2721 DBGC_DEBUG(DBGC_SMB2_CREDITS
,
2722 "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2723 (unsigned long long) BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
),
2724 credit_charge
, needed_charge
);
2726 if (needed_charge
> credit_charge
) {
2727 DBGC_WARNING(DBGC_SMB2_CREDITS
,
2728 "CreditCharge too low, given %d, needed %d\n",
2729 credit_charge
, needed_charge
);
2730 return NT_STATUS_INVALID_PARAMETER
;
2733 return NT_STATUS_OK
;
2736 NTSTATUS
smbd_smb2_request_verify_sizes(struct smbd_smb2_request
*req
,
2737 size_t expected_body_size
)
2739 struct iovec
*inhdr_v
;
2740 const uint8_t *inhdr
;
2742 const uint8_t *inbody
;
2744 size_t min_dyn_size
= expected_body_size
& 0x00000001;
2745 int max_idx
= req
->in
.vector_count
- SMBD_SMB2_NUM_IOV_PER_REQ
;
2748 * The following should be checked already.
2750 if (req
->in
.vector_count
< SMBD_SMB2_NUM_IOV_PER_REQ
) {
2751 return NT_STATUS_INTERNAL_ERROR
;
2753 if (req
->current_idx
> max_idx
) {
2754 return NT_STATUS_INTERNAL_ERROR
;
2757 inhdr_v
= SMBD_SMB2_IN_HDR_IOV(req
);
2758 if (inhdr_v
->iov_len
!= SMB2_HDR_BODY
) {
2759 return NT_STATUS_INTERNAL_ERROR
;
2761 if (SMBD_SMB2_IN_BODY_LEN(req
) < 2) {
2762 return NT_STATUS_INTERNAL_ERROR
;
2765 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2766 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2770 case SMB2_OP_GETINFO
:
2777 * Now check the expected body size,
2778 * where the last byte might be in the
2781 if (SMBD_SMB2_IN_BODY_LEN(req
) != (expected_body_size
& 0xFFFFFFFE)) {
2782 return NT_STATUS_INVALID_PARAMETER
;
2784 if (SMBD_SMB2_IN_DYN_LEN(req
) < min_dyn_size
) {
2785 return NT_STATUS_INVALID_PARAMETER
;
2788 inbody
= SMBD_SMB2_IN_BODY_PTR(req
);
2790 body_size
= SVAL(inbody
, 0x00);
2791 if (body_size
!= expected_body_size
) {
2792 return NT_STATUS_INVALID_PARAMETER
;
2795 return NT_STATUS_OK
;
2798 bool smbXsrv_is_encrypted(uint8_t encryption_flags
)
2800 return (!(encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
)
2802 (encryption_flags
& (SMBXSRV_PROCESSED_ENCRYPTED_PACKET
|
2803 SMBXSRV_ENCRYPTION_DESIRED
|
2804 SMBXSRV_ENCRYPTION_REQUIRED
)));
2807 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags
)
2809 return ((encryption_flags
& SMBXSRV_PROCESSED_ENCRYPTED_PACKET
) &&
2810 (encryption_flags
& SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
));
2813 /* Set a flag if not already set, return true if set */
2814 bool smbXsrv_set_crypto_flag(uint8_t *flags
, uint8_t flag
)
2816 if ((flag
== 0) || (*flags
& flag
)) {
2825 * Update encryption state tracking flags, this can be used to
2826 * determine whether whether the session or tcon is "encrypted".
2828 static void smb2srv_update_crypto_flags(struct smbd_smb2_request
*req
,
2830 bool *update_session_globalp
,
2831 bool *update_tcon_globalp
)
2833 /* Default: assume unecrypted and unsigned */
2834 struct smbXsrv_session
*session
= req
->session
;
2835 struct smbXsrv_tcon
*tcon
= req
->tcon
;
2836 uint8_t encrypt_flag
= SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
;
2837 uint8_t sign_flag
= SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
2838 bool update_session
= false;
2839 bool update_tcon
= false;
2841 if (session
->table
== NULL
) {
2843 * sessions from smb2srv_session_lookup_global()
2844 * have NT_STATUS_BAD_LOGON_SESSION_STATE
2845 * and session->table == NULL.
2847 * They only used to give the correct error
2848 * status, we should not update any state.
2853 if (req
->was_encrypted
&& req
->do_encryption
) {
2854 encrypt_flag
= SMBXSRV_PROCESSED_ENCRYPTED_PACKET
;
2855 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2857 /* Unencrypted packet, can be signed */
2858 if (req
->do_signing
) {
2859 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
2863 update_session
|= smbXsrv_set_crypto_flag(
2864 &session
->global
->encryption_flags
, encrypt_flag
);
2865 update_session
|= smbXsrv_set_crypto_flag(
2866 &session
->global
->signing_flags
, sign_flag
);
2869 update_tcon
|= smbXsrv_set_crypto_flag(
2870 &tcon
->global
->encryption_flags
, encrypt_flag
);
2871 update_tcon
|= smbXsrv_set_crypto_flag(
2872 &tcon
->global
->signing_flags
, sign_flag
);
2876 *update_session_globalp
= update_session
;
2877 *update_tcon_globalp
= update_tcon
;
2881 bool smbXsrv_is_signed(uint8_t signing_flags
)
2884 * Signing is always enabled, so unless we got an unsigned
2885 * packet and at least one signed packet that was not
2886 * encrypted, the session or tcon is "signed".
2888 return (!(signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2889 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2892 bool smbXsrv_is_partially_signed(uint8_t signing_flags
)
2894 return ((signing_flags
& SMBXSRV_PROCESSED_UNSIGNED_PACKET
) &&
2895 (signing_flags
& SMBXSRV_PROCESSED_SIGNED_PACKET
));
2898 static NTSTATUS
smbd_smb2_request_dispatch_update_counts(
2899 struct smbd_smb2_request
*req
,
2902 struct smbXsrv_connection
*xconn
= req
->xconn
;
2903 const uint8_t *inhdr
;
2904 uint16_t channel_sequence
;
2905 uint8_t generation_wrap
= 0;
2908 struct smbXsrv_open
*op
;
2909 bool update_open
= false;
2910 NTSTATUS status
= NT_STATUS_OK
;
2912 SMB_ASSERT(!req
->request_counters_updated
);
2914 if (xconn
->protocol
< PROTOCOL_SMB3_00
) {
2915 return NT_STATUS_OK
;
2918 if (req
->compat_chain_fsp
== NULL
) {
2919 return NT_STATUS_OK
;
2922 op
= req
->compat_chain_fsp
->op
;
2924 return NT_STATUS_OK
;
2927 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2928 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2929 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
2931 cmp
= channel_sequence
- op
->global
->channel_sequence
;
2934 * csn wrap. We need to watch out for long-running
2935 * requests that are still sitting on a previously
2936 * used csn. SMB2_OP_NOTIFY can take VERY long.
2938 generation_wrap
+= 1;
2941 if (abs(cmp
) > INT16_MAX
) {
2943 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2945 * If the channel sequence number of the request and the one
2946 * known to the server are not equal, the channel sequence
2947 * number and outstanding request counts are only updated
2948 * "... if the unsigned difference using 16-bit arithmetic
2949 * between ChannelSequence and Open.ChannelSequence is less than
2950 * or equal to 0x7FFF ...".
2951 * Otherwise, an error is returned for the modifying
2952 * calls write, set_info, and ioctl.
2954 * There are currently two issues with the description:
2956 * * For the other calls, the document seems to imply
2957 * that processing continues without adapting the
2958 * counters (if the sequence numbers are not equal).
2960 * TODO: This needs clarification!
2962 * * Also, the behaviour if the difference is larger
2963 * than 0x7FFF is not clear. The document seems to
2964 * imply that if such a difference is reached,
2965 * the server starts to ignore the counters or
2966 * in the case of the modifying calls, return errors.
2968 * TODO: This needs clarification!
2970 * At this point Samba tries to be a little more
2971 * clever than the description in the MS-SMB2 document
2972 * by heuristically detecting and properly treating
2973 * a 16 bit overflow of the client-submitted sequence
2976 * If the stored channel sequence number is more than
2977 * 0x7FFF larger than the one from the request, then
2978 * the client-provided sequence number has likely
2979 * overflown. We treat this case as valid instead
2982 * The MS-SMB2 behaviour would be setting cmp = -1.
2987 if (flags
& SMB2_HDR_FLAG_REPLAY_OPERATION
) {
2988 if (cmp
== 0 && op
->pre_request_count
== 0) {
2989 op
->request_count
+= 1;
2990 req
->request_counters_updated
= true;
2991 } else if (cmp
> 0 && op
->pre_request_count
== 0) {
2992 op
->pre_request_count
+= op
->request_count
;
2993 op
->request_count
= 1;
2994 op
->global
->channel_sequence
= channel_sequence
;
2995 op
->global
->channel_generation
+= generation_wrap
;
2997 req
->request_counters_updated
= true;
2998 } else if (modify_call
) {
2999 return NT_STATUS_FILE_NOT_AVAILABLE
;
3003 op
->request_count
+= 1;
3004 req
->request_counters_updated
= true;
3005 } else if (cmp
> 0) {
3006 op
->pre_request_count
+= op
->request_count
;
3007 op
->request_count
= 1;
3008 op
->global
->channel_sequence
= channel_sequence
;
3009 op
->global
->channel_generation
+= generation_wrap
;
3011 req
->request_counters_updated
= true;
3012 } else if (modify_call
) {
3013 return NT_STATUS_FILE_NOT_AVAILABLE
;
3016 req
->channel_generation
= op
->global
->channel_generation
;
3019 status
= smbXsrv_open_update(op
);
3025 NTSTATUS
smbd_smb2_request_dispatch(struct smbd_smb2_request
*req
)
3027 struct smbXsrv_connection
*xconn
= req
->xconn
;
3028 const struct smbd_smb2_dispatch_table
*call
= NULL
;
3029 const struct iovec
*intf_v
= SMBD_SMB2_IN_TF_IOV(req
);
3030 const uint8_t *inhdr
;
3035 NTSTATUS session_status
;
3036 uint32_t allowed_flags
;
3037 NTSTATUS return_value
;
3038 struct smbXsrv_session
*x
= NULL
;
3039 bool signing_required
= false;
3040 bool encryption_desired
= false;
3041 bool encryption_required
= false;
3043 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
3045 DO_PROFILE_INC(request
);
3047 SMB_ASSERT(!req
->request_counters_updated
);
3049 /* TODO: verify more things */
3051 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
3052 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
3053 mid
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
3054 DBG_DEBUG("opcode[%s] mid = %"PRIu64
"\n",
3055 smb2_opcode_name(opcode
),
3058 if (xconn
->protocol
>= PROTOCOL_SMB2_02
) {
3060 * once the protocol is negotiated
3061 * SMB2_OP_NEGPROT is not allowed anymore
3063 if (opcode
== SMB2_OP_NEGPROT
) {
3064 /* drop the connection */
3065 return NT_STATUS_INVALID_PARAMETER
;
3069 * if the protocol is not negotiated yet
3070 * only SMB2_OP_NEGPROT is allowed.
3072 if (opcode
!= SMB2_OP_NEGPROT
) {
3073 /* drop the connection */
3074 return NT_STATUS_INVALID_PARAMETER
;
3079 * Check if the client provided a valid session id.
3081 * As some command don't require a valid session id
3082 * we defer the check of the session_status
3084 session_status
= smbd_smb2_request_check_session(req
);
3087 signing_required
= x
->global
->signing_flags
& SMBXSRV_SIGNING_REQUIRED
;
3088 encryption_desired
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
;
3089 encryption_required
= x
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
;
3092 req
->async_internal
= false;
3093 req
->do_signing
= false;
3094 if (opcode
!= SMB2_OP_SESSSETUP
) {
3095 req
->do_encryption
= encryption_desired
;
3097 req
->do_encryption
= false;
3099 req
->was_encrypted
= false;
3100 if (intf_v
->iov_len
== SMB2_TF_HDR_SIZE
) {
3101 const uint8_t *intf
= SMBD_SMB2_IN_TF_PTR(req
);
3102 uint64_t tf_session_id
= BVAL(intf
, SMB2_TF_SESSION_ID
);
3104 if (x
!= NULL
&& x
->global
->session_wire_id
!= tf_session_id
) {
3105 DBG_ERR("invalid session_id "
3106 "in SMB2_HDR[%" PRIu64
"], SMB2_TF[%" PRIu64
3108 x
->global
->session_wire_id
,
3111 * TODO: windows allows this...
3112 * should we drop the connection?
3114 * For now we just return ACCESS_DENIED
3115 * (Windows clients never trigger this)
3116 * and wait for an update of [MS-SMB2].
3118 return smbd_smb2_request_error(req
,
3119 NT_STATUS_ACCESS_DENIED
);
3122 req
->was_encrypted
= true;
3123 req
->do_encryption
= true;
3126 if (encryption_required
&& !req
->was_encrypted
) {
3127 req
->do_encryption
= true;
3128 return smbd_smb2_request_error(req
,
3129 NT_STATUS_ACCESS_DENIED
);
3132 call
= smbd_smb2_call(opcode
);
3134 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3137 allowed_flags
= SMB2_HDR_FLAG_CHAINED
|
3138 SMB2_HDR_FLAG_SIGNED
|
3140 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
3141 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
3143 if (opcode
== SMB2_OP_NEGPROT
) {
3144 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11
) {
3145 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
3148 if (opcode
== SMB2_OP_CANCEL
) {
3149 allowed_flags
|= SMB2_HDR_FLAG_ASYNC
;
3151 if (xconn
->protocol
>= PROTOCOL_SMB3_00
) {
3152 allowed_flags
|= SMB2_HDR_FLAG_REPLAY_OPERATION
;
3154 if ((flags
& ~allowed_flags
) != 0) {
3155 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3158 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3160 * This check is mostly for giving the correct error code
3161 * for compounded requests.
3163 if (!NT_STATUS_IS_OK(session_status
)) {
3164 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3167 req
->compat_chain_fsp
= NULL
;
3170 if (req
->was_encrypted
) {
3171 signing_required
= false;
3172 } else if (signing_required
|| (flags
& SMB2_HDR_FLAG_SIGNED
)) {
3173 struct smb2_signing_key
*signing_key
= NULL
;
3174 bool has_channel
= false;
3178 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3179 * If the SMB2 header of the SMB2 NEGOTIATE
3180 * request has the SMB2_FLAGS_SIGNED bit set in the
3181 * Flags field, the server MUST fail the request
3182 * with STATUS_INVALID_PARAMETER.
3184 * Microsoft test tool checks this.
3187 if ((opcode
== SMB2_OP_NEGPROT
) &&
3188 (flags
& SMB2_HDR_FLAG_SIGNED
)) {
3189 status
= NT_STATUS_INVALID_PARAMETER
;
3191 status
= NT_STATUS_USER_SESSION_DELETED
;
3193 return smbd_smb2_request_error(req
, status
);
3196 signing_key
= smbd_smb2_signing_key(x
, xconn
, &has_channel
);
3199 * If we have a signing key, we should
3202 if (smb2_signing_key_valid(signing_key
) && opcode
!= SMB2_OP_CANCEL
) {
3203 req
->do_signing
= true;
3206 status
= smb2_signing_check_pdu(signing_key
,
3207 SMBD_SMB2_IN_HDR_IOV(req
),
3208 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3209 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) &&
3210 opcode
== SMB2_OP_SESSSETUP
&& !has_channel
&&
3211 NT_STATUS_IS_OK(session_status
))
3213 if (!NT_STATUS_EQUAL(x
->status
, NT_STATUS_BAD_LOGON_SESSION_STATE
)) {
3214 struct smbXsrv_session
*session
= NULL
;
3217 error
= smb2srv_session_lookup_global(req
->xconn
->client
,
3218 x
->global
->session_wire_id
,
3221 if (!NT_STATUS_IS_OK(error
)) {
3222 return smbd_smb2_request_error(req
, error
);
3226 * We fallback to a session of
3227 * another process in order to
3228 * get the signing correct.
3230 * We don't set req->last_session_id here.
3232 req
->session
= x
= session
;
3234 goto skipped_signing
;
3236 if (!NT_STATUS_IS_OK(status
)) {
3237 return smbd_smb2_request_error(req
, status
);
3241 * Now that we know the request was correctly signed
3242 * we have to sign the response too.
3244 if (opcode
!= SMB2_OP_CANCEL
) {
3245 req
->do_signing
= true;
3248 if (!NT_STATUS_IS_OK(session_status
)) {
3249 return smbd_smb2_request_error(req
, session_status
);
3253 if (opcode
== SMB2_OP_IOCTL
) {
3255 * Some special IOCTL calls don't require
3256 * file, tcon nor session.
3258 * They typically don't do any real action
3259 * on behalf of the client.
3261 * They are mainly used to alter the behavior
3262 * of the connection for testing. So we can
3263 * run as root and skip all file, tcon and session
3266 static const struct smbd_smb2_dispatch_table _root_ioctl_call
= {
3267 .opcode
= SMB2_OP_IOCTL
,
3270 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
3271 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
3272 uint32_t in_ctl_code
;
3275 if (needed
> body_size
) {
3276 return smbd_smb2_request_error(req
,
3277 NT_STATUS_INVALID_PARAMETER
);
3280 in_ctl_code
= IVAL(body
, 0x04);
3282 * Only add trusted IOCTL codes here!
3284 switch (in_ctl_code
) {
3285 case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT
:
3286 call
= &_root_ioctl_call
;
3288 case FSCTL_VALIDATE_NEGOTIATE_INFO
:
3289 call
= &_root_ioctl_call
;
3291 case FSCTL_QUERY_NETWORK_INTERFACE_INFO
:
3292 call
= &_root_ioctl_call
;
3299 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3300 req
->compound_related
= true;
3303 if (call
->need_session
) {
3304 if (!NT_STATUS_IS_OK(session_status
)) {
3305 return smbd_smb2_request_error(req
, session_status
);
3309 if (call
->need_tcon
) {
3310 SMB_ASSERT(call
->need_session
);
3313 * This call needs to be run as user.
3315 * smbd_smb2_request_check_tcon()
3316 * calls change_to_user() on success.
3317 * Which implies set_current_user_info()
3318 * and chdir_current_service().
3320 status
= smbd_smb2_request_check_tcon(req
);
3321 if (!NT_STATUS_IS_OK(status
)) {
3322 return smbd_smb2_request_error(req
, status
);
3324 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_DESIRED
) {
3325 encryption_desired
= true;
3327 if (req
->tcon
->global
->encryption_flags
& SMBXSRV_ENCRYPTION_REQUIRED
) {
3328 encryption_required
= true;
3330 if (encryption_required
&& !req
->was_encrypted
) {
3331 req
->do_encryption
= true;
3332 return smbd_smb2_request_error(req
,
3333 NT_STATUS_ACCESS_DENIED
);
3334 } else if (encryption_desired
) {
3335 req
->do_encryption
= true;
3337 } else if (call
->need_session
) {
3338 struct auth_session_info
*session_info
= NULL
;
3341 * Unless we also have need_tcon (see above),
3342 * we still need to call set_current_user_info().
3345 session_info
= req
->session
->global
->auth_session_info
;
3346 if (session_info
== NULL
) {
3347 return NT_STATUS_INVALID_HANDLE
;
3350 set_current_user_info(session_info
->unix_info
->sanitized_username
,
3351 session_info
->unix_info
->unix_name
,
3352 session_info
->info
->domain_name
);
3356 bool update_session_global
= false;
3357 bool update_tcon_global
= false;
3359 smb2srv_update_crypto_flags(req
, opcode
,
3360 &update_session_global
,
3361 &update_tcon_global
);
3363 if (update_session_global
) {
3364 status
= smbXsrv_session_update(x
);
3365 if (!NT_STATUS_IS_OK(status
)) {
3366 return smbd_smb2_request_error(req
, status
);
3369 if (update_tcon_global
) {
3370 status
= smbXsrv_tcon_update(req
->tcon
);
3371 if (!NT_STATUS_IS_OK(status
)) {
3372 return smbd_smb2_request_error(req
, status
);
3377 if (call
->fileid_ofs
!= 0) {
3378 size_t needed
= call
->fileid_ofs
+ 16;
3379 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
3380 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
3381 uint64_t file_id_persistent
;
3382 uint64_t file_id_volatile
;
3383 struct files_struct
*fsp
;
3385 SMB_ASSERT(call
->need_tcon
);
3387 if (needed
> body_size
) {
3388 return smbd_smb2_request_error(req
,
3389 NT_STATUS_INVALID_PARAMETER
);
3392 file_id_persistent
= BVAL(body
, call
->fileid_ofs
+ 0);
3393 file_id_volatile
= BVAL(body
, call
->fileid_ofs
+ 8);
3395 fsp
= file_fsp_smb2(req
, file_id_persistent
, file_id_volatile
);
3397 if (req
->compound_related
&&
3398 !NT_STATUS_IS_OK(req
->compound_create_err
))
3400 return smbd_smb2_request_error(req
,
3401 req
->compound_create_err
);
3404 * smbd_smb2_request_process_ioctl()
3405 * has more checks in order to return more
3406 * detailed error codes...
3408 if (opcode
!= SMB2_OP_IOCTL
) {
3409 return smbd_smb2_request_error(req
,
3410 NT_STATUS_FILE_CLOSED
);
3413 if (fsp
->fsp_flags
.encryption_required
&& !req
->was_encrypted
) {
3414 return smbd_smb2_request_error(req
,
3415 NT_STATUS_ACCESS_DENIED
);
3420 status
= smbd_smb2_request_dispatch_update_counts(req
, call
->modify
);
3421 if (!NT_STATUS_IS_OK(status
)) {
3422 return smbd_smb2_request_error(req
, status
);
3425 if (call
->as_root
) {
3426 SMB_ASSERT(call
->fileid_ofs
== 0);
3427 /* This call needs to be run as root */
3428 change_to_root_user();
3429 } else if (opcode
!= SMB2_OP_KEEPALIVE
) {
3430 SMB_ASSERT(call
->need_tcon
);
3433 #define _INBYTES(_r) \
3434 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3437 case SMB2_OP_NEGPROT
:
3438 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot
, profile_p
,
3439 req
->profile
, _INBYTES(req
));
3440 return_value
= smbd_smb2_request_process_negprot(req
);
3443 case SMB2_OP_SESSSETUP
:
3444 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup
, profile_p
,
3445 req
->profile
, _INBYTES(req
));
3446 return_value
= smbd_smb2_request_process_sesssetup(req
);
3449 case SMB2_OP_LOGOFF
:
3450 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff
, profile_p
,
3451 req
->profile
, _INBYTES(req
));
3452 return_value
= smbd_smb2_request_process_logoff(req
);
3456 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon
, profile_p
,
3457 req
->profile
, _INBYTES(req
));
3458 return_value
= smbd_smb2_request_process_tcon(req
);
3462 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis
, profile_p
,
3463 req
->profile
, _INBYTES(req
));
3464 return_value
= smbd_smb2_request_process_tdis(req
);
3467 case SMB2_OP_CREATE
:
3468 if (req
->subreq
== NULL
) {
3469 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create
, profile_p
,
3470 req
->profile
, _INBYTES(req
));
3472 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req
->profile
);
3474 return_value
= smbd_smb2_request_process_create(req
);
3478 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close
, profile_p
,
3479 req
->profile
, _INBYTES(req
));
3480 return_value
= smbd_smb2_request_process_close(req
);
3484 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush
, profile_p
,
3485 req
->profile
, _INBYTES(req
));
3486 return_value
= smbd_smb2_request_process_flush(req
);
3490 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read
, profile_p
,
3491 req
->profile
, _INBYTES(req
));
3492 return_value
= smbd_smb2_request_process_read(req
);
3496 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write
, profile_p
,
3497 req
->profile
, _INBYTES(req
));
3498 return_value
= smbd_smb2_request_process_write(req
);
3502 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock
, profile_p
,
3503 req
->profile
, _INBYTES(req
));
3504 return_value
= smbd_smb2_request_process_lock(req
);
3508 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl
, profile_p
,
3509 req
->profile
, _INBYTES(req
));
3510 return_value
= smbd_smb2_request_process_ioctl(req
);
3513 case SMB2_OP_CANCEL
:
3514 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel
, profile_p
,
3515 req
->profile
, _INBYTES(req
));
3516 return_value
= smbd_smb2_request_process_cancel(req
);
3517 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
, 0);
3520 * We don't need the request anymore cancel requests never
3523 * smbd_smb2_request_process_cancel() already called
3524 * DLIST_REMOVE(xconn->smb2.requests, req);
3530 case SMB2_OP_KEEPALIVE
:
3531 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive
, profile_p
,
3532 req
->profile
, _INBYTES(req
));
3533 return_value
= smbd_smb2_request_process_keepalive(req
);
3536 case SMB2_OP_QUERY_DIRECTORY
:
3537 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find
, profile_p
,
3538 req
->profile
, _INBYTES(req
));
3539 return_value
= smbd_smb2_request_process_query_directory(req
);
3542 case SMB2_OP_NOTIFY
:
3543 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify
, profile_p
,
3544 req
->profile
, _INBYTES(req
));
3545 return_value
= smbd_smb2_request_process_notify(req
);
3548 case SMB2_OP_GETINFO
:
3549 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo
, profile_p
,
3550 req
->profile
, _INBYTES(req
));
3551 return_value
= smbd_smb2_request_process_getinfo(req
);
3554 case SMB2_OP_SETINFO
:
3555 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo
, profile_p
,
3556 req
->profile
, _INBYTES(req
));
3557 return_value
= smbd_smb2_request_process_setinfo(req
);
3561 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break
, profile_p
,
3562 req
->profile
, _INBYTES(req
));
3563 return_value
= smbd_smb2_request_process_break(req
);
3567 return_value
= smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
3570 return return_value
;
3573 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request
*req
)
3575 struct smbXsrv_connection
*xconn
= req
->xconn
;
3576 const uint8_t *inhdr
;
3577 uint16_t channel_sequence
;
3578 struct smbXsrv_open
*op
;
3580 if (!req
->request_counters_updated
) {
3584 req
->request_counters_updated
= false;
3586 if (xconn
->protocol
< PROTOCOL_SMB3_00
) {
3590 if (req
->compat_chain_fsp
== NULL
) {
3594 op
= req
->compat_chain_fsp
->op
;
3599 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
3600 channel_sequence
= SVAL(inhdr
, SMB2_HDR_CHANNEL_SEQUENCE
);
3602 if ((op
->global
->channel_sequence
== channel_sequence
) &&
3603 (op
->global
->channel_generation
== req
->channel_generation
)) {
3604 SMB_ASSERT(op
->request_count
> 0);
3605 op
->request_count
-= 1;
3607 SMB_ASSERT(op
->pre_request_count
> 0);
3608 op
->pre_request_count
-= 1;
3612 static NTSTATUS
smbd_smb2_request_reply(struct smbd_smb2_request
*req
)
3614 struct smbXsrv_connection
*xconn
= req
->xconn
;
3616 struct iovec
*firsttf
= SMBD_SMB2_IDX_TF_IOV(req
,out
,first_idx
);
3617 struct iovec
*outhdr
= SMBD_SMB2_OUT_HDR_IOV(req
);
3618 struct iovec
*outdyn
= SMBD_SMB2_OUT_DYN_IOV(req
);
3623 TALLOC_FREE(req
->async_te
);
3625 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3626 smbd_smb2_request_reply_update_counts(req
);
3628 if (req
->do_encryption
&&
3629 (firsttf
->iov_len
== 0) &&
3630 (!smb2_signing_key_valid(req
->first_enc_key
)) &&
3631 (req
->session
!= NULL
) &&
3632 smb2_signing_key_valid(req
->session
->global
->encryption_key
))
3634 struct smb2_signing_key
*encryption_key
=
3635 req
->session
->global
->encryption_key
;
3637 uint64_t session_id
= req
->session
->global
->session_wire_id
;
3638 uint64_t nonce_high
;
3641 status
= smb2_get_new_nonce(req
->session
,
3644 if (!NT_STATUS_IS_OK(status
)) {
3649 * We need to place the SMB2_TRANSFORM header before the
3654 * we need to remember the encryption key
3655 * and defer the signing/encryption until
3656 * we are sure that we do not change
3659 status
= smb2_signing_key_copy(req
,
3661 &req
->first_enc_key
);
3662 if (!NT_STATUS_IS_OK(status
)) {
3666 tf
= talloc_zero_array(req
, uint8_t,
3669 return NT_STATUS_NO_MEMORY
;
3672 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
3673 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
3674 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
3675 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
3677 firsttf
->iov_base
= (void *)tf
;
3678 firsttf
->iov_len
= SMB2_TF_HDR_SIZE
;
3681 if ((req
->current_idx
> SMBD_SMB2_NUM_IOV_PER_REQ
) &&
3682 (smb2_signing_key_valid(req
->last_sign_key
)) &&
3683 (firsttf
->iov_len
== 0))
3685 int last_idx
= req
->current_idx
- SMBD_SMB2_NUM_IOV_PER_REQ
;
3686 struct iovec
*lasthdr
= SMBD_SMB2_IDX_HDR_IOV(req
,out
,last_idx
);
3689 * As we are sure the header of the last request in the
3690 * compound chain will not change, we can to sign here
3691 * with the last signing key we remembered.
3693 status
= smb2_signing_sign_pdu(req
->last_sign_key
,
3695 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3696 if (!NT_STATUS_IS_OK(status
)) {
3700 TALLOC_FREE(req
->last_sign_key
);
3702 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
,
3703 iov_buflen(outhdr
, SMBD_SMB2_NUM_IOV_PER_REQ
-1));
3705 req
->current_idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
3707 if (req
->current_idx
< req
->out
.vector_count
) {
3709 * We must process the remaining compound
3710 * SMB2 requests before any new incoming SMB2
3711 * requests. This is because incoming SMB2
3712 * requests may include a cancel for a
3713 * compound request we haven't processed
3716 struct tevent_immediate
*im
= tevent_create_immediate(req
);
3718 return NT_STATUS_NO_MEMORY
;
3721 if (req
->do_signing
&& firsttf
->iov_len
== 0) {
3722 struct smbXsrv_session
*x
= req
->session
;
3723 struct smb2_signing_key
*signing_key
=
3724 smbd_smb2_signing_key(x
, xconn
, NULL
);
3727 * we need to remember the signing key
3728 * and defer the signing until
3729 * we are sure that we do not change
3732 status
= smb2_signing_key_copy(req
,
3734 &req
->last_sign_key
);
3735 if (!NT_STATUS_IS_OK(status
)) {
3741 * smbd_smb2_request_dispatch() will redo the impersonation.
3742 * So we use req->xconn->client->raw_ev_ctx instead
3743 * of req->ev_ctx here.
3745 tevent_schedule_immediate(im
,
3746 req
->xconn
->client
->raw_ev_ctx
,
3747 smbd_smb2_request_dispatch_immediate
,
3749 return NT_STATUS_OK
;
3752 if (req
->compound_related
) {
3753 req
->compound_related
= false;
3756 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
3758 return NT_STATUS_INVALID_PARAMETER_MIX
;
3761 /* Set credit for these operations (zero credits if this
3762 is a final reply for an async operation). */
3763 smb2_calculate_credits(req
, req
);
3766 * now check if we need to sign the current response
3768 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
3769 status
= smb2_signing_encrypt_pdu(req
->first_enc_key
,
3771 req
->out
.vector_count
- first_idx
);
3772 if (!NT_STATUS_IS_OK(status
)) {
3775 } else if (req
->do_signing
) {
3776 struct smbXsrv_session
*x
= req
->session
;
3777 struct smb2_signing_key
*signing_key
=
3778 smbd_smb2_signing_key(x
, xconn
, NULL
);
3780 status
= smb2_signing_sign_pdu(signing_key
,
3782 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
3783 if (!NT_STATUS_IS_OK(status
)) {
3787 TALLOC_FREE(req
->first_enc_key
);
3789 if (req
->preauth
!= NULL
) {
3790 gnutls_hash_hd_t hash_hnd
= NULL
;
3794 rc
= gnutls_hash_init(&hash_hnd
, GNUTLS_DIG_SHA512
);
3796 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3798 rc
= gnutls_hash(hash_hnd
,
3799 req
->preauth
->sha512_value
,
3800 sizeof(req
->preauth
->sha512_value
));
3802 gnutls_hash_deinit(hash_hnd
, NULL
);
3803 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3805 for (i
= 1; i
< req
->in
.vector_count
; i
++) {
3806 rc
= gnutls_hash(hash_hnd
,
3807 req
->in
.vector
[i
].iov_base
,
3808 req
->in
.vector
[i
].iov_len
);
3810 gnutls_hash_deinit(hash_hnd
, NULL
);
3811 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3814 gnutls_hash_output(hash_hnd
, req
->preauth
->sha512_value
);
3816 rc
= gnutls_hash(hash_hnd
,
3817 req
->preauth
->sha512_value
,
3818 sizeof(req
->preauth
->sha512_value
));
3820 gnutls_hash_deinit(hash_hnd
, NULL
);
3821 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3823 for (i
= 1; i
< req
->out
.vector_count
; i
++) {
3824 rc
= gnutls_hash(hash_hnd
,
3825 req
->out
.vector
[i
].iov_base
,
3826 req
->out
.vector
[i
].iov_len
);
3828 gnutls_hash_deinit(hash_hnd
, NULL
);
3829 return gnutls_error_to_ntstatus(rc
, NT_STATUS_HASH_NOT_SUPPORTED
);
3833 gnutls_hash_deinit(hash_hnd
, req
->preauth
->sha512_value
);
3835 req
->preauth
= NULL
;
3838 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3839 if (req
->out
.vector_count
< (2*SMBD_SMB2_NUM_IOV_PER_REQ
) &&
3840 outdyn
->iov_base
== NULL
&& outdyn
->iov_len
!= 0) {
3841 /* Dynamic part is NULL. Chop it off,
3842 We're going to send it via sendfile. */
3843 req
->out
.vector_count
-= 1;
3847 * We're done with this request -
3848 * move it off the "being processed" queue.
3850 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
3852 req
->queue_entry
.mem_ctx
= req
;
3853 req
->queue_entry
.vector
= req
->out
.vector
;
3854 req
->queue_entry
.count
= req
->out
.vector_count
;
3855 DLIST_ADD_END(xconn
->smb2
.send_queue
, &req
->queue_entry
);
3856 xconn
->smb2
.send_queue_len
++;
3858 status
= smbd_smb2_flush_send_queue(xconn
);
3859 if (!NT_STATUS_IS_OK(status
)) {
3863 return NT_STATUS_OK
;
3866 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
);
3868 void smbd_smb2_request_dispatch_immediate(struct tevent_context
*ctx
,
3869 struct tevent_immediate
*im
,
3872 struct smbd_smb2_request
*req
= talloc_get_type_abort(private_data
,
3873 struct smbd_smb2_request
);
3874 struct smbXsrv_connection
*xconn
= req
->xconn
;
3879 if (DEBUGLEVEL
>= 10) {
3880 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3881 req
->current_idx
, req
->in
.vector_count
));
3882 print_req_vectors(req
);
3885 status
= smbd_smb2_request_dispatch(req
);
3886 if (!NT_STATUS_IS_OK(status
)) {
3887 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3891 status
= smbd_smb2_request_next_incoming(xconn
);
3892 if (!NT_STATUS_IS_OK(status
)) {
3893 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3898 NTSTATUS
smbd_smb2_request_done_ex(struct smbd_smb2_request
*req
,
3900 DATA_BLOB body
, DATA_BLOB
*dyn
,
3901 const char *location
)
3904 struct iovec
*outbody_v
;
3905 struct iovec
*outdyn_v
;
3906 uint32_t next_command_ofs
;
3909 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
3910 mid
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
3912 DBG_DEBUG("mid [%"PRIu64
"] idx[%d] status[%s] "
3913 "body[%u] dyn[%s:%u] at %s\n",
3917 (unsigned int)body
.length
,
3919 (unsigned int)(dyn
? dyn
->length
: 0),
3922 if (body
.length
< 2) {
3923 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
3926 if ((body
.length
% 2) != 0) {
3927 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
3930 outbody_v
= SMBD_SMB2_OUT_BODY_IOV(req
);
3931 outdyn_v
= SMBD_SMB2_OUT_DYN_IOV(req
);
3933 next_command_ofs
= IVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
);
3934 SIVAL(outhdr
, SMB2_HDR_STATUS
, NT_STATUS_V(status
));
3936 outbody_v
->iov_base
= (void *)body
.data
;
3937 outbody_v
->iov_len
= body
.length
;
3940 outdyn_v
->iov_base
= (void *)dyn
->data
;
3941 outdyn_v
->iov_len
= dyn
->length
;
3943 outdyn_v
->iov_base
= NULL
;
3944 outdyn_v
->iov_len
= 0;
3948 * See if we need to recalculate the offset to the next response
3950 * Note that all responses may require padding (including the very last
3953 if (req
->out
.vector_count
>= (2 * SMBD_SMB2_NUM_IOV_PER_REQ
)) {
3954 next_command_ofs
= SMB2_HDR_BODY
;
3955 next_command_ofs
+= SMBD_SMB2_OUT_BODY_LEN(req
);
3956 next_command_ofs
+= SMBD_SMB2_OUT_DYN_LEN(req
);
3959 if ((next_command_ofs
% 8) != 0) {
3960 size_t pad_size
= 8 - (next_command_ofs
% 8);
3961 if (SMBD_SMB2_OUT_DYN_LEN(req
) == 0) {
3963 * if the dyn buffer is empty
3964 * we can use it to add padding
3968 pad
= talloc_zero_array(req
,
3971 return smbd_smb2_request_error(req
,
3972 NT_STATUS_NO_MEMORY
);
3975 outdyn_v
->iov_base
= (void *)pad
;
3976 outdyn_v
->iov_len
= pad_size
;
3979 * For now we copy the dynamic buffer
3980 * and add the padding to the new buffer
3987 old_size
= SMBD_SMB2_OUT_DYN_LEN(req
);
3988 old_dyn
= SMBD_SMB2_OUT_DYN_PTR(req
);
3990 new_size
= old_size
+ pad_size
;
3991 new_dyn
= talloc_zero_array(req
,
3993 if (new_dyn
== NULL
) {
3994 return smbd_smb2_request_error(req
,
3995 NT_STATUS_NO_MEMORY
);
3998 memcpy(new_dyn
, old_dyn
, old_size
);
3999 memset(new_dyn
+ old_size
, 0, pad_size
);
4001 outdyn_v
->iov_base
= (void *)new_dyn
;
4002 outdyn_v
->iov_len
= new_size
;
4004 next_command_ofs
+= pad_size
;
4007 if ((req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) >= req
->out
.vector_count
) {
4008 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
4010 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
4012 return smbd_smb2_request_reply(req
);
4015 NTSTATUS
smbd_smb2_request_error_ex(struct smbd_smb2_request
*req
,
4017 uint8_t error_context_count
,
4019 const char *location
)
4021 struct smbXsrv_connection
*xconn
= req
->xconn
;
4024 uint8_t *outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
4025 size_t unread_bytes
= smbd_smb2_unread_bytes(req
);
4027 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
4028 "at %s\n", req
->current_idx
, nt_errstr(status
),
4029 info
? " +info" : "", location
);
4032 /* Recvfile error. Drain incoming socket. */
4036 ret
= drain_socket(xconn
->transport
.sock
, unread_bytes
);
4037 if (ret
!= unread_bytes
) {
4041 error
= NT_STATUS_IO_DEVICE_ERROR
;
4043 error
= map_nt_error_from_unix_common(errno
);
4046 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
4047 "ret[%u] errno[%d] => %s\n",
4048 (unsigned)unread_bytes
,
4049 (unsigned)ret
, errno
, nt_errstr(error
)));
4054 body
.data
= outhdr
+ SMB2_HDR_BODY
;
4056 SSVAL(body
.data
, 0, 9);
4057 SCVAL(body
.data
, 2, error_context_count
);
4060 SIVAL(body
.data
, 0x04, info
->length
);
4062 /* Allocated size of req->out.vector[i].iov_base
4063 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
4064 * 1 byte without having to do an alloc.
4067 info
->data
= ((uint8_t *)outhdr
) +
4068 OUTVEC_ALLOC_SIZE
- 1;
4070 SCVAL(info
->data
, 0, 0);
4074 * Note: Even if there is an error, continue to process the request.
4078 return smbd_smb2_request_done_ex(req
, status
, body
, info
, __location__
);
4081 struct smbd_smb2_break_state
{
4082 struct tevent_req
*req
;
4083 struct smbd_smb2_send_queue queue_entry
;
4084 uint8_t nbt_hdr
[NBT_HDR_SIZE
];
4085 uint8_t hdr
[SMB2_HDR_BODY
];
4086 struct iovec vector
[1+SMBD_SMB2_NUM_IOV_PER_REQ
];
4089 static struct tevent_req
*smbd_smb2_break_send(TALLOC_CTX
*mem_ctx
,
4090 struct tevent_context
*ev
,
4091 struct smbXsrv_connection
*xconn
,
4092 uint64_t session_id
,
4093 const uint8_t *body
,
4096 struct tevent_req
*req
= NULL
;
4097 struct smbd_smb2_break_state
*state
= NULL
;
4101 req
= tevent_req_create(mem_ctx
, &state
,
4102 struct smbd_smb2_break_state
);
4108 tevent_req_defer_callback(req
, ev
);
4110 SIVAL(state
->hdr
, 0, SMB2_MAGIC
);
4111 SSVAL(state
->hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
4112 SSVAL(state
->hdr
, SMB2_HDR_EPOCH
, 0);
4113 SIVAL(state
->hdr
, SMB2_HDR_STATUS
, 0);
4114 SSVAL(state
->hdr
, SMB2_HDR_OPCODE
, SMB2_OP_BREAK
);
4115 SSVAL(state
->hdr
, SMB2_HDR_CREDIT
, 0);
4116 SIVAL(state
->hdr
, SMB2_HDR_FLAGS
, SMB2_HDR_FLAG_REDIRECT
);
4117 SIVAL(state
->hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
4118 SBVAL(state
->hdr
, SMB2_HDR_MESSAGE_ID
, UINT64_MAX
);
4119 SIVAL(state
->hdr
, SMB2_HDR_PID
, 0);
4120 SIVAL(state
->hdr
, SMB2_HDR_TID
, 0);
4121 SBVAL(state
->hdr
, SMB2_HDR_SESSION_ID
, session_id
);
4122 memset(state
->hdr
+SMB2_HDR_SIGNATURE
, 0, 16);
4124 state
->vector
[0] = (struct iovec
) {
4125 .iov_base
= state
->nbt_hdr
,
4126 .iov_len
= sizeof(state
->nbt_hdr
)
4129 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
4134 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
] = (struct iovec
) {
4135 .iov_base
= state
->hdr
,
4136 .iov_len
= sizeof(state
->hdr
)
4139 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
] = (struct iovec
) {
4140 .iov_base
= discard_const_p(uint8_t, body
),
4141 .iov_len
= body_len
,
4145 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4148 ok
= smb2_setup_nbt_length(state
->vector
,
4149 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
4151 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
4152 return tevent_req_post(req
, ev
);
4156 * We require TCP acks for this PDU to the client!
4157 * We want 5 retransmissions and timeout when the
4158 * retransmission timeout (rto) passed 6 times.
4160 * required_acked_bytes gets a dummy value of
4161 * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4162 * it'll get the real value when it's moved to
4165 * state->queue_entry.ack.req gets completed with
4166 * 1. tevent_req_done(), when all bytes are acked.
4167 * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4168 * the timeout expired before all bytes were acked.
4169 * 2b. tevent_req_nterror(transport_error), when the
4170 * connection got a disconnect from the kernel.
4172 state
->queue_entry
.ack
.timeout
=
4173 timeval_current_ofs_usec(xconn
->ack
.rto_usecs
* 6);
4174 state
->queue_entry
.ack
.required_acked_bytes
= UINT64_MAX
;
4175 state
->queue_entry
.ack
.req
= req
;
4176 state
->queue_entry
.mem_ctx
= state
;
4177 state
->queue_entry
.vector
= state
->vector
;
4178 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
4179 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
);
4180 xconn
->smb2
.send_queue_len
++;
4182 status
= smbd_smb2_flush_send_queue(xconn
);
4183 if (tevent_req_nterror(req
, status
)) {
4184 return tevent_req_post(req
, ev
);
4190 static NTSTATUS
smbd_smb2_break_recv(struct tevent_req
*req
)
4192 return tevent_req_simple_recv_ntstatus(req
);
4195 struct smbXsrv_pending_break
{
4196 struct smbXsrv_pending_break
*prev
, *next
;
4197 struct smbXsrv_client
*client
;
4198 bool disable_oplock_break_retries
;
4199 uint64_t session_id
;
4200 uint64_t last_channel_id
;
4203 uint8_t oplock
[0x18];
4204 uint8_t lease
[0x2c];
4209 static void smbXsrv_pending_break_done(struct tevent_req
*subreq
);
4211 static struct smbXsrv_pending_break
*smbXsrv_pending_break_create(
4212 struct smbXsrv_client
*client
,
4213 uint64_t session_id
)
4215 struct smbXsrv_pending_break
*pb
= NULL
;
4217 pb
= talloc_zero(client
, struct smbXsrv_pending_break
);
4221 pb
->client
= client
;
4222 pb
->session_id
= session_id
;
4223 pb
->disable_oplock_break_retries
= lp_smb2_disable_oplock_break_retry();
4228 static NTSTATUS
smbXsrv_pending_break_submit(struct smbXsrv_pending_break
*pb
);
4230 static NTSTATUS
smbXsrv_pending_break_schedule(struct smbXsrv_pending_break
*pb
)
4232 struct smbXsrv_client
*client
= pb
->client
;
4235 DLIST_ADD_END(client
->pending_breaks
, pb
);
4236 status
= smbXsrv_client_pending_breaks_updated(client
);
4237 if (!NT_STATUS_IS_OK(status
)) {
4241 status
= smbXsrv_pending_break_submit(pb
);
4242 if (!NT_STATUS_IS_OK(status
)) {
4246 return NT_STATUS_OK
;
4249 static NTSTATUS
smbXsrv_pending_break_submit(struct smbXsrv_pending_break
*pb
)
4251 struct smbXsrv_client
*client
= pb
->client
;
4252 struct smbXsrv_session
*session
= NULL
;
4253 struct smbXsrv_connection
*xconn
= NULL
;
4254 struct smbXsrv_connection
*oplock_xconn
= NULL
;
4255 struct tevent_req
*subreq
= NULL
;
4258 if (pb
->session_id
!= 0) {
4259 status
= get_valid_smbXsrv_session(client
,
4262 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
4263 return NT_STATUS_ABANDONED
;
4265 if (!NT_STATUS_IS_OK(status
)) {
4269 if (pb
->last_channel_id
!= 0) {
4271 * This is what current Windows servers
4272 * do, they don't retry on all available
4273 * channels. They only use the last channel.
4275 * But it doesn't match the specification in
4276 * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4279 * Per default disable_oplock_break_retries is false
4280 * and we behave like the specification.
4282 if (pb
->disable_oplock_break_retries
) {
4283 return NT_STATUS_ABANDONED
;
4288 for (xconn
= client
->connections
; xconn
!= NULL
; xconn
= xconn
->next
) {
4289 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4293 if (xconn
->channel_id
== 0) {
4295 * non-multichannel case
4300 if (session
!= NULL
) {
4301 struct smbXsrv_channel_global0
*c
= NULL
;
4304 * Having a session means we're handling
4305 * an oplock break and we only need to
4306 * use channels available on the
4309 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
4310 if (!NT_STATUS_IS_OK(status
)) {
4315 * This is what current Windows servers
4316 * do, they don't retry on all available
4317 * channels. They only use the last channel.
4319 * But it doesn't match the specification
4320 * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4323 * Per default disable_oplock_break_retries is false
4324 * and we behave like the specification.
4326 if (pb
->disable_oplock_break_retries
) {
4327 oplock_xconn
= xconn
;
4332 if (xconn
->channel_id
> pb
->last_channel_id
) {
4340 if (xconn
== NULL
) {
4341 xconn
= oplock_xconn
;
4344 if (xconn
== NULL
) {
4346 * If there's no remaining connection available
4347 * tell the caller to stop...
4349 return NT_STATUS_ABANDONED
;
4352 pb
->last_channel_id
= xconn
->channel_id
;
4354 subreq
= smbd_smb2_break_send(pb
,
4360 if (subreq
== NULL
) {
4361 return NT_STATUS_NO_MEMORY
;
4363 tevent_req_set_callback(subreq
,
4364 smbXsrv_pending_break_done
,
4367 return NT_STATUS_OK
;
4370 static void smbXsrv_pending_break_done(struct tevent_req
*subreq
)
4372 struct smbXsrv_pending_break
*pb
=
4373 tevent_req_callback_data(subreq
,
4374 struct smbXsrv_pending_break
);
4375 struct smbXsrv_client
*client
= pb
->client
;
4378 status
= smbd_smb2_break_recv(subreq
);
4379 TALLOC_FREE(subreq
);
4380 if (!NT_STATUS_IS_OK(status
)) {
4381 status
= smbXsrv_pending_break_submit(pb
);
4382 if (NT_STATUS_EQUAL(status
, NT_STATUS_ABANDONED
)) {
4384 * If there's no remaining connection
4385 * there's no need to send a break again.
4389 if (!NT_STATUS_IS_OK(status
)) {
4390 smbd_server_disconnect_client(client
, nt_errstr(status
));
4397 DLIST_REMOVE(client
->pending_breaks
, pb
);
4400 status
= smbXsrv_client_pending_breaks_updated(client
);
4401 if (!NT_STATUS_IS_OK(status
)) {
4402 smbd_server_disconnect_client(client
, nt_errstr(status
));
4407 NTSTATUS
smbd_smb2_send_oplock_break(struct smbXsrv_client
*client
,
4408 struct smbXsrv_open
*op
,
4409 uint8_t oplock_level
)
4411 struct smbXsrv_pending_break
*pb
= NULL
;
4412 uint8_t *body
= NULL
;
4414 pb
= smbXsrv_pending_break_create(client
,
4417 return NT_STATUS_NO_MEMORY
;
4419 pb
->body_len
= sizeof(pb
->body
.oplock
);
4420 body
= pb
->body
.oplock
;
4422 SSVAL(body
, 0x00, pb
->body_len
);
4423 SCVAL(body
, 0x02, oplock_level
);
4424 SCVAL(body
, 0x03, 0); /* reserved */
4425 SIVAL(body
, 0x04, 0); /* reserved */
4426 SBVAL(body
, 0x08, op
->global
->open_persistent_id
);
4427 SBVAL(body
, 0x10, op
->global
->open_volatile_id
);
4429 return smbXsrv_pending_break_schedule(pb
);
4432 NTSTATUS
smbd_smb2_send_lease_break(struct smbXsrv_client
*client
,
4434 uint32_t lease_flags
,
4435 struct smb2_lease_key
*lease_key
,
4436 uint32_t current_lease_state
,
4437 uint32_t new_lease_state
)
4439 struct smbXsrv_pending_break
*pb
= NULL
;
4440 uint8_t *body
= NULL
;
4442 pb
= smbXsrv_pending_break_create(client
,
4443 0); /* no session_id */
4445 return NT_STATUS_NO_MEMORY
;
4447 pb
->body_len
= sizeof(pb
->body
.lease
);
4448 body
= pb
->body
.lease
;
4450 SSVAL(body
, 0x00, pb
->body_len
);
4451 SSVAL(body
, 0x02, new_epoch
);
4452 SIVAL(body
, 0x04, lease_flags
);
4453 SBVAL(body
, 0x08, lease_key
->data
[0]);
4454 SBVAL(body
, 0x10, lease_key
->data
[1]);
4455 SIVAL(body
, 0x18, current_lease_state
);
4456 SIVAL(body
, 0x1c, new_lease_state
);
4457 SIVAL(body
, 0x20, 0); /* BreakReason, MUST be 0 */
4458 SIVAL(body
, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4459 SIVAL(body
, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4461 return smbXsrv_pending_break_schedule(pb
);
4464 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state
*state
)
4468 uint64_t file_id_persistent
;
4469 uint64_t file_id_volatile
;
4470 struct smbXsrv_open
*op
= NULL
;
4471 struct files_struct
*fsp
= NULL
;
4472 const uint8_t *body
= NULL
;
4475 * This is only called with a pktbuf
4476 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4480 if (IVAL(state
->pktbuf
, 0) == SMB2_TF_MAGIC
) {
4481 /* Transform header. Cannot recvfile. */
4484 if (IVAL(state
->pktbuf
, 0) != SMB2_MAGIC
) {
4485 /* Not SMB2. Normal error path will cope. */
4488 if (SVAL(state
->pktbuf
, 4) != SMB2_HDR_BODY
) {
4489 /* Not SMB2. Normal error path will cope. */
4492 if (SVAL(state
->pktbuf
, SMB2_HDR_OPCODE
) != SMB2_OP_WRITE
) {
4493 /* Needs to be a WRITE. */
4496 if (IVAL(state
->pktbuf
, SMB2_HDR_NEXT_COMMAND
) != 0) {
4497 /* Chained. Cannot recvfile. */
4500 flags
= IVAL(state
->pktbuf
, SMB2_HDR_FLAGS
);
4501 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
4502 /* Chained. Cannot recvfile. */
4505 if (flags
& SMB2_HDR_FLAG_SIGNED
) {
4506 /* Signed. Cannot recvfile. */
4510 body
= &state
->pktbuf
[SMB2_HDR_BODY
];
4512 file_id_persistent
= BVAL(body
, 0x10);
4513 file_id_volatile
= BVAL(body
, 0x18);
4515 status
= smb2srv_open_lookup(state
->req
->xconn
,
4520 if (!NT_STATUS_IS_OK(status
)) {
4528 if (fsp
->conn
== NULL
) {
4532 if (IS_IPC(fsp
->conn
)) {
4535 if (IS_PRINT(fsp
->conn
)) {
4538 if (fsp_is_alternate_stream(fsp
)) {
4542 DEBUG(10,("Doing recvfile write len = %u\n",
4543 (unsigned int)(state
->pktfull
- state
->pktlen
)));
4548 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
)
4550 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
4551 struct smbd_smb2_request
*req
= NULL
;
4552 size_t max_send_queue_len
;
4553 size_t cur_send_queue_len
;
4555 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4557 * we're not supposed to do any io
4559 return NT_STATUS_OK
;
4562 if (state
->req
!= NULL
) {
4564 * if there is already a tstream_readv_pdu
4565 * pending, we are done.
4567 return NT_STATUS_OK
;
4570 max_send_queue_len
= MAX(1, xconn
->smb2
.credits
.max
/16);
4571 cur_send_queue_len
= xconn
->smb2
.send_queue_len
;
4573 if (cur_send_queue_len
> max_send_queue_len
) {
4575 * if we have a lot of requests to send,
4576 * we wait until they are on the wire until we
4577 * ask for the next request.
4579 return NT_STATUS_OK
;
4582 /* ask for the next request */
4583 req
= smbd_smb2_request_allocate(xconn
);
4585 return NT_STATUS_NO_MEMORY
;
4587 *state
= (struct smbd_smb2_request_read_state
) {
4589 .min_recv_size
= lp_min_receive_file_size(),
4591 [0] = (struct iovec
) {
4592 .iov_base
= (void *)state
->hdr
.nbt
,
4593 .iov_len
= NBT_HDR_SIZE
,
4596 .vector
= state
->_vector
,
4600 TEVENT_FD_READABLE(xconn
->transport
.fde
);
4602 return NT_STATUS_OK
;
4605 NTSTATUS
smbd_smb2_process_negprot(struct smbXsrv_connection
*xconn
,
4606 uint64_t expected_seq_low
,
4607 const uint8_t *inpdu
, size_t size
)
4609 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
4611 struct smbd_smb2_request
*req
= NULL
;
4613 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4614 (unsigned int)size
));
4616 status
= smbd_initialize_smb2(xconn
, expected_seq_low
);
4617 if (!NT_STATUS_IS_OK(status
)) {
4618 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4623 * If a new connection joins the process, when we're
4624 * already in a "pending break cycle", we need to
4625 * turn on the ack checker on the new connection.
4627 status
= smbXsrv_client_pending_breaks_updated(xconn
->client
);
4628 if (!NT_STATUS_IS_OK(status
)) {
4630 * If there's a problem, we disconnect the whole
4631 * client with all connections here!
4633 * Instead of just the new connection.
4635 smbd_server_disconnect_client(xconn
->client
, nt_errstr(status
));
4639 status
= smbd_smb2_request_create(xconn
, inpdu
, size
, &req
);
4640 if (!NT_STATUS_IS_OK(status
)) {
4641 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4645 status
= smbd_smb2_request_validate(req
);
4646 if (!NT_STATUS_IS_OK(status
)) {
4647 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4651 status
= smbd_smb2_request_setup_out(req
);
4652 if (!NT_STATUS_IS_OK(status
)) {
4653 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4659 * this was already counted at the SMB1 layer =>
4660 * smbd_smb2_request_dispatch() should not count it twice.
4662 if (profile_p
->values
.request_stats
.count
> 0) {
4663 profile_p
->values
.request_stats
.count
--;
4666 status
= smbd_smb2_request_dispatch(req
);
4667 if (!NT_STATUS_IS_OK(status
)) {
4668 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4672 status
= smbd_smb2_request_next_incoming(xconn
);
4673 if (!NT_STATUS_IS_OK(status
)) {
4674 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
4678 sconn
->num_requests
++;
4679 return NT_STATUS_OK
;
4682 static int socket_error_from_errno(int ret
,
4696 if (sys_errno
== 0) {
4700 if (sys_errno
== EINTR
) {
4705 if (sys_errno
== EINPROGRESS
) {
4710 if (sys_errno
== EAGAIN
) {
4715 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4716 if (sys_errno
== ENOMEM
) {
4722 #if EWOULDBLOCK != EAGAIN
4723 if (sys_errno
== EWOULDBLOCK
) {
4733 static NTSTATUS
smbd_smb2_advance_send_queue(struct smbXsrv_connection
*xconn
,
4734 struct smbd_smb2_send_queue
**_e
,
4737 struct smbd_smb2_send_queue
*e
= *_e
;
4740 xconn
->ack
.unacked_bytes
+= n
;
4742 ok
= iov_advance(&e
->vector
, &e
->count
, n
);
4744 return NT_STATUS_INTERNAL_ERROR
;
4748 return NT_STATUS_RETRY
;
4751 xconn
->smb2
.send_queue_len
--;
4752 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4754 if (e
->ack
.req
== NULL
) {
4756 talloc_free(e
->mem_ctx
);
4757 return NT_STATUS_OK
;
4760 e
->ack
.required_acked_bytes
= xconn
->ack
.unacked_bytes
;
4761 DLIST_ADD_END(xconn
->ack
.queue
, e
);
4763 return NT_STATUS_OK
;
4766 static NTSTATUS
smbd_smb2_flush_with_sendmsg(struct smbXsrv_connection
*xconn
)
4773 if (xconn
->smb2
.send_queue
== NULL
) {
4774 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
4775 return NT_STATUS_OK
;
4778 while (xconn
->smb2
.send_queue
!= NULL
) {
4779 struct smbd_smb2_send_queue
*e
= xconn
->smb2
.send_queue
;
4780 unsigned sendmsg_flags
= 0;
4782 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
4784 * we're not supposed to do any io
4785 * just flush all pending stuff.
4787 xconn
->smb2
.send_queue_len
--;
4788 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4790 talloc_free(e
->mem_ctx
);
4794 if (e
->sendfile_header
!= NULL
) {
4799 status
= NT_STATUS_INTERNAL_ERROR
;
4801 for (i
=0; i
< e
->count
; i
++) {
4802 size
+= e
->vector
[i
].iov_len
;
4805 if (size
<= e
->sendfile_header
->length
) {
4806 buf
= e
->sendfile_header
->data
;
4808 buf
= talloc_array(e
->mem_ctx
, uint8_t, size
);
4810 return NT_STATUS_NO_MEMORY
;
4815 for (i
=0; i
< e
->count
; i
++) {
4817 e
->vector
[i
].iov_base
,
4818 e
->vector
[i
].iov_len
);
4819 size
+= e
->vector
[i
].iov_len
;
4822 e
->sendfile_header
->data
= buf
;
4823 e
->sendfile_header
->length
= size
;
4824 e
->sendfile_status
= &status
;
4827 xconn
->smb2
.send_queue_len
--;
4828 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
4830 size
+= e
->sendfile_body_size
;
4833 * This triggers the sendfile path via
4836 talloc_free(e
->mem_ctx
);
4838 if (!NT_STATUS_IS_OK(status
)) {
4839 smbXsrv_connection_disconnect_transport(xconn
,
4843 xconn
->ack
.unacked_bytes
+= size
;
4847 e
->msg
= (struct msghdr
) {
4848 .msg_iov
= e
->vector
,
4849 .msg_iovlen
= e
->count
,
4853 sendmsg_flags
|= MSG_NOSIGNAL
;
4856 sendmsg_flags
|= MSG_DONTWAIT
;
4859 ret
= sendmsg(xconn
->transport
.sock
, &e
->msg
, sendmsg_flags
);
4861 /* propagate end of file */
4862 return NT_STATUS_INTERNAL_ERROR
;
4864 err
= socket_error_from_errno(ret
, errno
, &retry
);
4867 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
4868 return NT_STATUS_OK
;
4871 status
= map_nt_error_from_unix_common(err
);
4872 smbXsrv_connection_disconnect_transport(xconn
,
4877 status
= smbd_smb2_advance_send_queue(xconn
, &e
, ret
);
4878 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
4880 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
4881 return NT_STATUS_OK
;
4883 if (!NT_STATUS_IS_OK(status
)) {
4884 smbXsrv_connection_disconnect_transport(xconn
,
4890 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
4893 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
)
4897 status
= smbd_smb2_flush_with_sendmsg(xconn
);
4898 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
4903 * Restart reads if we were blocked on
4904 * draining the send queue.
4907 status
= smbd_smb2_request_next_incoming(xconn
);
4908 if (!NT_STATUS_IS_OK(status
)) {
4912 return NT_STATUS_OK
;
4915 static NTSTATUS
smbd_smb2_advance_incoming(struct smbXsrv_connection
*xconn
, size_t n
)
4917 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
4918 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
4919 struct smbd_smb2_request
*req
= NULL
;
4920 size_t min_recvfile_size
= UINT32_MAX
;
4925 ok
= iov_advance(&state
->vector
, &state
->count
, n
);
4927 return NT_STATUS_INTERNAL_ERROR
;
4930 if (state
->count
> 0) {
4931 return NT_STATUS_PENDING
;
4934 if (state
->pktlen
> 0) {
4935 if (!state
->doing_receivefile
) {
4937 * we have all the data.
4942 if (!is_smb2_recvfile_write(state
)) {
4943 size_t ofs
= state
->pktlen
;
4946 * Not a possible receivefile write.
4947 * Read the rest of the data.
4949 state
->doing_receivefile
= false;
4951 state
->pktbuf
= talloc_realloc(state
->req
,
4955 if (state
->pktbuf
== NULL
) {
4956 return NT_STATUS_NO_MEMORY
;
4959 state
->_vector
[0] = (struct iovec
) {
4960 .iov_base
= (void *)(state
->pktbuf
+ ofs
),
4961 .iov_len
= (state
->pktfull
- ofs
),
4963 state
->vector
= state
->_vector
;
4966 state
->pktlen
= state
->pktfull
;
4967 return NT_STATUS_RETRY
;
4971 * This is a receivefile write so we've
4972 * done a short read.
4978 * Now we analyze the NBT header
4980 if (state
->hdr
.nbt
[0] != 0x00) {
4981 state
->min_recv_size
= 0;
4983 state
->pktfull
= smb2_len(state
->hdr
.nbt
);
4984 if (state
->pktfull
== 0) {
4988 if (state
->min_recv_size
!= 0) {
4989 min_recvfile_size
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
4990 min_recvfile_size
+= state
->min_recv_size
;
4993 if (state
->pktfull
> min_recvfile_size
) {
4995 * Might be a receivefile write. Read the SMB2 HEADER +
4996 * SMB2_WRITE header first. Set 'doing_receivefile'
4997 * as we're *attempting* receivefile write. If this
4998 * turns out not to be a SMB2_WRITE request or otherwise
4999 * not suitable then we'll just read the rest of the data
5000 * the next time this function is called.
5002 state
->pktlen
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
5003 state
->doing_receivefile
= true;
5005 state
->pktlen
= state
->pktfull
;
5008 state
->pktbuf
= talloc_array(state
->req
, uint8_t, state
->pktlen
);
5009 if (state
->pktbuf
== NULL
) {
5010 return NT_STATUS_NO_MEMORY
;
5013 state
->_vector
[0] = (struct iovec
) {
5014 .iov_base
= (void *)state
->pktbuf
,
5015 .iov_len
= state
->pktlen
,
5017 state
->vector
= state
->_vector
;
5020 return NT_STATUS_RETRY
;
5024 if (state
->hdr
.nbt
[0] != 0x00) {
5025 DEBUG(1,("ignore NBT[0x%02X] msg\n",
5026 state
->hdr
.nbt
[0]));
5029 *state
= (struct smbd_smb2_request_read_state
) {
5031 .min_recv_size
= lp_min_receive_file_size(),
5033 [0] = (struct iovec
) {
5034 .iov_base
= (void *)state
->hdr
.nbt
,
5035 .iov_len
= NBT_HDR_SIZE
,
5038 .vector
= state
->_vector
,
5041 return NT_STATUS_RETRY
;
5046 req
->request_time
= timeval_current();
5047 now
= timeval_to_nttime(&req
->request_time
);
5049 status
= smbd_smb2_inbuf_parse_compound(xconn
,
5055 &req
->in
.vector_count
);
5056 if (!NT_STATUS_IS_OK(status
)) {
5060 if (state
->doing_receivefile
) {
5061 req
->smb1req
= talloc_zero(req
, struct smb_request
);
5062 if (req
->smb1req
== NULL
) {
5063 return NT_STATUS_NO_MEMORY
;
5065 req
->smb1req
->unread_bytes
= state
->pktfull
- state
->pktlen
;
5068 *state
= (struct smbd_smb2_request_read_state
) {
5072 req
->current_idx
= 1;
5074 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
5075 req
->current_idx
, req
->in
.vector_count
));
5077 status
= smbd_smb2_request_validate(req
);
5078 if (!NT_STATUS_IS_OK(status
)) {
5082 status
= smbd_smb2_request_setup_out(req
);
5083 if (!NT_STATUS_IS_OK(status
)) {
5087 status
= smbd_smb2_request_dispatch(req
);
5088 if (!NT_STATUS_IS_OK(status
)) {
5092 sconn
->num_requests
++;
5094 /* The timeout_processing function isn't run nearly
5095 often enough to implement 'max log size' without
5096 overrunning the size of the file by many megabytes.
5097 This is especially true if we are running at debug
5098 level 10. Checking every 50 SMB2s is a nice
5099 tradeoff of performance vs log file size overrun. */
5101 if ((sconn
->num_requests
% 50) == 0 &&
5102 need_to_check_log_size()) {
5103 change_to_root_user();
5107 status
= smbd_smb2_request_next_incoming(xconn
);
5108 if (!NT_STATUS_IS_OK(status
)) {
5112 return NT_STATUS_OK
;
5115 static NTSTATUS
smbd_smb2_io_handler(struct smbXsrv_connection
*xconn
,
5118 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
5119 unsigned recvmsg_flags
= 0;
5125 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
5127 * we're not supposed to do any io
5129 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
5130 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
5131 TEVENT_FD_NOT_WANTERROR(xconn
->transport
.fde
);
5132 return NT_STATUS_OK
;
5135 if (fde_flags
& TEVENT_FD_ERROR
) {
5136 ret
= samba_socket_poll_or_sock_error(xconn
->transport
.sock
);
5139 status
= map_nt_error_from_unix_common(err
);
5140 smbXsrv_connection_disconnect_transport(xconn
,
5144 /* This should not happen */
5145 status
= NT_STATUS_REMOTE_DISCONNECT
;
5146 smbXsrv_connection_disconnect_transport(xconn
,
5151 if (fde_flags
& TEVENT_FD_WRITE
) {
5152 status
= smbd_smb2_flush_send_queue(xconn
);
5153 if (!NT_STATUS_IS_OK(status
)) {
5158 if (!(fde_flags
& TEVENT_FD_READ
)) {
5159 return NT_STATUS_OK
;
5162 if (state
->req
== NULL
) {
5163 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
5164 return NT_STATUS_OK
;
5169 state
->msg
= (struct msghdr
) {
5170 .msg_iov
= state
->vector
,
5171 .msg_iovlen
= state
->count
,
5175 recvmsg_flags
|= MSG_NOSIGNAL
;
5178 recvmsg_flags
|= MSG_DONTWAIT
;
5181 ret
= recvmsg(xconn
->transport
.sock
, &state
->msg
, recvmsg_flags
);
5183 /* propagate end of file */
5184 status
= NT_STATUS_END_OF_FILE
;
5185 smbXsrv_connection_disconnect_transport(xconn
,
5189 err
= socket_error_from_errno(ret
, errno
, &retry
);
5192 TEVENT_FD_READABLE(xconn
->transport
.fde
);
5193 return NT_STATUS_OK
;
5196 status
= map_nt_error_from_unix_common(err
);
5197 smbXsrv_connection_disconnect_transport(xconn
,
5202 status
= smbd_smb2_advance_incoming(xconn
, ret
);
5203 if (NT_STATUS_EQUAL(status
, NT_STATUS_PENDING
)) {
5204 /* we have more to read */
5205 TEVENT_FD_READABLE(xconn
->transport
.fde
);
5206 return NT_STATUS_OK
;
5208 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
5210 * smbd_smb2_advance_incoming setup a new vector
5211 * that we should try to read immediately.
5215 if (!NT_STATUS_IS_OK(status
)) {
5219 return NT_STATUS_OK
;
5222 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
5223 struct tevent_fd
*fde
,
5227 struct smbXsrv_connection
*xconn
=
5228 talloc_get_type_abort(private_data
,
5229 struct smbXsrv_connection
);
5232 status
= smbd_smb2_io_handler(xconn
, flags
);
5233 if (!NT_STATUS_IS_OK(status
)) {
5234 smbd_server_connection_terminate(xconn
, nt_errstr(status
));