2 Unix SMB/CIFS implementation.
5 Copyright (C) Stefan Metzmacher 2009
6 Copyright (C) Jeremy Allison 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/network.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "smbd/smbXsrv_open.h"
27 #include "lib/param/param.h"
28 #include "../libcli/smb/smb_common.h"
29 #include "../lib/tsocket/tsocket.h"
30 #include "../lib/util/tevent_ntstatus.h"
31 #include "smbprofile.h"
32 #include "../lib/util/bitmap.h"
33 #include "../librpc/gen_ndr/krb5pac.h"
34 #include "lib/util/iov_buf.h"
36 #include "libcli/smb/smbXcli_base.h"
37 #include "source3/lib/substitute.h"
40 /* SIOCOUTQ TIOCOUTQ are the same */
41 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
42 #define __HAVE_TCP_INFO_RTO 1
43 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
44 #elif defined(FREEBSD)
45 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
46 #define __HAVE_TCP_INFO_RTO 1
47 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
50 #include "lib/crypto/gnutls_helpers.h"
51 #include <gnutls/gnutls.h>
52 #include <gnutls/crypto.h>
55 #define DBGC_CLASS DBGC_SMB2
57 static void smbd_smb2_connection_handler(struct tevent_context *ev,
58 struct tevent_fd *fde,
61 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
63 static const struct smbd_smb2_dispatch_table {
71 } smbd_smb2_table[] = {
72 #define _OP(o) .opcode = o, .name = #o
77 _OP(SMB2_OP_SESSSETUP),
87 * This call needs to be run as root.
89 * smbd_smb2_request_process_tcon()
90 * calls make_connection_snum(), which will call
91 * change_to_user(), when needed.
101 .need_session = true,
105 .need_session = true,
110 .need_session = true,
115 .need_session = true,
120 .need_session = true,
126 .need_session = true,
131 .need_session = 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));
2276 * The STATUS_PENDING response has SMB2_HDR_FLAG_SIGNED
2277 * clearedm, but echoes the signature field.
2279 flags &= ~SMB2_HDR_FLAG_SIGNED;
2280 SIVAL(hdr, SMB2_HDR_FLAGS, flags);
2281 SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
2282 SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
2283 SBVAL(hdr, SMB2_HDR_PID, async_id);
2284 SBVAL(hdr, SMB2_HDR_SESSION_ID,
2285 BVAL(outhdr, SMB2_HDR_SESSION_ID));
2286 memcpy(hdr+SMB2_HDR_SIGNATURE,
2287 outhdr+SMB2_HDR_SIGNATURE, 16);
2289 SSVAL(body, 0x00, 0x08 + 1);
2291 SCVAL(body, 0x02, 0);
2292 SCVAL(body, 0x03, 0);
2293 SIVAL(body, 0x04, 0);
2294 /* Match W2K8R2... */
2295 SCVAL(dyn, 0x00, 0x21);
2297 state->vector[0].iov_base = (void *)state->buf;
2298 state->vector[0].iov_len = NBT_HDR_SIZE;
2300 if (req->do_encryption) {
2301 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
2302 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len =
2305 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
2306 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
2309 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
2310 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
2312 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
2313 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
2315 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
2316 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len = 1;
2318 ok = smb2_setup_nbt_length(state->vector,
2319 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2321 smbd_server_connection_terminate(
2322 xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
2326 /* Ensure we correctly go through crediting. Grant
2327 the credits now, and zero credits on the final
2329 smb2_set_operation_credit(req->xconn,
2330 SMBD_SMB2_IN_HDR_IOV(req),
2331 &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
2334 * We add SMB2_HDR_FLAG_ASYNC after smb2_set_operation_credit()
2335 * as it reacts on it
2337 SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2342 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
2343 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2345 (unsigned int)ARRAY_SIZE(state->vector),
2346 (unsigned int)state->vector[i].iov_len);
2350 if (req->do_encryption) {
2351 struct smbXsrv_session *x = req->session;
2352 struct smb2_signing_key *encryption_key = x->global->encryption_key;
2354 status = smb2_signing_encrypt_pdu(encryption_key,
2355 &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2356 SMBD_SMB2_NUM_IOV_PER_REQ);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 smbd_server_connection_terminate(xconn,
2364 state->queue_entry.mem_ctx = state;
2365 state->queue_entry.vector = state->vector;
2366 state->queue_entry.count = ARRAY_SIZE(state->vector);
2367 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
2368 xconn->smb2.send_queue_len++;
2370 status = smbd_smb2_flush_send_queue(xconn);
2371 if (!NT_STATUS_IS_OK(status)) {
2372 smbd_server_connection_terminate(xconn,
2378 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
2380 struct smbXsrv_connection *xconn = req->xconn;
2381 struct smbd_smb2_request *cur;
2382 const uint8_t *inhdr;
2384 uint64_t search_message_id;
2385 uint64_t search_async_id;
2388 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2390 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2391 search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2392 search_async_id = BVAL(inhdr, SMB2_HDR_PID);
2395 * We don't need the request anymore cancel requests never
2398 * We defer the TALLOC_FREE(req) to the caller.
2400 DLIST_REMOVE(xconn->smb2.requests, req);
2402 for (cur = xconn->smb2.requests; cur; cur = cur->next) {
2403 const uint8_t *outhdr;
2404 uint64_t message_id;
2407 if (cur->session != req->session) {
2411 if (cur->compound_related) {
2413 * Never cancel anything in a compound request.
2414 * Way too hard to deal with the result.
2419 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
2421 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2422 async_id = BVAL(outhdr, SMB2_HDR_PID);
2424 if (flags & SMB2_HDR_FLAG_ASYNC) {
2425 if (search_async_id == async_id) {
2426 found_id = async_id;
2430 if (search_message_id == message_id) {
2431 found_id = message_id;
2437 if (cur && cur->subreq) {
2438 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
2439 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2440 "cancel opcode[%s] mid %llu\n",
2441 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2442 (unsigned long long)found_id ));
2443 tevent_req_cancel(cur->subreq);
2446 return NT_STATUS_OK;
2449 /*************************************************************
2450 Ensure an incoming tid is a valid one for us to access.
2451 Change to the associated uid credentials and chdir to the
2452 valid tid directory.
2453 *************************************************************/
2455 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
2457 const uint8_t *inhdr;
2460 struct smbXsrv_tcon *tcon;
2462 NTTIME now = timeval_to_nttime(&req->request_time);
2466 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2468 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2469 in_tid = IVAL(inhdr, SMB2_HDR_TID);
2471 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2472 in_tid = req->last_tid;
2477 status = smb2srv_tcon_lookup(req->session,
2478 in_tid, now, &tcon);
2479 if (!NT_STATUS_IS_OK(status)) {
2483 if (!change_to_user_and_service(
2485 req->session->global->session_wire_id))
2487 return NT_STATUS_ACCESS_DENIED;
2491 req->last_tid = in_tid;
2493 return NT_STATUS_OK;
2496 /*************************************************************
2497 Ensure an incoming session_id is a valid one for us to access.
2498 *************************************************************/
2500 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
2502 const uint8_t *inhdr;
2505 uint64_t in_session_id;
2506 struct smbXsrv_session *session = NULL;
2507 struct auth_session_info *session_info;
2509 NTTIME now = timeval_to_nttime(&req->request_time);
2511 req->session = NULL;
2514 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2516 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2517 in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2518 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
2520 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2521 in_session_id = req->last_session_id;
2524 req->last_session_id = 0;
2526 /* look an existing session up */
2527 switch (in_opcode) {
2528 case SMB2_OP_SESSSETUP:
2530 * For a session bind request, we don't have the
2531 * channel set up at this point yet, so we defer
2532 * the verification that the connection belongs
2533 * to the session to the session setup code, which
2534 * can look at the session binding flags.
2536 status = smb2srv_session_lookup_client(req->xconn->client,
2541 status = smb2srv_session_lookup_conn(req->xconn,
2547 req->session = session;
2548 req->last_session_id = in_session_id;
2550 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
2551 switch (in_opcode) {
2552 case SMB2_OP_SESSSETUP:
2553 status = smb2srv_session_lookup_global(req->xconn->client,
2557 if (NT_STATUS_IS_OK(status)) {
2559 * We fallback to a session of
2560 * another process in order to
2561 * get the signing correct.
2563 * We don't set req->last_session_id here.
2565 req->session = session;
2572 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
2573 switch (in_opcode) {
2574 case SMB2_OP_SESSSETUP:
2575 status = NT_STATUS_OK;
2577 case SMB2_OP_LOGOFF:
2580 case SMB2_OP_CANCEL:
2581 case SMB2_OP_KEEPALIVE:
2583 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2584 * specifies that LOGOFF, CLOSE and (UN)LOCK
2585 * should always be processed even on expired sessions.
2587 * Also see the logic in
2588 * smbd_smb2_request_process_lock().
2590 * The smb2.session.expire2 test shows that
2591 * CANCEL and KEEPALIVE/ECHO should also
2594 status = NT_STATUS_OK;
2600 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2601 switch (in_opcode) {
2603 case SMB2_OP_CREATE:
2604 case SMB2_OP_GETINFO:
2605 case SMB2_OP_SETINFO:
2606 return NT_STATUS_INVALID_HANDLE;
2609 * Notice the check for
2610 * (session_info == NULL)
2613 status = NT_STATUS_OK;
2617 if (!NT_STATUS_IS_OK(status)) {
2621 session_info = session->global->auth_session_info;
2622 if (session_info == NULL) {
2623 return NT_STATUS_INVALID_HANDLE;
2626 return NT_STATUS_OK;
2629 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
2630 uint32_t data_length)
2632 struct smbXsrv_connection *xconn = req->xconn;
2633 uint16_t needed_charge;
2634 uint16_t credit_charge = 1;
2635 const uint8_t *inhdr;
2637 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2639 if (xconn->smb2.credits.multicredit) {
2640 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
2641 credit_charge = MAX(credit_charge, 1);
2644 needed_charge = (data_length - 1)/ 65536 + 1;
2646 DBGC_DEBUG(DBGC_SMB2_CREDITS,
2647 "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2648 (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
2649 credit_charge, needed_charge);
2651 if (needed_charge > credit_charge) {
2652 DBGC_WARNING(DBGC_SMB2_CREDITS,
2653 "CreditCharge too low, given %d, needed %d\n",
2654 credit_charge, needed_charge);
2655 return NT_STATUS_INVALID_PARAMETER;
2658 return NT_STATUS_OK;
2661 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
2662 size_t expected_body_size)
2664 struct iovec *inhdr_v;
2665 const uint8_t *inhdr;
2667 const uint8_t *inbody;
2669 size_t min_dyn_size = expected_body_size & 0x00000001;
2670 int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2673 * The following should be checked already.
2675 if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2676 return NT_STATUS_INTERNAL_ERROR;
2678 if (req->current_idx > max_idx) {
2679 return NT_STATUS_INTERNAL_ERROR;
2682 inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2683 if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2684 return NT_STATUS_INTERNAL_ERROR;
2686 if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2687 return NT_STATUS_INTERNAL_ERROR;
2690 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2691 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2695 case SMB2_OP_GETINFO:
2702 * Now check the expected body size,
2703 * where the last byte might be in the
2706 if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2707 return NT_STATUS_INVALID_PARAMETER;
2709 if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2710 return NT_STATUS_INVALID_PARAMETER;
2713 inbody = SMBD_SMB2_IN_BODY_PTR(req);
2715 body_size = SVAL(inbody, 0x00);
2716 if (body_size != expected_body_size) {
2717 return NT_STATUS_INVALID_PARAMETER;
2720 return NT_STATUS_OK;
2723 bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2725 return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2727 (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2728 SMBXSRV_ENCRYPTION_DESIRED |
2729 SMBXSRV_ENCRYPTION_REQUIRED)));
2732 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2734 return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2735 (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2738 /* Set a flag if not already set, return true if set */
2739 bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2741 if ((flag == 0) || (*flags & flag)) {
2750 * Update encryption state tracking flags, this can be used to
2751 * determine whether whether the session or tcon is "encrypted".
2753 static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2755 bool *update_session_globalp,
2756 bool *update_tcon_globalp)
2758 /* Default: assume unecrypted and unsigned */
2759 struct smbXsrv_session *session = req->session;
2760 struct smbXsrv_tcon *tcon = req->tcon;
2761 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2762 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2763 bool update_session = false;
2764 bool update_tcon = false;
2766 if (session->table == NULL) {
2768 * sessions from smb2srv_session_lookup_global()
2769 * have NT_STATUS_BAD_LOGON_SESSION_STATE
2770 * and session->table == NULL.
2772 * They only used to give the correct error
2773 * status, we should not update any state.
2778 if (req->was_encrypted && req->do_encryption) {
2779 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2780 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2782 /* Unencrypted packet, can be signed */
2783 if (req->do_signing) {
2784 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2788 update_session |= smbXsrv_set_crypto_flag(
2789 &session->global->encryption_flags, encrypt_flag);
2790 update_session |= smbXsrv_set_crypto_flag(
2791 &session->global->signing_flags, sign_flag);
2794 update_tcon |= smbXsrv_set_crypto_flag(
2795 &tcon->global->encryption_flags, encrypt_flag);
2796 update_tcon |= smbXsrv_set_crypto_flag(
2797 &tcon->global->signing_flags, sign_flag);
2801 *update_session_globalp = update_session;
2802 *update_tcon_globalp = update_tcon;
2806 bool smbXsrv_is_signed(uint8_t signing_flags)
2809 * Signing is always enabled, so unless we got an unsigned
2810 * packet and at least one signed packet that was not
2811 * encrypted, the session or tcon is "signed".
2813 return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2814 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2817 bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2819 return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2820 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2823 static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2824 struct smbd_smb2_request *req,
2827 struct smbXsrv_connection *xconn = req->xconn;
2828 const uint8_t *inhdr;
2829 uint16_t channel_sequence;
2830 uint8_t generation_wrap = 0;
2833 struct smbXsrv_open *op;
2834 bool update_open = false;
2835 NTSTATUS status = NT_STATUS_OK;
2837 SMB_ASSERT(!req->request_counters_updated);
2839 if (xconn->protocol < PROTOCOL_SMB3_00) {
2840 return NT_STATUS_OK;
2843 if (req->compat_chain_fsp == NULL) {
2844 return NT_STATUS_OK;
2847 op = req->compat_chain_fsp->op;
2849 return NT_STATUS_OK;
2852 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2853 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2854 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2856 cmp = channel_sequence - op->global->channel_sequence;
2859 * csn wrap. We need to watch out for long-running
2860 * requests that are still sitting on a previously
2861 * used csn. SMB2_OP_NOTIFY can take VERY long.
2863 generation_wrap += 1;
2866 if (abs(cmp) > INT16_MAX) {
2868 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2870 * If the channel sequence number of the request and the one
2871 * known to the server are not equal, the channel sequence
2872 * number and outstanding request counts are only updated
2873 * "... if the unsigned difference using 16-bit arithmetic
2874 * between ChannelSequence and Open.ChannelSequence is less than
2875 * or equal to 0x7FFF ...".
2876 * Otherwise, an error is returned for the modifying
2877 * calls write, set_info, and ioctl.
2879 * There are currently two issues with the description:
2881 * * For the other calls, the document seems to imply
2882 * that processing continues without adapting the
2883 * counters (if the sequence numbers are not equal).
2885 * TODO: This needs clarification!
2887 * * Also, the behaviour if the difference is larger
2888 * than 0x7FFF is not clear. The document seems to
2889 * imply that if such a difference is reached,
2890 * the server starts to ignore the counters or
2891 * in the case of the modifying calls, return errors.
2893 * TODO: This needs clarification!
2895 * At this point Samba tries to be a little more
2896 * clever than the description in the MS-SMB2 document
2897 * by heuristically detecting and properly treating
2898 * a 16 bit overflow of the client-submitted sequence
2901 * If the stored channel sequence number is more than
2902 * 0x7FFF larger than the one from the request, then
2903 * the client-provided sequence number has likely
2904 * overflown. We treat this case as valid instead
2907 * The MS-SMB2 behaviour would be setting cmp = -1.
2912 if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2913 if (cmp == 0 && op->pre_request_count == 0) {
2914 op->request_count += 1;
2915 req->request_counters_updated = true;
2916 } else if (cmp > 0 && op->pre_request_count == 0) {
2917 op->pre_request_count += op->request_count;
2918 op->request_count = 1;
2919 op->global->channel_sequence = channel_sequence;
2920 op->global->channel_generation += generation_wrap;
2922 req->request_counters_updated = true;
2923 } else if (modify_call) {
2924 return NT_STATUS_FILE_NOT_AVAILABLE;
2928 op->request_count += 1;
2929 req->request_counters_updated = true;
2930 } else if (cmp > 0) {
2931 op->pre_request_count += op->request_count;
2932 op->request_count = 1;
2933 op->global->channel_sequence = channel_sequence;
2934 op->global->channel_generation += generation_wrap;
2936 req->request_counters_updated = true;
2937 } else if (modify_call) {
2938 return NT_STATUS_FILE_NOT_AVAILABLE;
2941 req->channel_generation = op->global->channel_generation;
2944 status = smbXsrv_open_update(op);
2950 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2952 struct smbXsrv_connection *xconn = req->xconn;
2953 const struct smbd_smb2_dispatch_table *call = NULL;
2954 const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2955 const uint8_t *inhdr;
2960 NTSTATUS session_status;
2961 uint32_t allowed_flags;
2962 NTSTATUS return_value;
2963 struct smbXsrv_session *x = NULL;
2964 bool signing_required = false;
2965 bool encryption_desired = false;
2966 bool encryption_required = false;
2968 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2970 DO_PROFILE_INC(request);
2972 SMB_ASSERT(!req->request_counters_updated);
2974 /* TODO: verify more things */
2976 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2977 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2978 mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2979 DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2980 smb2_opcode_name(opcode),
2981 (unsigned long long)mid));
2983 if (xconn->protocol >= PROTOCOL_SMB2_02) {
2985 * once the protocol is negotiated
2986 * SMB2_OP_NEGPROT is not allowed anymore
2988 if (opcode == SMB2_OP_NEGPROT) {
2989 /* drop the connection */
2990 return NT_STATUS_INVALID_PARAMETER;
2994 * if the protocol is not negotiated yet
2995 * only SMB2_OP_NEGPROT is allowed.
2997 if (opcode != SMB2_OP_NEGPROT) {
2998 /* drop the connection */
2999 return NT_STATUS_INVALID_PARAMETER;
3004 * Check if the client provided a valid session id.
3006 * As some command don't require a valid session id
3007 * we defer the check of the session_status
3009 session_status = smbd_smb2_request_check_session(req);
3012 signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
3013 encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3014 encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
3017 req->async_internal = false;
3018 req->do_signing = false;
3019 if (opcode != SMB2_OP_SESSSETUP) {
3020 req->do_encryption = encryption_desired;
3022 req->do_encryption = false;
3024 req->was_encrypted = false;
3025 if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
3026 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
3027 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
3029 if (x != NULL && x->global->session_wire_id != tf_session_id) {
3030 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
3031 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
3032 (unsigned long long)x->global->session_wire_id,
3033 (unsigned long long)tf_session_id));
3035 * TODO: windows allows this...
3036 * should we drop the connection?
3038 * For now we just return ACCESS_DENIED
3039 * (Windows clients never trigger this)
3040 * and wait for an update of [MS-SMB2].
3042 return smbd_smb2_request_error(req,
3043 NT_STATUS_ACCESS_DENIED);
3046 req->was_encrypted = true;
3047 req->do_encryption = true;
3050 if (encryption_required && !req->was_encrypted) {
3051 req->do_encryption = true;
3052 return smbd_smb2_request_error(req,
3053 NT_STATUS_ACCESS_DENIED);
3056 call = smbd_smb2_call(opcode);
3058 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3061 allowed_flags = SMB2_HDR_FLAG_CHAINED |
3062 SMB2_HDR_FLAG_SIGNED |
3064 if (xconn->protocol >= PROTOCOL_SMB3_11) {
3065 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3067 if (opcode == SMB2_OP_NEGPROT) {
3068 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
3069 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3072 if (opcode == SMB2_OP_CANCEL) {
3073 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
3075 if (xconn->protocol >= PROTOCOL_SMB3_00) {
3076 allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3078 if ((flags & ~allowed_flags) != 0) {
3079 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3082 if (flags & SMB2_HDR_FLAG_CHAINED) {
3084 * This check is mostly for giving the correct error code
3085 * for compounded requests.
3087 if (!NT_STATUS_IS_OK(session_status)) {
3088 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3091 req->compat_chain_fsp = NULL;
3094 if (req->was_encrypted) {
3095 signing_required = false;
3096 } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
3097 struct smb2_signing_key *signing_key = NULL;
3098 bool has_channel = false;
3102 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3103 * If the SMB2 header of the SMB2 NEGOTIATE
3104 * request has the SMB2_FLAGS_SIGNED bit set in the
3105 * Flags field, the server MUST fail the request
3106 * with STATUS_INVALID_PARAMETER.
3108 * Microsoft test tool checks this.
3111 if ((opcode == SMB2_OP_NEGPROT) &&
3112 (flags & SMB2_HDR_FLAG_SIGNED)) {
3113 status = NT_STATUS_INVALID_PARAMETER;
3115 status = NT_STATUS_USER_SESSION_DELETED;
3117 return smbd_smb2_request_error(req, status);
3120 signing_key = smbd_smb2_signing_key(x, xconn, &has_channel);
3123 * If we have a signing key, we should
3126 if (smb2_signing_key_valid(signing_key) && opcode != SMB2_OP_CANCEL) {
3127 req->do_signing = true;
3130 status = smb2_signing_check_pdu(signing_key,
3131 SMBD_SMB2_IN_HDR_IOV(req),
3132 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3133 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
3134 opcode == SMB2_OP_SESSSETUP && !has_channel &&
3135 NT_STATUS_IS_OK(session_status))
3137 if (!NT_STATUS_EQUAL(x->status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
3138 struct smbXsrv_session *session = NULL;
3141 error = smb2srv_session_lookup_global(req->xconn->client,
3142 x->global->session_wire_id,
3145 if (!NT_STATUS_IS_OK(error)) {
3146 return smbd_smb2_request_error(req, error);
3150 * We fallback to a session of
3151 * another process in order to
3152 * get the signing correct.
3154 * We don't set req->last_session_id here.
3156 req->session = x = session;
3158 goto skipped_signing;
3160 if (!NT_STATUS_IS_OK(status)) {
3161 return smbd_smb2_request_error(req, status);
3165 * Now that we know the request was correctly signed
3166 * we have to sign the response too.
3168 if (opcode != SMB2_OP_CANCEL) {
3169 req->do_signing = true;
3172 if (!NT_STATUS_IS_OK(session_status)) {
3173 return smbd_smb2_request_error(req, session_status);
3177 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;
3212 case FSCTL_VALIDATE_NEGOTIATE_INFO:
3213 call = &_root_ioctl_call;
3220 if (flags & SMB2_HDR_FLAG_CHAINED) {
3221 req->compound_related = true;
3224 if (call->need_session) {
3225 if (!NT_STATUS_IS_OK(session_status)) {
3226 return smbd_smb2_request_error(req, session_status);
3230 if (call->need_tcon) {
3231 SMB_ASSERT(call->need_session);
3234 * This call needs to be run as user.
3236 * smbd_smb2_request_check_tcon()
3237 * calls change_to_user() on success.
3238 * Which implies set_current_user_info()
3239 * and chdir_current_service().
3241 status = smbd_smb2_request_check_tcon(req);
3242 if (!NT_STATUS_IS_OK(status)) {
3243 return smbd_smb2_request_error(req, status);
3245 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3246 encryption_desired = true;
3248 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
3249 encryption_required = true;
3251 if (encryption_required && !req->was_encrypted) {
3252 req->do_encryption = true;
3253 return smbd_smb2_request_error(req,
3254 NT_STATUS_ACCESS_DENIED);
3255 } else if (encryption_desired) {
3256 req->do_encryption = true;
3258 } else if (call->need_session) {
3259 struct auth_session_info *session_info = NULL;
3262 * Unless we also have need_tcon (see above),
3263 * we still need to call set_current_user_info().
3266 session_info = req->session->global->auth_session_info;
3267 if (session_info == NULL) {
3268 return NT_STATUS_INVALID_HANDLE;
3271 set_current_user_info(session_info->unix_info->sanitized_username,
3272 session_info->unix_info->unix_name,
3273 session_info->info->domain_name);
3277 bool update_session_global = false;
3278 bool update_tcon_global = false;
3280 smb2srv_update_crypto_flags(req, opcode,
3281 &update_session_global,
3282 &update_tcon_global);
3284 if (update_session_global) {
3285 status = smbXsrv_session_update(x);
3286 if (!NT_STATUS_IS_OK(status)) {
3287 return smbd_smb2_request_error(req, status);
3290 if (update_tcon_global) {
3291 status = smbXsrv_tcon_update(req->tcon);
3292 if (!NT_STATUS_IS_OK(status)) {
3293 return smbd_smb2_request_error(req, status);
3298 if (call->fileid_ofs != 0) {
3299 size_t needed = call->fileid_ofs + 16;
3300 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3301 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3302 uint64_t file_id_persistent;
3303 uint64_t file_id_volatile;
3304 struct files_struct *fsp;
3306 SMB_ASSERT(call->need_tcon);
3308 if (needed > body_size) {
3309 return smbd_smb2_request_error(req,
3310 NT_STATUS_INVALID_PARAMETER);
3313 file_id_persistent = BVAL(body, call->fileid_ofs + 0);
3314 file_id_volatile = BVAL(body, call->fileid_ofs + 8);
3316 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
3318 if (req->compound_related &&
3319 !NT_STATUS_IS_OK(req->compound_create_err))
3321 return smbd_smb2_request_error(req,
3322 req->compound_create_err);
3325 * smbd_smb2_request_process_ioctl()
3326 * has more checks in order to return more
3327 * detailed error codes...
3329 if (opcode != SMB2_OP_IOCTL) {
3330 return smbd_smb2_request_error(req,
3331 NT_STATUS_FILE_CLOSED);
3334 if (fsp->fsp_flags.encryption_required && !req->was_encrypted) {
3335 return smbd_smb2_request_error(req,
3336 NT_STATUS_ACCESS_DENIED);
3341 status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
3342 if (!NT_STATUS_IS_OK(status)) {
3343 return smbd_smb2_request_error(req, status);
3346 if (call->as_root) {
3347 SMB_ASSERT(call->fileid_ofs == 0);
3348 /* This call needs to be run as root */
3349 change_to_root_user();
3351 SMB_ASSERT(call->need_tcon);
3354 #define _INBYTES(_r) \
3355 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3358 case SMB2_OP_NEGPROT:
3359 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
3360 req->profile, _INBYTES(req));
3361 return_value = smbd_smb2_request_process_negprot(req);
3364 case SMB2_OP_SESSSETUP:
3365 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
3366 req->profile, _INBYTES(req));
3367 return_value = smbd_smb2_request_process_sesssetup(req);
3370 case SMB2_OP_LOGOFF:
3371 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
3372 req->profile, _INBYTES(req));
3373 return_value = smbd_smb2_request_process_logoff(req);
3377 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
3378 req->profile, _INBYTES(req));
3379 return_value = smbd_smb2_request_process_tcon(req);
3383 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
3384 req->profile, _INBYTES(req));
3385 return_value = smbd_smb2_request_process_tdis(req);
3388 case SMB2_OP_CREATE:
3389 if (req->subreq == NULL) {
3390 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
3391 req->profile, _INBYTES(req));
3393 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
3395 return_value = smbd_smb2_request_process_create(req);
3399 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
3400 req->profile, _INBYTES(req));
3401 return_value = smbd_smb2_request_process_close(req);
3405 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
3406 req->profile, _INBYTES(req));
3407 return_value = smbd_smb2_request_process_flush(req);
3411 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
3412 req->profile, _INBYTES(req));
3413 return_value = smbd_smb2_request_process_read(req);
3417 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
3418 req->profile, _INBYTES(req));
3419 return_value = smbd_smb2_request_process_write(req);
3423 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
3424 req->profile, _INBYTES(req));
3425 return_value = smbd_smb2_request_process_lock(req);
3429 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
3430 req->profile, _INBYTES(req));
3431 return_value = smbd_smb2_request_process_ioctl(req);
3434 case SMB2_OP_CANCEL:
3435 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
3436 req->profile, _INBYTES(req));
3437 return_value = smbd_smb2_request_process_cancel(req);
3438 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
3441 * We don't need the request anymore cancel requests never
3444 * smbd_smb2_request_process_cancel() already called
3445 * DLIST_REMOVE(xconn->smb2.requests, req);
3451 case SMB2_OP_KEEPALIVE:
3452 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
3453 req->profile, _INBYTES(req));
3454 return_value = smbd_smb2_request_process_keepalive(req);
3457 case SMB2_OP_QUERY_DIRECTORY:
3458 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
3459 req->profile, _INBYTES(req));
3460 return_value = smbd_smb2_request_process_query_directory(req);
3463 case SMB2_OP_NOTIFY:
3464 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
3465 req->profile, _INBYTES(req));
3466 return_value = smbd_smb2_request_process_notify(req);
3469 case SMB2_OP_GETINFO:
3470 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
3471 req->profile, _INBYTES(req));
3472 return_value = smbd_smb2_request_process_getinfo(req);
3475 case SMB2_OP_SETINFO:
3476 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
3477 req->profile, _INBYTES(req));
3478 return_value = smbd_smb2_request_process_setinfo(req);
3482 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
3483 req->profile, _INBYTES(req));
3484 return_value = smbd_smb2_request_process_break(req);
3488 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3491 return return_value;
3494 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
3496 struct smbXsrv_connection *xconn = req->xconn;
3497 const uint8_t *inhdr;
3498 uint16_t channel_sequence;
3499 struct smbXsrv_open *op;
3501 if (!req->request_counters_updated) {
3505 req->request_counters_updated = false;
3507 if (xconn->protocol < PROTOCOL_SMB3_00) {
3511 if (req->compat_chain_fsp == NULL) {
3515 op = req->compat_chain_fsp->op;
3520 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
3521 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
3523 if ((op->global->channel_sequence == channel_sequence) &&
3524 (op->global->channel_generation == req->channel_generation)) {
3525 SMB_ASSERT(op->request_count > 0);
3526 op->request_count -= 1;
3528 SMB_ASSERT(op->pre_request_count > 0);
3529 op->pre_request_count -= 1;
3533 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
3535 struct smbXsrv_connection *xconn = req->xconn;
3537 struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
3538 struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
3539 struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
3544 TALLOC_FREE(req->async_te);
3546 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3547 smbd_smb2_request_reply_update_counts(req);
3549 if (req->do_encryption &&
3550 (firsttf->iov_len == 0) &&
3551 (!smb2_signing_key_valid(req->first_enc_key)) &&
3552 (req->session != NULL) &&
3553 smb2_signing_key_valid(req->session->global->encryption_key))
3555 struct smb2_signing_key *encryption_key =
3556 req->session->global->encryption_key;
3558 uint64_t session_id = req->session->global->session_wire_id;
3559 uint64_t nonce_high;
3562 status = smb2_get_new_nonce(req->session,
3565 if (!NT_STATUS_IS_OK(status)) {
3570 * We need to place the SMB2_TRANSFORM header before the
3575 * we need to remember the encryption key
3576 * and defer the signing/encryption until
3577 * we are sure that we do not change
3580 status = smb2_signing_key_copy(req,
3582 &req->first_enc_key);
3583 if (!NT_STATUS_IS_OK(status)) {
3587 tf = talloc_zero_array(req, uint8_t,
3590 return NT_STATUS_NO_MEMORY;
3593 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3594 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
3595 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
3596 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
3598 firsttf->iov_base = (void *)tf;
3599 firsttf->iov_len = SMB2_TF_HDR_SIZE;
3602 if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
3603 (smb2_signing_key_valid(req->last_sign_key)) &&
3604 (firsttf->iov_len == 0))
3606 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
3607 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
3610 * As we are sure the header of the last request in the
3611 * compound chain will not change, we can to sign here
3612 * with the last signing key we remembered.
3614 status = smb2_signing_sign_pdu(req->last_sign_key,
3616 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3617 if (!NT_STATUS_IS_OK(status)) {
3621 TALLOC_FREE(req->last_sign_key);
3623 SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
3624 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
3626 req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
3628 if (req->current_idx < req->out.vector_count) {
3630 * We must process the remaining compound
3631 * SMB2 requests before any new incoming SMB2
3632 * requests. This is because incoming SMB2
3633 * requests may include a cancel for a
3634 * compound request we haven't processed
3637 struct tevent_immediate *im = tevent_create_immediate(req);
3639 return NT_STATUS_NO_MEMORY;
3642 if (req->do_signing && firsttf->iov_len == 0) {
3643 struct smbXsrv_session *x = req->session;
3644 struct smb2_signing_key *signing_key =
3645 smbd_smb2_signing_key(x, xconn, NULL);
3648 * we need to remember the signing key
3649 * and defer the signing until
3650 * we are sure that we do not change
3653 status = smb2_signing_key_copy(req,
3655 &req->last_sign_key);
3656 if (!NT_STATUS_IS_OK(status)) {
3662 * smbd_smb2_request_dispatch() will redo the impersonation.
3663 * So we use req->xconn->client->raw_ev_ctx instead
3664 * of req->ev_ctx here.
3666 tevent_schedule_immediate(im,
3667 req->xconn->client->raw_ev_ctx,
3668 smbd_smb2_request_dispatch_immediate,
3670 return NT_STATUS_OK;
3673 if (req->compound_related) {
3674 req->compound_related = false;
3677 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
3679 return NT_STATUS_INVALID_PARAMETER_MIX;
3682 /* Set credit for these operations (zero credits if this
3683 is a final reply for an async operation). */
3684 smb2_calculate_credits(req, req);
3687 * now check if we need to sign the current response
3689 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3690 status = smb2_signing_encrypt_pdu(req->first_enc_key,
3692 req->out.vector_count - first_idx);
3693 if (!NT_STATUS_IS_OK(status)) {
3696 } else if (req->do_signing) {
3697 struct smbXsrv_session *x = req->session;
3698 struct smb2_signing_key *signing_key =
3699 smbd_smb2_signing_key(x, xconn, NULL);
3701 status = smb2_signing_sign_pdu(signing_key,
3703 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3704 if (!NT_STATUS_IS_OK(status)) {
3708 TALLOC_FREE(req->first_enc_key);
3710 if (req->preauth != NULL) {
3711 gnutls_hash_hd_t hash_hnd = NULL;
3715 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3717 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3719 rc = gnutls_hash(hash_hnd,
3720 req->preauth->sha512_value,
3721 sizeof(req->preauth->sha512_value));
3723 gnutls_hash_deinit(hash_hnd, NULL);
3724 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3726 for (i = 1; i < req->in.vector_count; i++) {
3727 rc = gnutls_hash(hash_hnd,
3728 req->in.vector[i].iov_base,
3729 req->in.vector[i].iov_len);
3731 gnutls_hash_deinit(hash_hnd, NULL);
3732 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3736 gnutls_hash_deinit(hash_hnd, NULL);
3737 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3739 gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3741 rc = gnutls_hash(hash_hnd,
3742 req->preauth->sha512_value,
3743 sizeof(req->preauth->sha512_value));
3745 gnutls_hash_deinit(hash_hnd, NULL);
3746 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3748 for (i = 1; i < req->out.vector_count; i++) {
3749 rc = gnutls_hash(hash_hnd,
3750 req->out.vector[i].iov_base,
3751 req->out.vector[i].iov_len);
3753 gnutls_hash_deinit(hash_hnd, NULL);
3754 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3758 gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3760 req->preauth = NULL;
3763 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3764 if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3765 outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3766 /* Dynamic part is NULL. Chop it off,
3767 We're going to send it via sendfile. */
3768 req->out.vector_count -= 1;
3772 * We're done with this request -
3773 * move it off the "being processed" queue.
3775 DLIST_REMOVE(xconn->smb2.requests, req);
3777 req->queue_entry.mem_ctx = req;
3778 req->queue_entry.vector = req->out.vector;
3779 req->queue_entry.count = req->out.vector_count;
3780 DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3781 xconn->smb2.send_queue_len++;
3783 status = smbd_smb2_flush_send_queue(xconn);
3784 if (!NT_STATUS_IS_OK(status)) {
3788 return NT_STATUS_OK;
3791 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3793 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3794 struct tevent_immediate *im,
3797 struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3798 struct smbd_smb2_request);
3799 struct smbXsrv_connection *xconn = req->xconn;
3804 if (DEBUGLEVEL >= 10) {
3805 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3806 req->current_idx, req->in.vector_count));
3807 print_req_vectors(req);
3810 status = smbd_smb2_request_dispatch(req);
3811 if (!NT_STATUS_IS_OK(status)) {
3812 smbd_server_connection_terminate(xconn, nt_errstr(status));
3816 status = smbd_smb2_request_next_incoming(xconn);
3817 if (!NT_STATUS_IS_OK(status)) {
3818 smbd_server_connection_terminate(xconn, nt_errstr(status));
3823 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3825 DATA_BLOB body, DATA_BLOB *dyn,
3826 const char *location)
3829 struct iovec *outbody_v;
3830 struct iovec *outdyn_v;
3831 uint32_t next_command_ofs;
3834 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3835 mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
3837 DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
3838 "body[%u] dyn[%s:%u] at %s\n",
3842 (unsigned int)body.length,
3844 (unsigned int)(dyn ? dyn->length : 0),
3847 if (body.length < 2) {
3848 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3851 if ((body.length % 2) != 0) {
3852 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3855 outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3856 outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3858 next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3859 SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3861 outbody_v->iov_base = (void *)body.data;
3862 outbody_v->iov_len = body.length;
3865 outdyn_v->iov_base = (void *)dyn->data;
3866 outdyn_v->iov_len = dyn->length;
3868 outdyn_v->iov_base = NULL;
3869 outdyn_v->iov_len = 0;
3873 * See if we need to recalculate the offset to the next response
3875 * Note that all responses may require padding (including the very last
3878 if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3879 next_command_ofs = SMB2_HDR_BODY;
3880 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3881 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3884 if ((next_command_ofs % 8) != 0) {
3885 size_t pad_size = 8 - (next_command_ofs % 8);
3886 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3888 * if the dyn buffer is empty
3889 * we can use it to add padding
3893 pad = talloc_zero_array(req,
3896 return smbd_smb2_request_error(req,
3897 NT_STATUS_NO_MEMORY);
3900 outdyn_v->iov_base = (void *)pad;
3901 outdyn_v->iov_len = pad_size;
3904 * For now we copy the dynamic buffer
3905 * and add the padding to the new buffer
3912 old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3913 old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3915 new_size = old_size + pad_size;
3916 new_dyn = talloc_zero_array(req,
3918 if (new_dyn == NULL) {
3919 return smbd_smb2_request_error(req,
3920 NT_STATUS_NO_MEMORY);
3923 memcpy(new_dyn, old_dyn, old_size);
3924 memset(new_dyn + old_size, 0, pad_size);
3926 outdyn_v->iov_base = (void *)new_dyn;
3927 outdyn_v->iov_len = new_size;
3929 next_command_ofs += pad_size;
3932 if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3933 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3935 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3937 return smbd_smb2_request_reply(req);
3940 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3943 const char *location)
3945 struct smbXsrv_connection *xconn = req->xconn;
3948 uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3949 size_t unread_bytes = smbd_smb2_unread_bytes(req);
3951 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3952 "at %s\n", req->current_idx, nt_errstr(status),
3953 info ? " +info" : "", location);
3956 /* Recvfile error. Drain incoming socket. */
3960 ret = drain_socket(xconn->transport.sock, unread_bytes);
3961 if (ret != unread_bytes) {
3965 error = NT_STATUS_IO_DEVICE_ERROR;
3967 error = map_nt_error_from_unix_common(errno);
3970 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3971 "ret[%u] errno[%d] => %s\n",
3972 (unsigned)unread_bytes,
3973 (unsigned)ret, errno, nt_errstr(error)));
3978 body.data = outhdr + SMB2_HDR_BODY;
3980 SSVAL(body.data, 0, 9);
3983 SIVAL(body.data, 0x04, info->length);
3985 /* Allocated size of req->out.vector[i].iov_base
3986 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3987 * 1 byte without having to do an alloc.
3990 info->data = ((uint8_t *)outhdr) +
3991 OUTVEC_ALLOC_SIZE - 1;
3993 SCVAL(info->data, 0, 0);
3997 * Note: Even if there is an error, continue to process the request.
4001 return smbd_smb2_request_done_ex(req, status, body, info, __location__);
4004 struct smbd_smb2_break_state {
4005 struct tevent_req *req;
4006 struct smbd_smb2_send_queue queue_entry;
4007 uint8_t nbt_hdr[NBT_HDR_SIZE];
4008 uint8_t hdr[SMB2_HDR_BODY];
4009 struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
4012 static struct tevent_req *smbd_smb2_break_send(TALLOC_CTX *mem_ctx,
4013 struct tevent_context *ev,
4014 struct smbXsrv_connection *xconn,
4015 uint64_t session_id,
4016 const uint8_t *body,
4019 struct tevent_req *req = NULL;
4020 struct smbd_smb2_break_state *state = NULL;
4024 req = tevent_req_create(mem_ctx, &state,
4025 struct smbd_smb2_break_state);
4031 tevent_req_defer_callback(req, ev);
4033 SIVAL(state->hdr, 0, SMB2_MAGIC);
4034 SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
4035 SSVAL(state->hdr, SMB2_HDR_EPOCH, 0);
4036 SIVAL(state->hdr, SMB2_HDR_STATUS, 0);
4037 SSVAL(state->hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK);
4038 SSVAL(state->hdr, SMB2_HDR_CREDIT, 0);
4039 SIVAL(state->hdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
4040 SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, 0);
4041 SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
4042 SIVAL(state->hdr, SMB2_HDR_PID, 0);
4043 SIVAL(state->hdr, SMB2_HDR_TID, 0);
4044 SBVAL(state->hdr, SMB2_HDR_SESSION_ID, session_id);
4045 memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
4047 state->vector[0] = (struct iovec) {
4048 .iov_base = state->nbt_hdr,
4049 .iov_len = sizeof(state->nbt_hdr)
4052 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
4057 state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
4058 .iov_base = state->hdr,
4059 .iov_len = sizeof(state->hdr)
4062 state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
4063 .iov_base = discard_const_p(uint8_t, body),
4064 .iov_len = body_len,
4068 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4071 ok = smb2_setup_nbt_length(state->vector,
4072 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
4074 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4075 return tevent_req_post(req, ev);
4079 * We require TCP acks for this PDU to the client!
4080 * We want 5 retransmissions and timeout when the
4081 * retransmission timeout (rto) passed 6 times.
4083 * required_acked_bytes gets a dummy value of
4084 * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4085 * it'll get the real value when it's moved to
4088 * state->queue_entry.ack.req gets completed with
4089 * 1. tevent_req_done(), when all bytes are acked.
4090 * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4091 * the timeout expired before all bytes were acked.
4092 * 2b. tevent_req_nterror(transport_error), when the
4093 * connection got a disconnect from the kernel.
4095 state->queue_entry.ack.timeout =
4096 timeval_current_ofs_usec(xconn->ack.rto_usecs * 6);
4097 state->queue_entry.ack.required_acked_bytes = UINT64_MAX;
4098 state->queue_entry.ack.req = req;
4099 state->queue_entry.mem_ctx = state;
4100 state->queue_entry.vector = state->vector;
4101 state->queue_entry.count = ARRAY_SIZE(state->vector);
4102 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
4103 xconn->smb2.send_queue_len++;
4105 status = smbd_smb2_flush_send_queue(xconn);
4106 if (tevent_req_nterror(req, status)) {
4107 return tevent_req_post(req, ev);
4113 static NTSTATUS smbd_smb2_break_recv(struct tevent_req *req)
4115 return tevent_req_simple_recv_ntstatus(req);
4118 struct smbXsrv_pending_break {
4119 struct smbXsrv_pending_break *prev, *next;
4120 struct smbXsrv_client *client;
4121 bool disable_oplock_break_retries;
4122 uint64_t session_id;
4123 uint64_t last_channel_id;
4126 uint8_t oplock[0x18];
4127 uint8_t lease[0x2c];
4132 static void smbXsrv_pending_break_done(struct tevent_req *subreq);
4134 static struct smbXsrv_pending_break *smbXsrv_pending_break_create(
4135 struct smbXsrv_client *client,
4136 uint64_t session_id)
4138 struct smbXsrv_pending_break *pb = NULL;
4140 pb = talloc_zero(client, struct smbXsrv_pending_break);
4144 pb->client = client;
4145 pb->session_id = session_id;
4146 pb->disable_oplock_break_retries = lp_smb2_disable_oplock_break_retry();
4151 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb);
4153 static NTSTATUS smbXsrv_pending_break_schedule(struct smbXsrv_pending_break *pb)
4155 struct smbXsrv_client *client = pb->client;
4158 DLIST_ADD_END(client->pending_breaks, pb);
4159 status = smbXsrv_client_pending_breaks_updated(client);
4160 if (!NT_STATUS_IS_OK(status)) {
4164 status = smbXsrv_pending_break_submit(pb);
4165 if (!NT_STATUS_IS_OK(status)) {
4169 return NT_STATUS_OK;
4172 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb)
4174 struct smbXsrv_client *client = pb->client;
4175 struct smbXsrv_session *session = NULL;
4176 struct smbXsrv_connection *xconn = NULL;
4177 struct smbXsrv_connection *oplock_xconn = NULL;
4178 struct tevent_req *subreq = NULL;
4181 if (pb->session_id != 0) {
4182 status = get_valid_smbXsrv_session(client,
4185 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
4186 return NT_STATUS_ABANDONED;
4188 if (!NT_STATUS_IS_OK(status)) {
4192 if (pb->last_channel_id != 0) {
4194 * This is what current Windows servers
4195 * do, they don't retry on all available
4196 * channels. They only use the last channel.
4198 * But it doesn't match the specification in
4199 * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4202 * Per default disable_oplock_break_retries is false
4203 * and we behave like the specification.
4205 if (pb->disable_oplock_break_retries) {
4206 return NT_STATUS_ABANDONED;
4211 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
4212 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4216 if (xconn->channel_id == 0) {
4218 * non-multichannel case
4223 if (session != NULL) {
4224 struct smbXsrv_channel_global0 *c = NULL;
4227 * Having a session means we're handling
4228 * an oplock break and we only need to
4229 * use channels available on the
4232 status = smbXsrv_session_find_channel(session, xconn, &c);
4233 if (!NT_STATUS_IS_OK(status)) {
4238 * This is what current Windows servers
4239 * do, they don't retry on all available
4240 * channels. They only use the last channel.
4242 * But it doesn't match the specification
4243 * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4246 * Per default disable_oplock_break_retries is false
4247 * and we behave like the specification.
4249 if (pb->disable_oplock_break_retries) {
4250 oplock_xconn = xconn;
4255 if (xconn->channel_id > pb->last_channel_id) {
4263 if (xconn == NULL) {
4264 xconn = oplock_xconn;
4267 if (xconn == NULL) {
4269 * If there's no remaining connection available
4270 * tell the caller to stop...
4272 return NT_STATUS_ABANDONED;
4275 pb->last_channel_id = xconn->channel_id;
4277 subreq = smbd_smb2_break_send(pb,
4283 if (subreq == NULL) {
4284 return NT_STATUS_NO_MEMORY;
4286 tevent_req_set_callback(subreq,
4287 smbXsrv_pending_break_done,
4290 return NT_STATUS_OK;
4293 static void smbXsrv_pending_break_done(struct tevent_req *subreq)
4295 struct smbXsrv_pending_break *pb =
4296 tevent_req_callback_data(subreq,
4297 struct smbXsrv_pending_break);
4298 struct smbXsrv_client *client = pb->client;
4301 status = smbd_smb2_break_recv(subreq);
4302 TALLOC_FREE(subreq);
4303 if (!NT_STATUS_IS_OK(status)) {
4304 status = smbXsrv_pending_break_submit(pb);
4305 if (NT_STATUS_EQUAL(status, NT_STATUS_ABANDONED)) {
4307 * If there's no remaing connection
4308 * there's no need to send a break again.
4312 if (!NT_STATUS_IS_OK(status)) {
4313 smbd_server_disconnect_client(client, nt_errstr(status));
4320 DLIST_REMOVE(client->pending_breaks, pb);
4323 status = smbXsrv_client_pending_breaks_updated(client);
4324 if (!NT_STATUS_IS_OK(status)) {
4325 smbd_server_disconnect_client(client, nt_errstr(status));
4330 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_client *client,
4331 struct smbXsrv_open *op,
4332 uint8_t oplock_level)
4334 struct smbXsrv_pending_break *pb = NULL;
4335 uint8_t *body = NULL;
4337 pb = smbXsrv_pending_break_create(client,
4340 return NT_STATUS_NO_MEMORY;
4342 pb->body_len = sizeof(pb->body.oplock);
4343 body = pb->body.oplock;
4345 SSVAL(body, 0x00, pb->body_len);
4346 SCVAL(body, 0x02, oplock_level);
4347 SCVAL(body, 0x03, 0); /* reserved */
4348 SIVAL(body, 0x04, 0); /* reserved */
4349 SBVAL(body, 0x08, op->global->open_persistent_id);
4350 SBVAL(body, 0x10, op->global->open_volatile_id);
4352 return smbXsrv_pending_break_schedule(pb);
4355 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_client *client,
4357 uint32_t lease_flags,
4358 struct smb2_lease_key *lease_key,
4359 uint32_t current_lease_state,
4360 uint32_t new_lease_state)
4362 struct smbXsrv_pending_break *pb = NULL;
4363 uint8_t *body = NULL;
4365 pb = smbXsrv_pending_break_create(client,
4366 0); /* no session_id */
4368 return NT_STATUS_NO_MEMORY;
4370 pb->body_len = sizeof(pb->body.lease);
4371 body = pb->body.lease;
4373 SSVAL(body, 0x00, pb->body_len);
4374 SSVAL(body, 0x02, new_epoch);
4375 SIVAL(body, 0x04, lease_flags);
4376 SBVAL(body, 0x08, lease_key->data[0]);
4377 SBVAL(body, 0x10, lease_key->data[1]);
4378 SIVAL(body, 0x18, current_lease_state);
4379 SIVAL(body, 0x1c, new_lease_state);
4380 SIVAL(body, 0x20, 0); /* BreakReason, MUST be 0 */
4381 SIVAL(body, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4382 SIVAL(body, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4384 return smbXsrv_pending_break_schedule(pb);
4387 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
4391 uint64_t file_id_persistent;
4392 uint64_t file_id_volatile;
4393 struct smbXsrv_open *op = NULL;
4394 struct files_struct *fsp = NULL;
4395 const uint8_t *body = NULL;
4398 * This is only called with a pktbuf
4399 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4403 if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
4404 /* Transform header. Cannot recvfile. */
4407 if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
4408 /* Not SMB2. Normal error path will cope. */
4411 if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
4412 /* Not SMB2. Normal error path will cope. */
4415 if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
4416 /* Needs to be a WRITE. */
4419 if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
4420 /* Chained. Cannot recvfile. */
4423 flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
4424 if (flags & SMB2_HDR_FLAG_CHAINED) {
4425 /* Chained. Cannot recvfile. */
4428 if (flags & SMB2_HDR_FLAG_SIGNED) {
4429 /* Signed. Cannot recvfile. */
4433 body = &state->pktbuf[SMB2_HDR_BODY];
4435 file_id_persistent = BVAL(body, 0x10);
4436 file_id_volatile = BVAL(body, 0x18);
4438 status = smb2srv_open_lookup(state->req->xconn,
4443 if (!NT_STATUS_IS_OK(status)) {
4451 if (fsp->conn == NULL) {
4455 if (IS_IPC(fsp->conn)) {
4458 if (IS_PRINT(fsp->conn)) {
4461 if (fsp->base_fsp != NULL) {
4465 DEBUG(10,("Doing recvfile write len = %u\n",
4466 (unsigned int)(state->pktfull - state->pktlen)));
4471 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
4473 struct smbd_server_connection *sconn = xconn->client->sconn;
4474 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4475 size_t max_send_queue_len;
4476 size_t cur_send_queue_len;
4478 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4480 * we're not supposed to do any io
4482 return NT_STATUS_OK;
4485 if (state->req != NULL) {
4487 * if there is already a tstream_readv_pdu
4488 * pending, we are done.
4490 return NT_STATUS_OK;
4493 max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
4494 cur_send_queue_len = xconn->smb2.send_queue_len;
4496 if (cur_send_queue_len > max_send_queue_len) {
4498 * if we have a lot of requests to send,
4499 * we wait until they are on the wire until we
4500 * ask for the next request.
4502 return NT_STATUS_OK;
4505 /* ask for the next request */
4506 ZERO_STRUCTP(state);
4507 state->req = smbd_smb2_request_allocate(xconn);
4508 if (state->req == NULL) {
4509 return NT_STATUS_NO_MEMORY;
4511 state->req->sconn = sconn;
4512 state->req->xconn = xconn;
4513 state->min_recv_size = lp_min_receive_file_size();
4515 TEVENT_FD_READABLE(xconn->transport.fde);
4517 return NT_STATUS_OK;
4520 NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
4521 uint64_t expected_seq_low,
4522 const uint8_t *inpdu, size_t size)
4524 struct smbd_server_connection *sconn = xconn->client->sconn;
4526 struct smbd_smb2_request *req = NULL;
4528 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4529 (unsigned int)size));
4531 status = smbd_initialize_smb2(xconn, expected_seq_low);
4532 if (!NT_STATUS_IS_OK(status)) {
4533 smbd_server_connection_terminate(xconn, nt_errstr(status));
4538 * If a new connection joins the process, when we're
4539 * already in a "pending break cycle", we need to
4540 * turn on the ack checker on the new connection.
4542 status = smbXsrv_client_pending_breaks_updated(xconn->client);
4543 if (!NT_STATUS_IS_OK(status)) {
4545 * If there's a problem, we disconnect the whole
4546 * client with all connections here!
4548 * Instead of just the new connection.
4550 smbd_server_disconnect_client(xconn->client, nt_errstr(status));
4554 status = smbd_smb2_request_create(xconn, inpdu, size, &req);
4555 if (!NT_STATUS_IS_OK(status)) {
4556 smbd_server_connection_terminate(xconn, nt_errstr(status));
4560 status = smbd_smb2_request_validate(req);
4561 if (!NT_STATUS_IS_OK(status)) {
4562 smbd_server_connection_terminate(xconn, nt_errstr(status));
4566 status = smbd_smb2_request_setup_out(req);
4567 if (!NT_STATUS_IS_OK(status)) {
4568 smbd_server_connection_terminate(xconn, nt_errstr(status));
4574 * this was already counted at the SMB1 layer =>
4575 * smbd_smb2_request_dispatch() should not count it twice.
4577 if (profile_p->values.request_stats.count > 0) {
4578 profile_p->values.request_stats.count--;
4581 status = smbd_smb2_request_dispatch(req);
4582 if (!NT_STATUS_IS_OK(status)) {
4583 smbd_server_connection_terminate(xconn, nt_errstr(status));
4587 status = smbd_smb2_request_next_incoming(xconn);
4588 if (!NT_STATUS_IS_OK(status)) {
4589 smbd_server_connection_terminate(xconn, nt_errstr(status));
4593 sconn->num_requests++;
4594 return NT_STATUS_OK;
4597 static int socket_error_from_errno(int ret,
4611 if (sys_errno == 0) {
4615 if (sys_errno == EINTR) {
4620 if (sys_errno == EINPROGRESS) {
4625 if (sys_errno == EAGAIN) {
4630 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4631 if (sys_errno == ENOMEM) {
4637 #if EWOULDBLOCK != EAGAIN
4638 if (sys_errno == EWOULDBLOCK) {
4648 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
4655 if (xconn->smb2.send_queue == NULL) {
4656 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4657 return NT_STATUS_OK;
4660 while (xconn->smb2.send_queue != NULL) {
4661 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
4665 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4667 * we're not supposed to do any io
4668 * just flush all pending stuff.
4670 xconn->smb2.send_queue_len--;
4671 DLIST_REMOVE(xconn->smb2.send_queue, e);
4673 talloc_free(e->mem_ctx);
4677 if (e->sendfile_header != NULL) {
4682 status = NT_STATUS_INTERNAL_ERROR;
4684 for (i=0; i < e->count; i++) {
4685 size += e->vector[i].iov_len;
4688 if (size <= e->sendfile_header->length) {
4689 buf = e->sendfile_header->data;
4691 buf = talloc_array(e->mem_ctx, uint8_t, size);
4693 return NT_STATUS_NO_MEMORY;
4698 for (i=0; i < e->count; i++) {
4700 e->vector[i].iov_base,
4701 e->vector[i].iov_len);
4702 size += e->vector[i].iov_len;
4705 e->sendfile_header->data = buf;
4706 e->sendfile_header->length = size;
4707 e->sendfile_status = &status;
4710 xconn->smb2.send_queue_len--;
4711 DLIST_REMOVE(xconn->smb2.send_queue, e);
4713 size += e->sendfile_body_size;
4716 * This triggers the sendfile path via
4719 talloc_free(e->mem_ctx);
4721 if (!NT_STATUS_IS_OK(status)) {
4722 smbXsrv_connection_disconnect_transport(xconn,
4726 xconn->ack.unacked_bytes += size;
4730 msg = (struct msghdr) {
4731 .msg_iov = e->vector,
4732 .msg_iovlen = e->count,
4735 ret = sendmsg(xconn->transport.sock, &msg, 0);
4737 /* propagate end of file */
4738 return NT_STATUS_INTERNAL_ERROR;
4740 err = socket_error_from_errno(ret, errno, &retry);
4743 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4744 return NT_STATUS_OK;
4747 status = map_nt_error_from_unix_common(err);
4748 smbXsrv_connection_disconnect_transport(xconn,
4753 xconn->ack.unacked_bytes += ret;
4755 ok = iov_advance(&e->vector, &e->count, ret);
4757 return NT_STATUS_INTERNAL_ERROR;
4761 /* we have more to write */
4762 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4763 return NT_STATUS_OK;
4766 xconn->smb2.send_queue_len--;
4767 DLIST_REMOVE(xconn->smb2.send_queue, e);
4769 if (e->ack.req == NULL) {
4770 talloc_free(e->mem_ctx);
4774 e->ack.required_acked_bytes = xconn->ack.unacked_bytes;
4775 DLIST_ADD_END(xconn->ack.queue, e);
4779 * Restart reads if we were blocked on
4780 * draining the send queue.
4783 status = smbd_smb2_request_next_incoming(xconn);
4784 if (!NT_STATUS_IS_OK(status)) {
4788 return NT_STATUS_OK;
4791 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
4794 struct smbd_server_connection *sconn = xconn->client->sconn;
4795 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4796 struct smbd_smb2_request *req = NULL;
4797 size_t min_recvfile_size = UINT32_MAX;
4805 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4807 * we're not supposed to do any io
4809 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4810 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4811 return NT_STATUS_OK;
4814 if (fde_flags & TEVENT_FD_WRITE) {
4815 status = smbd_smb2_flush_send_queue(xconn);
4816 if (!NT_STATUS_IS_OK(status)) {
4821 if (!(fde_flags & TEVENT_FD_READ)) {
4822 return NT_STATUS_OK;
4825 if (state->req == NULL) {
4826 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4827 return NT_STATUS_OK;
4831 if (!state->hdr.done) {
4832 state->hdr.done = true;
4834 state->vector.iov_base = (void *)state->hdr.nbt;
4835 state->vector.iov_len = NBT_HDR_SIZE;
4838 msg = (struct msghdr) {
4839 .msg_iov = &state->vector,
4843 ret = recvmsg(xconn->transport.sock, &msg, 0);
4845 /* propagate end of file */
4846 status = NT_STATUS_END_OF_FILE;
4847 smbXsrv_connection_disconnect_transport(xconn,
4851 err = socket_error_from_errno(ret, errno, &retry);
4854 TEVENT_FD_READABLE(xconn->transport.fde);
4855 return NT_STATUS_OK;
4858 status = map_nt_error_from_unix_common(err);
4859 smbXsrv_connection_disconnect_transport(xconn,
4864 if (ret < state->vector.iov_len) {
4866 base = (uint8_t *)state->vector.iov_base;
4868 state->vector.iov_base = (void *)base;
4869 state->vector.iov_len -= ret;
4870 /* we have more to read */
4871 TEVENT_FD_READABLE(xconn->transport.fde);
4872 return NT_STATUS_OK;
4875 if (state->pktlen > 0) {
4876 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
4878 * Not a possible receivefile write.
4879 * Read the rest of the data.
4881 state->doing_receivefile = false;
4883 state->pktbuf = talloc_realloc(state->req,
4887 if (state->pktbuf == NULL) {
4888 return NT_STATUS_NO_MEMORY;
4891 state->vector.iov_base = (void *)(state->pktbuf +
4893 state->vector.iov_len = (state->pktfull -
4896 state->pktlen = state->pktfull;
4901 * Either this is a receivefile write so we've
4902 * done a short read, or if not we have all the data.
4908 * Now we analyze the NBT header
4910 if (state->hdr.nbt[0] != 0x00) {
4911 state->min_recv_size = 0;
4913 state->pktfull = smb2_len(state->hdr.nbt);
4914 if (state->pktfull == 0) {
4918 if (state->min_recv_size != 0) {
4919 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4920 min_recvfile_size += state->min_recv_size;
4923 if (state->pktfull > min_recvfile_size) {
4925 * Might be a receivefile write. Read the SMB2 HEADER +
4926 * SMB2_WRITE header first. Set 'doing_receivefile'
4927 * as we're *attempting* receivefile write. If this
4928 * turns out not to be a SMB2_WRITE request or otherwise
4929 * not suitable then we'll just read the rest of the data
4930 * the next time this function is called.
4932 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4933 state->doing_receivefile = true;
4935 state->pktlen = state->pktfull;
4938 state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
4939 if (state->pktbuf == NULL) {
4940 return NT_STATUS_NO_MEMORY;
4943 state->vector.iov_base = (void *)state->pktbuf;
4944 state->vector.iov_len = state->pktlen;
4950 if (state->hdr.nbt[0] != 0x00) {
4951 DEBUG(1,("ignore NBT[0x%02X] msg\n",
4952 state->hdr.nbt[0]));
4955 ZERO_STRUCTP(state);
4957 state->min_recv_size = lp_min_receive_file_size();
4965 req->request_time = timeval_current();
4966 now = timeval_to_nttime(&req->request_time);
4968 status = smbd_smb2_inbuf_parse_compound(xconn,
4974 &req->in.vector_count);
4975 if (!NT_STATUS_IS_OK(status)) {
4979 if (state->doing_receivefile) {
4980 req->smb1req = talloc_zero(req, struct smb_request);
4981 if (req->smb1req == NULL) {
4982 return NT_STATUS_NO_MEMORY;
4984 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
4987 ZERO_STRUCTP(state);
4989 req->current_idx = 1;
4991 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
4992 req->current_idx, req->in.vector_count));
4994 status = smbd_smb2_request_validate(req);
4995 if (!NT_STATUS_IS_OK(status)) {
4999 status = smbd_smb2_request_setup_out(req);
5000 if (!NT_STATUS_IS_OK(status)) {
5004 status = smbd_smb2_request_dispatch(req);
5005 if (!NT_STATUS_IS_OK(status)) {
5009 sconn->num_requests++;
5011 /* The timeout_processing function isn't run nearly
5012 often enough to implement 'max log size' without
5013 overrunning the size of the file by many megabytes.
5014 This is especially true if we are running at debug
5015 level 10. Checking every 50 SMB2s is a nice
5016 tradeoff of performance vs log file size overrun. */
5018 if ((sconn->num_requests % 50) == 0 &&
5019 need_to_check_log_size()) {
5020 change_to_root_user();
5024 status = smbd_smb2_request_next_incoming(xconn);
5025 if (!NT_STATUS_IS_OK(status)) {
5029 return NT_STATUS_OK;
5032 static void smbd_smb2_connection_handler(struct tevent_context *ev,
5033 struct tevent_fd *fde,
5037 struct smbXsrv_connection *xconn =
5038 talloc_get_type_abort(private_data,
5039 struct smbXsrv_connection);
5042 status = smbd_smb2_io_handler(xconn, flags);
5043 if (!NT_STATUS_IS_OK(status)) {
5044 smbd_server_connection_terminate(xconn, nt_errstr(status));