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 "lib/param/param.h"
27 #include "../libcli/smb/smb_common.h"
28 #include "../lib/tsocket/tsocket.h"
29 #include "../lib/util/tevent_ntstatus.h"
30 #include "smbprofile.h"
31 #include "../lib/util/bitmap.h"
32 #include "../librpc/gen_ndr/krb5pac.h"
33 #include "lib/util/iov_buf.h"
35 #include "libcli/smb/smbXcli_base.h"
38 /* SIOCOUTQ TIOCOUTQ are the same */
39 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
40 #define __HAVE_TCP_INFO_RTO 1
41 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
42 #elif defined(FREEBSD)
43 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
44 #define __HAVE_TCP_INFO_RTO 1
45 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
48 #include "lib/crypto/gnutls_helpers.h"
49 #include <gnutls/gnutls.h>
50 #include <gnutls/crypto.h>
53 #define DBGC_CLASS DBGC_SMB2
55 static void smbd_smb2_connection_handler(struct tevent_context *ev,
56 struct tevent_fd *fde,
59 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
61 static const struct smbd_smb2_dispatch_table {
68 bool allow_invalid_fileid;
70 } smbd_smb2_table[] = {
71 #define _OP(o) .opcode = o, .name = #o
76 _OP(SMB2_OP_SESSSETUP),
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.
100 .need_session = true,
104 .need_session = true,
109 .need_session = true,
114 .need_session = true,
119 .need_session = true,
125 .need_session = true,
130 .need_session = true,
133 .allow_invalid_fileid = true,
139 _OP(SMB2_OP_KEEPALIVE),
142 _OP(SMB2_OP_QUERY_DIRECTORY),
143 .need_session = true,
148 .need_session = true,
152 _OP(SMB2_OP_GETINFO),
153 .need_session = true,
157 _OP(SMB2_OP_SETINFO),
158 .need_session = true,
164 .need_session = true,
169 * as LEASE breaks does not
175 const char *smb2_opcode_name(uint16_t opcode)
177 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
178 return "Bad SMB2 opcode";
180 return smbd_smb2_table[opcode].name;
183 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
185 const struct smbd_smb2_dispatch_table *ret = NULL;
187 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
191 ret = &smbd_smb2_table[opcode];
193 SMB_ASSERT(ret->opcode == opcode);
198 static void print_req_vectors(const struct smbd_smb2_request *req)
202 for (i = 0; i < req->in.vector_count; i++) {
203 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
205 (unsigned int)req->in.vector[i].iov_len);
207 for (i = 0; i < req->out.vector_count; i++) {
208 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
210 (unsigned int)req->out.vector[i].iov_len);
214 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
216 if (size < (4 + SMB2_HDR_BODY)) {
220 if (IVAL(inbuf, 4) != SMB2_MAGIC) {
227 bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
229 return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
232 static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
233 uint64_t expected_seq_low)
237 xconn->smb2.credits.seq_low = expected_seq_low;
238 xconn->smb2.credits.seq_range = 1;
239 xconn->smb2.credits.granted = 1;
240 xconn->smb2.credits.max = lp_smb2_max_credits();
241 xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
242 xconn->smb2.credits.max);
243 if (xconn->smb2.credits.bitmap == NULL) {
244 return NT_STATUS_NO_MEMORY;
247 tevent_fd_set_close_fn(xconn->transport.fde, NULL);
248 TALLOC_FREE(xconn->transport.fde);
250 xconn->transport.fde = tevent_add_fd(
251 xconn->client->raw_ev_ctx,
253 xconn->transport.sock,
255 smbd_smb2_connection_handler,
257 if (xconn->transport.fde == NULL) {
258 close(xconn->transport.sock);
259 xconn->transport.sock = -1;
260 return NT_STATUS_NO_MEMORY;
262 tevent_fd_set_auto_close(xconn->transport.fde);
264 /* Ensure child is set to non-blocking mode */
265 rc = set_blocking(xconn->transport.sock, false);
267 return NT_STATUS_INTERNAL_ERROR;
273 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
274 #define _smb2_setlen(_buf,len) do { \
275 uint8_t *buf = (uint8_t *)_buf; \
277 buf[1] = ((len)&0xFF0000)>>16; \
278 buf[2] = ((len)&0xFF00)>>8; \
279 buf[3] = (len)&0xFF; \
282 static bool smb2_setup_nbt_length(struct iovec *vector, int count)
290 len = iov_buflen(vector+1, count-1);
292 if ((len == -1) || (len > 0xFFFFFF)) {
296 _smb2_setlen(vector[0].iov_base, len);
300 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
302 TALLOC_FREE(req->first_enc_key);
303 TALLOC_FREE(req->last_sign_key);
307 void smb2_request_set_async_internal(struct smbd_smb2_request *req,
310 req->async_internal = async_internal;
313 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
315 TALLOC_CTX *mem_pool;
316 struct smbd_smb2_request *req;
319 /* Enable this to find subtle valgrind errors. */
320 mem_pool = talloc_init("smbd_smb2_request_allocate");
322 mem_pool = talloc_tos();
324 if (mem_pool == NULL) {
328 req = talloc_zero(mem_pool, struct smbd_smb2_request);
330 talloc_free(mem_pool);
333 talloc_reparent(mem_pool, mem_ctx, req);
335 TALLOC_FREE(mem_pool);
338 req->last_session_id = UINT64_MAX;
339 req->last_tid = UINT32_MAX;
341 talloc_set_destructor(req, smbd_smb2_request_destructor);
346 static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
350 struct smbd_smb2_request *req,
354 TALLOC_CTX *mem_ctx = req;
358 uint8_t *first_hdr = buf;
359 size_t verified_buflen = 0;
364 * Note: index '0' is reserved for the transport protocol
366 iov = req->in._vector;
368 while (taken < buflen) {
369 size_t len = buflen - taken;
370 uint8_t *hdr = first_hdr + taken;
373 size_t next_command_ofs;
375 uint8_t *body = NULL;
378 struct iovec *iov_alloc = NULL;
380 if (iov != req->in._vector) {
384 if (verified_buflen > taken) {
385 len = verified_buflen - taken;
392 DEBUG(10, ("%d bytes left, expected at least %d\n",
396 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
397 struct smbXsrv_session *s = NULL;
399 struct iovec tf_iov[2];
403 if (xconn->protocol < PROTOCOL_SMB3_00) {
404 DEBUG(10, ("Got SMB2_TRANSFORM header, "
405 "but dialect[0x%04X] is used\n",
406 xconn->smb2.server.dialect));
410 if (xconn->smb2.server.cipher == 0) {
411 DEBUG(10, ("Got SMB2_TRANSFORM header, "
412 "but not negotiated "
413 "client[0x%08X] server[0x%08X]\n",
414 xconn->smb2.client.capabilities,
415 xconn->smb2.server.capabilities));
419 if (len < SMB2_TF_HDR_SIZE) {
420 DEBUG(1, ("%d bytes left, expected at least %d\n",
421 (int)len, SMB2_TF_HDR_SIZE));
425 tf_len = SMB2_TF_HDR_SIZE;
428 hdr = first_hdr + taken;
429 enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
430 uid = BVAL(tf, SMB2_TF_SESSION_ID);
432 if (len < SMB2_TF_HDR_SIZE + enc_len) {
433 DEBUG(1, ("%d bytes left, expected at least %d\n",
435 (int)(SMB2_TF_HDR_SIZE + enc_len)));
439 status = smb2srv_session_lookup_conn(xconn, uid, now,
442 status = smb2srv_session_lookup_global(xconn->client,
446 DEBUG(1, ("invalid session[%llu] in "
447 "SMB2_TRANSFORM header\n",
448 (unsigned long long)uid));
449 TALLOC_FREE(iov_alloc);
450 return NT_STATUS_USER_SESSION_DELETED;
453 tf_iov[0].iov_base = (void *)tf;
454 tf_iov[0].iov_len = tf_len;
455 tf_iov[1].iov_base = (void *)hdr;
456 tf_iov[1].iov_len = enc_len;
458 status = smb2_signing_decrypt_pdu(s->global->decryption_key,
460 if (!NT_STATUS_IS_OK(status)) {
461 TALLOC_FREE(iov_alloc);
465 verified_buflen = taken + enc_len;
470 * We need the header plus the body length field
473 if (len < SMB2_HDR_BODY + 2) {
476 (IVAL(hdr, 0) == SMB_SUICIDE_PACKET) &&
477 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
478 uint8_t exitcode = CVAL(hdr, 4);
479 DBG_WARNING("SUICIDE: Exiting immediately "
480 "with code %"PRIu8"\n",
485 DEBUG(10, ("%d bytes left, expected at least %d\n",
486 (int)len, SMB2_HDR_BODY));
489 if (IVAL(hdr, 0) != SMB2_MAGIC) {
490 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
494 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
495 DEBUG(10, ("Got HDR len %d, expected %d\n",
496 SVAL(hdr, 4), SMB2_HDR_BODY));
501 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
502 body_size = SVAL(hdr, SMB2_HDR_BODY);
504 if (next_command_ofs != 0) {
505 if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
508 if (next_command_ofs > full_size) {
511 full_size = next_command_ofs;
518 if (body_size > (full_size - SMB2_HDR_BODY)) {
520 * let the caller handle the error
522 body_size = full_size - SMB2_HDR_BODY;
524 body = hdr + SMB2_HDR_BODY;
525 dyn = body + body_size;
526 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
528 if (num_iov >= ARRAY_SIZE(req->in._vector)) {
529 struct iovec *iov_tmp = NULL;
531 iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
534 SMBD_SMB2_NUM_IOV_PER_REQ);
535 if (iov_tmp == NULL) {
536 TALLOC_FREE(iov_alloc);
537 return NT_STATUS_NO_MEMORY;
540 if (iov_alloc == NULL) {
543 sizeof(req->in._vector));
549 num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
551 cur[SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
552 cur[SMBD_SMB2_TF_IOV_OFS].iov_len = tf_len;
553 cur[SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
554 cur[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
555 cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
556 cur[SMBD_SMB2_BODY_IOV_OFS].iov_len = body_size;
557 cur[SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
558 cur[SMBD_SMB2_DYN_IOV_OFS].iov_len = dyn_size;
568 if (iov != req->in._vector) {
571 return NT_STATUS_INVALID_PARAMETER;
574 static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
575 const uint8_t *_inpdu, size_t size,
576 struct smbd_smb2_request **_req)
578 struct smbd_server_connection *sconn = xconn->client->sconn;
579 struct smbd_smb2_request *req;
580 uint32_t protocol_version;
581 uint8_t *inpdu = NULL;
582 const uint8_t *inhdr = NULL;
584 uint32_t next_command_ofs;
588 if (size < (SMB2_HDR_BODY + 2)) {
589 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
590 return NT_STATUS_INVALID_PARAMETER;
595 protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
596 if (protocol_version != SMB2_MAGIC) {
597 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
599 return NT_STATUS_INVALID_PARAMETER;
602 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
603 if (cmd != SMB2_OP_NEGPROT) {
604 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
606 return NT_STATUS_INVALID_PARAMETER;
609 next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
610 if (next_command_ofs != 0) {
611 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
613 return NT_STATUS_INVALID_PARAMETER;
616 req = smbd_smb2_request_allocate(xconn);
618 return NT_STATUS_NO_MEMORY;
623 inpdu = talloc_memdup(req, _inpdu, size);
625 return NT_STATUS_NO_MEMORY;
628 req->request_time = timeval_current();
629 now = timeval_to_nttime(&req->request_time);
631 status = smbd_smb2_inbuf_parse_compound(xconn,
635 req, &req->in.vector,
636 &req->in.vector_count);
637 if (!NT_STATUS_IS_OK(status)) {
642 req->current_idx = 1;
648 static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
649 uint64_t message_id, uint64_t seq_id)
651 struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
655 seq_tmp = xconn->smb2.credits.seq_low;
656 if (seq_id < seq_tmp) {
657 DBGC_ERR(DBGC_SMB2_CREDITS,
658 "smb2_validate_sequence_number: bad message_id "
659 "%llu (sequence id %llu) "
660 "(granted = %u, low = %llu, range = %u)\n",
661 (unsigned long long)message_id,
662 (unsigned long long)seq_id,
663 (unsigned int)xconn->smb2.credits.granted,
664 (unsigned long long)xconn->smb2.credits.seq_low,
665 (unsigned int)xconn->smb2.credits.seq_range);
669 seq_tmp += xconn->smb2.credits.seq_range;
670 if (seq_id >= seq_tmp) {
671 DBGC_ERR(DBGC_SMB2_CREDITS,
672 "smb2_validate_sequence_number: bad message_id "
673 "%llu (sequence id %llu) "
674 "(granted = %u, low = %llu, range = %u)\n",
675 (unsigned long long)message_id,
676 (unsigned long long)seq_id,
677 (unsigned int)xconn->smb2.credits.granted,
678 (unsigned long long)xconn->smb2.credits.seq_low,
679 (unsigned int)xconn->smb2.credits.seq_range);
683 offset = seq_id % xconn->smb2.credits.max;
685 if (bitmap_query(credits_bm, offset)) {
686 DBGC_ERR(DBGC_SMB2_CREDITS,
687 "smb2_validate_sequence_number: duplicate message_id "
688 "%llu (sequence id %llu) "
689 "(granted = %u, low = %llu, range = %u) "
691 (unsigned long long)message_id,
692 (unsigned long long)seq_id,
693 (unsigned int)xconn->smb2.credits.granted,
694 (unsigned long long)xconn->smb2.credits.seq_low,
695 (unsigned int)xconn->smb2.credits.seq_range,
700 /* Mark the message_ids as seen in the bitmap. */
701 bitmap_set(credits_bm, offset);
703 if (seq_id != xconn->smb2.credits.seq_low) {
708 * Move the window forward by all the message_id's
711 while (bitmap_query(credits_bm, offset)) {
712 DBGC_DEBUG(DBGC_SMB2_CREDITS,
713 "smb2_validate_sequence_number: clearing "
714 "id %llu (position %u) from bitmap\n",
715 (unsigned long long)(xconn->smb2.credits.seq_low),
717 bitmap_clear(credits_bm, offset);
719 xconn->smb2.credits.seq_low += 1;
720 xconn->smb2.credits.seq_range -= 1;
721 offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
727 static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
728 const uint8_t *inhdr)
730 uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
731 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
732 uint16_t credit_charge = 1;
735 if (opcode == SMB2_OP_CANCEL) {
736 /* SMB2_CANCEL requests by definition resend messageids. */
740 if (xconn->smb2.credits.multicredit) {
741 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
742 credit_charge = MAX(credit_charge, 1);
747 ("smb2_validate_message_id: mid %llu (charge %llu), "
748 "credits_granted %llu, "
749 "seqnum low/range: %llu/%llu\n",
750 (unsigned long long) message_id,
751 (unsigned long long) credit_charge,
752 (unsigned long long) xconn->smb2.credits.granted,
753 (unsigned long long) xconn->smb2.credits.seq_low,
754 (unsigned long long) xconn->smb2.credits.seq_range));
756 if (xconn->smb2.credits.granted < credit_charge) {
757 DBGC_ERR(DBGC_SMB2_CREDITS,
758 "smb2_validate_message_id: client used more "
759 "credits than granted, mid %llu, charge %llu, "
760 "credits_granted %llu, "
761 "seqnum low/range: %llu/%llu\n",
762 (unsigned long long) message_id,
763 (unsigned long long) credit_charge,
764 (unsigned long long) xconn->smb2.credits.granted,
765 (unsigned long long) xconn->smb2.credits.seq_low,
766 (unsigned long long) xconn->smb2.credits.seq_range);
771 * now check the message ids
773 * for multi-credit requests we need to check all current mid plus
774 * the implicit mids caused by the credit charge
775 * e.g. current mid = 15, charge 5 => mark 15-19 as used
778 for (i = 0; i <= (credit_charge-1); i++) {
779 uint64_t id = message_id + i;
784 ("Iterating mid %llu charge %u (sequence %llu)\n",
785 (unsigned long long)message_id,
787 (unsigned long long)id));
789 ok = smb2_validate_sequence_number(xconn, message_id, id);
795 /* substract used credits */
796 xconn->smb2.credits.granted -= credit_charge;
801 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
806 count = req->in.vector_count;
808 if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
809 /* It's not a SMB2 request */
810 return NT_STATUS_INVALID_PARAMETER;
813 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
814 struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
815 struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
816 const uint8_t *inhdr = NULL;
818 if (hdr->iov_len != SMB2_HDR_BODY) {
819 return NT_STATUS_INVALID_PARAMETER;
822 if (body->iov_len < 2) {
823 return NT_STATUS_INVALID_PARAMETER;
826 inhdr = (const uint8_t *)hdr->iov_base;
828 /* Check the SMB2 header */
829 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
830 return NT_STATUS_INVALID_PARAMETER;
833 if (!smb2_validate_message_id(req->xconn, inhdr)) {
834 return NT_STATUS_INVALID_PARAMETER;
841 static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
842 const struct iovec *in_vector,
843 struct iovec *out_vector)
845 const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
846 uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
847 uint16_t credit_charge = 1;
848 uint16_t credits_requested;
852 uint16_t credits_granted = 0;
853 uint64_t credits_possible;
854 uint16_t current_max_credits;
857 * first we grant only 1/16th of the max range.
859 * Windows also starts with the 1/16th and then grants
860 * more later. I was only able to trigger higher
861 * values, when using a very high credit charge.
863 * TODO: scale up depending on load, free memory
865 * Maybe also on the relationship between number
866 * of requests and the used sequence number.
867 * Which means we would grant more credits
868 * for client which use multi credit requests.
870 * The above is what Windows Server < 2016 is doing,
871 * but new servers use all credits (8192 by default).
873 current_max_credits = xconn->smb2.credits.max;
874 current_max_credits = MAX(current_max_credits, 1);
876 if (xconn->smb2.credits.multicredit) {
877 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
878 credit_charge = MAX(credit_charge, 1);
881 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
882 credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
883 credits_requested = MAX(credits_requested, 1);
884 out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
885 out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
887 SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
889 if (xconn->smb2.credits.max < credit_charge) {
890 smbd_server_connection_terminate(xconn,
891 "client error: credit charge > max credits\n");
895 if (out_flags & SMB2_HDR_FLAG_ASYNC) {
897 * In case we already send an async interim
898 * response, we should not grant
899 * credits on the final response.
903 uint16_t additional_possible =
904 xconn->smb2.credits.max - credit_charge;
905 uint16_t additional_max = 0;
906 uint16_t additional_credits = credits_requested - 1;
909 case SMB2_OP_NEGPROT:
911 case SMB2_OP_SESSSETUP:
913 * Windows 2012 RC1 starts to grant
915 * with a successful session setup
917 if (NT_STATUS_IS_OK(out_status)) {
918 additional_max = xconn->smb2.credits.max;
923 * Windows Server < 2016 and older Samba versions
924 * used to only grant additional credits in
925 * chunks of 32 credits.
927 * But we match Windows Server 2016 and grant
928 * all credits as requested.
930 additional_max = xconn->smb2.credits.max;
934 additional_max = MIN(additional_max, additional_possible);
935 additional_credits = MIN(additional_credits, additional_max);
937 credits_granted = credit_charge + additional_credits;
941 * sequence numbers should not wrap
943 * 1. calculate the possible credits until
944 * the sequence numbers start to wrap on 64-bit.
946 * 2. UINT64_MAX is used for Break Notifications.
948 * 2. truncate the possible credits to the maximum
949 * credits we want to grant to the client in total.
951 * 3. remove the range we'll already granted to the client
952 * this makes sure the client consumes the lowest sequence
953 * number, before we can grant additional credits.
955 credits_possible = UINT64_MAX - xconn->smb2.credits.seq_low;
956 if (credits_possible > 0) {
957 /* remove UINT64_MAX */
958 credits_possible -= 1;
960 credits_possible = MIN(credits_possible, current_max_credits);
961 credits_possible -= xconn->smb2.credits.seq_range;
963 credits_granted = MIN(credits_granted, credits_possible);
965 SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
966 xconn->smb2.credits.granted += credits_granted;
967 xconn->smb2.credits.seq_range += credits_granted;
969 DBGC_DEBUG(DBGC_SMB2_CREDITS,
970 "smb2_set_operation_credit: requested %u, charge %u, "
971 "granted %u, current possible/max %u/%u, "
972 "total granted/max/low/range %u/%u/%llu/%u\n",
973 (unsigned int)credits_requested,
974 (unsigned int)credit_charge,
975 (unsigned int)credits_granted,
976 (unsigned int)credits_possible,
977 (unsigned int)current_max_credits,
978 (unsigned int)xconn->smb2.credits.granted,
979 (unsigned int)xconn->smb2.credits.max,
980 (unsigned long long)xconn->smb2.credits.seq_low,
981 (unsigned int)xconn->smb2.credits.seq_range);
984 static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
985 struct smbd_smb2_request *outreq)
988 uint16_t total_credits = 0;
990 count = outreq->out.vector_count;
992 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
993 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
994 struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
995 uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
997 smb2_set_operation_credit(outreq->xconn, inhdr_v, outhdr_v);
999 /* To match Windows, count up what we
1001 total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
1002 /* Set to zero in all but the last reply. */
1003 if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
1004 SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
1006 SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
1011 DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size)
1013 if (req->current_idx <= 1) {
1014 if (size <= sizeof(req->out._body)) {
1015 return data_blob_const(req->out._body, size);
1019 return data_blob_talloc(req, NULL, size);
1022 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
1024 struct smbXsrv_connection *xconn = req->xconn;
1025 TALLOC_CTX *mem_ctx;
1026 struct iovec *vector;
1031 count = req->in.vector_count;
1032 if (count <= ARRAY_SIZE(req->out._vector)) {
1034 vector = req->out._vector;
1036 vector = talloc_zero_array(req, struct iovec, count);
1037 if (vector == NULL) {
1038 return NT_STATUS_NO_MEMORY;
1043 vector[0].iov_base = req->out.nbt_hdr;
1044 vector[0].iov_len = 4;
1045 SIVAL(req->out.nbt_hdr, 0, 0);
1047 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
1048 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
1049 const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
1050 uint8_t *outhdr = NULL;
1051 uint8_t *outbody = NULL;
1052 uint32_t next_command_ofs = 0;
1053 struct iovec *current = &vector[idx];
1055 if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
1056 /* we have a next command -
1057 * setup for the error case. */
1058 next_command_ofs = SMB2_HDR_BODY + 9;
1062 outhdr = req->out._hdr;
1064 outhdr = talloc_zero_array(mem_ctx, uint8_t,
1066 if (outhdr == NULL) {
1067 return NT_STATUS_NO_MEMORY;
1071 outbody = outhdr + SMB2_HDR_BODY;
1074 * SMBD_SMB2_TF_IOV_OFS might be used later
1076 current[SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
1077 current[SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
1079 current[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)outhdr;
1080 current[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1082 current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
1083 current[SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
1085 current[SMBD_SMB2_DYN_IOV_OFS].iov_base = NULL;
1086 current[SMBD_SMB2_DYN_IOV_OFS].iov_len = 0;
1088 /* setup the SMB2 header */
1089 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1090 SSVAL(outhdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1091 SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1092 SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1093 SIVAL(outhdr, SMB2_HDR_STATUS,
1094 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1095 SSVAL(outhdr, SMB2_HDR_OPCODE,
1096 SVAL(inhdr, SMB2_HDR_OPCODE));
1097 SIVAL(outhdr, SMB2_HDR_FLAGS,
1098 IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1099 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1100 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1101 BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1102 SIVAL(outhdr, SMB2_HDR_PID,
1103 IVAL(inhdr, SMB2_HDR_PID));
1104 SIVAL(outhdr, SMB2_HDR_TID,
1105 IVAL(inhdr, SMB2_HDR_TID));
1106 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1107 BVAL(inhdr, SMB2_HDR_SESSION_ID));
1108 memcpy(outhdr + SMB2_HDR_SIGNATURE,
1109 inhdr + SMB2_HDR_SIGNATURE, 16);
1111 /* setup error body header */
1112 SSVAL(outbody, 0x00, 0x08 + 1);
1113 SSVAL(outbody, 0x02, 0);
1114 SIVAL(outbody, 0x04, 0);
1117 req->out.vector = vector;
1118 req->out.vector_count = count;
1120 /* setup the length of the NBT packet */
1121 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1123 return NT_STATUS_INVALID_PARAMETER_MIX;
1126 DLIST_ADD_END(xconn->smb2.requests, req);
1128 return NT_STATUS_OK;
1131 bool smbXsrv_server_multi_channel_enabled(void)
1133 bool enabled = lp_server_multi_channel_support();
1134 #ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1135 bool forced = false;
1136 struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
1137 bool unspecified = lpcfg_parm_is_unspecified(lp_ctx, "server multi channel support");
1142 * If we don't have support from the kernel
1143 * to ask for the un-acked number of bytes
1144 * in the socket send queue, we better
1145 * don't support multi-channel.
1147 forced = lp_parm_bool(-1, "force", "server multi channel support", false);
1148 if (enabled && !forced) {
1149 D_NOTICE("'server multi channel support' enabled "
1150 "but not supported on %s (%s)\n",
1151 SYSTEM_UNAME_SYSNAME, SYSTEM_UNAME_RELEASE);
1152 DEBUGADD(DBGLVL_NOTICE, ("Please report this on "
1153 "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1156 TALLOC_FREE(lp_ctx);
1157 #endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1161 static NTSTATUS smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection *xconn,
1162 uint32_t *_rto_usecs)
1165 * Define an Retransmission Timeout
1166 * of 1 second, if there's no way for the
1167 * kernel to tell us the current value.
1169 uint32_t rto_usecs = 1000000;
1171 #ifdef __HAVE_TCP_INFO_RTO
1173 struct tcp_info info;
1174 socklen_t ilen = sizeof(info);
1178 ret = getsockopt(xconn->transport.sock,
1179 IPPROTO_TCP, TCP_INFO,
1180 (void *)&info, &ilen);
1182 int saved_errno = errno;
1183 NTSTATUS status = map_nt_error_from_unix(errno);
1184 DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1185 saved_errno, strerror(saved_errno),
1190 DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1191 (unsigned)info.tcpi_rto,
1192 (unsigned)info.tcpi_rtt,
1193 (unsigned)info.tcpi_rttvar);
1194 rto_usecs = info.tcpi_rto;
1196 #endif /* __HAVE_TCP_INFO_RTO */
1198 rto_usecs = MAX(rto_usecs, 200000); /* at least 0.2s */
1199 rto_usecs = MIN(rto_usecs, 1000000); /* at max 1.0s */
1200 *_rto_usecs = rto_usecs;
1201 return NT_STATUS_OK;
1204 static NTSTATUS smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection *xconn,
1205 uint64_t *_acked_bytes)
1208 * Unless the kernel has an interface
1209 * to reveal the number of un-acked bytes
1210 * in the socket send queue, we'll assume
1211 * everything is already acked.
1213 * But that would mean that we better don't
1214 * pretent to support multi-channel.
1216 uint64_t unacked_bytes = 0;
1220 if (xconn->ack.force_unacked_timeout) {
1222 * Smbtorture tries to test channel failures...
1223 * Just pretend nothing was acked...
1225 DBG_INFO("Simulating channel failure: "
1226 "xconn->ack.unacked_bytes[%llu]\n",
1227 (unsigned long long)xconn->ack.unacked_bytes);
1228 return NT_STATUS_OK;
1231 #ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1237 * If we have kernel support to get
1238 * the number of bytes waiting in
1239 * the socket's send queue, we
1240 * use that in order to find out
1241 * the number of unacked bytes.
1243 ret = ioctl(xconn->transport.sock,
1244 __IOCTL_SEND_QUEUE_SIZE_OPCODE,
1247 int saved_errno = errno;
1248 NTSTATUS status = map_nt_error_from_unix(saved_errno);
1249 DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1250 "errno %d (%s) - %s\n",
1251 saved_errno, strerror(saved_errno),
1257 DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1258 (unsigned long long)xconn->ack.unacked_bytes,
1260 return NT_STATUS_INTERNAL_ERROR;
1262 unacked_bytes = value;
1265 if (xconn->ack.unacked_bytes == 0) {
1266 xconn->ack.unacked_bytes = unacked_bytes;
1267 return NT_STATUS_OK;
1270 if (xconn->ack.unacked_bytes < unacked_bytes) {
1271 DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1272 (unsigned long long)xconn->ack.unacked_bytes,
1273 (unsigned long long)unacked_bytes);
1274 return NT_STATUS_INTERNAL_ERROR;
1277 *_acked_bytes = xconn->ack.unacked_bytes - unacked_bytes;
1278 xconn->ack.unacked_bytes = unacked_bytes;
1279 return NT_STATUS_OK;
1282 static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue **queue,
1285 struct smbd_smb2_send_queue *e = NULL;
1286 struct smbd_smb2_send_queue *n = NULL;
1288 for (e = *queue; e != NULL; e = n) {
1291 DLIST_REMOVE(*queue, e);
1292 if (e->ack.req != NULL) {
1293 tevent_req_nterror(e->ack.req, status);
1298 static NTSTATUS smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue **queue,
1299 uint64_t acked_bytes)
1301 struct smbd_smb2_send_queue *e = NULL;
1302 struct smbd_smb2_send_queue *n = NULL;
1304 for (e = *queue; e != NULL; e = n) {
1309 if (e->ack.req == NULL) {
1313 if (e->ack.required_acked_bytes <= acked_bytes) {
1314 e->ack.required_acked_bytes = 0;
1315 DLIST_REMOVE(*queue, e);
1316 tevent_req_done(e->ack.req);
1319 e->ack.required_acked_bytes -= acked_bytes;
1321 expired = timeval_expired(&e->ack.timeout);
1323 return NT_STATUS_IO_TIMEOUT;
1327 return NT_STATUS_OK;
1330 static NTSTATUS smbd_smb2_check_ack_queue(struct smbXsrv_connection *xconn)
1332 uint64_t acked_bytes = 0;
1335 status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1336 if (!NT_STATUS_IS_OK(status)) {
1340 status = smbd_smb2_send_queue_ack_bytes(&xconn->ack.queue, acked_bytes);
1341 if (!NT_STATUS_IS_OK(status)) {
1345 status = smbd_smb2_send_queue_ack_bytes(&xconn->smb2.send_queue, 0);
1346 if (!NT_STATUS_IS_OK(status)) {
1350 return NT_STATUS_OK;
1353 static void smbXsrv_connection_ack_checker(struct tevent_req *subreq)
1355 struct smbXsrv_connection *xconn =
1356 tevent_req_callback_data(subreq,
1357 struct smbXsrv_connection);
1358 struct smbXsrv_client *client = xconn->client;
1359 struct timeval next_check;
1363 xconn->ack.checker_subreq = NULL;
1365 ok = tevent_wakeup_recv(subreq);
1366 TALLOC_FREE(subreq);
1368 smbd_server_connection_terminate(xconn,
1369 "tevent_wakeup_recv() failed");
1373 status = smbd_smb2_check_ack_queue(xconn);
1374 if (!NT_STATUS_IS_OK(status)) {
1375 smbd_server_connection_terminate(xconn, nt_errstr(status));
1379 next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1380 xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1383 if (xconn->ack.checker_subreq == NULL) {
1384 smbd_server_connection_terminate(xconn,
1385 "tevent_wakeup_send() failed");
1388 tevent_req_set_callback(xconn->ack.checker_subreq,
1389 smbXsrv_connection_ack_checker,
1393 static NTSTATUS smbXsrv_client_pending_breaks_updated(struct smbXsrv_client *client)
1395 struct smbXsrv_connection *xconn = NULL;
1397 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1398 struct timeval next_check;
1399 uint64_t acked_bytes = 0;
1403 * A new 'pending break cycle' starts
1404 * with a first pending break and lasts until
1405 * all pending breaks are finished.
1407 * This is typically a very short time,
1408 * the value of one retransmission timeout.
1411 if (client->pending_breaks == NULL) {
1413 * No more pending breaks, remove a pending
1416 TALLOC_FREE(xconn->ack.checker_subreq);
1420 if (xconn->ack.checker_subreq != NULL) {
1422 * The cycle already started =>
1429 * Get the current retransmission timeout value.
1431 * It may change over time, but fetching it once
1432 * per 'pending break' cycled should be enough.
1434 status = smbXsrv_connection_get_rto_usecs(xconn,
1435 &xconn->ack.rto_usecs);
1436 if (!NT_STATUS_IS_OK(status)) {
1441 * At the start of the cycle we reset the
1442 * unacked_bytes counter (first to 0 and
1443 * within smbXsrv_connection_get_acked_bytes()
1444 * to the current value in the kernel
1447 xconn->ack.unacked_bytes = 0;
1448 status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1449 if (!NT_STATUS_IS_OK(status)) {
1454 * We setup a timer in order to check for
1455 * acked bytes after one retransmission timeout.
1457 * The code that sets up the send_queue.ack.timeout
1458 * uses a multiple of the retransmission timeout.
1460 next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1461 xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1464 if (xconn->ack.checker_subreq == NULL) {
1465 return NT_STATUS_NO_MEMORY;
1467 tevent_req_set_callback(xconn->ack.checker_subreq,
1468 smbXsrv_connection_ack_checker,
1472 return NT_STATUS_OK;
1475 void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
1478 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
1482 xconn->transport.status = status;
1483 TALLOC_FREE(xconn->transport.fde);
1484 if (xconn->transport.sock != -1) {
1485 xconn->transport.sock = -1;
1487 smbd_smb2_send_queue_ack_fail(&xconn->ack.queue, status);
1488 smbd_smb2_send_queue_ack_fail(&xconn->smb2.send_queue, status);
1489 xconn->smb2.send_queue_len = 0;
1490 DO_PROFILE_INC(disconnect);
1493 size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
1495 struct smbXsrv_connection *xconn = NULL;
1498 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1499 if (NT_STATUS_IS_OK(xconn->transport.status)) {
1507 struct smbXsrv_connection_shutdown_state {
1508 struct smbXsrv_connection *xconn;
1511 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
1513 static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
1514 struct tevent_context *ev,
1515 struct smbXsrv_connection *xconn)
1517 struct tevent_req *req = NULL;
1518 struct smbXsrv_connection_shutdown_state *state = NULL;
1519 struct tevent_req *subreq = NULL;
1521 struct smbd_smb2_request *preq = NULL;
1525 * The caller should have called
1526 * smbXsrv_connection_disconnect_transport() before.
1528 SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
1529 SMB_ASSERT(xconn->transport.terminating);
1530 SMB_ASSERT(xconn->transport.shutdown_wait_queue == NULL);
1532 req = tevent_req_create(mem_ctx, &state,
1533 struct smbXsrv_connection_shutdown_state);
1538 state->xconn = xconn;
1539 tevent_req_defer_callback(req, ev);
1541 xconn->transport.shutdown_wait_queue =
1542 tevent_queue_create(state, "smbXsrv_connection_shutdown_queue");
1543 if (tevent_req_nomem(xconn->transport.shutdown_wait_queue, req)) {
1544 return tevent_req_post(req, ev);
1547 for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next) {
1549 * Now wait until the request is finished.
1551 * We don't set a callback, as we just want to block the
1552 * wait queue and the talloc_free() of the request will
1553 * remove the item from the wait queue.
1555 * Note that we don't cancel the requests here
1556 * in order to keep the replay detection logic correct.
1558 * However if we teardown the last channel of
1559 * a connection, we'll call some logic via
1560 * smbXsrv_session_disconnect_xconn()
1561 * -> smbXsrv_session_disconnect_xconn_callback()
1562 * -> smbXsrv_session_remove_channel()
1563 * -> smb2srv_session_shutdown_send()
1564 * will indeed cancel the request.
1566 subreq = tevent_queue_wait_send(preq, ev,
1567 xconn->transport.shutdown_wait_queue);
1568 if (tevent_req_nomem(subreq, req)) {
1569 return tevent_req_post(req, ev);
1574 * This may attach sessions with num_channels == 0
1575 * to xconn->transport.shutdown_wait_queue.
1577 status = smbXsrv_session_disconnect_xconn(xconn);
1578 if (tevent_req_nterror(req, status)) {
1579 return tevent_req_post(req, ev);
1582 len = tevent_queue_length(xconn->transport.shutdown_wait_queue);
1584 tevent_req_done(req);
1585 return tevent_req_post(req, ev);
1589 * Now we add our own waiter to the end of the queue,
1590 * this way we get notified when all pending requests are finished
1591 * and send to the socket.
1593 subreq = tevent_queue_wait_send(state, ev, xconn->transport.shutdown_wait_queue);
1594 if (tevent_req_nomem(subreq, req)) {
1595 return tevent_req_post(req, ev);
1597 tevent_req_set_callback(subreq, smbXsrv_connection_shutdown_wait_done, req);
1602 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
1604 struct tevent_req *req =
1605 tevent_req_callback_data(subreq,
1607 struct smbXsrv_connection_shutdown_state *state =
1608 tevent_req_data(req,
1609 struct smbXsrv_connection_shutdown_state);
1610 struct smbXsrv_connection *xconn = state->xconn;
1612 tevent_queue_wait_recv(subreq);
1613 TALLOC_FREE(subreq);
1615 tevent_req_done(req);
1617 * make sure the xconn pointer is still valid,
1618 * it should as we used tevent_req_defer_callback()
1620 SMB_ASSERT(xconn->transport.terminating);
1623 static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
1625 struct smbXsrv_connection_shutdown_state *state =
1626 tevent_req_data(req,
1627 struct smbXsrv_connection_shutdown_state);
1628 struct smbXsrv_connection *xconn = state->xconn;
1630 * make sure the xconn pointer is still valid,
1631 * it should as we used tevent_req_defer_callback()
1633 SMB_ASSERT(xconn->transport.terminating);
1634 return tevent_req_simple_recv_ntstatus(req);
1637 static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
1639 struct smbXsrv_connection *xconn =
1640 tevent_req_callback_data(subreq,
1641 struct smbXsrv_connection);
1642 struct smbXsrv_client *client = xconn->client;
1645 status = smbXsrv_connection_shutdown_recv(subreq);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 exit_server("smbXsrv_connection_shutdown_recv failed");
1650 DLIST_REMOVE(client->connections, xconn);
1654 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
1656 const char *location)
1658 struct smbXsrv_client *client = xconn->client;
1662 * Make sure that no new request will be able to use this session.
1664 * smbXsrv_connection_disconnect_transport() might be called already,
1665 * but calling it again is a no-op.
1667 smbXsrv_connection_disconnect_transport(xconn,
1668 NT_STATUS_CONNECTION_DISCONNECTED);
1670 num_ok = smbXsrv_client_valid_connections(client);
1672 if (xconn->transport.terminating) {
1673 DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1674 smbXsrv_connection_dbg(xconn), num_ok,
1678 xconn->transport.terminating = true;
1680 DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1681 smbXsrv_connection_dbg(xconn), num_ok,
1684 if (xconn->has_cluster_movable_ip) {
1686 * If the connection has a movable cluster public address
1687 * we disconnect all client connections,
1688 * as the public address might be moved to
1691 * In future we may recheck which node currently
1692 * holds this address, but for now we keep it simple.
1694 smbd_server_disconnect_client_ex(xconn->client,
1701 struct tevent_req *subreq = NULL;
1703 subreq = smbXsrv_connection_shutdown_send(client,
1706 if (subreq == NULL) {
1707 exit_server("smbXsrv_connection_shutdown_send failed");
1709 tevent_req_set_callback(subreq,
1710 smbd_server_connection_terminate_done,
1716 * The last connection was disconnected
1718 exit_server_cleanly(reason);
1721 void smbd_server_disconnect_client_ex(struct smbXsrv_client *client,
1723 const char *location)
1727 num_ok = smbXsrv_client_valid_connections(client);
1729 DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1730 client->global->remote_address, num_ok,
1734 * Something bad happened we need to disconnect all connections.
1736 exit_server_cleanly(reason);
1739 static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1740 struct iovec *outvec,
1741 const struct iovec *srcvec)
1743 const uint8_t *srctf;
1745 const uint8_t *srchdr;
1747 const uint8_t *srcbody;
1749 const uint8_t *expected_srcbody;
1750 const uint8_t *srcdyn;
1752 const uint8_t *expected_srcdyn;
1758 srctf = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1759 srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1760 srchdr = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1761 srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1762 srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1763 srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1764 expected_srcbody = srchdr + SMB2_HDR_BODY;
1765 srcdyn = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1766 srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1767 expected_srcdyn = srcbody + 8;
1769 if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1773 if (srchdr_len != SMB2_HDR_BODY) {
1777 if (srctf_len == SMB2_TF_HDR_SIZE) {
1778 dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1779 if (dsttf == NULL) {
1785 outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1786 outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1788 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1789 * be allocated with size OUTVEC_ALLOC_SIZE. */
1791 dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1792 if (dsthdr == NULL) {
1795 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1796 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1799 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1800 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1801 * then duplicate this. Else use talloc_memdup().
1804 if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1805 dstbody = dsthdr + SMB2_HDR_BODY;
1807 dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1808 if (dstbody == NULL) {
1812 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1813 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1816 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1818 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1819 * then duplicate this. Else use talloc_memdup().
1822 if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1823 dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1824 } else if (srcdyn == NULL) {
1827 dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1828 if (dstdyn == NULL) {
1832 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1833 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1838 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1840 struct smbd_smb2_request *newreq = NULL;
1841 struct iovec *outvec = NULL;
1842 int count = req->out.vector_count;
1846 newreq = smbd_smb2_request_allocate(req->xconn);
1851 newreq->sconn = req->sconn;
1852 newreq->xconn = req->xconn;
1853 newreq->session = req->session;
1854 newreq->do_encryption = req->do_encryption;
1855 newreq->do_signing = req->do_signing;
1856 newreq->current_idx = req->current_idx;
1858 outvec = talloc_zero_array(newreq, struct iovec, count);
1860 TALLOC_FREE(newreq);
1863 newreq->out.vector = outvec;
1864 newreq->out.vector_count = count;
1866 /* Setup the outvec's identically to req. */
1867 outvec[0].iov_base = newreq->out.nbt_hdr;
1868 outvec[0].iov_len = 4;
1869 memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1871 /* Setup the vectors identically to the ones in req. */
1872 for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1873 if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1880 TALLOC_FREE(newreq);
1884 ok = smb2_setup_nbt_length(newreq->out.vector,
1885 newreq->out.vector_count);
1887 TALLOC_FREE(newreq);
1894 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
1896 struct smbXsrv_connection *xconn = req->xconn;
1898 struct iovec *firsttf = NULL;
1899 struct iovec *outhdr_v = NULL;
1900 uint8_t *outhdr = NULL;
1901 struct smbd_smb2_request *nreq = NULL;
1905 /* Create a new smb2 request we'll use
1906 for the interim return. */
1907 nreq = dup_smb2_req(req);
1909 return NT_STATUS_NO_MEMORY;
1912 /* Lose the last X out vectors. They're the
1913 ones we'll be using for the async reply. */
1914 nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
1916 ok = smb2_setup_nbt_length(nreq->out.vector,
1917 nreq->out.vector_count);
1919 return NT_STATUS_INVALID_PARAMETER_MIX;
1922 /* Step back to the previous reply. */
1923 nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
1924 firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
1925 outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
1926 outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
1927 /* And end the chain. */
1928 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
1930 /* Calculate outgoing credits */
1931 smb2_calculate_credits(req, nreq);
1933 if (DEBUGLEVEL >= 10) {
1934 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1935 (unsigned int)nreq->current_idx );
1936 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1937 (unsigned int)nreq->out.vector_count );
1938 print_req_vectors(nreq);
1942 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1943 * we need to sign/encrypt here with the last/first key we remembered
1945 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
1946 status = smb2_signing_encrypt_pdu(req->first_enc_key,
1948 nreq->out.vector_count - first_idx);
1949 if (!NT_STATUS_IS_OK(status)) {
1952 } else if (smb2_signing_key_valid(req->last_sign_key)) {
1953 status = smb2_signing_sign_pdu(req->last_sign_key,
1955 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1956 if (!NT_STATUS_IS_OK(status)) {
1961 nreq->queue_entry.mem_ctx = nreq;
1962 nreq->queue_entry.vector = nreq->out.vector;
1963 nreq->queue_entry.count = nreq->out.vector_count;
1964 DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
1965 xconn->smb2.send_queue_len++;
1967 status = smbd_smb2_flush_send_queue(xconn);
1968 if (!NT_STATUS_IS_OK(status)) {
1972 return NT_STATUS_OK;
1975 struct smbd_smb2_request_pending_state {
1976 struct smbd_smb2_send_queue queue_entry;
1977 uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1978 struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1981 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1982 struct tevent_timer *te,
1983 struct timeval current_time,
1984 void *private_data);
1986 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1987 struct tevent_req *subreq,
1988 uint32_t defer_time)
1991 struct timeval defer_endtime;
1992 uint8_t *outhdr = NULL;
1995 if (!tevent_req_is_in_progress(subreq)) {
1997 * This is a performance optimization,
1998 * it avoids one tevent_loop iteration,
1999 * which means we avoid one
2000 * talloc_stackframe_pool/talloc_free pair.
2002 tevent_req_notify_callback(subreq);
2003 return NT_STATUS_OK;
2006 req->subreq = subreq;
2009 if (req->async_te) {
2010 /* We're already async. */
2011 return NT_STATUS_OK;
2014 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2015 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2016 if (flags & SMB2_HDR_FLAG_ASYNC) {
2017 /* We're already async. */
2018 return NT_STATUS_OK;
2021 if (req->async_internal || defer_time == 0) {
2023 * An SMB2 request implementation wants to handle the request
2024 * asynchronously "internally" while keeping synchronous
2025 * behaviour for the SMB2 request. This means we don't send an
2026 * interim response and we can allow processing of compound SMB2
2027 * requests (cf the subsequent check) for all cases.
2029 return NT_STATUS_OK;
2032 if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
2034 * We're trying to go async in a compound request
2035 * chain. This is only allowed for opens that cause an
2036 * oplock break or for the last operation in the
2037 * chain, otherwise it is not allowed. See
2038 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2040 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2042 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
2044 * Cancel the outstanding request.
2046 bool ok = tevent_req_cancel(req->subreq);
2048 return NT_STATUS_OK;
2050 TALLOC_FREE(req->subreq);
2051 return smbd_smb2_request_error(req,
2052 NT_STATUS_INTERNAL_ERROR);
2056 if (DEBUGLEVEL >= 10) {
2057 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2058 (unsigned int)req->current_idx );
2059 print_req_vectors(req);
2062 if (req->current_idx > 1) {
2064 * We're going async in a compound
2065 * chain after the first request has
2066 * already been processed. Send an
2067 * interim response containing the
2068 * set of replies already generated.
2070 int idx = req->current_idx;
2072 status = smb2_send_async_interim_response(req);
2073 if (!NT_STATUS_IS_OK(status)) {
2076 TALLOC_FREE(req->first_enc_key);
2078 req->current_idx = 1;
2081 * Re-arrange the in.vectors to remove what
2084 memmove(&req->in.vector[1],
2085 &req->in.vector[idx],
2086 sizeof(req->in.vector[0])*(req->in.vector_count - idx));
2087 req->in.vector_count = 1 + (req->in.vector_count - idx);
2089 /* Re-arrange the out.vectors to match. */
2090 memmove(&req->out.vector[1],
2091 &req->out.vector[idx],
2092 sizeof(req->out.vector[0])*(req->out.vector_count - idx));
2093 req->out.vector_count = 1 + (req->out.vector_count - idx);
2095 if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
2097 * We only have one remaining request as
2098 * we've processed everything else.
2099 * This is no longer a compound request.
2101 req->compound_related = false;
2102 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2103 flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
2104 SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
2107 TALLOC_FREE(req->last_sign_key);
2110 * smbd_smb2_request_pending_timer() just send a packet
2111 * to the client and doesn't need any impersonation.
2112 * So we use req->xconn->client->raw_ev_ctx instead
2113 * of req->ev_ctx here.
2115 defer_endtime = timeval_current_ofs_usec(defer_time);
2116 req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
2118 smbd_smb2_request_pending_timer,
2120 if (req->async_te == NULL) {
2121 return NT_STATUS_NO_MEMORY;
2124 return NT_STATUS_OK;
2128 struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
2129 struct smbXsrv_connection *xconn,
2132 struct smbXsrv_channel_global0 *c = NULL;
2134 struct smb2_signing_key *key = NULL;
2135 bool has_channel = false;
2137 status = smbXsrv_session_find_channel(session, xconn, &c);
2138 if (NT_STATUS_IS_OK(status)) {
2139 key = c->signing_key;
2143 if (!smb2_signing_key_valid(key)) {
2144 key = session->global->signing_key;
2145 has_channel = false;
2148 if (_has_channel != NULL) {
2149 *_has_channel = has_channel;
2155 static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
2156 uint64_t *new_nonce_high,
2157 uint64_t *new_nonce_low)
2159 uint64_t nonce_high;
2162 session->nonce_low += 1;
2163 if (session->nonce_low == 0) {
2164 session->nonce_low += 1;
2165 session->nonce_high += 1;
2169 * CCM and GCM algorithms must never have their
2170 * nonce wrap, or the security of the whole
2171 * communication and the keys is destroyed.
2172 * We must drop the connection once we have
2173 * transfered too much data.
2175 * NOTE: We assume nonces greater than 8 bytes.
2177 if (session->nonce_high >= session->nonce_high_max) {
2178 return NT_STATUS_ENCRYPTION_FAILED;
2181 nonce_high = session->nonce_high_random;
2182 nonce_high += session->nonce_high;
2183 nonce_low = session->nonce_low;
2185 *new_nonce_high = nonce_high;
2186 *new_nonce_low = nonce_low;
2187 return NT_STATUS_OK;
2190 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
2191 struct tevent_timer *te,
2192 struct timeval current_time,
2195 struct smbd_smb2_request *req =
2196 talloc_get_type_abort(private_data,
2197 struct smbd_smb2_request);
2198 struct smbXsrv_connection *xconn = req->xconn;
2199 struct smbd_smb2_request_pending_state *state = NULL;
2200 uint8_t *outhdr = NULL;
2201 const uint8_t *inhdr = NULL;
2203 uint8_t *hdr = NULL;
2204 uint8_t *body = NULL;
2205 uint8_t *dyn = NULL;
2207 uint64_t message_id = 0;
2208 uint64_t async_id = 0;
2212 TALLOC_FREE(req->async_te);
2214 /* Ensure our final reply matches the interim one. */
2215 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2216 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2217 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2218 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2220 async_id = message_id; /* keep it simple for now... */
2222 SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2223 SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
2225 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2227 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2228 (unsigned long long)async_id ));
2231 * What we send is identical to a smbd_smb2_request_error
2232 * packet with an error status of STATUS_PENDING. Make use
2233 * of this fact sometime when refactoring. JRA.
2236 state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
2237 if (state == NULL) {
2238 smbd_server_connection_terminate(xconn,
2239 nt_errstr(NT_STATUS_NO_MEMORY));
2243 tf = state->buf + NBT_HDR_SIZE;
2245 hdr = tf + SMB2_TF_HDR_SIZE;
2246 body = hdr + SMB2_HDR_BODY;
2249 if (req->do_encryption) {
2250 uint64_t nonce_high = 0;
2251 uint64_t nonce_low = 0;
2252 uint64_t session_id = req->session->global->session_wire_id;
2254 status = smb2_get_new_nonce(req->session,
2257 if (!NT_STATUS_IS_OK(status)) {
2258 smbd_server_connection_terminate(xconn,
2263 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2264 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2265 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2266 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2269 SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
2270 SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
2271 SSVAL(hdr, SMB2_HDR_EPOCH, 0);
2272 SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_PENDING));
2273 SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
2275 SIVAL(hdr, SMB2_HDR_FLAGS, flags);
2276 SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
2277 SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
2278 SBVAL(hdr, SMB2_HDR_PID, async_id);
2279 SBVAL(hdr, SMB2_HDR_SESSION_ID,
2280 BVAL(outhdr, SMB2_HDR_SESSION_ID));
2281 memcpy(hdr+SMB2_HDR_SIGNATURE,
2282 outhdr+SMB2_HDR_SIGNATURE, 16);
2284 SSVAL(body, 0x00, 0x08 + 1);
2286 SCVAL(body, 0x02, 0);
2287 SCVAL(body, 0x03, 0);
2288 SIVAL(body, 0x04, 0);
2289 /* Match W2K8R2... */
2290 SCVAL(dyn, 0x00, 0x21);
2292 state->vector[0].iov_base = (void *)state->buf;
2293 state->vector[0].iov_len = NBT_HDR_SIZE;
2295 if (req->do_encryption) {
2296 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
2297 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len =
2300 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
2301 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
2304 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
2305 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
2307 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
2308 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
2310 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
2311 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len = 1;
2313 ok = smb2_setup_nbt_length(state->vector,
2314 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2316 smbd_server_connection_terminate(
2317 xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
2321 /* Ensure we correctly go through crediting. Grant
2322 the credits now, and zero credits on the final
2324 smb2_set_operation_credit(req->xconn,
2325 SMBD_SMB2_IN_HDR_IOV(req),
2326 &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
2328 SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2333 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
2334 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2336 (unsigned int)ARRAY_SIZE(state->vector),
2337 (unsigned int)state->vector[i].iov_len);
2341 if (req->do_encryption) {
2342 struct smbXsrv_session *x = req->session;
2343 struct smb2_signing_key *encryption_key = x->global->encryption_key;
2345 status = smb2_signing_encrypt_pdu(encryption_key,
2346 &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2347 SMBD_SMB2_NUM_IOV_PER_REQ);
2348 if (!NT_STATUS_IS_OK(status)) {
2349 smbd_server_connection_terminate(xconn,
2353 } else if (req->do_signing) {
2354 struct smbXsrv_session *x = req->session;
2355 struct smb2_signing_key *signing_key =
2356 smbd_smb2_signing_key(x, xconn, NULL);
2358 status = smb2_signing_sign_pdu(signing_key,
2359 &state->vector[1+SMBD_SMB2_HDR_IOV_OFS],
2360 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2361 if (!NT_STATUS_IS_OK(status)) {
2362 smbd_server_connection_terminate(xconn,
2368 state->queue_entry.mem_ctx = state;
2369 state->queue_entry.vector = state->vector;
2370 state->queue_entry.count = ARRAY_SIZE(state->vector);
2371 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
2372 xconn->smb2.send_queue_len++;
2374 status = smbd_smb2_flush_send_queue(xconn);
2375 if (!NT_STATUS_IS_OK(status)) {
2376 smbd_server_connection_terminate(xconn,
2382 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
2384 struct smbXsrv_connection *xconn = req->xconn;
2385 struct smbd_smb2_request *cur;
2386 const uint8_t *inhdr;
2388 uint64_t search_message_id;
2389 uint64_t search_async_id;
2392 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2394 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2395 search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2396 search_async_id = BVAL(inhdr, SMB2_HDR_PID);
2399 * We don't need the request anymore cancel requests never
2402 * We defer the TALLOC_FREE(req) to the caller.
2404 DLIST_REMOVE(xconn->smb2.requests, req);
2406 for (cur = xconn->smb2.requests; cur; cur = cur->next) {
2407 const uint8_t *outhdr;
2408 uint64_t message_id;
2411 if (cur->session != req->session) {
2415 if (cur->compound_related) {
2417 * Never cancel anything in a compound request.
2418 * Way too hard to deal with the result.
2423 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
2425 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2426 async_id = BVAL(outhdr, SMB2_HDR_PID);
2428 if (flags & SMB2_HDR_FLAG_ASYNC) {
2429 if (search_async_id == async_id) {
2430 found_id = async_id;
2434 if (search_message_id == message_id) {
2435 found_id = message_id;
2441 if (cur && cur->subreq) {
2442 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
2443 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2444 "cancel opcode[%s] mid %llu\n",
2445 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2446 (unsigned long long)found_id ));
2447 tevent_req_cancel(cur->subreq);
2450 return NT_STATUS_OK;
2453 /*************************************************************
2454 Ensure an incoming tid is a valid one for us to access.
2455 Change to the associated uid credentials and chdir to the
2456 valid tid directory.
2457 *************************************************************/
2459 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
2461 const uint8_t *inhdr;
2464 struct smbXsrv_tcon *tcon;
2466 NTTIME now = timeval_to_nttime(&req->request_time);
2470 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2472 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2473 in_tid = IVAL(inhdr, SMB2_HDR_TID);
2475 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2476 in_tid = req->last_tid;
2481 status = smb2srv_tcon_lookup(req->session,
2482 in_tid, now, &tcon);
2483 if (!NT_STATUS_IS_OK(status)) {
2487 if (!change_to_user_and_service(
2489 req->session->global->session_wire_id))
2491 return NT_STATUS_ACCESS_DENIED;
2495 req->last_tid = in_tid;
2497 return NT_STATUS_OK;
2500 /*************************************************************
2501 Ensure an incoming session_id is a valid one for us to access.
2502 *************************************************************/
2504 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
2506 const uint8_t *inhdr;
2509 uint64_t in_session_id;
2510 struct smbXsrv_session *session = NULL;
2511 struct auth_session_info *session_info;
2513 NTTIME now = timeval_to_nttime(&req->request_time);
2515 req->session = NULL;
2518 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2520 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2521 in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2522 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
2524 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2525 in_session_id = req->last_session_id;
2528 req->last_session_id = 0;
2530 /* look an existing session up */
2531 switch (in_opcode) {
2532 case SMB2_OP_SESSSETUP:
2534 * For a session bind request, we don't have the
2535 * channel set up at this point yet, so we defer
2536 * the verification that the connection belongs
2537 * to the session to the session setup code, which
2538 * can look at the session binding flags.
2540 status = smb2srv_session_lookup_client(req->xconn->client,
2545 status = smb2srv_session_lookup_conn(req->xconn,
2551 req->session = session;
2552 req->last_session_id = in_session_id;
2554 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
2555 switch (in_opcode) {
2556 case SMB2_OP_SESSSETUP:
2557 status = smb2srv_session_lookup_global(req->xconn->client,
2561 if (NT_STATUS_IS_OK(status)) {
2563 * We fallback to a session of
2564 * another process in order to
2565 * get the signing correct.
2567 * We don't set req->last_session_id here.
2569 req->session = session;
2576 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
2577 switch (in_opcode) {
2578 case SMB2_OP_SESSSETUP:
2579 status = NT_STATUS_OK;
2581 case SMB2_OP_LOGOFF:
2584 case SMB2_OP_CANCEL:
2585 case SMB2_OP_KEEPALIVE:
2587 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2588 * specifies that LOGOFF, CLOSE and (UN)LOCK
2589 * should always be processed even on expired sessions.
2591 * Also see the logic in
2592 * smbd_smb2_request_process_lock().
2594 * The smb2.session.expire2 test shows that
2595 * CANCEL and KEEPALIVE/ECHO should also
2598 status = NT_STATUS_OK;
2604 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2605 switch (in_opcode) {
2607 case SMB2_OP_CREATE:
2608 case SMB2_OP_GETINFO:
2609 case SMB2_OP_SETINFO:
2610 return NT_STATUS_INVALID_HANDLE;
2613 * Notice the check for
2614 * (session_info == NULL)
2617 status = NT_STATUS_OK;
2621 if (!NT_STATUS_IS_OK(status)) {
2625 session_info = session->global->auth_session_info;
2626 if (session_info == NULL) {
2627 return NT_STATUS_INVALID_HANDLE;
2630 return NT_STATUS_OK;
2633 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
2634 uint32_t data_length)
2636 struct smbXsrv_connection *xconn = req->xconn;
2637 uint16_t needed_charge;
2638 uint16_t credit_charge = 1;
2639 const uint8_t *inhdr;
2641 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2643 if (xconn->smb2.credits.multicredit) {
2644 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
2645 credit_charge = MAX(credit_charge, 1);
2648 needed_charge = (data_length - 1)/ 65536 + 1;
2650 DBGC_DEBUG(DBGC_SMB2_CREDITS,
2651 "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2652 (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
2653 credit_charge, needed_charge);
2655 if (needed_charge > credit_charge) {
2656 DBGC_WARNING(DBGC_SMB2_CREDITS,
2657 "CreditCharge too low, given %d, needed %d\n",
2658 credit_charge, needed_charge);
2659 return NT_STATUS_INVALID_PARAMETER;
2662 return NT_STATUS_OK;
2665 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
2666 size_t expected_body_size)
2668 struct iovec *inhdr_v;
2669 const uint8_t *inhdr;
2671 const uint8_t *inbody;
2673 size_t min_dyn_size = expected_body_size & 0x00000001;
2674 int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2677 * The following should be checked already.
2679 if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2680 return NT_STATUS_INTERNAL_ERROR;
2682 if (req->current_idx > max_idx) {
2683 return NT_STATUS_INTERNAL_ERROR;
2686 inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2687 if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2688 return NT_STATUS_INTERNAL_ERROR;
2690 if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2691 return NT_STATUS_INTERNAL_ERROR;
2694 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2695 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2699 case SMB2_OP_GETINFO:
2706 * Now check the expected body size,
2707 * where the last byte might be in the
2710 if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2711 return NT_STATUS_INVALID_PARAMETER;
2713 if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2714 return NT_STATUS_INVALID_PARAMETER;
2717 inbody = SMBD_SMB2_IN_BODY_PTR(req);
2719 body_size = SVAL(inbody, 0x00);
2720 if (body_size != expected_body_size) {
2721 return NT_STATUS_INVALID_PARAMETER;
2724 return NT_STATUS_OK;
2727 bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2729 return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2731 (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2732 SMBXSRV_ENCRYPTION_DESIRED |
2733 SMBXSRV_ENCRYPTION_REQUIRED)));
2736 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2738 return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2739 (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2742 /* Set a flag if not already set, return true if set */
2743 bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2745 if ((flag == 0) || (*flags & flag)) {
2754 * Update encryption state tracking flags, this can be used to
2755 * determine whether whether the session or tcon is "encrypted".
2757 static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2759 bool *update_session_globalp,
2760 bool *update_tcon_globalp)
2762 /* Default: assume unecrypted and unsigned */
2763 struct smbXsrv_session *session = req->session;
2764 struct smbXsrv_tcon *tcon = req->tcon;
2765 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2766 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2767 bool update_session = false;
2768 bool update_tcon = false;
2770 if (session->table == NULL) {
2772 * sessions from smb2srv_session_lookup_global()
2773 * have NT_STATUS_BAD_LOGON_SESSION_STATE
2774 * and session->table == NULL.
2776 * They only used to give the correct error
2777 * status, we should not update any state.
2782 if (req->was_encrypted && req->do_encryption) {
2783 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2784 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2786 /* Unencrypted packet, can be signed */
2787 if (req->do_signing) {
2788 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2792 update_session |= smbXsrv_set_crypto_flag(
2793 &session->global->encryption_flags, encrypt_flag);
2794 update_session |= smbXsrv_set_crypto_flag(
2795 &session->global->signing_flags, sign_flag);
2798 update_tcon |= smbXsrv_set_crypto_flag(
2799 &tcon->global->encryption_flags, encrypt_flag);
2800 update_tcon |= smbXsrv_set_crypto_flag(
2801 &tcon->global->signing_flags, sign_flag);
2805 *update_session_globalp = update_session;
2806 *update_tcon_globalp = update_tcon;
2810 bool smbXsrv_is_signed(uint8_t signing_flags)
2813 * Signing is always enabled, so unless we got an unsigned
2814 * packet and at least one signed packet that was not
2815 * encrypted, the session or tcon is "signed".
2817 return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2818 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2821 bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2823 return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2824 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2827 static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2828 struct smbd_smb2_request *req,
2831 struct smbXsrv_connection *xconn = req->xconn;
2832 const uint8_t *inhdr;
2833 uint16_t channel_sequence;
2834 uint8_t generation_wrap = 0;
2837 struct smbXsrv_open *op;
2838 bool update_open = false;
2839 NTSTATUS status = NT_STATUS_OK;
2841 SMB_ASSERT(!req->request_counters_updated);
2843 if (xconn->protocol < PROTOCOL_SMB3_00) {
2844 return NT_STATUS_OK;
2847 if (req->compat_chain_fsp == NULL) {
2848 return NT_STATUS_OK;
2851 op = req->compat_chain_fsp->op;
2853 return NT_STATUS_OK;
2856 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2857 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2858 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2860 cmp = channel_sequence - op->global->channel_sequence;
2863 * csn wrap. We need to watch out for long-running
2864 * requests that are still sitting on a previously
2865 * used csn. SMB2_OP_NOTIFY can take VERY long.
2867 generation_wrap += 1;
2870 if (abs(cmp) > INT16_MAX) {
2872 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2874 * If the channel sequence number of the request and the one
2875 * known to the server are not equal, the channel sequence
2876 * number and outstanding request counts are only updated
2877 * "... if the unsigned difference using 16-bit arithmetic
2878 * between ChannelSequence and Open.ChannelSequence is less than
2879 * or equal to 0x7FFF ...".
2880 * Otherwise, an error is returned for the modifying
2881 * calls write, set_info, and ioctl.
2883 * There are currently two issues with the description:
2885 * * For the other calls, the document seems to imply
2886 * that processing continues without adapting the
2887 * counters (if the sequence numbers are not equal).
2889 * TODO: This needs clarification!
2891 * * Also, the behaviour if the difference is larger
2892 * than 0x7FFF is not clear. The document seems to
2893 * imply that if such a difference is reached,
2894 * the server starts to ignore the counters or
2895 * in the case of the modifying calls, return errors.
2897 * TODO: This needs clarification!
2899 * At this point Samba tries to be a little more
2900 * clever than the description in the MS-SMB2 document
2901 * by heuristically detecting and properly treating
2902 * a 16 bit overflow of the client-submitted sequence
2905 * If the stored channel sequence number is more than
2906 * 0x7FFF larger than the one from the request, then
2907 * the client-provided sequence number has likely
2908 * overflown. We treat this case as valid instead
2911 * The MS-SMB2 behaviour would be setting cmp = -1.
2916 if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2917 if (cmp == 0 && op->pre_request_count == 0) {
2918 op->request_count += 1;
2919 req->request_counters_updated = true;
2920 } else if (cmp > 0 && op->pre_request_count == 0) {
2921 op->pre_request_count += op->request_count;
2922 op->request_count = 1;
2923 op->global->channel_sequence = channel_sequence;
2924 op->global->channel_generation += generation_wrap;
2926 req->request_counters_updated = true;
2927 } else if (modify_call) {
2928 return NT_STATUS_FILE_NOT_AVAILABLE;
2932 op->request_count += 1;
2933 req->request_counters_updated = true;
2934 } else if (cmp > 0) {
2935 op->pre_request_count += op->request_count;
2936 op->request_count = 1;
2937 op->global->channel_sequence = channel_sequence;
2938 op->global->channel_generation += generation_wrap;
2940 req->request_counters_updated = true;
2941 } else if (modify_call) {
2942 return NT_STATUS_FILE_NOT_AVAILABLE;
2945 req->channel_generation = op->global->channel_generation;
2948 status = smbXsrv_open_update(op);
2954 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2956 struct smbXsrv_connection *xconn = req->xconn;
2957 const struct smbd_smb2_dispatch_table *call = NULL;
2958 const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2959 const uint8_t *inhdr;
2964 NTSTATUS session_status;
2965 uint32_t allowed_flags;
2966 NTSTATUS return_value;
2967 struct smbXsrv_session *x = NULL;
2968 bool signing_required = false;
2969 bool encryption_desired = false;
2970 bool encryption_required = false;
2972 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2974 DO_PROFILE_INC(request);
2976 SMB_ASSERT(!req->request_counters_updated);
2978 /* TODO: verify more things */
2980 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2981 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2982 mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2983 DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2984 smb2_opcode_name(opcode),
2985 (unsigned long long)mid));
2987 if (xconn->protocol >= PROTOCOL_SMB2_02) {
2989 * once the protocol is negotiated
2990 * SMB2_OP_NEGPROT is not allowed anymore
2992 if (opcode == SMB2_OP_NEGPROT) {
2993 /* drop the connection */
2994 return NT_STATUS_INVALID_PARAMETER;
2998 * if the protocol is not negotiated yet
2999 * only SMB2_OP_NEGPROT is allowed.
3001 if (opcode != SMB2_OP_NEGPROT) {
3002 /* drop the connection */
3003 return NT_STATUS_INVALID_PARAMETER;
3008 * Check if the client provided a valid session id.
3010 * As some command don't require a valid session id
3011 * we defer the check of the session_status
3013 session_status = smbd_smb2_request_check_session(req);
3016 signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
3017 encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3018 encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
3021 req->async_internal = false;
3022 req->do_signing = false;
3023 if (opcode != SMB2_OP_SESSSETUP) {
3024 req->do_encryption = encryption_desired;
3026 req->do_encryption = false;
3028 req->was_encrypted = false;
3029 if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
3030 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
3031 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
3033 if (x != NULL && x->global->session_wire_id != tf_session_id) {
3034 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
3035 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
3036 (unsigned long long)x->global->session_wire_id,
3037 (unsigned long long)tf_session_id));
3039 * TODO: windows allows this...
3040 * should we drop the connection?
3042 * For now we just return ACCESS_DENIED
3043 * (Windows clients never trigger this)
3044 * and wait for an update of [MS-SMB2].
3046 return smbd_smb2_request_error(req,
3047 NT_STATUS_ACCESS_DENIED);
3050 req->was_encrypted = true;
3051 req->do_encryption = true;
3054 if (encryption_required && !req->was_encrypted) {
3055 req->do_encryption = true;
3056 return smbd_smb2_request_error(req,
3057 NT_STATUS_ACCESS_DENIED);
3060 call = smbd_smb2_call(opcode);
3062 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3065 allowed_flags = SMB2_HDR_FLAG_CHAINED |
3066 SMB2_HDR_FLAG_SIGNED |
3068 if (xconn->protocol >= PROTOCOL_SMB3_11) {
3069 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3071 if (opcode == SMB2_OP_NEGPROT) {
3072 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
3073 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3076 if (opcode == SMB2_OP_CANCEL) {
3077 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
3079 if (xconn->protocol >= PROTOCOL_SMB3_00) {
3080 allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3082 if ((flags & ~allowed_flags) != 0) {
3083 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3086 if (flags & SMB2_HDR_FLAG_CHAINED) {
3088 * This check is mostly for giving the correct error code
3089 * for compounded requests.
3091 if (!NT_STATUS_IS_OK(session_status)) {
3092 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3095 req->compat_chain_fsp = NULL;
3098 if (req->was_encrypted) {
3099 signing_required = false;
3100 } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
3101 struct smb2_signing_key *signing_key = NULL;
3102 bool has_channel = false;
3106 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3107 * If the SMB2 header of the SMB2 NEGOTIATE
3108 * request has the SMB2_FLAGS_SIGNED bit set in the
3109 * Flags field, the server MUST fail the request
3110 * with STATUS_INVALID_PARAMETER.
3112 * Microsoft test tool checks this.
3115 if ((opcode == SMB2_OP_NEGPROT) &&
3116 (flags & SMB2_HDR_FLAG_SIGNED)) {
3117 status = NT_STATUS_INVALID_PARAMETER;
3119 status = NT_STATUS_USER_SESSION_DELETED;
3121 return smbd_smb2_request_error(req, status);
3124 signing_key = smbd_smb2_signing_key(x, xconn, &has_channel);
3127 * If we have a signing key, we should
3130 if (smb2_signing_key_valid(signing_key)) {
3131 req->do_signing = true;
3134 status = smb2_signing_check_pdu(signing_key,
3135 SMBD_SMB2_IN_HDR_IOV(req),
3136 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3137 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
3138 opcode == SMB2_OP_SESSSETUP && !has_channel &&
3139 NT_STATUS_IS_OK(session_status))
3141 if (!NT_STATUS_EQUAL(x->status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
3142 struct smbXsrv_session *session = NULL;
3145 error = smb2srv_session_lookup_global(req->xconn->client,
3146 x->global->session_wire_id,
3149 if (!NT_STATUS_IS_OK(error)) {
3150 return smbd_smb2_request_error(req, error);
3154 * We fallback to a session of
3155 * another process in order to
3156 * get the signing correct.
3158 * We don't set req->last_session_id here.
3160 req->session = x = session;
3162 goto skipped_signing;
3164 if (!NT_STATUS_IS_OK(status)) {
3165 return smbd_smb2_request_error(req, status);
3169 * Now that we know the request was correctly signed
3170 * we have to sign the response too.
3172 req->do_signing = true;
3174 if (!NT_STATUS_IS_OK(session_status)) {
3175 return smbd_smb2_request_error(req, session_status);
3177 } else if (opcode == SMB2_OP_IOCTL) {
3179 * Some special IOCTL calls don't require
3180 * file, tcon nor session.
3182 * They typically don't do any real action
3183 * on behalf of the client.
3185 * They are mainly used to alter the behavior
3186 * of the connection for testing. So we can
3187 * run as root and skip all file, tcon and session
3190 static const struct smbd_smb2_dispatch_table _root_ioctl_call = {
3194 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3195 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3196 uint32_t in_ctl_code;
3199 if (needed > body_size) {
3200 return smbd_smb2_request_error(req,
3201 NT_STATUS_INVALID_PARAMETER);
3204 in_ctl_code = IVAL(body, 0x04);
3206 * Only add trusted IOCTL codes here!
3208 switch (in_ctl_code) {
3209 case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
3210 call = &_root_ioctl_call;
3217 if (flags & SMB2_HDR_FLAG_CHAINED) {
3218 req->compound_related = true;
3221 if (call->need_session) {
3222 if (!NT_STATUS_IS_OK(session_status)) {
3223 return smbd_smb2_request_error(req, session_status);
3227 if (call->need_tcon) {
3228 SMB_ASSERT(call->need_session);
3231 * This call needs to be run as user.
3233 * smbd_smb2_request_check_tcon()
3234 * calls change_to_user() on success.
3235 * Which implies set_current_user_info()
3236 * and chdir_current_service().
3238 status = smbd_smb2_request_check_tcon(req);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 return smbd_smb2_request_error(req, status);
3242 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3243 encryption_desired = true;
3245 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
3246 encryption_required = true;
3248 if (encryption_required && !req->was_encrypted) {
3249 req->do_encryption = true;
3250 return smbd_smb2_request_error(req,
3251 NT_STATUS_ACCESS_DENIED);
3252 } else if (encryption_desired) {
3253 req->do_encryption = true;
3255 } else if (call->need_session) {
3256 struct auth_session_info *session_info = NULL;
3259 * Unless we also have need_tcon (see above),
3260 * we still need to call set_current_user_info().
3263 session_info = req->session->global->auth_session_info;
3264 if (session_info == NULL) {
3265 return NT_STATUS_INVALID_HANDLE;
3268 set_current_user_info(session_info->unix_info->sanitized_username,
3269 session_info->unix_info->unix_name,
3270 session_info->info->domain_name);
3274 bool update_session_global = false;
3275 bool update_tcon_global = false;
3277 smb2srv_update_crypto_flags(req, opcode,
3278 &update_session_global,
3279 &update_tcon_global);
3281 if (update_session_global) {
3282 status = smbXsrv_session_update(x);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 return smbd_smb2_request_error(req, status);
3287 if (update_tcon_global) {
3288 status = smbXsrv_tcon_update(req->tcon);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 return smbd_smb2_request_error(req, status);
3295 if (call->fileid_ofs != 0) {
3296 size_t needed = call->fileid_ofs + 16;
3297 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3298 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3299 uint64_t file_id_persistent;
3300 uint64_t file_id_volatile;
3301 struct files_struct *fsp;
3303 SMB_ASSERT(call->need_tcon);
3305 if (needed > body_size) {
3306 return smbd_smb2_request_error(req,
3307 NT_STATUS_INVALID_PARAMETER);
3310 file_id_persistent = BVAL(body, call->fileid_ofs + 0);
3311 file_id_volatile = BVAL(body, call->fileid_ofs + 8);
3313 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
3315 if (req->compound_related &&
3316 !NT_STATUS_IS_OK(req->compound_create_err))
3318 return smbd_smb2_request_error(req,
3319 req->compound_create_err);
3321 if (!call->allow_invalid_fileid) {
3322 return smbd_smb2_request_error(req,
3323 NT_STATUS_FILE_CLOSED);
3326 if (file_id_persistent != UINT64_MAX) {
3327 return smbd_smb2_request_error(req,
3328 NT_STATUS_FILE_CLOSED);
3330 if (file_id_volatile != UINT64_MAX) {
3331 return smbd_smb2_request_error(req,
3332 NT_STATUS_FILE_CLOSED);
3335 if (fsp->fsp_flags.encryption_required && !req->was_encrypted) {
3336 return smbd_smb2_request_error(req,
3337 NT_STATUS_ACCESS_DENIED);
3342 status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
3343 if (!NT_STATUS_IS_OK(status)) {
3344 return smbd_smb2_request_error(req, status);
3347 if (call->as_root) {
3348 SMB_ASSERT(call->fileid_ofs == 0);
3349 /* This call needs to be run as root */
3350 change_to_root_user();
3352 SMB_ASSERT(call->need_tcon);
3355 #define _INBYTES(_r) \
3356 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3359 case SMB2_OP_NEGPROT:
3360 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
3361 req->profile, _INBYTES(req));
3362 return_value = smbd_smb2_request_process_negprot(req);
3365 case SMB2_OP_SESSSETUP:
3366 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
3367 req->profile, _INBYTES(req));
3368 return_value = smbd_smb2_request_process_sesssetup(req);
3371 case SMB2_OP_LOGOFF:
3372 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
3373 req->profile, _INBYTES(req));
3374 return_value = smbd_smb2_request_process_logoff(req);
3378 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
3379 req->profile, _INBYTES(req));
3380 return_value = smbd_smb2_request_process_tcon(req);
3384 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
3385 req->profile, _INBYTES(req));
3386 return_value = smbd_smb2_request_process_tdis(req);
3389 case SMB2_OP_CREATE:
3390 if (req->subreq == NULL) {
3391 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
3392 req->profile, _INBYTES(req));
3394 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
3396 return_value = smbd_smb2_request_process_create(req);
3400 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
3401 req->profile, _INBYTES(req));
3402 return_value = smbd_smb2_request_process_close(req);
3406 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
3407 req->profile, _INBYTES(req));
3408 return_value = smbd_smb2_request_process_flush(req);
3412 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
3413 req->profile, _INBYTES(req));
3414 return_value = smbd_smb2_request_process_read(req);
3418 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
3419 req->profile, _INBYTES(req));
3420 return_value = smbd_smb2_request_process_write(req);
3424 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
3425 req->profile, _INBYTES(req));
3426 return_value = smbd_smb2_request_process_lock(req);
3430 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
3431 req->profile, _INBYTES(req));
3432 return_value = smbd_smb2_request_process_ioctl(req);
3435 case SMB2_OP_CANCEL:
3436 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
3437 req->profile, _INBYTES(req));
3438 return_value = smbd_smb2_request_process_cancel(req);
3439 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
3442 * We don't need the request anymore cancel requests never
3445 * smbd_smb2_request_process_cancel() already called
3446 * DLIST_REMOVE(xconn->smb2.requests, req);
3452 case SMB2_OP_KEEPALIVE:
3453 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
3454 req->profile, _INBYTES(req));
3455 return_value = smbd_smb2_request_process_keepalive(req);
3458 case SMB2_OP_QUERY_DIRECTORY:
3459 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
3460 req->profile, _INBYTES(req));
3461 return_value = smbd_smb2_request_process_query_directory(req);
3464 case SMB2_OP_NOTIFY:
3465 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
3466 req->profile, _INBYTES(req));
3467 return_value = smbd_smb2_request_process_notify(req);
3470 case SMB2_OP_GETINFO:
3471 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
3472 req->profile, _INBYTES(req));
3473 return_value = smbd_smb2_request_process_getinfo(req);
3476 case SMB2_OP_SETINFO:
3477 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
3478 req->profile, _INBYTES(req));
3479 return_value = smbd_smb2_request_process_setinfo(req);
3483 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
3484 req->profile, _INBYTES(req));
3485 return_value = smbd_smb2_request_process_break(req);
3489 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3492 return return_value;
3495 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
3497 struct smbXsrv_connection *xconn = req->xconn;
3498 const uint8_t *inhdr;
3499 uint16_t channel_sequence;
3500 struct smbXsrv_open *op;
3502 if (!req->request_counters_updated) {
3506 req->request_counters_updated = false;
3508 if (xconn->protocol < PROTOCOL_SMB3_00) {
3512 if (req->compat_chain_fsp == NULL) {
3516 op = req->compat_chain_fsp->op;
3521 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
3522 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
3524 if ((op->global->channel_sequence == channel_sequence) &&
3525 (op->global->channel_generation == req->channel_generation)) {
3526 SMB_ASSERT(op->request_count > 0);
3527 op->request_count -= 1;
3529 SMB_ASSERT(op->pre_request_count > 0);
3530 op->pre_request_count -= 1;
3534 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
3536 struct smbXsrv_connection *xconn = req->xconn;
3538 struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
3539 struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
3540 struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
3545 TALLOC_FREE(req->async_te);
3547 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3548 smbd_smb2_request_reply_update_counts(req);
3550 if (req->do_encryption &&
3551 (firsttf->iov_len == 0) &&
3552 (!smb2_signing_key_valid(req->first_enc_key)) &&
3553 (req->session != NULL) &&
3554 smb2_signing_key_valid(req->session->global->encryption_key))
3556 struct smb2_signing_key *encryption_key =
3557 req->session->global->encryption_key;
3559 uint64_t session_id = req->session->global->session_wire_id;
3560 uint64_t nonce_high;
3563 status = smb2_get_new_nonce(req->session,
3566 if (!NT_STATUS_IS_OK(status)) {
3571 * We need to place the SMB2_TRANSFORM header before the
3576 * we need to remember the encryption key
3577 * and defer the signing/encryption until
3578 * we are sure that we do not change
3581 status = smb2_signing_key_copy(req,
3583 &req->first_enc_key);
3584 if (!NT_STATUS_IS_OK(status)) {
3588 tf = talloc_zero_array(req, uint8_t,
3591 return NT_STATUS_NO_MEMORY;
3594 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3595 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
3596 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
3597 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
3599 firsttf->iov_base = (void *)tf;
3600 firsttf->iov_len = SMB2_TF_HDR_SIZE;
3603 if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
3604 (smb2_signing_key_valid(req->last_sign_key)) &&
3605 (firsttf->iov_len == 0))
3607 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
3608 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
3611 * As we are sure the header of the last request in the
3612 * compound chain will not change, we can to sign here
3613 * with the last signing key we remembered.
3615 status = smb2_signing_sign_pdu(req->last_sign_key,
3617 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3618 if (!NT_STATUS_IS_OK(status)) {
3622 TALLOC_FREE(req->last_sign_key);
3624 SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
3625 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
3627 req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
3629 if (req->current_idx < req->out.vector_count) {
3631 * We must process the remaining compound
3632 * SMB2 requests before any new incoming SMB2
3633 * requests. This is because incoming SMB2
3634 * requests may include a cancel for a
3635 * compound request we haven't processed
3638 struct tevent_immediate *im = tevent_create_immediate(req);
3640 return NT_STATUS_NO_MEMORY;
3643 if (req->do_signing && firsttf->iov_len == 0) {
3644 struct smbXsrv_session *x = req->session;
3645 struct smb2_signing_key *signing_key =
3646 smbd_smb2_signing_key(x, xconn, NULL);
3649 * we need to remember the signing key
3650 * and defer the signing until
3651 * we are sure that we do not change
3654 status = smb2_signing_key_copy(req,
3656 &req->last_sign_key);
3657 if (!NT_STATUS_IS_OK(status)) {
3663 * smbd_smb2_request_dispatch() will redo the impersonation.
3664 * So we use req->xconn->client->raw_ev_ctx instead
3665 * of req->ev_ctx here.
3667 tevent_schedule_immediate(im,
3668 req->xconn->client->raw_ev_ctx,
3669 smbd_smb2_request_dispatch_immediate,
3671 return NT_STATUS_OK;
3674 if (req->compound_related) {
3675 req->compound_related = false;
3678 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
3680 return NT_STATUS_INVALID_PARAMETER_MIX;
3683 /* Set credit for these operations (zero credits if this
3684 is a final reply for an async operation). */
3685 smb2_calculate_credits(req, req);
3688 * now check if we need to sign the current response
3690 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3691 status = smb2_signing_encrypt_pdu(req->first_enc_key,
3693 req->out.vector_count - first_idx);
3694 if (!NT_STATUS_IS_OK(status)) {
3697 } else if (req->do_signing) {
3698 struct smbXsrv_session *x = req->session;
3699 struct smb2_signing_key *signing_key =
3700 smbd_smb2_signing_key(x, xconn, NULL);
3702 status = smb2_signing_sign_pdu(signing_key,
3704 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3705 if (!NT_STATUS_IS_OK(status)) {
3709 TALLOC_FREE(req->first_enc_key);
3711 if (req->preauth != NULL) {
3712 gnutls_hash_hd_t hash_hnd = NULL;
3716 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3718 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3720 rc = gnutls_hash(hash_hnd,
3721 req->preauth->sha512_value,
3722 sizeof(req->preauth->sha512_value));
3724 gnutls_hash_deinit(hash_hnd, NULL);
3725 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3727 for (i = 1; i < req->in.vector_count; i++) {
3728 rc = gnutls_hash(hash_hnd,
3729 req->in.vector[i].iov_base,
3730 req->in.vector[i].iov_len);
3732 gnutls_hash_deinit(hash_hnd, NULL);
3733 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3737 gnutls_hash_deinit(hash_hnd, NULL);
3738 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3740 gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3742 rc = gnutls_hash(hash_hnd,
3743 req->preauth->sha512_value,
3744 sizeof(req->preauth->sha512_value));
3746 gnutls_hash_deinit(hash_hnd, NULL);
3747 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3749 for (i = 1; i < req->out.vector_count; i++) {
3750 rc = gnutls_hash(hash_hnd,
3751 req->out.vector[i].iov_base,
3752 req->out.vector[i].iov_len);
3754 gnutls_hash_deinit(hash_hnd, NULL);
3755 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3759 gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3761 req->preauth = NULL;
3764 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3765 if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3766 outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3767 /* Dynamic part is NULL. Chop it off,
3768 We're going to send it via sendfile. */
3769 req->out.vector_count -= 1;
3773 * We're done with this request -
3774 * move it off the "being processed" queue.
3776 DLIST_REMOVE(xconn->smb2.requests, req);
3778 req->queue_entry.mem_ctx = req;
3779 req->queue_entry.vector = req->out.vector;
3780 req->queue_entry.count = req->out.vector_count;
3781 DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3782 xconn->smb2.send_queue_len++;
3784 status = smbd_smb2_flush_send_queue(xconn);
3785 if (!NT_STATUS_IS_OK(status)) {
3789 return NT_STATUS_OK;
3792 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3794 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3795 struct tevent_immediate *im,
3798 struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3799 struct smbd_smb2_request);
3800 struct smbXsrv_connection *xconn = req->xconn;
3805 if (DEBUGLEVEL >= 10) {
3806 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3807 req->current_idx, req->in.vector_count));
3808 print_req_vectors(req);
3811 status = smbd_smb2_request_dispatch(req);
3812 if (!NT_STATUS_IS_OK(status)) {
3813 smbd_server_connection_terminate(xconn, nt_errstr(status));
3817 status = smbd_smb2_request_next_incoming(xconn);
3818 if (!NT_STATUS_IS_OK(status)) {
3819 smbd_server_connection_terminate(xconn, nt_errstr(status));
3824 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3826 DATA_BLOB body, DATA_BLOB *dyn,
3827 const char *location)
3830 struct iovec *outbody_v;
3831 struct iovec *outdyn_v;
3832 uint32_t next_command_ofs;
3835 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3836 mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
3838 DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
3839 "body[%u] dyn[%s:%u] at %s\n",
3843 (unsigned int)body.length,
3845 (unsigned int)(dyn ? dyn->length : 0),
3848 if (body.length < 2) {
3849 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3852 if ((body.length % 2) != 0) {
3853 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3856 outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3857 outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3859 next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3860 SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3862 outbody_v->iov_base = (void *)body.data;
3863 outbody_v->iov_len = body.length;
3866 outdyn_v->iov_base = (void *)dyn->data;
3867 outdyn_v->iov_len = dyn->length;
3869 outdyn_v->iov_base = NULL;
3870 outdyn_v->iov_len = 0;
3874 * See if we need to recalculate the offset to the next response
3876 * Note that all responses may require padding (including the very last
3879 if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3880 next_command_ofs = SMB2_HDR_BODY;
3881 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3882 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3885 if ((next_command_ofs % 8) != 0) {
3886 size_t pad_size = 8 - (next_command_ofs % 8);
3887 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3889 * if the dyn buffer is empty
3890 * we can use it to add padding
3894 pad = talloc_zero_array(req,
3897 return smbd_smb2_request_error(req,
3898 NT_STATUS_NO_MEMORY);
3901 outdyn_v->iov_base = (void *)pad;
3902 outdyn_v->iov_len = pad_size;
3905 * For now we copy the dynamic buffer
3906 * and add the padding to the new buffer
3913 old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3914 old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3916 new_size = old_size + pad_size;
3917 new_dyn = talloc_zero_array(req,
3919 if (new_dyn == NULL) {
3920 return smbd_smb2_request_error(req,
3921 NT_STATUS_NO_MEMORY);
3924 memcpy(new_dyn, old_dyn, old_size);
3925 memset(new_dyn + old_size, 0, pad_size);
3927 outdyn_v->iov_base = (void *)new_dyn;
3928 outdyn_v->iov_len = new_size;
3930 next_command_ofs += pad_size;
3933 if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3934 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3936 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3938 return smbd_smb2_request_reply(req);
3941 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3944 const char *location)
3946 struct smbXsrv_connection *xconn = req->xconn;
3949 uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3950 size_t unread_bytes = smbd_smb2_unread_bytes(req);
3952 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3953 "at %s\n", req->current_idx, nt_errstr(status),
3954 info ? " +info" : "", location);
3957 /* Recvfile error. Drain incoming socket. */
3961 ret = drain_socket(xconn->transport.sock, unread_bytes);
3962 if (ret != unread_bytes) {
3966 error = NT_STATUS_IO_DEVICE_ERROR;
3968 error = map_nt_error_from_unix_common(errno);
3971 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3972 "ret[%u] errno[%d] => %s\n",
3973 (unsigned)unread_bytes,
3974 (unsigned)ret, errno, nt_errstr(error)));
3979 body.data = outhdr + SMB2_HDR_BODY;
3981 SSVAL(body.data, 0, 9);
3984 SIVAL(body.data, 0x04, info->length);
3986 /* Allocated size of req->out.vector[i].iov_base
3987 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3988 * 1 byte without having to do an alloc.
3991 info->data = ((uint8_t *)outhdr) +
3992 OUTVEC_ALLOC_SIZE - 1;
3994 SCVAL(info->data, 0, 0);
3998 * Note: Even if there is an error, continue to process the request.
4002 return smbd_smb2_request_done_ex(req, status, body, info, __location__);
4005 struct smbd_smb2_break_state {
4006 struct tevent_req *req;
4007 struct smbd_smb2_send_queue queue_entry;
4008 uint8_t nbt_hdr[NBT_HDR_SIZE];
4009 uint8_t hdr[SMB2_HDR_BODY];
4010 struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
4013 static struct tevent_req *smbd_smb2_break_send(TALLOC_CTX *mem_ctx,
4014 struct tevent_context *ev,
4015 struct smbXsrv_connection *xconn,
4016 uint64_t session_id,
4017 const uint8_t *body,
4020 struct tevent_req *req = NULL;
4021 struct smbd_smb2_break_state *state = NULL;
4025 req = tevent_req_create(mem_ctx, &state,
4026 struct smbd_smb2_break_state);
4032 tevent_req_defer_callback(req, ev);
4034 SIVAL(state->hdr, 0, SMB2_MAGIC);
4035 SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
4036 SSVAL(state->hdr, SMB2_HDR_EPOCH, 0);
4037 SIVAL(state->hdr, SMB2_HDR_STATUS, 0);
4038 SSVAL(state->hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK);
4039 SSVAL(state->hdr, SMB2_HDR_CREDIT, 0);
4040 SIVAL(state->hdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
4041 SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, 0);
4042 SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
4043 SIVAL(state->hdr, SMB2_HDR_PID, 0);
4044 SIVAL(state->hdr, SMB2_HDR_TID, 0);
4045 SBVAL(state->hdr, SMB2_HDR_SESSION_ID, session_id);
4046 memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
4048 state->vector[0] = (struct iovec) {
4049 .iov_base = state->nbt_hdr,
4050 .iov_len = sizeof(state->nbt_hdr)
4053 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
4058 state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
4059 .iov_base = state->hdr,
4060 .iov_len = sizeof(state->hdr)
4063 state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
4064 .iov_base = discard_const_p(uint8_t, body),
4065 .iov_len = body_len,
4069 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4072 ok = smb2_setup_nbt_length(state->vector,
4073 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
4075 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4076 return tevent_req_post(req, ev);
4080 * We require TCP acks for this PDU to the client!
4081 * We want 5 retransmissions and timeout when the
4082 * retransmission timeout (rto) passed 6 times.
4084 * required_acked_bytes gets a dummy value of
4085 * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4086 * it'll get the real value when it's moved to
4089 * state->queue_entry.ack.req gets completed with
4090 * 1. tevent_req_done(), when all bytes are acked.
4091 * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4092 * the timeout expired before all bytes were acked.
4093 * 2b. tevent_req_nterror(transport_error), when the
4094 * connection got a disconnect from the kernel.
4096 state->queue_entry.ack.timeout =
4097 timeval_current_ofs_usec(xconn->ack.rto_usecs * 6);
4098 state->queue_entry.ack.required_acked_bytes = UINT64_MAX;
4099 state->queue_entry.ack.req = req;
4100 state->queue_entry.mem_ctx = state;
4101 state->queue_entry.vector = state->vector;
4102 state->queue_entry.count = ARRAY_SIZE(state->vector);
4103 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
4104 xconn->smb2.send_queue_len++;
4106 status = smbd_smb2_flush_send_queue(xconn);
4107 if (tevent_req_nterror(req, status)) {
4108 return tevent_req_post(req, ev);
4114 static NTSTATUS smbd_smb2_break_recv(struct tevent_req *req)
4116 return tevent_req_simple_recv_ntstatus(req);
4119 struct smbXsrv_pending_break {
4120 struct smbXsrv_pending_break *prev, *next;
4121 struct smbXsrv_client *client;
4122 bool disable_oplock_break_retries;
4123 uint64_t session_id;
4124 uint64_t last_channel_id;
4127 uint8_t oplock[0x18];
4128 uint8_t lease[0x2c];
4133 static void smbXsrv_pending_break_done(struct tevent_req *subreq);
4135 static struct smbXsrv_pending_break *smbXsrv_pending_break_create(
4136 struct smbXsrv_client *client,
4137 uint64_t session_id)
4139 struct smbXsrv_pending_break *pb = NULL;
4141 pb = talloc_zero(client, struct smbXsrv_pending_break);
4145 pb->client = client;
4146 pb->session_id = session_id;
4147 pb->disable_oplock_break_retries = lp_smb2_disable_oplock_break_retry();
4152 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb);
4154 static NTSTATUS smbXsrv_pending_break_schedule(struct smbXsrv_pending_break *pb)
4156 struct smbXsrv_client *client = pb->client;
4159 DLIST_ADD_END(client->pending_breaks, pb);
4160 status = smbXsrv_client_pending_breaks_updated(client);
4161 if (!NT_STATUS_IS_OK(status)) {
4165 status = smbXsrv_pending_break_submit(pb);
4166 if (!NT_STATUS_IS_OK(status)) {
4170 return NT_STATUS_OK;
4173 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb)
4175 struct smbXsrv_client *client = pb->client;
4176 struct smbXsrv_session *session = NULL;
4177 struct smbXsrv_connection *xconn = NULL;
4178 struct smbXsrv_connection *oplock_xconn = NULL;
4179 struct tevent_req *subreq = NULL;
4182 if (pb->session_id != 0) {
4183 status = get_valid_smbXsrv_session(client,
4186 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
4187 return NT_STATUS_ABANDONED;
4189 if (!NT_STATUS_IS_OK(status)) {
4193 if (pb->last_channel_id != 0) {
4195 * This is what current Windows servers
4196 * do, they don't retry on all available
4197 * channels. They only use the last channel.
4199 * But it doesn't match the specification in
4200 * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4203 * Per default disable_oplock_break_retries is false
4204 * and we behave like the specification.
4206 if (pb->disable_oplock_break_retries) {
4207 return NT_STATUS_ABANDONED;
4212 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
4213 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4217 if (xconn->channel_id == 0) {
4219 * non-multichannel case
4224 if (session != NULL) {
4225 struct smbXsrv_channel_global0 *c = NULL;
4228 * Having a session means we're handling
4229 * an oplock break and we only need to
4230 * use channels available on the
4233 status = smbXsrv_session_find_channel(session, xconn, &c);
4234 if (!NT_STATUS_IS_OK(status)) {
4239 * This is what current Windows servers
4240 * do, they don't retry on all available
4241 * channels. They only use the last channel.
4243 * But it doesn't match the specification
4244 * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4247 * Per default disable_oplock_break_retries is false
4248 * and we behave like the specification.
4250 if (pb->disable_oplock_break_retries) {
4251 oplock_xconn = xconn;
4256 if (xconn->channel_id > pb->last_channel_id) {
4264 if (xconn == NULL) {
4265 xconn = oplock_xconn;
4268 if (xconn == NULL) {
4270 * If there's no remaining connection available
4271 * tell the caller to stop...
4273 return NT_STATUS_ABANDONED;
4276 pb->last_channel_id = xconn->channel_id;
4278 subreq = smbd_smb2_break_send(pb,
4284 if (subreq == NULL) {
4285 return NT_STATUS_NO_MEMORY;
4287 tevent_req_set_callback(subreq,
4288 smbXsrv_pending_break_done,
4291 return NT_STATUS_OK;
4294 static void smbXsrv_pending_break_done(struct tevent_req *subreq)
4296 struct smbXsrv_pending_break *pb =
4297 tevent_req_callback_data(subreq,
4298 struct smbXsrv_pending_break);
4299 struct smbXsrv_client *client = pb->client;
4302 status = smbd_smb2_break_recv(subreq);
4303 TALLOC_FREE(subreq);
4304 if (!NT_STATUS_IS_OK(status)) {
4305 status = smbXsrv_pending_break_submit(pb);
4306 if (NT_STATUS_EQUAL(status, NT_STATUS_ABANDONED)) {
4308 * If there's no remaing connection
4309 * there's no need to send a break again.
4313 if (!NT_STATUS_IS_OK(status)) {
4314 smbd_server_disconnect_client(client, nt_errstr(status));
4321 DLIST_REMOVE(client->pending_breaks, pb);
4324 status = smbXsrv_client_pending_breaks_updated(client);
4325 if (!NT_STATUS_IS_OK(status)) {
4326 smbd_server_disconnect_client(client, nt_errstr(status));
4331 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_client *client,
4332 struct smbXsrv_open *op,
4333 uint8_t oplock_level)
4335 struct smbXsrv_pending_break *pb = NULL;
4336 uint8_t *body = NULL;
4338 pb = smbXsrv_pending_break_create(client,
4341 return NT_STATUS_NO_MEMORY;
4343 pb->body_len = sizeof(pb->body.oplock);
4344 body = pb->body.oplock;
4346 SSVAL(body, 0x00, pb->body_len);
4347 SCVAL(body, 0x02, oplock_level);
4348 SCVAL(body, 0x03, 0); /* reserved */
4349 SIVAL(body, 0x04, 0); /* reserved */
4350 SBVAL(body, 0x08, op->global->open_persistent_id);
4351 SBVAL(body, 0x10, op->global->open_volatile_id);
4353 return smbXsrv_pending_break_schedule(pb);
4356 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_client *client,
4358 uint32_t lease_flags,
4359 struct smb2_lease_key *lease_key,
4360 uint32_t current_lease_state,
4361 uint32_t new_lease_state)
4363 struct smbXsrv_pending_break *pb = NULL;
4364 uint8_t *body = NULL;
4366 pb = smbXsrv_pending_break_create(client,
4367 0); /* no session_id */
4369 return NT_STATUS_NO_MEMORY;
4371 pb->body_len = sizeof(pb->body.lease);
4372 body = pb->body.lease;
4374 SSVAL(body, 0x00, pb->body_len);
4375 SSVAL(body, 0x02, new_epoch);
4376 SIVAL(body, 0x04, lease_flags);
4377 SBVAL(body, 0x08, lease_key->data[0]);
4378 SBVAL(body, 0x10, lease_key->data[1]);
4379 SIVAL(body, 0x18, current_lease_state);
4380 SIVAL(body, 0x1c, new_lease_state);
4381 SIVAL(body, 0x20, 0); /* BreakReason, MUST be 0 */
4382 SIVAL(body, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4383 SIVAL(body, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4385 return smbXsrv_pending_break_schedule(pb);
4388 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
4392 uint64_t file_id_persistent;
4393 uint64_t file_id_volatile;
4394 struct smbXsrv_open *op = NULL;
4395 struct files_struct *fsp = NULL;
4396 const uint8_t *body = NULL;
4399 * This is only called with a pktbuf
4400 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4404 if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
4405 /* Transform header. Cannot recvfile. */
4408 if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
4409 /* Not SMB2. Normal error path will cope. */
4412 if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
4413 /* Not SMB2. Normal error path will cope. */
4416 if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
4417 /* Needs to be a WRITE. */
4420 if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
4421 /* Chained. Cannot recvfile. */
4424 flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
4425 if (flags & SMB2_HDR_FLAG_CHAINED) {
4426 /* Chained. Cannot recvfile. */
4429 if (flags & SMB2_HDR_FLAG_SIGNED) {
4430 /* Signed. Cannot recvfile. */
4434 body = &state->pktbuf[SMB2_HDR_BODY];
4436 file_id_persistent = BVAL(body, 0x10);
4437 file_id_volatile = BVAL(body, 0x18);
4439 status = smb2srv_open_lookup(state->req->xconn,
4444 if (!NT_STATUS_IS_OK(status)) {
4452 if (fsp->conn == NULL) {
4456 if (IS_IPC(fsp->conn)) {
4459 if (IS_PRINT(fsp->conn)) {
4462 if (fsp->base_fsp != NULL) {
4466 DEBUG(10,("Doing recvfile write len = %u\n",
4467 (unsigned int)(state->pktfull - state->pktlen)));
4472 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
4474 struct smbd_server_connection *sconn = xconn->client->sconn;
4475 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4476 size_t max_send_queue_len;
4477 size_t cur_send_queue_len;
4479 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4481 * we're not supposed to do any io
4483 return NT_STATUS_OK;
4486 if (state->req != NULL) {
4488 * if there is already a tstream_readv_pdu
4489 * pending, we are done.
4491 return NT_STATUS_OK;
4494 max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
4495 cur_send_queue_len = xconn->smb2.send_queue_len;
4497 if (cur_send_queue_len > max_send_queue_len) {
4499 * if we have a lot of requests to send,
4500 * we wait until they are on the wire until we
4501 * ask for the next request.
4503 return NT_STATUS_OK;
4506 /* ask for the next request */
4507 ZERO_STRUCTP(state);
4508 state->req = smbd_smb2_request_allocate(xconn);
4509 if (state->req == NULL) {
4510 return NT_STATUS_NO_MEMORY;
4512 state->req->sconn = sconn;
4513 state->req->xconn = xconn;
4514 state->min_recv_size = lp_min_receive_file_size();
4516 TEVENT_FD_READABLE(xconn->transport.fde);
4518 return NT_STATUS_OK;
4521 NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
4522 uint64_t expected_seq_low,
4523 const uint8_t *inpdu, size_t size)
4525 struct smbd_server_connection *sconn = xconn->client->sconn;
4527 struct smbd_smb2_request *req = NULL;
4529 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4530 (unsigned int)size));
4532 status = smbd_initialize_smb2(xconn, expected_seq_low);
4533 if (!NT_STATUS_IS_OK(status)) {
4534 smbd_server_connection_terminate(xconn, nt_errstr(status));
4539 * If a new connection joins the process, when we're
4540 * already in a "pending break cycle", we need to
4541 * turn on the ack checker on the new connection.
4543 status = smbXsrv_client_pending_breaks_updated(xconn->client);
4544 if (!NT_STATUS_IS_OK(status)) {
4546 * If there's a problem, we disconnect the whole
4547 * client with all connections here!
4549 * Instead of just the new connection.
4551 smbd_server_disconnect_client(xconn->client, nt_errstr(status));
4555 status = smbd_smb2_request_create(xconn, inpdu, size, &req);
4556 if (!NT_STATUS_IS_OK(status)) {
4557 smbd_server_connection_terminate(xconn, nt_errstr(status));
4561 status = smbd_smb2_request_validate(req);
4562 if (!NT_STATUS_IS_OK(status)) {
4563 smbd_server_connection_terminate(xconn, nt_errstr(status));
4567 status = smbd_smb2_request_setup_out(req);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 smbd_server_connection_terminate(xconn, nt_errstr(status));
4575 * this was already counted at the SMB1 layer =>
4576 * smbd_smb2_request_dispatch() should not count it twice.
4578 if (profile_p->values.request_stats.count > 0) {
4579 profile_p->values.request_stats.count--;
4582 status = smbd_smb2_request_dispatch(req);
4583 if (!NT_STATUS_IS_OK(status)) {
4584 smbd_server_connection_terminate(xconn, nt_errstr(status));
4588 status = smbd_smb2_request_next_incoming(xconn);
4589 if (!NT_STATUS_IS_OK(status)) {
4590 smbd_server_connection_terminate(xconn, nt_errstr(status));
4594 sconn->num_requests++;
4595 return NT_STATUS_OK;
4598 static int socket_error_from_errno(int ret,
4612 if (sys_errno == 0) {
4616 if (sys_errno == EINTR) {
4621 if (sys_errno == EINPROGRESS) {
4626 if (sys_errno == EAGAIN) {
4631 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4632 if (sys_errno == ENOMEM) {
4638 #if EWOULDBLOCK != EAGAIN
4639 if (sys_errno == EWOULDBLOCK) {
4649 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
4656 if (xconn->smb2.send_queue == NULL) {
4657 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4658 return NT_STATUS_OK;
4661 while (xconn->smb2.send_queue != NULL) {
4662 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
4666 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4668 * we're not supposed to do any io
4669 * just flush all pending stuff.
4671 xconn->smb2.send_queue_len--;
4672 DLIST_REMOVE(xconn->smb2.send_queue, e);
4674 talloc_free(e->mem_ctx);
4678 if (e->sendfile_header != NULL) {
4683 status = NT_STATUS_INTERNAL_ERROR;
4685 for (i=0; i < e->count; i++) {
4686 size += e->vector[i].iov_len;
4689 if (size <= e->sendfile_header->length) {
4690 buf = e->sendfile_header->data;
4692 buf = talloc_array(e->mem_ctx, uint8_t, size);
4694 return NT_STATUS_NO_MEMORY;
4699 for (i=0; i < e->count; i++) {
4701 e->vector[i].iov_base,
4702 e->vector[i].iov_len);
4703 size += e->vector[i].iov_len;
4706 e->sendfile_header->data = buf;
4707 e->sendfile_header->length = size;
4708 e->sendfile_status = &status;
4711 xconn->smb2.send_queue_len--;
4712 DLIST_REMOVE(xconn->smb2.send_queue, e);
4714 size += e->sendfile_body_size;
4717 * This triggers the sendfile path via
4720 talloc_free(e->mem_ctx);
4722 if (!NT_STATUS_IS_OK(status)) {
4723 smbXsrv_connection_disconnect_transport(xconn,
4727 xconn->ack.unacked_bytes += size;
4731 msg = (struct msghdr) {
4732 .msg_iov = e->vector,
4733 .msg_iovlen = e->count,
4736 ret = sendmsg(xconn->transport.sock, &msg, 0);
4738 /* propagate end of file */
4739 return NT_STATUS_INTERNAL_ERROR;
4741 err = socket_error_from_errno(ret, errno, &retry);
4744 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4745 return NT_STATUS_OK;
4748 status = map_nt_error_from_unix_common(err);
4749 smbXsrv_connection_disconnect_transport(xconn,
4754 xconn->ack.unacked_bytes += ret;
4756 ok = iov_advance(&e->vector, &e->count, ret);
4758 return NT_STATUS_INTERNAL_ERROR;
4762 /* we have more to write */
4763 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4764 return NT_STATUS_OK;
4767 xconn->smb2.send_queue_len--;
4768 DLIST_REMOVE(xconn->smb2.send_queue, e);
4770 if (e->ack.req == NULL) {
4771 talloc_free(e->mem_ctx);
4775 e->ack.required_acked_bytes = xconn->ack.unacked_bytes;
4776 DLIST_ADD_END(xconn->ack.queue, e);
4780 * Restart reads if we were blocked on
4781 * draining the send queue.
4784 status = smbd_smb2_request_next_incoming(xconn);
4785 if (!NT_STATUS_IS_OK(status)) {
4789 return NT_STATUS_OK;
4792 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
4795 struct smbd_server_connection *sconn = xconn->client->sconn;
4796 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4797 struct smbd_smb2_request *req = NULL;
4798 size_t min_recvfile_size = UINT32_MAX;
4806 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4808 * we're not supposed to do any io
4810 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4811 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4812 return NT_STATUS_OK;
4815 if (fde_flags & TEVENT_FD_WRITE) {
4816 status = smbd_smb2_flush_send_queue(xconn);
4817 if (!NT_STATUS_IS_OK(status)) {
4822 if (!(fde_flags & TEVENT_FD_READ)) {
4823 return NT_STATUS_OK;
4826 if (state->req == NULL) {
4827 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4828 return NT_STATUS_OK;
4832 if (!state->hdr.done) {
4833 state->hdr.done = true;
4835 state->vector.iov_base = (void *)state->hdr.nbt;
4836 state->vector.iov_len = NBT_HDR_SIZE;
4839 msg = (struct msghdr) {
4840 .msg_iov = &state->vector,
4844 ret = recvmsg(xconn->transport.sock, &msg, 0);
4846 /* propagate end of file */
4847 status = NT_STATUS_END_OF_FILE;
4848 smbXsrv_connection_disconnect_transport(xconn,
4852 err = socket_error_from_errno(ret, errno, &retry);
4855 TEVENT_FD_READABLE(xconn->transport.fde);
4856 return NT_STATUS_OK;
4859 status = map_nt_error_from_unix_common(err);
4860 smbXsrv_connection_disconnect_transport(xconn,
4865 if (ret < state->vector.iov_len) {
4867 base = (uint8_t *)state->vector.iov_base;
4869 state->vector.iov_base = (void *)base;
4870 state->vector.iov_len -= ret;
4871 /* we have more to read */
4872 TEVENT_FD_READABLE(xconn->transport.fde);
4873 return NT_STATUS_OK;
4876 if (state->pktlen > 0) {
4877 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
4879 * Not a possible receivefile write.
4880 * Read the rest of the data.
4882 state->doing_receivefile = false;
4884 state->pktbuf = talloc_realloc(state->req,
4888 if (state->pktbuf == NULL) {
4889 return NT_STATUS_NO_MEMORY;
4892 state->vector.iov_base = (void *)(state->pktbuf +
4894 state->vector.iov_len = (state->pktfull -
4897 state->pktlen = state->pktfull;
4902 * Either this is a receivefile write so we've
4903 * done a short read, or if not we have all the data.
4909 * Now we analyze the NBT header
4911 if (state->hdr.nbt[0] != 0x00) {
4912 state->min_recv_size = 0;
4914 state->pktfull = smb2_len(state->hdr.nbt);
4915 if (state->pktfull == 0) {
4919 if (state->min_recv_size != 0) {
4920 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4921 min_recvfile_size += state->min_recv_size;
4924 if (state->pktfull > min_recvfile_size) {
4926 * Might be a receivefile write. Read the SMB2 HEADER +
4927 * SMB2_WRITE header first. Set 'doing_receivefile'
4928 * as we're *attempting* receivefile write. If this
4929 * turns out not to be a SMB2_WRITE request or otherwise
4930 * not suitable then we'll just read the rest of the data
4931 * the next time this function is called.
4933 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4934 state->doing_receivefile = true;
4936 state->pktlen = state->pktfull;
4939 state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
4940 if (state->pktbuf == NULL) {
4941 return NT_STATUS_NO_MEMORY;
4944 state->vector.iov_base = (void *)state->pktbuf;
4945 state->vector.iov_len = state->pktlen;
4951 if (state->hdr.nbt[0] != 0x00) {
4952 DEBUG(1,("ignore NBT[0x%02X] msg\n",
4953 state->hdr.nbt[0]));
4956 ZERO_STRUCTP(state);
4958 state->min_recv_size = lp_min_receive_file_size();
4966 req->request_time = timeval_current();
4967 now = timeval_to_nttime(&req->request_time);
4969 status = smbd_smb2_inbuf_parse_compound(xconn,
4975 &req->in.vector_count);
4976 if (!NT_STATUS_IS_OK(status)) {
4980 if (state->doing_receivefile) {
4981 req->smb1req = talloc_zero(req, struct smb_request);
4982 if (req->smb1req == NULL) {
4983 return NT_STATUS_NO_MEMORY;
4985 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
4988 ZERO_STRUCTP(state);
4990 req->current_idx = 1;
4992 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
4993 req->current_idx, req->in.vector_count));
4995 status = smbd_smb2_request_validate(req);
4996 if (!NT_STATUS_IS_OK(status)) {
5000 status = smbd_smb2_request_setup_out(req);
5001 if (!NT_STATUS_IS_OK(status)) {
5005 status = smbd_smb2_request_dispatch(req);
5006 if (!NT_STATUS_IS_OK(status)) {
5010 sconn->num_requests++;
5012 /* The timeout_processing function isn't run nearly
5013 often enough to implement 'max log size' without
5014 overrunning the size of the file by many megabytes.
5015 This is especially true if we are running at debug
5016 level 10. Checking every 50 SMB2s is a nice
5017 tradeoff of performance vs log file size overrun. */
5019 if ((sconn->num_requests % 50) == 0 &&
5020 need_to_check_log_size()) {
5021 change_to_root_user();
5025 status = smbd_smb2_request_next_incoming(xconn);
5026 if (!NT_STATUS_IS_OK(status)) {
5030 return NT_STATUS_OK;
5033 static void smbd_smb2_connection_handler(struct tevent_context *ev,
5034 struct tevent_fd *fde,
5038 struct smbXsrv_connection *xconn =
5039 talloc_get_type_abort(private_data,
5040 struct smbXsrv_connection);
5043 status = smbd_smb2_io_handler(xconn, flags);
5044 if (!NT_STATUS_IS_OK(status)) {
5045 smbd_server_connection_terminate(xconn, nt_errstr(status));