2 Unix SMB/CIFS implementation.
5 Copyright (C) Stefan Metzmacher 2009
6 Copyright (C) Jeremy Allison 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/network.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "lib/param/param.h"
27 #include "../libcli/smb/smb_common.h"
28 #include "../lib/tsocket/tsocket.h"
29 #include "../lib/util/tevent_ntstatus.h"
30 #include "smbprofile.h"
31 #include "../lib/util/bitmap.h"
32 #include "../librpc/gen_ndr/krb5pac.h"
33 #include "lib/util/iov_buf.h"
35 #include "libcli/smb/smbXcli_base.h"
38 /* SIOCOUTQ TIOCOUTQ are the same */
39 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
40 #define __HAVE_TCP_INFO_RTO 1
41 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
42 #elif defined(FREEBSD)
43 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
44 #define __HAVE_TCP_INFO_RTO 1
45 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
48 #include "lib/crypto/gnutls_helpers.h"
49 #include <gnutls/gnutls.h>
50 #include <gnutls/crypto.h>
53 #define DBGC_CLASS DBGC_SMB2
55 static void smbd_smb2_connection_handler(struct tevent_context *ev,
56 struct tevent_fd *fde,
59 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
61 static const struct smbd_smb2_dispatch_table {
68 bool allow_invalid_fileid;
70 } smbd_smb2_table[] = {
71 #define _OP(o) .opcode = o, .name = #o
76 _OP(SMB2_OP_SESSSETUP),
86 * This call needs to be run as root.
88 * smbd_smb2_request_process_tcon()
89 * calls make_connection_snum(), which will call
90 * change_to_user(), when needed.
100 .need_session = true,
104 .need_session = true,
109 .need_session = true,
114 .need_session = true,
119 .need_session = true,
125 .need_session = true,
130 .need_session = true,
133 .allow_invalid_fileid = true,
139 _OP(SMB2_OP_KEEPALIVE),
142 _OP(SMB2_OP_QUERY_DIRECTORY),
143 .need_session = true,
148 .need_session = true,
152 _OP(SMB2_OP_GETINFO),
153 .need_session = true,
157 _OP(SMB2_OP_SETINFO),
158 .need_session = true,
164 .need_session = true,
169 * as LEASE breaks does not
175 const char *smb2_opcode_name(uint16_t opcode)
177 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
178 return "Bad SMB2 opcode";
180 return smbd_smb2_table[opcode].name;
183 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
185 const struct smbd_smb2_dispatch_table *ret = NULL;
187 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
191 ret = &smbd_smb2_table[opcode];
193 SMB_ASSERT(ret->opcode == opcode);
198 static void print_req_vectors(const struct smbd_smb2_request *req)
202 for (i = 0; i < req->in.vector_count; i++) {
203 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
205 (unsigned int)req->in.vector[i].iov_len);
207 for (i = 0; i < req->out.vector_count; i++) {
208 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
210 (unsigned int)req->out.vector[i].iov_len);
214 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
216 if (size < (4 + SMB2_HDR_BODY)) {
220 if (IVAL(inbuf, 4) != SMB2_MAGIC) {
227 bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
229 return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
232 static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
233 uint64_t expected_seq_low)
237 xconn->smb2.credits.seq_low = expected_seq_low;
238 xconn->smb2.credits.seq_range = 1;
239 xconn->smb2.credits.granted = 1;
240 xconn->smb2.credits.max = lp_smb2_max_credits();
241 xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
242 xconn->smb2.credits.max);
243 if (xconn->smb2.credits.bitmap == NULL) {
244 return NT_STATUS_NO_MEMORY;
247 tevent_fd_set_close_fn(xconn->transport.fde, NULL);
248 TALLOC_FREE(xconn->transport.fde);
250 xconn->transport.fde = tevent_add_fd(
251 xconn->client->raw_ev_ctx,
253 xconn->transport.sock,
255 smbd_smb2_connection_handler,
257 if (xconn->transport.fde == NULL) {
258 close(xconn->transport.sock);
259 xconn->transport.sock = -1;
260 return NT_STATUS_NO_MEMORY;
262 tevent_fd_set_auto_close(xconn->transport.fde);
264 /* Ensure child is set to non-blocking mode */
265 rc = set_blocking(xconn->transport.sock, false);
267 return NT_STATUS_INTERNAL_ERROR;
273 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
274 #define _smb2_setlen(_buf,len) do { \
275 uint8_t *buf = (uint8_t *)_buf; \
277 buf[1] = ((len)&0xFF0000)>>16; \
278 buf[2] = ((len)&0xFF00)>>8; \
279 buf[3] = (len)&0xFF; \
282 static bool smb2_setup_nbt_length(struct iovec *vector, int count)
290 len = iov_buflen(vector+1, count-1);
292 if ((len == -1) || (len > 0xFFFFFF)) {
296 _smb2_setlen(vector[0].iov_base, len);
300 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
302 TALLOC_FREE(req->first_enc_key);
303 TALLOC_FREE(req->last_sign_key);
307 void smb2_request_set_async_internal(struct smbd_smb2_request *req,
310 req->async_internal = async_internal;
313 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
315 TALLOC_CTX *mem_pool;
316 struct smbd_smb2_request *req;
319 /* Enable this to find subtle valgrind errors. */
320 mem_pool = talloc_init("smbd_smb2_request_allocate");
322 mem_pool = talloc_tos();
324 if (mem_pool == NULL) {
328 req = talloc_zero(mem_pool, struct smbd_smb2_request);
330 talloc_free(mem_pool);
333 talloc_reparent(mem_pool, mem_ctx, req);
335 TALLOC_FREE(mem_pool);
338 req->last_session_id = UINT64_MAX;
339 req->last_tid = UINT32_MAX;
341 talloc_set_destructor(req, smbd_smb2_request_destructor);
346 static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
350 struct smbd_smb2_request *req,
354 TALLOC_CTX *mem_ctx = req;
358 uint8_t *first_hdr = buf;
359 size_t verified_buflen = 0;
364 * Note: index '0' is reserved for the transport protocol
366 iov = req->in._vector;
368 while (taken < buflen) {
369 size_t len = buflen - taken;
370 uint8_t *hdr = first_hdr + taken;
373 size_t next_command_ofs;
375 uint8_t *body = NULL;
378 struct iovec *iov_alloc = NULL;
380 if (iov != req->in._vector) {
384 if (verified_buflen > taken) {
385 len = verified_buflen - taken;
392 DEBUG(10, ("%d bytes left, expected at least %d\n",
396 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
397 struct smbXsrv_session *s = NULL;
399 struct iovec tf_iov[2];
403 if (xconn->protocol < PROTOCOL_SMB3_00) {
404 DEBUG(10, ("Got SMB2_TRANSFORM header, "
405 "but dialect[0x%04X] is used\n",
406 xconn->smb2.server.dialect));
410 if (xconn->smb2.server.cipher == 0) {
411 DEBUG(10, ("Got SMB2_TRANSFORM header, "
412 "but not negotiated "
413 "client[0x%08X] server[0x%08X]\n",
414 xconn->smb2.client.capabilities,
415 xconn->smb2.server.capabilities));
419 if (len < SMB2_TF_HDR_SIZE) {
420 DEBUG(1, ("%d bytes left, expected at least %d\n",
421 (int)len, SMB2_TF_HDR_SIZE));
425 tf_len = SMB2_TF_HDR_SIZE;
428 hdr = first_hdr + taken;
429 enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
430 uid = BVAL(tf, SMB2_TF_SESSION_ID);
432 if (len < SMB2_TF_HDR_SIZE + enc_len) {
433 DEBUG(1, ("%d bytes left, expected at least %d\n",
435 (int)(SMB2_TF_HDR_SIZE + enc_len)));
439 status = smb2srv_session_lookup_conn(xconn, uid, now,
442 status = smb2srv_session_lookup_global(xconn->client,
446 DEBUG(1, ("invalid session[%llu] in "
447 "SMB2_TRANSFORM header\n",
448 (unsigned long long)uid));
449 TALLOC_FREE(iov_alloc);
450 return NT_STATUS_USER_SESSION_DELETED;
453 tf_iov[0].iov_base = (void *)tf;
454 tf_iov[0].iov_len = tf_len;
455 tf_iov[1].iov_base = (void *)hdr;
456 tf_iov[1].iov_len = enc_len;
458 status = smb2_signing_decrypt_pdu(s->global->decryption_key,
460 if (!NT_STATUS_IS_OK(status)) {
461 TALLOC_FREE(iov_alloc);
465 verified_buflen = taken + enc_len;
470 * We need the header plus the body length field
473 if (len < SMB2_HDR_BODY + 2) {
476 (IVAL(hdr, 0) == SMB_SUICIDE_PACKET) &&
477 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
478 uint8_t exitcode = CVAL(hdr, 4);
479 DBG_WARNING("SUICIDE: Exiting immediately "
480 "with code %"PRIu8"\n",
485 DEBUG(10, ("%d bytes left, expected at least %d\n",
486 (int)len, SMB2_HDR_BODY));
489 if (IVAL(hdr, 0) != SMB2_MAGIC) {
490 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
494 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
495 DEBUG(10, ("Got HDR len %d, expected %d\n",
496 SVAL(hdr, 4), SMB2_HDR_BODY));
501 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
502 body_size = SVAL(hdr, SMB2_HDR_BODY);
504 if (next_command_ofs != 0) {
505 if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
508 if (next_command_ofs > full_size) {
511 full_size = next_command_ofs;
518 if (body_size > (full_size - SMB2_HDR_BODY)) {
520 * let the caller handle the error
522 body_size = full_size - SMB2_HDR_BODY;
524 body = hdr + SMB2_HDR_BODY;
525 dyn = body + body_size;
526 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
528 if (num_iov >= ARRAY_SIZE(req->in._vector)) {
529 struct iovec *iov_tmp = NULL;
531 iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
534 SMBD_SMB2_NUM_IOV_PER_REQ);
535 if (iov_tmp == NULL) {
536 TALLOC_FREE(iov_alloc);
537 return NT_STATUS_NO_MEMORY;
540 if (iov_alloc == NULL) {
543 sizeof(req->in._vector));
549 num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
551 cur[SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
552 cur[SMBD_SMB2_TF_IOV_OFS].iov_len = tf_len;
553 cur[SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
554 cur[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
555 cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
556 cur[SMBD_SMB2_BODY_IOV_OFS].iov_len = body_size;
557 cur[SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
558 cur[SMBD_SMB2_DYN_IOV_OFS].iov_len = dyn_size;
568 if (iov != req->in._vector) {
571 return NT_STATUS_INVALID_PARAMETER;
574 static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
575 const uint8_t *_inpdu, size_t size,
576 struct smbd_smb2_request **_req)
578 struct smbd_server_connection *sconn = xconn->client->sconn;
579 struct smbd_smb2_request *req;
580 uint32_t protocol_version;
581 uint8_t *inpdu = NULL;
582 const uint8_t *inhdr = NULL;
584 uint32_t next_command_ofs;
588 if (size < (SMB2_HDR_BODY + 2)) {
589 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
590 return NT_STATUS_INVALID_PARAMETER;
595 protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
596 if (protocol_version != SMB2_MAGIC) {
597 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
599 return NT_STATUS_INVALID_PARAMETER;
602 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
603 if (cmd != SMB2_OP_NEGPROT) {
604 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
606 return NT_STATUS_INVALID_PARAMETER;
609 next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
610 if (next_command_ofs != 0) {
611 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
613 return NT_STATUS_INVALID_PARAMETER;
616 req = smbd_smb2_request_allocate(xconn);
618 return NT_STATUS_NO_MEMORY;
623 inpdu = talloc_memdup(req, _inpdu, size);
625 return NT_STATUS_NO_MEMORY;
628 req->request_time = timeval_current();
629 now = timeval_to_nttime(&req->request_time);
631 status = smbd_smb2_inbuf_parse_compound(xconn,
635 req, &req->in.vector,
636 &req->in.vector_count);
637 if (!NT_STATUS_IS_OK(status)) {
642 req->current_idx = 1;
648 static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
649 uint64_t message_id, uint64_t seq_id)
651 struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
655 seq_tmp = xconn->smb2.credits.seq_low;
656 if (seq_id < seq_tmp) {
657 DBGC_ERR(DBGC_SMB2_CREDITS,
658 "smb2_validate_sequence_number: bad message_id "
659 "%llu (sequence id %llu) "
660 "(granted = %u, low = %llu, range = %u)\n",
661 (unsigned long long)message_id,
662 (unsigned long long)seq_id,
663 (unsigned int)xconn->smb2.credits.granted,
664 (unsigned long long)xconn->smb2.credits.seq_low,
665 (unsigned int)xconn->smb2.credits.seq_range);
669 seq_tmp += xconn->smb2.credits.seq_range;
670 if (seq_id >= seq_tmp) {
671 DBGC_ERR(DBGC_SMB2_CREDITS,
672 "smb2_validate_sequence_number: bad message_id "
673 "%llu (sequence id %llu) "
674 "(granted = %u, low = %llu, range = %u)\n",
675 (unsigned long long)message_id,
676 (unsigned long long)seq_id,
677 (unsigned int)xconn->smb2.credits.granted,
678 (unsigned long long)xconn->smb2.credits.seq_low,
679 (unsigned int)xconn->smb2.credits.seq_range);
683 offset = seq_id % xconn->smb2.credits.max;
685 if (bitmap_query(credits_bm, offset)) {
686 DBGC_ERR(DBGC_SMB2_CREDITS,
687 "smb2_validate_sequence_number: duplicate message_id "
688 "%llu (sequence id %llu) "
689 "(granted = %u, low = %llu, range = %u) "
691 (unsigned long long)message_id,
692 (unsigned long long)seq_id,
693 (unsigned int)xconn->smb2.credits.granted,
694 (unsigned long long)xconn->smb2.credits.seq_low,
695 (unsigned int)xconn->smb2.credits.seq_range,
700 /* Mark the message_ids as seen in the bitmap. */
701 bitmap_set(credits_bm, offset);
703 if (seq_id != xconn->smb2.credits.seq_low) {
708 * Move the window forward by all the message_id's
711 while (bitmap_query(credits_bm, offset)) {
712 DBGC_DEBUG(DBGC_SMB2_CREDITS,
713 "smb2_validate_sequence_number: clearing "
714 "id %llu (position %u) from bitmap\n",
715 (unsigned long long)(xconn->smb2.credits.seq_low),
717 bitmap_clear(credits_bm, offset);
719 xconn->smb2.credits.seq_low += 1;
720 xconn->smb2.credits.seq_range -= 1;
721 offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
727 static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
728 const uint8_t *inhdr)
730 uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
731 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
732 uint16_t credit_charge = 1;
735 if (opcode == SMB2_OP_CANCEL) {
736 /* SMB2_CANCEL requests by definition resend messageids. */
740 if (xconn->smb2.credits.multicredit) {
741 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
742 credit_charge = MAX(credit_charge, 1);
747 ("smb2_validate_message_id: mid %llu (charge %llu), "
748 "credits_granted %llu, "
749 "seqnum low/range: %llu/%llu\n",
750 (unsigned long long) message_id,
751 (unsigned long long) credit_charge,
752 (unsigned long long) xconn->smb2.credits.granted,
753 (unsigned long long) xconn->smb2.credits.seq_low,
754 (unsigned long long) xconn->smb2.credits.seq_range));
756 if (xconn->smb2.credits.granted < credit_charge) {
757 DBGC_ERR(DBGC_SMB2_CREDITS,
758 "smb2_validate_message_id: client used more "
759 "credits than granted, mid %llu, charge %llu, "
760 "credits_granted %llu, "
761 "seqnum low/range: %llu/%llu\n",
762 (unsigned long long) message_id,
763 (unsigned long long) credit_charge,
764 (unsigned long long) xconn->smb2.credits.granted,
765 (unsigned long long) xconn->smb2.credits.seq_low,
766 (unsigned long long) xconn->smb2.credits.seq_range);
771 * now check the message ids
773 * for multi-credit requests we need to check all current mid plus
774 * the implicit mids caused by the credit charge
775 * e.g. current mid = 15, charge 5 => mark 15-19 as used
778 for (i = 0; i <= (credit_charge-1); i++) {
779 uint64_t id = message_id + i;
784 ("Iterating mid %llu charge %u (sequence %llu)\n",
785 (unsigned long long)message_id,
787 (unsigned long long)id));
789 ok = smb2_validate_sequence_number(xconn, message_id, id);
795 /* substract used credits */
796 xconn->smb2.credits.granted -= credit_charge;
801 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
806 count = req->in.vector_count;
808 if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
809 /* It's not a SMB2 request */
810 return NT_STATUS_INVALID_PARAMETER;
813 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
814 struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
815 struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
816 const uint8_t *inhdr = NULL;
818 if (hdr->iov_len != SMB2_HDR_BODY) {
819 return NT_STATUS_INVALID_PARAMETER;
822 if (body->iov_len < 2) {
823 return NT_STATUS_INVALID_PARAMETER;
826 inhdr = (const uint8_t *)hdr->iov_base;
828 /* Check the SMB2 header */
829 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
830 return NT_STATUS_INVALID_PARAMETER;
833 if (!smb2_validate_message_id(req->xconn, inhdr)) {
834 return NT_STATUS_INVALID_PARAMETER;
841 static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
842 const struct iovec *in_vector,
843 struct iovec *out_vector)
845 const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
846 uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
847 uint16_t credit_charge = 1;
848 uint16_t credits_requested;
852 uint16_t credits_granted = 0;
853 uint64_t credits_possible;
854 uint16_t current_max_credits;
857 * first we grant only 1/16th of the max range.
859 * Windows also starts with the 1/16th and then grants
860 * more later. I was only able to trigger higher
861 * values, when using a very high credit charge.
863 * TODO: scale up depending on load, free memory
865 * Maybe also on the relationship between number
866 * of requests and the used sequence number.
867 * Which means we would grant more credits
868 * for client which use multi credit requests.
870 * The above is what Windows Server < 2016 is doing,
871 * but new servers use all credits (8192 by default).
873 current_max_credits = xconn->smb2.credits.max;
874 current_max_credits = MAX(current_max_credits, 1);
876 if (xconn->smb2.credits.multicredit) {
877 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
878 credit_charge = MAX(credit_charge, 1);
881 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
882 credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
883 credits_requested = MAX(credits_requested, 1);
884 out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
885 out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
887 SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
889 if (xconn->smb2.credits.max < credit_charge) {
890 smbd_server_connection_terminate(xconn,
891 "client error: credit charge > max credits\n");
895 if (out_flags & SMB2_HDR_FLAG_ASYNC) {
897 * In case we already send an async interim
898 * response, we should not grant
899 * credits on the final response.
903 uint16_t additional_possible =
904 xconn->smb2.credits.max - credit_charge;
905 uint16_t additional_max = 0;
906 uint16_t additional_credits = credits_requested - 1;
909 case SMB2_OP_NEGPROT:
911 case SMB2_OP_SESSSETUP:
913 * Windows 2012 RC1 starts to grant
915 * with a successful session setup
917 if (NT_STATUS_IS_OK(out_status)) {
918 additional_max = xconn->smb2.credits.max;
923 * Windows Server < 2016 and older Samba versions
924 * used to only grant additional credits in
925 * chunks of 32 credits.
927 * But we match Windows Server 2016 and grant
928 * all credits as requested.
930 additional_max = xconn->smb2.credits.max;
934 additional_max = MIN(additional_max, additional_possible);
935 additional_credits = MIN(additional_credits, additional_max);
937 credits_granted = credit_charge + additional_credits;
941 * sequence numbers should not wrap
943 * 1. calculate the possible credits until
944 * the sequence numbers start to wrap on 64-bit.
946 * 2. UINT64_MAX is used for Break Notifications.
948 * 2. truncate the possible credits to the maximum
949 * credits we want to grant to the client in total.
951 * 3. remove the range we'll already granted to the client
952 * this makes sure the client consumes the lowest sequence
953 * number, before we can grant additional credits.
955 credits_possible = UINT64_MAX - xconn->smb2.credits.seq_low;
956 if (credits_possible > 0) {
957 /* remove UINT64_MAX */
958 credits_possible -= 1;
960 credits_possible = MIN(credits_possible, current_max_credits);
961 credits_possible -= xconn->smb2.credits.seq_range;
963 credits_granted = MIN(credits_granted, credits_possible);
965 SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
966 xconn->smb2.credits.granted += credits_granted;
967 xconn->smb2.credits.seq_range += credits_granted;
969 DBGC_DEBUG(DBGC_SMB2_CREDITS,
970 "smb2_set_operation_credit: requested %u, charge %u, "
971 "granted %u, current possible/max %u/%u, "
972 "total granted/max/low/range %u/%u/%llu/%u\n",
973 (unsigned int)credits_requested,
974 (unsigned int)credit_charge,
975 (unsigned int)credits_granted,
976 (unsigned int)credits_possible,
977 (unsigned int)current_max_credits,
978 (unsigned int)xconn->smb2.credits.granted,
979 (unsigned int)xconn->smb2.credits.max,
980 (unsigned long long)xconn->smb2.credits.seq_low,
981 (unsigned int)xconn->smb2.credits.seq_range);
984 static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
985 struct smbd_smb2_request *outreq)
988 uint16_t total_credits = 0;
990 count = outreq->out.vector_count;
992 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
993 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
994 struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
995 uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
997 smb2_set_operation_credit(outreq->xconn, inhdr_v, outhdr_v);
999 /* To match Windows, count up what we
1001 total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
1002 /* Set to zero in all but the last reply. */
1003 if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
1004 SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
1006 SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
1011 DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size)
1013 if (req->current_idx <= 1) {
1014 if (size <= sizeof(req->out._body)) {
1015 return data_blob_const(req->out._body, size);
1019 return data_blob_talloc(req, NULL, size);
1022 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
1024 struct smbXsrv_connection *xconn = req->xconn;
1025 TALLOC_CTX *mem_ctx;
1026 struct iovec *vector;
1031 count = req->in.vector_count;
1032 if (count <= ARRAY_SIZE(req->out._vector)) {
1034 vector = req->out._vector;
1036 vector = talloc_zero_array(req, struct iovec, count);
1037 if (vector == NULL) {
1038 return NT_STATUS_NO_MEMORY;
1043 vector[0].iov_base = req->out.nbt_hdr;
1044 vector[0].iov_len = 4;
1045 SIVAL(req->out.nbt_hdr, 0, 0);
1047 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
1048 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
1049 const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
1050 uint8_t *outhdr = NULL;
1051 uint8_t *outbody = NULL;
1052 uint32_t next_command_ofs = 0;
1053 struct iovec *current = &vector[idx];
1055 if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
1056 /* we have a next command -
1057 * setup for the error case. */
1058 next_command_ofs = SMB2_HDR_BODY + 9;
1062 outhdr = req->out._hdr;
1064 outhdr = talloc_zero_array(mem_ctx, uint8_t,
1066 if (outhdr == NULL) {
1067 return NT_STATUS_NO_MEMORY;
1071 outbody = outhdr + SMB2_HDR_BODY;
1074 * SMBD_SMB2_TF_IOV_OFS might be used later
1076 current[SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
1077 current[SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
1079 current[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)outhdr;
1080 current[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1082 current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
1083 current[SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
1085 current[SMBD_SMB2_DYN_IOV_OFS].iov_base = NULL;
1086 current[SMBD_SMB2_DYN_IOV_OFS].iov_len = 0;
1088 /* setup the SMB2 header */
1089 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1090 SSVAL(outhdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1091 SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1092 SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1093 SIVAL(outhdr, SMB2_HDR_STATUS,
1094 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1095 SSVAL(outhdr, SMB2_HDR_OPCODE,
1096 SVAL(inhdr, SMB2_HDR_OPCODE));
1097 SIVAL(outhdr, SMB2_HDR_FLAGS,
1098 IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1099 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1100 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1101 BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1102 SIVAL(outhdr, SMB2_HDR_PID,
1103 IVAL(inhdr, SMB2_HDR_PID));
1104 SIVAL(outhdr, SMB2_HDR_TID,
1105 IVAL(inhdr, SMB2_HDR_TID));
1106 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1107 BVAL(inhdr, SMB2_HDR_SESSION_ID));
1108 memcpy(outhdr + SMB2_HDR_SIGNATURE,
1109 inhdr + SMB2_HDR_SIGNATURE, 16);
1111 /* setup error body header */
1112 SSVAL(outbody, 0x00, 0x08 + 1);
1113 SSVAL(outbody, 0x02, 0);
1114 SIVAL(outbody, 0x04, 0);
1117 req->out.vector = vector;
1118 req->out.vector_count = count;
1120 /* setup the length of the NBT packet */
1121 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1123 return NT_STATUS_INVALID_PARAMETER_MIX;
1126 DLIST_ADD_END(xconn->smb2.requests, req);
1128 return NT_STATUS_OK;
1131 bool smbXsrv_server_multi_channel_enabled(void)
1133 bool enabled = lp_server_multi_channel_support();
1134 #ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1135 bool forced = false;
1136 struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
1137 bool unspecified = lpcfg_parm_is_unspecified(lp_ctx, "server multi channel support");
1142 * If we don't have support from the kernel
1143 * to ask for the un-acked number of bytes
1144 * in the socket send queue, we better
1145 * don't support multi-channel.
1147 forced = lp_parm_bool(-1, "force", "server multi channel support", false);
1148 if (enabled && !forced) {
1149 D_NOTICE("'server multi channel support' enabled "
1150 "but not supported on %s (%s)\n",
1151 SYSTEM_UNAME_SYSNAME, SYSTEM_UNAME_RELEASE);
1152 DEBUGADD(DBGLVL_NOTICE, ("Please report this on "
1153 "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1156 TALLOC_FREE(lp_ctx);
1157 #endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1161 static NTSTATUS smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection *xconn,
1162 uint32_t *_rto_usecs)
1165 * Define an Retransmission Timeout
1166 * of 1 second, if there's no way for the
1167 * kernel to tell us the current value.
1169 uint32_t rto_usecs = 1000000;
1171 #ifdef __HAVE_TCP_INFO_RTO
1173 struct tcp_info info;
1174 socklen_t ilen = sizeof(info);
1178 ret = getsockopt(xconn->transport.sock,
1179 IPPROTO_TCP, TCP_INFO,
1180 (void *)&info, &ilen);
1182 int saved_errno = errno;
1183 NTSTATUS status = map_nt_error_from_unix(errno);
1184 DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1185 saved_errno, strerror(saved_errno),
1190 DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1191 (unsigned)info.tcpi_rto,
1192 (unsigned)info.tcpi_rtt,
1193 (unsigned)info.tcpi_rttvar);
1194 rto_usecs = info.tcpi_rto;
1196 #endif /* __HAVE_TCP_INFO_RTO */
1198 rto_usecs = MAX(rto_usecs, 200000); /* at least 0.2s */
1199 rto_usecs = MIN(rto_usecs, 1000000); /* at max 1.0s */
1200 *_rto_usecs = rto_usecs;
1201 return NT_STATUS_OK;
1204 static NTSTATUS smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection *xconn,
1205 uint64_t *_acked_bytes)
1208 * Unless the kernel has an interface
1209 * to reveal the number of un-acked bytes
1210 * in the socket send queue, we'll assume
1211 * everything is already acked.
1213 * But that would mean that we better don't
1214 * pretent to support multi-channel.
1216 uint64_t unacked_bytes = 0;
1220 if (xconn->ack.force_unacked_timeout) {
1222 * Smbtorture tries to test channel failures...
1223 * Just pretend nothing was acked...
1225 DBG_INFO("Simulating channel failure: "
1226 "xconn->ack.unacked_bytes[%llu]\n",
1227 (unsigned long long)xconn->ack.unacked_bytes);
1228 return NT_STATUS_OK;
1231 #ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1237 * If we have kernel support to get
1238 * the number of bytes waiting in
1239 * the socket's send queue, we
1240 * use that in order to find out
1241 * the number of unacked bytes.
1243 ret = ioctl(xconn->transport.sock,
1244 __IOCTL_SEND_QUEUE_SIZE_OPCODE,
1247 int saved_errno = errno;
1248 NTSTATUS status = map_nt_error_from_unix(saved_errno);
1249 DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1250 "errno %d (%s) - %s\n",
1251 saved_errno, strerror(saved_errno),
1257 DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1258 (unsigned long long)xconn->ack.unacked_bytes,
1260 return NT_STATUS_INTERNAL_ERROR;
1262 unacked_bytes = value;
1265 if (xconn->ack.unacked_bytes == 0) {
1266 xconn->ack.unacked_bytes = unacked_bytes;
1267 return NT_STATUS_OK;
1270 if (xconn->ack.unacked_bytes < unacked_bytes) {
1271 DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1272 (unsigned long long)xconn->ack.unacked_bytes,
1273 (unsigned long long)unacked_bytes);
1274 return NT_STATUS_INTERNAL_ERROR;
1277 *_acked_bytes = xconn->ack.unacked_bytes - unacked_bytes;
1278 xconn->ack.unacked_bytes = unacked_bytes;
1279 return NT_STATUS_OK;
1282 static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue **queue,
1285 struct smbd_smb2_send_queue *e = NULL;
1286 struct smbd_smb2_send_queue *n = NULL;
1288 for (e = *queue; e != NULL; e = n) {
1291 DLIST_REMOVE(*queue, e);
1292 if (e->ack.req != NULL) {
1293 tevent_req_nterror(e->ack.req, status);
1298 static NTSTATUS smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue **queue,
1299 uint64_t acked_bytes)
1301 struct smbd_smb2_send_queue *e = NULL;
1302 struct smbd_smb2_send_queue *n = NULL;
1304 for (e = *queue; e != NULL; e = n) {
1309 if (e->ack.req == NULL) {
1313 if (e->ack.required_acked_bytes <= acked_bytes) {
1314 e->ack.required_acked_bytes = 0;
1315 DLIST_REMOVE(*queue, e);
1316 tevent_req_done(e->ack.req);
1319 e->ack.required_acked_bytes -= acked_bytes;
1321 expired = timeval_expired(&e->ack.timeout);
1323 return NT_STATUS_IO_TIMEOUT;
1327 return NT_STATUS_OK;
1330 static NTSTATUS smbd_smb2_check_ack_queue(struct smbXsrv_connection *xconn)
1332 uint64_t acked_bytes = 0;
1335 status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1336 if (!NT_STATUS_IS_OK(status)) {
1340 status = smbd_smb2_send_queue_ack_bytes(&xconn->ack.queue, acked_bytes);
1341 if (!NT_STATUS_IS_OK(status)) {
1345 status = smbd_smb2_send_queue_ack_bytes(&xconn->smb2.send_queue, 0);
1346 if (!NT_STATUS_IS_OK(status)) {
1350 return NT_STATUS_OK;
1353 static void smbXsrv_connection_ack_checker(struct tevent_req *subreq)
1355 struct smbXsrv_connection *xconn =
1356 tevent_req_callback_data(subreq,
1357 struct smbXsrv_connection);
1358 struct smbXsrv_client *client = xconn->client;
1359 struct timeval next_check;
1363 xconn->ack.checker_subreq = NULL;
1365 ok = tevent_wakeup_recv(subreq);
1366 TALLOC_FREE(subreq);
1368 smbd_server_connection_terminate(xconn,
1369 "tevent_wakeup_recv() failed");
1373 status = smbd_smb2_check_ack_queue(xconn);
1374 if (!NT_STATUS_IS_OK(status)) {
1375 smbd_server_connection_terminate(xconn, nt_errstr(status));
1379 next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1380 xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1383 if (xconn->ack.checker_subreq == NULL) {
1384 smbd_server_connection_terminate(xconn,
1385 "tevent_wakeup_send() failed");
1388 tevent_req_set_callback(xconn->ack.checker_subreq,
1389 smbXsrv_connection_ack_checker,
1393 static NTSTATUS smbXsrv_client_pending_breaks_updated(struct smbXsrv_client *client)
1395 struct smbXsrv_connection *xconn = NULL;
1397 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1398 struct timeval next_check;
1399 uint64_t acked_bytes = 0;
1403 * A new 'pending break cycle' starts
1404 * with a first pending break and lasts until
1405 * all pending breaks are finished.
1407 * This is typically a very short time,
1408 * the value of one retransmission timeout.
1411 if (client->pending_breaks == NULL) {
1413 * No more pending breaks, remove a pending
1416 TALLOC_FREE(xconn->ack.checker_subreq);
1420 if (xconn->ack.checker_subreq != NULL) {
1422 * The cycle already started =>
1429 * Get the current retransmission timeout value.
1431 * It may change over time, but fetching it once
1432 * per 'pending break' cycled should be enough.
1434 status = smbXsrv_connection_get_rto_usecs(xconn,
1435 &xconn->ack.rto_usecs);
1436 if (!NT_STATUS_IS_OK(status)) {
1441 * At the start of the cycle we reset the
1442 * unacked_bytes counter (first to 0 and
1443 * within smbXsrv_connection_get_acked_bytes()
1444 * to the current value in the kernel
1447 xconn->ack.unacked_bytes = 0;
1448 status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1449 if (!NT_STATUS_IS_OK(status)) {
1454 * We setup a timer in order to check for
1455 * acked bytes after one retransmission timeout.
1457 * The code that sets up the send_queue.ack.timeout
1458 * uses a multiple of the retransmission timeout.
1460 next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1461 xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1464 if (xconn->ack.checker_subreq == NULL) {
1465 return NT_STATUS_NO_MEMORY;
1467 tevent_req_set_callback(xconn->ack.checker_subreq,
1468 smbXsrv_connection_ack_checker,
1472 return NT_STATUS_OK;
1475 void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
1478 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
1482 xconn->transport.status = status;
1483 TALLOC_FREE(xconn->transport.fde);
1484 if (xconn->transport.sock != -1) {
1485 xconn->transport.sock = -1;
1487 smbd_smb2_send_queue_ack_fail(&xconn->ack.queue, status);
1488 smbd_smb2_send_queue_ack_fail(&xconn->smb2.send_queue, status);
1489 xconn->smb2.send_queue_len = 0;
1490 DO_PROFILE_INC(disconnect);
1493 size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
1495 struct smbXsrv_connection *xconn = NULL;
1498 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1499 if (NT_STATUS_IS_OK(xconn->transport.status)) {
1507 struct smbXsrv_connection_shutdown_state {
1508 struct smbXsrv_connection *xconn;
1511 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
1513 static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
1514 struct tevent_context *ev,
1515 struct smbXsrv_connection *xconn)
1517 struct tevent_req *req = NULL;
1518 struct smbXsrv_connection_shutdown_state *state = NULL;
1519 struct tevent_req *subreq = NULL;
1521 struct smbd_smb2_request *preq = NULL;
1525 * The caller should have called
1526 * smbXsrv_connection_disconnect_transport() before.
1528 SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
1529 SMB_ASSERT(xconn->transport.terminating);
1530 SMB_ASSERT(xconn->transport.shutdown_wait_queue == NULL);
1532 req = tevent_req_create(mem_ctx, &state,
1533 struct smbXsrv_connection_shutdown_state);
1538 state->xconn = xconn;
1539 tevent_req_defer_callback(req, ev);
1541 xconn->transport.shutdown_wait_queue =
1542 tevent_queue_create(state, "smbXsrv_connection_shutdown_queue");
1543 if (tevent_req_nomem(xconn->transport.shutdown_wait_queue, req)) {
1544 return tevent_req_post(req, ev);
1547 for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next) {
1549 * Now wait until the request is finished.
1551 * We don't set a callback, as we just want to block the
1552 * wait queue and the talloc_free() of the request will
1553 * remove the item from the wait queue.
1555 * Note that we don't cancel the requests here
1556 * in order to keep the replay detection logic correct.
1558 * However if we teardown the last channel of
1559 * a connection, we'll call some logic via
1560 * smbXsrv_session_disconnect_xconn()
1561 * -> smbXsrv_session_disconnect_xconn_callback()
1562 * -> smbXsrv_session_remove_channel()
1563 * -> smb2srv_session_shutdown_send()
1564 * will indeed cancel the request.
1566 subreq = tevent_queue_wait_send(preq, ev,
1567 xconn->transport.shutdown_wait_queue);
1568 if (tevent_req_nomem(subreq, req)) {
1569 return tevent_req_post(req, ev);
1574 * This may attach sessions with num_channels == 0
1575 * to xconn->transport.shutdown_wait_queue.
1577 status = smbXsrv_session_disconnect_xconn(xconn);
1578 if (tevent_req_nterror(req, status)) {
1579 return tevent_req_post(req, ev);
1582 len = tevent_queue_length(xconn->transport.shutdown_wait_queue);
1584 tevent_req_done(req);
1585 return tevent_req_post(req, ev);
1589 * Now we add our own waiter to the end of the queue,
1590 * this way we get notified when all pending requests are finished
1591 * and send to the socket.
1593 subreq = tevent_queue_wait_send(state, ev, xconn->transport.shutdown_wait_queue);
1594 if (tevent_req_nomem(subreq, req)) {
1595 return tevent_req_post(req, ev);
1597 tevent_req_set_callback(subreq, smbXsrv_connection_shutdown_wait_done, req);
1602 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
1604 struct tevent_req *req =
1605 tevent_req_callback_data(subreq,
1607 struct smbXsrv_connection_shutdown_state *state =
1608 tevent_req_data(req,
1609 struct smbXsrv_connection_shutdown_state);
1610 struct smbXsrv_connection *xconn = state->xconn;
1612 tevent_queue_wait_recv(subreq);
1613 TALLOC_FREE(subreq);
1615 tevent_req_done(req);
1617 * make sure the xconn pointer is still valid,
1618 * it should as we used tevent_req_defer_callback()
1620 SMB_ASSERT(xconn->transport.terminating);
1623 static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
1625 struct smbXsrv_connection_shutdown_state *state =
1626 tevent_req_data(req,
1627 struct smbXsrv_connection_shutdown_state);
1628 struct smbXsrv_connection *xconn = state->xconn;
1630 * make sure the xconn pointer is still valid,
1631 * it should as we used tevent_req_defer_callback()
1633 SMB_ASSERT(xconn->transport.terminating);
1634 return tevent_req_simple_recv_ntstatus(req);
1637 static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
1639 struct smbXsrv_connection *xconn =
1640 tevent_req_callback_data(subreq,
1641 struct smbXsrv_connection);
1642 struct smbXsrv_client *client = xconn->client;
1645 status = smbXsrv_connection_shutdown_recv(subreq);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 exit_server("smbXsrv_connection_shutdown_recv failed");
1650 DLIST_REMOVE(client->connections, xconn);
1654 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
1656 const char *location)
1658 struct smbXsrv_client *client = xconn->client;
1662 * Make sure that no new request will be able to use this session.
1664 * smbXsrv_connection_disconnect_transport() might be called already,
1665 * but calling it again is a no-op.
1667 smbXsrv_connection_disconnect_transport(xconn,
1668 NT_STATUS_CONNECTION_DISCONNECTED);
1670 num_ok = smbXsrv_client_valid_connections(client);
1672 if (xconn->transport.terminating) {
1673 DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1674 smbXsrv_connection_dbg(xconn), num_ok,
1678 xconn->transport.terminating = true;
1680 DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1681 smbXsrv_connection_dbg(xconn), num_ok,
1684 if (xconn->has_cluster_movable_ip) {
1686 * If the connection has a movable cluster public address
1687 * we disconnect all client connections,
1688 * as the public address might be moved to
1691 * In future we may recheck which node currently
1692 * holds this address, but for now we keep it simple.
1694 smbd_server_disconnect_client_ex(xconn->client,
1701 struct tevent_req *subreq = NULL;
1703 subreq = smbXsrv_connection_shutdown_send(client,
1706 if (subreq == NULL) {
1707 exit_server("smbXsrv_connection_shutdown_send failed");
1709 tevent_req_set_callback(subreq,
1710 smbd_server_connection_terminate_done,
1716 * The last connection was disconnected
1718 exit_server_cleanly(reason);
1721 void smbd_server_disconnect_client_ex(struct smbXsrv_client *client,
1723 const char *location)
1727 num_ok = smbXsrv_client_valid_connections(client);
1729 DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1730 client->global->remote_address, num_ok,
1734 * Something bad happened we need to disconnect all connections.
1736 exit_server_cleanly(reason);
1739 static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1740 struct iovec *outvec,
1741 const struct iovec *srcvec)
1743 const uint8_t *srctf;
1745 const uint8_t *srchdr;
1747 const uint8_t *srcbody;
1749 const uint8_t *expected_srcbody;
1750 const uint8_t *srcdyn;
1752 const uint8_t *expected_srcdyn;
1758 srctf = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1759 srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1760 srchdr = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1761 srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1762 srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1763 srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1764 expected_srcbody = srchdr + SMB2_HDR_BODY;
1765 srcdyn = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1766 srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1767 expected_srcdyn = srcbody + 8;
1769 if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1773 if (srchdr_len != SMB2_HDR_BODY) {
1777 if (srctf_len == SMB2_TF_HDR_SIZE) {
1778 dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1779 if (dsttf == NULL) {
1785 outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1786 outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1788 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1789 * be allocated with size OUTVEC_ALLOC_SIZE. */
1791 dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1792 if (dsthdr == NULL) {
1795 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1796 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1799 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1800 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1801 * then duplicate this. Else use talloc_memdup().
1804 if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1805 dstbody = dsthdr + SMB2_HDR_BODY;
1807 dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1808 if (dstbody == NULL) {
1812 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1813 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1816 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1818 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1819 * then duplicate this. Else use talloc_memdup().
1822 if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1823 dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1824 } else if (srcdyn == NULL) {
1827 dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1828 if (dstdyn == NULL) {
1832 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1833 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1838 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1840 struct smbd_smb2_request *newreq = NULL;
1841 struct iovec *outvec = NULL;
1842 int count = req->out.vector_count;
1846 newreq = smbd_smb2_request_allocate(req->xconn);
1851 newreq->sconn = req->sconn;
1852 newreq->xconn = req->xconn;
1853 newreq->session = req->session;
1854 newreq->do_encryption = req->do_encryption;
1855 newreq->do_signing = req->do_signing;
1856 newreq->current_idx = req->current_idx;
1858 outvec = talloc_zero_array(newreq, struct iovec, count);
1860 TALLOC_FREE(newreq);
1863 newreq->out.vector = outvec;
1864 newreq->out.vector_count = count;
1866 /* Setup the outvec's identically to req. */
1867 outvec[0].iov_base = newreq->out.nbt_hdr;
1868 outvec[0].iov_len = 4;
1869 memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1871 /* Setup the vectors identically to the ones in req. */
1872 for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1873 if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1880 TALLOC_FREE(newreq);
1884 ok = smb2_setup_nbt_length(newreq->out.vector,
1885 newreq->out.vector_count);
1887 TALLOC_FREE(newreq);
1894 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
1896 struct smbXsrv_connection *xconn = req->xconn;
1898 struct iovec *firsttf = NULL;
1899 struct iovec *outhdr_v = NULL;
1900 uint8_t *outhdr = NULL;
1901 struct smbd_smb2_request *nreq = NULL;
1905 /* Create a new smb2 request we'll use
1906 for the interim return. */
1907 nreq = dup_smb2_req(req);
1909 return NT_STATUS_NO_MEMORY;
1912 /* Lose the last X out vectors. They're the
1913 ones we'll be using for the async reply. */
1914 nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
1916 ok = smb2_setup_nbt_length(nreq->out.vector,
1917 nreq->out.vector_count);
1919 return NT_STATUS_INVALID_PARAMETER_MIX;
1922 /* Step back to the previous reply. */
1923 nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
1924 firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
1925 outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
1926 outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
1927 /* And end the chain. */
1928 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
1930 /* Calculate outgoing credits */
1931 smb2_calculate_credits(req, nreq);
1933 if (DEBUGLEVEL >= 10) {
1934 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1935 (unsigned int)nreq->current_idx );
1936 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1937 (unsigned int)nreq->out.vector_count );
1938 print_req_vectors(nreq);
1942 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1943 * we need to sign/encrypt here with the last/first key we remembered
1945 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
1946 status = smb2_signing_encrypt_pdu(req->first_enc_key,
1948 nreq->out.vector_count - first_idx);
1949 if (!NT_STATUS_IS_OK(status)) {
1952 } else if (smb2_signing_key_valid(req->last_sign_key)) {
1953 status = smb2_signing_sign_pdu(req->last_sign_key,
1955 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1956 if (!NT_STATUS_IS_OK(status)) {
1961 nreq->queue_entry.mem_ctx = nreq;
1962 nreq->queue_entry.vector = nreq->out.vector;
1963 nreq->queue_entry.count = nreq->out.vector_count;
1964 DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
1965 xconn->smb2.send_queue_len++;
1967 status = smbd_smb2_flush_send_queue(xconn);
1968 if (!NT_STATUS_IS_OK(status)) {
1972 return NT_STATUS_OK;
1975 struct smbd_smb2_request_pending_state {
1976 struct smbd_smb2_send_queue queue_entry;
1977 uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1978 struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1981 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1982 struct tevent_timer *te,
1983 struct timeval current_time,
1984 void *private_data);
1986 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1987 struct tevent_req *subreq,
1988 uint32_t defer_time)
1991 struct timeval defer_endtime;
1992 uint8_t *outhdr = NULL;
1995 if (!tevent_req_is_in_progress(subreq)) {
1997 * This is a performance optimization,
1998 * it avoids one tevent_loop iteration,
1999 * which means we avoid one
2000 * talloc_stackframe_pool/talloc_free pair.
2002 tevent_req_notify_callback(subreq);
2003 return NT_STATUS_OK;
2006 req->subreq = subreq;
2009 if (req->async_te) {
2010 /* We're already async. */
2011 return NT_STATUS_OK;
2014 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2015 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2016 if (flags & SMB2_HDR_FLAG_ASYNC) {
2017 /* We're already async. */
2018 return NT_STATUS_OK;
2021 if (req->async_internal || defer_time == 0) {
2023 * An SMB2 request implementation wants to handle the request
2024 * asynchronously "internally" while keeping synchronous
2025 * behaviour for the SMB2 request. This means we don't send an
2026 * interim response and we can allow processing of compound SMB2
2027 * requests (cf the subsequent check) for all cases.
2029 return NT_STATUS_OK;
2032 if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
2034 * We're trying to go async in a compound request
2035 * chain. This is only allowed for opens that cause an
2036 * oplock break or for the last operation in the
2037 * chain, otherwise it is not allowed. See
2038 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2040 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2042 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
2044 * Cancel the outstanding request.
2046 bool ok = tevent_req_cancel(req->subreq);
2048 return NT_STATUS_OK;
2050 TALLOC_FREE(req->subreq);
2051 return smbd_smb2_request_error(req,
2052 NT_STATUS_INTERNAL_ERROR);
2056 if (DEBUGLEVEL >= 10) {
2057 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2058 (unsigned int)req->current_idx );
2059 print_req_vectors(req);
2062 if (req->current_idx > 1) {
2064 * We're going async in a compound
2065 * chain after the first request has
2066 * already been processed. Send an
2067 * interim response containing the
2068 * set of replies already generated.
2070 int idx = req->current_idx;
2072 status = smb2_send_async_interim_response(req);
2073 if (!NT_STATUS_IS_OK(status)) {
2076 TALLOC_FREE(req->first_enc_key);
2078 req->current_idx = 1;
2081 * Re-arrange the in.vectors to remove what
2084 memmove(&req->in.vector[1],
2085 &req->in.vector[idx],
2086 sizeof(req->in.vector[0])*(req->in.vector_count - idx));
2087 req->in.vector_count = 1 + (req->in.vector_count - idx);
2089 /* Re-arrange the out.vectors to match. */
2090 memmove(&req->out.vector[1],
2091 &req->out.vector[idx],
2092 sizeof(req->out.vector[0])*(req->out.vector_count - idx));
2093 req->out.vector_count = 1 + (req->out.vector_count - idx);
2095 if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
2097 * We only have one remaining request as
2098 * we've processed everything else.
2099 * This is no longer a compound request.
2101 req->compound_related = false;
2102 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2103 flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
2104 SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
2107 TALLOC_FREE(req->last_sign_key);
2110 * smbd_smb2_request_pending_timer() just send a packet
2111 * to the client and doesn't need any impersonation.
2112 * So we use req->xconn->client->raw_ev_ctx instead
2113 * of req->ev_ctx here.
2115 defer_endtime = timeval_current_ofs_usec(defer_time);
2116 req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
2118 smbd_smb2_request_pending_timer,
2120 if (req->async_te == NULL) {
2121 return NT_STATUS_NO_MEMORY;
2124 return NT_STATUS_OK;
2128 struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
2129 struct smbXsrv_connection *xconn,
2132 struct smbXsrv_channel_global0 *c = NULL;
2134 struct smb2_signing_key *key = NULL;
2135 bool has_channel = false;
2137 status = smbXsrv_session_find_channel(session, xconn, &c);
2138 if (NT_STATUS_IS_OK(status)) {
2139 key = c->signing_key;
2143 if (!smb2_signing_key_valid(key)) {
2144 key = session->global->signing_key;
2145 has_channel = false;
2148 if (_has_channel != NULL) {
2149 *_has_channel = has_channel;
2155 static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
2156 uint64_t *new_nonce_high,
2157 uint64_t *new_nonce_low)
2159 uint64_t nonce_high;
2162 session->nonce_low += 1;
2163 if (session->nonce_low == 0) {
2164 session->nonce_low += 1;
2165 session->nonce_high += 1;
2169 * CCM and GCM algorithms must never have their
2170 * nonce wrap, or the security of the whole
2171 * communication and the keys is destroyed.
2172 * We must drop the connection once we have
2173 * transfered too much data.
2175 * NOTE: We assume nonces greater than 8 bytes.
2177 if (session->nonce_high >= session->nonce_high_max) {
2178 return NT_STATUS_ENCRYPTION_FAILED;
2181 nonce_high = session->nonce_high_random;
2182 nonce_high += session->nonce_high;
2183 nonce_low = session->nonce_low;
2185 *new_nonce_high = nonce_high;
2186 *new_nonce_low = nonce_low;
2187 return NT_STATUS_OK;
2190 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
2191 struct tevent_timer *te,
2192 struct timeval current_time,
2195 struct smbd_smb2_request *req =
2196 talloc_get_type_abort(private_data,
2197 struct smbd_smb2_request);
2198 struct smbXsrv_connection *xconn = req->xconn;
2199 struct smbd_smb2_request_pending_state *state = NULL;
2200 uint8_t *outhdr = NULL;
2201 const uint8_t *inhdr = NULL;
2203 uint8_t *hdr = NULL;
2204 uint8_t *body = NULL;
2205 uint8_t *dyn = NULL;
2207 uint64_t message_id = 0;
2208 uint64_t async_id = 0;
2212 TALLOC_FREE(req->async_te);
2214 /* Ensure our final reply matches the interim one. */
2215 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2216 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2217 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2218 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2220 async_id = message_id; /* keep it simple for now... */
2222 SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2223 SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
2225 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2227 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2228 (unsigned long long)async_id ));
2231 * What we send is identical to a smbd_smb2_request_error
2232 * packet with an error status of STATUS_PENDING. Make use
2233 * of this fact sometime when refactoring. JRA.
2236 state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
2237 if (state == NULL) {
2238 smbd_server_connection_terminate(xconn,
2239 nt_errstr(NT_STATUS_NO_MEMORY));
2243 tf = state->buf + NBT_HDR_SIZE;
2245 hdr = tf + SMB2_TF_HDR_SIZE;
2246 body = hdr + SMB2_HDR_BODY;
2249 if (req->do_encryption) {
2250 uint64_t nonce_high = 0;
2251 uint64_t nonce_low = 0;
2252 uint64_t session_id = req->session->global->session_wire_id;
2254 status = smb2_get_new_nonce(req->session,
2257 if (!NT_STATUS_IS_OK(status)) {
2258 smbd_server_connection_terminate(xconn,
2263 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2264 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2265 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2266 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2269 SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
2270 SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
2271 SSVAL(hdr, SMB2_HDR_EPOCH, 0);
2272 SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_PENDING));
2273 SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
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);
3175 } else if (opcode == SMB2_OP_IOCTL) {
3177 * Some special IOCTL calls don't require
3178 * file, tcon nor session.
3180 * They typically don't do any real action
3181 * on behalf of the client.
3183 * They are mainly used to alter the behavior
3184 * of the connection for testing. So we can
3185 * run as root and skip all file, tcon and session
3188 static const struct smbd_smb2_dispatch_table _root_ioctl_call = {
3192 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3193 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3194 uint32_t in_ctl_code;
3197 if (needed > body_size) {
3198 return smbd_smb2_request_error(req,
3199 NT_STATUS_INVALID_PARAMETER);
3202 in_ctl_code = IVAL(body, 0x04);
3204 * Only add trusted IOCTL codes here!
3206 switch (in_ctl_code) {
3207 case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
3208 call = &_root_ioctl_call;
3215 if (flags & SMB2_HDR_FLAG_CHAINED) {
3216 req->compound_related = true;
3219 if (call->need_session) {
3220 if (!NT_STATUS_IS_OK(session_status)) {
3221 return smbd_smb2_request_error(req, session_status);
3225 if (call->need_tcon) {
3226 SMB_ASSERT(call->need_session);
3229 * This call needs to be run as user.
3231 * smbd_smb2_request_check_tcon()
3232 * calls change_to_user() on success.
3233 * Which implies set_current_user_info()
3234 * and chdir_current_service().
3236 status = smbd_smb2_request_check_tcon(req);
3237 if (!NT_STATUS_IS_OK(status)) {
3238 return smbd_smb2_request_error(req, status);
3240 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3241 encryption_desired = true;
3243 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
3244 encryption_required = true;
3246 if (encryption_required && !req->was_encrypted) {
3247 req->do_encryption = true;
3248 return smbd_smb2_request_error(req,
3249 NT_STATUS_ACCESS_DENIED);
3250 } else if (encryption_desired) {
3251 req->do_encryption = true;
3253 } else if (call->need_session) {
3254 struct auth_session_info *session_info = NULL;
3257 * Unless we also have need_tcon (see above),
3258 * we still need to call set_current_user_info().
3261 session_info = req->session->global->auth_session_info;
3262 if (session_info == NULL) {
3263 return NT_STATUS_INVALID_HANDLE;
3266 set_current_user_info(session_info->unix_info->sanitized_username,
3267 session_info->unix_info->unix_name,
3268 session_info->info->domain_name);
3272 bool update_session_global = false;
3273 bool update_tcon_global = false;
3275 smb2srv_update_crypto_flags(req, opcode,
3276 &update_session_global,
3277 &update_tcon_global);
3279 if (update_session_global) {
3280 status = smbXsrv_session_update(x);
3281 if (!NT_STATUS_IS_OK(status)) {
3282 return smbd_smb2_request_error(req, status);
3285 if (update_tcon_global) {
3286 status = smbXsrv_tcon_update(req->tcon);
3287 if (!NT_STATUS_IS_OK(status)) {
3288 return smbd_smb2_request_error(req, status);
3293 if (call->fileid_ofs != 0) {
3294 size_t needed = call->fileid_ofs + 16;
3295 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3296 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3297 uint64_t file_id_persistent;
3298 uint64_t file_id_volatile;
3299 struct files_struct *fsp;
3301 SMB_ASSERT(call->need_tcon);
3303 if (needed > body_size) {
3304 return smbd_smb2_request_error(req,
3305 NT_STATUS_INVALID_PARAMETER);
3308 file_id_persistent = BVAL(body, call->fileid_ofs + 0);
3309 file_id_volatile = BVAL(body, call->fileid_ofs + 8);
3311 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
3313 if (req->compound_related &&
3314 !NT_STATUS_IS_OK(req->compound_create_err))
3316 return smbd_smb2_request_error(req,
3317 req->compound_create_err);
3319 if (!call->allow_invalid_fileid) {
3320 return smbd_smb2_request_error(req,
3321 NT_STATUS_FILE_CLOSED);
3324 if (file_id_persistent != UINT64_MAX) {
3325 return smbd_smb2_request_error(req,
3326 NT_STATUS_FILE_CLOSED);
3328 if (file_id_volatile != UINT64_MAX) {
3329 return smbd_smb2_request_error(req,
3330 NT_STATUS_FILE_CLOSED);
3333 if (fsp->fsp_flags.encryption_required && !req->was_encrypted) {
3334 return smbd_smb2_request_error(req,
3335 NT_STATUS_ACCESS_DENIED);
3340 status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 return smbd_smb2_request_error(req, status);
3345 if (call->as_root) {
3346 SMB_ASSERT(call->fileid_ofs == 0);
3347 /* This call needs to be run as root */
3348 change_to_root_user();
3350 SMB_ASSERT(call->need_tcon);
3353 #define _INBYTES(_r) \
3354 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3357 case SMB2_OP_NEGPROT:
3358 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
3359 req->profile, _INBYTES(req));
3360 return_value = smbd_smb2_request_process_negprot(req);
3363 case SMB2_OP_SESSSETUP:
3364 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
3365 req->profile, _INBYTES(req));
3366 return_value = smbd_smb2_request_process_sesssetup(req);
3369 case SMB2_OP_LOGOFF:
3370 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
3371 req->profile, _INBYTES(req));
3372 return_value = smbd_smb2_request_process_logoff(req);
3376 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
3377 req->profile, _INBYTES(req));
3378 return_value = smbd_smb2_request_process_tcon(req);
3382 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
3383 req->profile, _INBYTES(req));
3384 return_value = smbd_smb2_request_process_tdis(req);
3387 case SMB2_OP_CREATE:
3388 if (req->subreq == NULL) {
3389 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
3390 req->profile, _INBYTES(req));
3392 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
3394 return_value = smbd_smb2_request_process_create(req);
3398 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
3399 req->profile, _INBYTES(req));
3400 return_value = smbd_smb2_request_process_close(req);
3404 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
3405 req->profile, _INBYTES(req));
3406 return_value = smbd_smb2_request_process_flush(req);
3410 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
3411 req->profile, _INBYTES(req));
3412 return_value = smbd_smb2_request_process_read(req);
3416 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
3417 req->profile, _INBYTES(req));
3418 return_value = smbd_smb2_request_process_write(req);
3422 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
3423 req->profile, _INBYTES(req));
3424 return_value = smbd_smb2_request_process_lock(req);
3428 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
3429 req->profile, _INBYTES(req));
3430 return_value = smbd_smb2_request_process_ioctl(req);
3433 case SMB2_OP_CANCEL:
3434 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
3435 req->profile, _INBYTES(req));
3436 return_value = smbd_smb2_request_process_cancel(req);
3437 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
3440 * We don't need the request anymore cancel requests never
3443 * smbd_smb2_request_process_cancel() already called
3444 * DLIST_REMOVE(xconn->smb2.requests, req);
3450 case SMB2_OP_KEEPALIVE:
3451 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
3452 req->profile, _INBYTES(req));
3453 return_value = smbd_smb2_request_process_keepalive(req);
3456 case SMB2_OP_QUERY_DIRECTORY:
3457 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
3458 req->profile, _INBYTES(req));
3459 return_value = smbd_smb2_request_process_query_directory(req);
3462 case SMB2_OP_NOTIFY:
3463 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
3464 req->profile, _INBYTES(req));
3465 return_value = smbd_smb2_request_process_notify(req);
3468 case SMB2_OP_GETINFO:
3469 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
3470 req->profile, _INBYTES(req));
3471 return_value = smbd_smb2_request_process_getinfo(req);
3474 case SMB2_OP_SETINFO:
3475 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
3476 req->profile, _INBYTES(req));
3477 return_value = smbd_smb2_request_process_setinfo(req);
3481 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
3482 req->profile, _INBYTES(req));
3483 return_value = smbd_smb2_request_process_break(req);
3487 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3490 return return_value;
3493 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
3495 struct smbXsrv_connection *xconn = req->xconn;
3496 const uint8_t *inhdr;
3497 uint16_t channel_sequence;
3498 struct smbXsrv_open *op;
3500 if (!req->request_counters_updated) {
3504 req->request_counters_updated = false;
3506 if (xconn->protocol < PROTOCOL_SMB3_00) {
3510 if (req->compat_chain_fsp == NULL) {
3514 op = req->compat_chain_fsp->op;
3519 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
3520 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
3522 if ((op->global->channel_sequence == channel_sequence) &&
3523 (op->global->channel_generation == req->channel_generation)) {
3524 SMB_ASSERT(op->request_count > 0);
3525 op->request_count -= 1;
3527 SMB_ASSERT(op->pre_request_count > 0);
3528 op->pre_request_count -= 1;
3532 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
3534 struct smbXsrv_connection *xconn = req->xconn;
3536 struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
3537 struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
3538 struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
3543 TALLOC_FREE(req->async_te);
3545 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3546 smbd_smb2_request_reply_update_counts(req);
3548 if (req->do_encryption &&
3549 (firsttf->iov_len == 0) &&
3550 (!smb2_signing_key_valid(req->first_enc_key)) &&
3551 (req->session != NULL) &&
3552 smb2_signing_key_valid(req->session->global->encryption_key))
3554 struct smb2_signing_key *encryption_key =
3555 req->session->global->encryption_key;
3557 uint64_t session_id = req->session->global->session_wire_id;
3558 uint64_t nonce_high;
3561 status = smb2_get_new_nonce(req->session,
3564 if (!NT_STATUS_IS_OK(status)) {
3569 * We need to place the SMB2_TRANSFORM header before the
3574 * we need to remember the encryption key
3575 * and defer the signing/encryption until
3576 * we are sure that we do not change
3579 status = smb2_signing_key_copy(req,
3581 &req->first_enc_key);
3582 if (!NT_STATUS_IS_OK(status)) {
3586 tf = talloc_zero_array(req, uint8_t,
3589 return NT_STATUS_NO_MEMORY;
3592 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3593 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
3594 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
3595 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
3597 firsttf->iov_base = (void *)tf;
3598 firsttf->iov_len = SMB2_TF_HDR_SIZE;
3601 if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
3602 (smb2_signing_key_valid(req->last_sign_key)) &&
3603 (firsttf->iov_len == 0))
3605 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
3606 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
3609 * As we are sure the header of the last request in the
3610 * compound chain will not change, we can to sign here
3611 * with the last signing key we remembered.
3613 status = smb2_signing_sign_pdu(req->last_sign_key,
3615 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3616 if (!NT_STATUS_IS_OK(status)) {
3620 TALLOC_FREE(req->last_sign_key);
3622 SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
3623 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
3625 req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
3627 if (req->current_idx < req->out.vector_count) {
3629 * We must process the remaining compound
3630 * SMB2 requests before any new incoming SMB2
3631 * requests. This is because incoming SMB2
3632 * requests may include a cancel for a
3633 * compound request we haven't processed
3636 struct tevent_immediate *im = tevent_create_immediate(req);
3638 return NT_STATUS_NO_MEMORY;
3641 if (req->do_signing && firsttf->iov_len == 0) {
3642 struct smbXsrv_session *x = req->session;
3643 struct smb2_signing_key *signing_key =
3644 smbd_smb2_signing_key(x, xconn, NULL);
3647 * we need to remember the signing key
3648 * and defer the signing until
3649 * we are sure that we do not change
3652 status = smb2_signing_key_copy(req,
3654 &req->last_sign_key);
3655 if (!NT_STATUS_IS_OK(status)) {
3661 * smbd_smb2_request_dispatch() will redo the impersonation.
3662 * So we use req->xconn->client->raw_ev_ctx instead
3663 * of req->ev_ctx here.
3665 tevent_schedule_immediate(im,
3666 req->xconn->client->raw_ev_ctx,
3667 smbd_smb2_request_dispatch_immediate,
3669 return NT_STATUS_OK;
3672 if (req->compound_related) {
3673 req->compound_related = false;
3676 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
3678 return NT_STATUS_INVALID_PARAMETER_MIX;
3681 /* Set credit for these operations (zero credits if this
3682 is a final reply for an async operation). */
3683 smb2_calculate_credits(req, req);
3686 * now check if we need to sign the current response
3688 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3689 status = smb2_signing_encrypt_pdu(req->first_enc_key,
3691 req->out.vector_count - first_idx);
3692 if (!NT_STATUS_IS_OK(status)) {
3695 } else if (req->do_signing) {
3696 struct smbXsrv_session *x = req->session;
3697 struct smb2_signing_key *signing_key =
3698 smbd_smb2_signing_key(x, xconn, NULL);
3700 status = smb2_signing_sign_pdu(signing_key,
3702 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3703 if (!NT_STATUS_IS_OK(status)) {
3707 TALLOC_FREE(req->first_enc_key);
3709 if (req->preauth != NULL) {
3710 gnutls_hash_hd_t hash_hnd = NULL;
3714 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3716 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3718 rc = gnutls_hash(hash_hnd,
3719 req->preauth->sha512_value,
3720 sizeof(req->preauth->sha512_value));
3722 gnutls_hash_deinit(hash_hnd, NULL);
3723 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3725 for (i = 1; i < req->in.vector_count; i++) {
3726 rc = gnutls_hash(hash_hnd,
3727 req->in.vector[i].iov_base,
3728 req->in.vector[i].iov_len);
3730 gnutls_hash_deinit(hash_hnd, NULL);
3731 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3735 gnutls_hash_deinit(hash_hnd, NULL);
3736 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3738 gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3740 rc = gnutls_hash(hash_hnd,
3741 req->preauth->sha512_value,
3742 sizeof(req->preauth->sha512_value));
3744 gnutls_hash_deinit(hash_hnd, NULL);
3745 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3747 for (i = 1; i < req->out.vector_count; i++) {
3748 rc = gnutls_hash(hash_hnd,
3749 req->out.vector[i].iov_base,
3750 req->out.vector[i].iov_len);
3752 gnutls_hash_deinit(hash_hnd, NULL);
3753 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3757 gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3759 req->preauth = NULL;
3762 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3763 if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3764 outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3765 /* Dynamic part is NULL. Chop it off,
3766 We're going to send it via sendfile. */
3767 req->out.vector_count -= 1;
3771 * We're done with this request -
3772 * move it off the "being processed" queue.
3774 DLIST_REMOVE(xconn->smb2.requests, req);
3776 req->queue_entry.mem_ctx = req;
3777 req->queue_entry.vector = req->out.vector;
3778 req->queue_entry.count = req->out.vector_count;
3779 DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3780 xconn->smb2.send_queue_len++;
3782 status = smbd_smb2_flush_send_queue(xconn);
3783 if (!NT_STATUS_IS_OK(status)) {
3787 return NT_STATUS_OK;
3790 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3792 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3793 struct tevent_immediate *im,
3796 struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3797 struct smbd_smb2_request);
3798 struct smbXsrv_connection *xconn = req->xconn;
3803 if (DEBUGLEVEL >= 10) {
3804 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3805 req->current_idx, req->in.vector_count));
3806 print_req_vectors(req);
3809 status = smbd_smb2_request_dispatch(req);
3810 if (!NT_STATUS_IS_OK(status)) {
3811 smbd_server_connection_terminate(xconn, nt_errstr(status));
3815 status = smbd_smb2_request_next_incoming(xconn);
3816 if (!NT_STATUS_IS_OK(status)) {
3817 smbd_server_connection_terminate(xconn, nt_errstr(status));
3822 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3824 DATA_BLOB body, DATA_BLOB *dyn,
3825 const char *location)
3828 struct iovec *outbody_v;
3829 struct iovec *outdyn_v;
3830 uint32_t next_command_ofs;
3833 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3834 mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
3836 DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
3837 "body[%u] dyn[%s:%u] at %s\n",
3841 (unsigned int)body.length,
3843 (unsigned int)(dyn ? dyn->length : 0),
3846 if (body.length < 2) {
3847 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3850 if ((body.length % 2) != 0) {
3851 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3854 outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3855 outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3857 next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3858 SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3860 outbody_v->iov_base = (void *)body.data;
3861 outbody_v->iov_len = body.length;
3864 outdyn_v->iov_base = (void *)dyn->data;
3865 outdyn_v->iov_len = dyn->length;
3867 outdyn_v->iov_base = NULL;
3868 outdyn_v->iov_len = 0;
3872 * See if we need to recalculate the offset to the next response
3874 * Note that all responses may require padding (including the very last
3877 if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3878 next_command_ofs = SMB2_HDR_BODY;
3879 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3880 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3883 if ((next_command_ofs % 8) != 0) {
3884 size_t pad_size = 8 - (next_command_ofs % 8);
3885 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3887 * if the dyn buffer is empty
3888 * we can use it to add padding
3892 pad = talloc_zero_array(req,
3895 return smbd_smb2_request_error(req,
3896 NT_STATUS_NO_MEMORY);
3899 outdyn_v->iov_base = (void *)pad;
3900 outdyn_v->iov_len = pad_size;
3903 * For now we copy the dynamic buffer
3904 * and add the padding to the new buffer
3911 old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3912 old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3914 new_size = old_size + pad_size;
3915 new_dyn = talloc_zero_array(req,
3917 if (new_dyn == NULL) {
3918 return smbd_smb2_request_error(req,
3919 NT_STATUS_NO_MEMORY);
3922 memcpy(new_dyn, old_dyn, old_size);
3923 memset(new_dyn + old_size, 0, pad_size);
3925 outdyn_v->iov_base = (void *)new_dyn;
3926 outdyn_v->iov_len = new_size;
3928 next_command_ofs += pad_size;
3931 if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3932 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3934 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3936 return smbd_smb2_request_reply(req);
3939 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3942 const char *location)
3944 struct smbXsrv_connection *xconn = req->xconn;
3947 uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3948 size_t unread_bytes = smbd_smb2_unread_bytes(req);
3950 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3951 "at %s\n", req->current_idx, nt_errstr(status),
3952 info ? " +info" : "", location);
3955 /* Recvfile error. Drain incoming socket. */
3959 ret = drain_socket(xconn->transport.sock, unread_bytes);
3960 if (ret != unread_bytes) {
3964 error = NT_STATUS_IO_DEVICE_ERROR;
3966 error = map_nt_error_from_unix_common(errno);
3969 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3970 "ret[%u] errno[%d] => %s\n",
3971 (unsigned)unread_bytes,
3972 (unsigned)ret, errno, nt_errstr(error)));
3977 body.data = outhdr + SMB2_HDR_BODY;
3979 SSVAL(body.data, 0, 9);
3982 SIVAL(body.data, 0x04, info->length);
3984 /* Allocated size of req->out.vector[i].iov_base
3985 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3986 * 1 byte without having to do an alloc.
3989 info->data = ((uint8_t *)outhdr) +
3990 OUTVEC_ALLOC_SIZE - 1;
3992 SCVAL(info->data, 0, 0);
3996 * Note: Even if there is an error, continue to process the request.
4000 return smbd_smb2_request_done_ex(req, status, body, info, __location__);
4003 struct smbd_smb2_break_state {
4004 struct tevent_req *req;
4005 struct smbd_smb2_send_queue queue_entry;
4006 uint8_t nbt_hdr[NBT_HDR_SIZE];
4007 uint8_t hdr[SMB2_HDR_BODY];
4008 struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
4011 static struct tevent_req *smbd_smb2_break_send(TALLOC_CTX *mem_ctx,
4012 struct tevent_context *ev,
4013 struct smbXsrv_connection *xconn,
4014 uint64_t session_id,
4015 const uint8_t *body,
4018 struct tevent_req *req = NULL;
4019 struct smbd_smb2_break_state *state = NULL;
4023 req = tevent_req_create(mem_ctx, &state,
4024 struct smbd_smb2_break_state);
4030 tevent_req_defer_callback(req, ev);
4032 SIVAL(state->hdr, 0, SMB2_MAGIC);
4033 SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
4034 SSVAL(state->hdr, SMB2_HDR_EPOCH, 0);
4035 SIVAL(state->hdr, SMB2_HDR_STATUS, 0);
4036 SSVAL(state->hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK);
4037 SSVAL(state->hdr, SMB2_HDR_CREDIT, 0);
4038 SIVAL(state->hdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
4039 SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, 0);
4040 SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
4041 SIVAL(state->hdr, SMB2_HDR_PID, 0);
4042 SIVAL(state->hdr, SMB2_HDR_TID, 0);
4043 SBVAL(state->hdr, SMB2_HDR_SESSION_ID, session_id);
4044 memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
4046 state->vector[0] = (struct iovec) {
4047 .iov_base = state->nbt_hdr,
4048 .iov_len = sizeof(state->nbt_hdr)
4051 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
4056 state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
4057 .iov_base = state->hdr,
4058 .iov_len = sizeof(state->hdr)
4061 state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
4062 .iov_base = discard_const_p(uint8_t, body),
4063 .iov_len = body_len,
4067 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4070 ok = smb2_setup_nbt_length(state->vector,
4071 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
4073 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4074 return tevent_req_post(req, ev);
4078 * We require TCP acks for this PDU to the client!
4079 * We want 5 retransmissions and timeout when the
4080 * retransmission timeout (rto) passed 6 times.
4082 * required_acked_bytes gets a dummy value of
4083 * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4084 * it'll get the real value when it's moved to
4087 * state->queue_entry.ack.req gets completed with
4088 * 1. tevent_req_done(), when all bytes are acked.
4089 * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4090 * the timeout expired before all bytes were acked.
4091 * 2b. tevent_req_nterror(transport_error), when the
4092 * connection got a disconnect from the kernel.
4094 state->queue_entry.ack.timeout =
4095 timeval_current_ofs_usec(xconn->ack.rto_usecs * 6);
4096 state->queue_entry.ack.required_acked_bytes = UINT64_MAX;
4097 state->queue_entry.ack.req = req;
4098 state->queue_entry.mem_ctx = state;
4099 state->queue_entry.vector = state->vector;
4100 state->queue_entry.count = ARRAY_SIZE(state->vector);
4101 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
4102 xconn->smb2.send_queue_len++;
4104 status = smbd_smb2_flush_send_queue(xconn);
4105 if (tevent_req_nterror(req, status)) {
4106 return tevent_req_post(req, ev);
4112 static NTSTATUS smbd_smb2_break_recv(struct tevent_req *req)
4114 return tevent_req_simple_recv_ntstatus(req);
4117 struct smbXsrv_pending_break {
4118 struct smbXsrv_pending_break *prev, *next;
4119 struct smbXsrv_client *client;
4120 bool disable_oplock_break_retries;
4121 uint64_t session_id;
4122 uint64_t last_channel_id;
4125 uint8_t oplock[0x18];
4126 uint8_t lease[0x2c];
4131 static void smbXsrv_pending_break_done(struct tevent_req *subreq);
4133 static struct smbXsrv_pending_break *smbXsrv_pending_break_create(
4134 struct smbXsrv_client *client,
4135 uint64_t session_id)
4137 struct smbXsrv_pending_break *pb = NULL;
4139 pb = talloc_zero(client, struct smbXsrv_pending_break);
4143 pb->client = client;
4144 pb->session_id = session_id;
4145 pb->disable_oplock_break_retries = lp_smb2_disable_oplock_break_retry();
4150 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb);
4152 static NTSTATUS smbXsrv_pending_break_schedule(struct smbXsrv_pending_break *pb)
4154 struct smbXsrv_client *client = pb->client;
4157 DLIST_ADD_END(client->pending_breaks, pb);
4158 status = smbXsrv_client_pending_breaks_updated(client);
4159 if (!NT_STATUS_IS_OK(status)) {
4163 status = smbXsrv_pending_break_submit(pb);
4164 if (!NT_STATUS_IS_OK(status)) {
4168 return NT_STATUS_OK;
4171 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb)
4173 struct smbXsrv_client *client = pb->client;
4174 struct smbXsrv_session *session = NULL;
4175 struct smbXsrv_connection *xconn = NULL;
4176 struct smbXsrv_connection *oplock_xconn = NULL;
4177 struct tevent_req *subreq = NULL;
4180 if (pb->session_id != 0) {
4181 status = get_valid_smbXsrv_session(client,
4184 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
4185 return NT_STATUS_ABANDONED;
4187 if (!NT_STATUS_IS_OK(status)) {
4191 if (pb->last_channel_id != 0) {
4193 * This is what current Windows servers
4194 * do, they don't retry on all available
4195 * channels. They only use the last channel.
4197 * But it doesn't match the specification in
4198 * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4201 * Per default disable_oplock_break_retries is false
4202 * and we behave like the specification.
4204 if (pb->disable_oplock_break_retries) {
4205 return NT_STATUS_ABANDONED;
4210 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
4211 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4215 if (xconn->channel_id == 0) {
4217 * non-multichannel case
4222 if (session != NULL) {
4223 struct smbXsrv_channel_global0 *c = NULL;
4226 * Having a session means we're handling
4227 * an oplock break and we only need to
4228 * use channels available on the
4231 status = smbXsrv_session_find_channel(session, xconn, &c);
4232 if (!NT_STATUS_IS_OK(status)) {
4237 * This is what current Windows servers
4238 * do, they don't retry on all available
4239 * channels. They only use the last channel.
4241 * But it doesn't match the specification
4242 * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4245 * Per default disable_oplock_break_retries is false
4246 * and we behave like the specification.
4248 if (pb->disable_oplock_break_retries) {
4249 oplock_xconn = xconn;
4254 if (xconn->channel_id > pb->last_channel_id) {
4262 if (xconn == NULL) {
4263 xconn = oplock_xconn;
4266 if (xconn == NULL) {
4268 * If there's no remaining connection available
4269 * tell the caller to stop...
4271 return NT_STATUS_ABANDONED;
4274 pb->last_channel_id = xconn->channel_id;
4276 subreq = smbd_smb2_break_send(pb,
4282 if (subreq == NULL) {
4283 return NT_STATUS_NO_MEMORY;
4285 tevent_req_set_callback(subreq,
4286 smbXsrv_pending_break_done,
4289 return NT_STATUS_OK;
4292 static void smbXsrv_pending_break_done(struct tevent_req *subreq)
4294 struct smbXsrv_pending_break *pb =
4295 tevent_req_callback_data(subreq,
4296 struct smbXsrv_pending_break);
4297 struct smbXsrv_client *client = pb->client;
4300 status = smbd_smb2_break_recv(subreq);
4301 TALLOC_FREE(subreq);
4302 if (!NT_STATUS_IS_OK(status)) {
4303 status = smbXsrv_pending_break_submit(pb);
4304 if (NT_STATUS_EQUAL(status, NT_STATUS_ABANDONED)) {
4306 * If there's no remaing connection
4307 * there's no need to send a break again.
4311 if (!NT_STATUS_IS_OK(status)) {
4312 smbd_server_disconnect_client(client, nt_errstr(status));
4319 DLIST_REMOVE(client->pending_breaks, pb);
4322 status = smbXsrv_client_pending_breaks_updated(client);
4323 if (!NT_STATUS_IS_OK(status)) {
4324 smbd_server_disconnect_client(client, nt_errstr(status));
4329 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_client *client,
4330 struct smbXsrv_open *op,
4331 uint8_t oplock_level)
4333 struct smbXsrv_pending_break *pb = NULL;
4334 uint8_t *body = NULL;
4336 pb = smbXsrv_pending_break_create(client,
4339 return NT_STATUS_NO_MEMORY;
4341 pb->body_len = sizeof(pb->body.oplock);
4342 body = pb->body.oplock;
4344 SSVAL(body, 0x00, pb->body_len);
4345 SCVAL(body, 0x02, oplock_level);
4346 SCVAL(body, 0x03, 0); /* reserved */
4347 SIVAL(body, 0x04, 0); /* reserved */
4348 SBVAL(body, 0x08, op->global->open_persistent_id);
4349 SBVAL(body, 0x10, op->global->open_volatile_id);
4351 return smbXsrv_pending_break_schedule(pb);
4354 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_client *client,
4356 uint32_t lease_flags,
4357 struct smb2_lease_key *lease_key,
4358 uint32_t current_lease_state,
4359 uint32_t new_lease_state)
4361 struct smbXsrv_pending_break *pb = NULL;
4362 uint8_t *body = NULL;
4364 pb = smbXsrv_pending_break_create(client,
4365 0); /* no session_id */
4367 return NT_STATUS_NO_MEMORY;
4369 pb->body_len = sizeof(pb->body.lease);
4370 body = pb->body.lease;
4372 SSVAL(body, 0x00, pb->body_len);
4373 SSVAL(body, 0x02, new_epoch);
4374 SIVAL(body, 0x04, lease_flags);
4375 SBVAL(body, 0x08, lease_key->data[0]);
4376 SBVAL(body, 0x10, lease_key->data[1]);
4377 SIVAL(body, 0x18, current_lease_state);
4378 SIVAL(body, 0x1c, new_lease_state);
4379 SIVAL(body, 0x20, 0); /* BreakReason, MUST be 0 */
4380 SIVAL(body, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4381 SIVAL(body, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4383 return smbXsrv_pending_break_schedule(pb);
4386 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
4390 uint64_t file_id_persistent;
4391 uint64_t file_id_volatile;
4392 struct smbXsrv_open *op = NULL;
4393 struct files_struct *fsp = NULL;
4394 const uint8_t *body = NULL;
4397 * This is only called with a pktbuf
4398 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4402 if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
4403 /* Transform header. Cannot recvfile. */
4406 if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
4407 /* Not SMB2. Normal error path will cope. */
4410 if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
4411 /* Not SMB2. Normal error path will cope. */
4414 if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
4415 /* Needs to be a WRITE. */
4418 if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
4419 /* Chained. Cannot recvfile. */
4422 flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
4423 if (flags & SMB2_HDR_FLAG_CHAINED) {
4424 /* Chained. Cannot recvfile. */
4427 if (flags & SMB2_HDR_FLAG_SIGNED) {
4428 /* Signed. Cannot recvfile. */
4432 body = &state->pktbuf[SMB2_HDR_BODY];
4434 file_id_persistent = BVAL(body, 0x10);
4435 file_id_volatile = BVAL(body, 0x18);
4437 status = smb2srv_open_lookup(state->req->xconn,
4442 if (!NT_STATUS_IS_OK(status)) {
4450 if (fsp->conn == NULL) {
4454 if (IS_IPC(fsp->conn)) {
4457 if (IS_PRINT(fsp->conn)) {
4460 if (fsp->base_fsp != NULL) {
4464 DEBUG(10,("Doing recvfile write len = %u\n",
4465 (unsigned int)(state->pktfull - state->pktlen)));
4470 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
4472 struct smbd_server_connection *sconn = xconn->client->sconn;
4473 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4474 size_t max_send_queue_len;
4475 size_t cur_send_queue_len;
4477 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4479 * we're not supposed to do any io
4481 return NT_STATUS_OK;
4484 if (state->req != NULL) {
4486 * if there is already a tstream_readv_pdu
4487 * pending, we are done.
4489 return NT_STATUS_OK;
4492 max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
4493 cur_send_queue_len = xconn->smb2.send_queue_len;
4495 if (cur_send_queue_len > max_send_queue_len) {
4497 * if we have a lot of requests to send,
4498 * we wait until they are on the wire until we
4499 * ask for the next request.
4501 return NT_STATUS_OK;
4504 /* ask for the next request */
4505 ZERO_STRUCTP(state);
4506 state->req = smbd_smb2_request_allocate(xconn);
4507 if (state->req == NULL) {
4508 return NT_STATUS_NO_MEMORY;
4510 state->req->sconn = sconn;
4511 state->req->xconn = xconn;
4512 state->min_recv_size = lp_min_receive_file_size();
4514 TEVENT_FD_READABLE(xconn->transport.fde);
4516 return NT_STATUS_OK;
4519 NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
4520 uint64_t expected_seq_low,
4521 const uint8_t *inpdu, size_t size)
4523 struct smbd_server_connection *sconn = xconn->client->sconn;
4525 struct smbd_smb2_request *req = NULL;
4527 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4528 (unsigned int)size));
4530 status = smbd_initialize_smb2(xconn, expected_seq_low);
4531 if (!NT_STATUS_IS_OK(status)) {
4532 smbd_server_connection_terminate(xconn, nt_errstr(status));
4537 * If a new connection joins the process, when we're
4538 * already in a "pending break cycle", we need to
4539 * turn on the ack checker on the new connection.
4541 status = smbXsrv_client_pending_breaks_updated(xconn->client);
4542 if (!NT_STATUS_IS_OK(status)) {
4544 * If there's a problem, we disconnect the whole
4545 * client with all connections here!
4547 * Instead of just the new connection.
4549 smbd_server_disconnect_client(xconn->client, nt_errstr(status));
4553 status = smbd_smb2_request_create(xconn, inpdu, size, &req);
4554 if (!NT_STATUS_IS_OK(status)) {
4555 smbd_server_connection_terminate(xconn, nt_errstr(status));
4559 status = smbd_smb2_request_validate(req);
4560 if (!NT_STATUS_IS_OK(status)) {
4561 smbd_server_connection_terminate(xconn, nt_errstr(status));
4565 status = smbd_smb2_request_setup_out(req);
4566 if (!NT_STATUS_IS_OK(status)) {
4567 smbd_server_connection_terminate(xconn, nt_errstr(status));
4573 * this was already counted at the SMB1 layer =>
4574 * smbd_smb2_request_dispatch() should not count it twice.
4576 if (profile_p->values.request_stats.count > 0) {
4577 profile_p->values.request_stats.count--;
4580 status = smbd_smb2_request_dispatch(req);
4581 if (!NT_STATUS_IS_OK(status)) {
4582 smbd_server_connection_terminate(xconn, nt_errstr(status));
4586 status = smbd_smb2_request_next_incoming(xconn);
4587 if (!NT_STATUS_IS_OK(status)) {
4588 smbd_server_connection_terminate(xconn, nt_errstr(status));
4592 sconn->num_requests++;
4593 return NT_STATUS_OK;
4596 static int socket_error_from_errno(int ret,
4610 if (sys_errno == 0) {
4614 if (sys_errno == EINTR) {
4619 if (sys_errno == EINPROGRESS) {
4624 if (sys_errno == EAGAIN) {
4629 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4630 if (sys_errno == ENOMEM) {
4636 #if EWOULDBLOCK != EAGAIN
4637 if (sys_errno == EWOULDBLOCK) {
4647 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
4654 if (xconn->smb2.send_queue == NULL) {
4655 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4656 return NT_STATUS_OK;
4659 while (xconn->smb2.send_queue != NULL) {
4660 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
4664 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4666 * we're not supposed to do any io
4667 * just flush all pending stuff.
4669 xconn->smb2.send_queue_len--;
4670 DLIST_REMOVE(xconn->smb2.send_queue, e);
4672 talloc_free(e->mem_ctx);
4676 if (e->sendfile_header != NULL) {
4681 status = NT_STATUS_INTERNAL_ERROR;
4683 for (i=0; i < e->count; i++) {
4684 size += e->vector[i].iov_len;
4687 if (size <= e->sendfile_header->length) {
4688 buf = e->sendfile_header->data;
4690 buf = talloc_array(e->mem_ctx, uint8_t, size);
4692 return NT_STATUS_NO_MEMORY;
4697 for (i=0; i < e->count; i++) {
4699 e->vector[i].iov_base,
4700 e->vector[i].iov_len);
4701 size += e->vector[i].iov_len;
4704 e->sendfile_header->data = buf;
4705 e->sendfile_header->length = size;
4706 e->sendfile_status = &status;
4709 xconn->smb2.send_queue_len--;
4710 DLIST_REMOVE(xconn->smb2.send_queue, e);
4712 size += e->sendfile_body_size;
4715 * This triggers the sendfile path via
4718 talloc_free(e->mem_ctx);
4720 if (!NT_STATUS_IS_OK(status)) {
4721 smbXsrv_connection_disconnect_transport(xconn,
4725 xconn->ack.unacked_bytes += size;
4729 msg = (struct msghdr) {
4730 .msg_iov = e->vector,
4731 .msg_iovlen = e->count,
4734 ret = sendmsg(xconn->transport.sock, &msg, 0);
4736 /* propagate end of file */
4737 return NT_STATUS_INTERNAL_ERROR;
4739 err = socket_error_from_errno(ret, errno, &retry);
4742 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4743 return NT_STATUS_OK;
4746 status = map_nt_error_from_unix_common(err);
4747 smbXsrv_connection_disconnect_transport(xconn,
4752 xconn->ack.unacked_bytes += ret;
4754 ok = iov_advance(&e->vector, &e->count, ret);
4756 return NT_STATUS_INTERNAL_ERROR;
4760 /* we have more to write */
4761 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4762 return NT_STATUS_OK;
4765 xconn->smb2.send_queue_len--;
4766 DLIST_REMOVE(xconn->smb2.send_queue, e);
4768 if (e->ack.req == NULL) {
4769 talloc_free(e->mem_ctx);
4773 e->ack.required_acked_bytes = xconn->ack.unacked_bytes;
4774 DLIST_ADD_END(xconn->ack.queue, e);
4778 * Restart reads if we were blocked on
4779 * draining the send queue.
4782 status = smbd_smb2_request_next_incoming(xconn);
4783 if (!NT_STATUS_IS_OK(status)) {
4787 return NT_STATUS_OK;
4790 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
4793 struct smbd_server_connection *sconn = xconn->client->sconn;
4794 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4795 struct smbd_smb2_request *req = NULL;
4796 size_t min_recvfile_size = UINT32_MAX;
4804 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4806 * we're not supposed to do any io
4808 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4809 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4810 return NT_STATUS_OK;
4813 if (fde_flags & TEVENT_FD_WRITE) {
4814 status = smbd_smb2_flush_send_queue(xconn);
4815 if (!NT_STATUS_IS_OK(status)) {
4820 if (!(fde_flags & TEVENT_FD_READ)) {
4821 return NT_STATUS_OK;
4824 if (state->req == NULL) {
4825 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4826 return NT_STATUS_OK;
4830 if (!state->hdr.done) {
4831 state->hdr.done = true;
4833 state->vector.iov_base = (void *)state->hdr.nbt;
4834 state->vector.iov_len = NBT_HDR_SIZE;
4837 msg = (struct msghdr) {
4838 .msg_iov = &state->vector,
4842 ret = recvmsg(xconn->transport.sock, &msg, 0);
4844 /* propagate end of file */
4845 status = NT_STATUS_END_OF_FILE;
4846 smbXsrv_connection_disconnect_transport(xconn,
4850 err = socket_error_from_errno(ret, errno, &retry);
4853 TEVENT_FD_READABLE(xconn->transport.fde);
4854 return NT_STATUS_OK;
4857 status = map_nt_error_from_unix_common(err);
4858 smbXsrv_connection_disconnect_transport(xconn,
4863 if (ret < state->vector.iov_len) {
4865 base = (uint8_t *)state->vector.iov_base;
4867 state->vector.iov_base = (void *)base;
4868 state->vector.iov_len -= ret;
4869 /* we have more to read */
4870 TEVENT_FD_READABLE(xconn->transport.fde);
4871 return NT_STATUS_OK;
4874 if (state->pktlen > 0) {
4875 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
4877 * Not a possible receivefile write.
4878 * Read the rest of the data.
4880 state->doing_receivefile = false;
4882 state->pktbuf = talloc_realloc(state->req,
4886 if (state->pktbuf == NULL) {
4887 return NT_STATUS_NO_MEMORY;
4890 state->vector.iov_base = (void *)(state->pktbuf +
4892 state->vector.iov_len = (state->pktfull -
4895 state->pktlen = state->pktfull;
4900 * Either this is a receivefile write so we've
4901 * done a short read, or if not we have all the data.
4907 * Now we analyze the NBT header
4909 if (state->hdr.nbt[0] != 0x00) {
4910 state->min_recv_size = 0;
4912 state->pktfull = smb2_len(state->hdr.nbt);
4913 if (state->pktfull == 0) {
4917 if (state->min_recv_size != 0) {
4918 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4919 min_recvfile_size += state->min_recv_size;
4922 if (state->pktfull > min_recvfile_size) {
4924 * Might be a receivefile write. Read the SMB2 HEADER +
4925 * SMB2_WRITE header first. Set 'doing_receivefile'
4926 * as we're *attempting* receivefile write. If this
4927 * turns out not to be a SMB2_WRITE request or otherwise
4928 * not suitable then we'll just read the rest of the data
4929 * the next time this function is called.
4931 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4932 state->doing_receivefile = true;
4934 state->pktlen = state->pktfull;
4937 state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
4938 if (state->pktbuf == NULL) {
4939 return NT_STATUS_NO_MEMORY;
4942 state->vector.iov_base = (void *)state->pktbuf;
4943 state->vector.iov_len = state->pktlen;
4949 if (state->hdr.nbt[0] != 0x00) {
4950 DEBUG(1,("ignore NBT[0x%02X] msg\n",
4951 state->hdr.nbt[0]));
4954 ZERO_STRUCTP(state);
4956 state->min_recv_size = lp_min_receive_file_size();
4964 req->request_time = timeval_current();
4965 now = timeval_to_nttime(&req->request_time);
4967 status = smbd_smb2_inbuf_parse_compound(xconn,
4973 &req->in.vector_count);
4974 if (!NT_STATUS_IS_OK(status)) {
4978 if (state->doing_receivefile) {
4979 req->smb1req = talloc_zero(req, struct smb_request);
4980 if (req->smb1req == NULL) {
4981 return NT_STATUS_NO_MEMORY;
4983 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
4986 ZERO_STRUCTP(state);
4988 req->current_idx = 1;
4990 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
4991 req->current_idx, req->in.vector_count));
4993 status = smbd_smb2_request_validate(req);
4994 if (!NT_STATUS_IS_OK(status)) {
4998 status = smbd_smb2_request_setup_out(req);
4999 if (!NT_STATUS_IS_OK(status)) {
5003 status = smbd_smb2_request_dispatch(req);
5004 if (!NT_STATUS_IS_OK(status)) {
5008 sconn->num_requests++;
5010 /* The timeout_processing function isn't run nearly
5011 often enough to implement 'max log size' without
5012 overrunning the size of the file by many megabytes.
5013 This is especially true if we are running at debug
5014 level 10. Checking every 50 SMB2s is a nice
5015 tradeoff of performance vs log file size overrun. */
5017 if ((sconn->num_requests % 50) == 0 &&
5018 need_to_check_log_size()) {
5019 change_to_root_user();
5023 status = smbd_smb2_request_next_incoming(xconn);
5024 if (!NT_STATUS_IS_OK(status)) {
5028 return NT_STATUS_OK;
5031 static void smbd_smb2_connection_handler(struct tevent_context *ev,
5032 struct tevent_fd *fde,
5036 struct smbXsrv_connection *xconn =
5037 talloc_get_type_abort(private_data,
5038 struct smbXsrv_connection);
5041 status = smbd_smb2_io_handler(xconn, flags);
5042 if (!NT_STATUS_IS_OK(status)) {
5043 smbd_server_connection_terminate(xconn, nt_errstr(status));