2 Unix SMB/CIFS implementation.
5 Copyright (C) Stefan Metzmacher 2009
6 Copyright (C) Jeremy Allison 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/network.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "smbd/smbXsrv_open.h"
27 #include "lib/param/param.h"
28 #include "../libcli/smb/smb_common.h"
29 #include "../lib/tsocket/tsocket.h"
30 #include "../lib/util/tevent_ntstatus.h"
31 #include "smbprofile.h"
32 #include "../lib/util/bitmap.h"
33 #include "../librpc/gen_ndr/krb5pac.h"
34 #include "lib/util/iov_buf.h"
36 #include "libcli/smb/smbXcli_base.h"
37 #include "source3/lib/substitute.h"
40 /* SIOCOUTQ TIOCOUTQ are the same */
41 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
42 #define __HAVE_TCP_INFO_RTO 1
43 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
44 #elif defined(FREEBSD)
45 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
46 #define __HAVE_TCP_INFO_RTO 1
47 #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
50 #include "lib/crypto/gnutls_helpers.h"
51 #include <gnutls/gnutls.h>
52 #include <gnutls/crypto.h>
55 #define DBGC_CLASS DBGC_SMB2
57 static void smbd_smb2_connection_handler(struct tevent_context *ev,
58 struct tevent_fd *fde,
61 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
63 static const struct smbd_smb2_dispatch_table {
71 } smbd_smb2_table[] = {
72 #define _OP(o) .opcode = o, .name = #o
77 _OP(SMB2_OP_SESSSETUP),
87 * This call needs to be run as root.
89 * smbd_smb2_request_process_tcon()
90 * calls make_connection_snum(), which will call
91 * change_to_user(), when needed.
101 .need_session = true,
105 .need_session = true,
110 .need_session = true,
115 .need_session = true,
120 .need_session = true,
126 .need_session = true,
131 .need_session = true,
139 _OP(SMB2_OP_KEEPALIVE),
142 _OP(SMB2_OP_QUERY_DIRECTORY),
143 .need_session = true,
148 .need_session = true,
152 _OP(SMB2_OP_GETINFO),
153 .need_session = true,
157 _OP(SMB2_OP_SETINFO),
158 .need_session = true,
164 .need_session = true,
169 * as LEASE breaks does not
175 const char *smb2_opcode_name(uint16_t opcode)
177 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
178 return "Bad SMB2 opcode";
180 return smbd_smb2_table[opcode].name;
183 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
185 const struct smbd_smb2_dispatch_table *ret = NULL;
187 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
191 ret = &smbd_smb2_table[opcode];
193 SMB_ASSERT(ret->opcode == opcode);
198 static void print_req_vectors(const struct smbd_smb2_request *req)
202 for (i = 0; i < req->in.vector_count; i++) {
203 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
205 (unsigned int)req->in.vector[i].iov_len);
207 for (i = 0; i < req->out.vector_count; i++) {
208 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
210 (unsigned int)req->out.vector[i].iov_len);
214 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
216 if (size < (4 + SMB2_HDR_BODY)) {
220 if (IVAL(inbuf, 4) != SMB2_MAGIC) {
227 bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
229 return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
232 bool smbd_smb2_is_last_in_compound(const struct smbd_smb2_request *req)
234 return (req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ ==
235 req->in.vector_count);
238 static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
239 uint64_t expected_seq_low)
243 xconn->smb2.credits.seq_low = expected_seq_low;
244 xconn->smb2.credits.seq_range = 1;
245 xconn->smb2.credits.granted = 1;
246 xconn->smb2.credits.max = lp_smb2_max_credits();
247 xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
248 xconn->smb2.credits.max);
249 if (xconn->smb2.credits.bitmap == NULL) {
250 return NT_STATUS_NO_MEMORY;
253 tevent_fd_set_close_fn(xconn->transport.fde, NULL);
254 TALLOC_FREE(xconn->transport.fde);
256 xconn->transport.fde = tevent_add_fd(
257 xconn->client->raw_ev_ctx,
259 xconn->transport.sock,
261 smbd_smb2_connection_handler,
263 if (xconn->transport.fde == NULL) {
264 close(xconn->transport.sock);
265 xconn->transport.sock = -1;
266 return NT_STATUS_NO_MEMORY;
268 tevent_fd_set_auto_close(xconn->transport.fde);
270 /* Ensure child is set to non-blocking mode */
271 rc = set_blocking(xconn->transport.sock, false);
273 return NT_STATUS_INTERNAL_ERROR;
279 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
280 #define _smb2_setlen(_buf,len) do { \
281 uint8_t *buf = (uint8_t *)_buf; \
283 buf[1] = ((len)&0xFF0000)>>16; \
284 buf[2] = ((len)&0xFF00)>>8; \
285 buf[3] = (len)&0xFF; \
288 static bool smb2_setup_nbt_length(struct iovec *vector, int count)
296 len = iov_buflen(vector+1, count-1);
298 if ((len == -1) || (len > 0xFFFFFF)) {
302 _smb2_setlen(vector[0].iov_base, len);
306 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
308 TALLOC_FREE(req->first_enc_key);
309 TALLOC_FREE(req->last_sign_key);
313 void smb2_request_set_async_internal(struct smbd_smb2_request *req,
316 req->async_internal = async_internal;
319 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
321 TALLOC_CTX *mem_pool;
322 struct smbd_smb2_request *req;
325 /* Enable this to find subtle valgrind errors. */
326 mem_pool = talloc_init("smbd_smb2_request_allocate");
328 mem_pool = talloc_tos();
330 if (mem_pool == NULL) {
334 req = talloc_zero(mem_pool, struct smbd_smb2_request);
336 talloc_free(mem_pool);
339 talloc_reparent(mem_pool, mem_ctx, req);
341 TALLOC_FREE(mem_pool);
344 req->last_session_id = UINT64_MAX;
345 req->last_tid = UINT32_MAX;
347 talloc_set_destructor(req, smbd_smb2_request_destructor);
352 static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
356 struct smbd_smb2_request *req,
360 TALLOC_CTX *mem_ctx = req;
364 uint8_t *first_hdr = buf;
365 size_t verified_buflen = 0;
370 * Note: index '0' is reserved for the transport protocol
372 iov = req->in._vector;
374 while (taken < buflen) {
375 size_t len = buflen - taken;
376 uint8_t *hdr = first_hdr + taken;
379 size_t next_command_ofs;
381 uint8_t *body = NULL;
384 struct iovec *iov_alloc = NULL;
386 if (iov != req->in._vector) {
390 if (verified_buflen > taken) {
391 len = verified_buflen - taken;
398 DEBUG(10, ("%d bytes left, expected at least %d\n",
402 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
403 struct smbXsrv_session *s = NULL;
405 struct iovec tf_iov[2];
409 if (xconn->protocol < PROTOCOL_SMB3_00) {
410 DEBUG(10, ("Got SMB2_TRANSFORM header, "
411 "but dialect[0x%04X] is used\n",
412 xconn->smb2.server.dialect));
416 if (xconn->smb2.server.cipher == 0) {
417 DEBUG(10, ("Got SMB2_TRANSFORM header, "
418 "but not negotiated "
419 "client[0x%08X] server[0x%08X]\n",
420 xconn->smb2.client.capabilities,
421 xconn->smb2.server.capabilities));
425 if (len < SMB2_TF_HDR_SIZE) {
426 DEBUG(1, ("%d bytes left, expected at least %d\n",
427 (int)len, SMB2_TF_HDR_SIZE));
431 tf_len = SMB2_TF_HDR_SIZE;
434 hdr = first_hdr + taken;
435 enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
436 uid = BVAL(tf, SMB2_TF_SESSION_ID);
438 if (len < SMB2_TF_HDR_SIZE + enc_len) {
439 DEBUG(1, ("%d bytes left, expected at least %d\n",
441 (int)(SMB2_TF_HDR_SIZE + enc_len)));
445 status = smb2srv_session_lookup_conn(xconn, uid, now,
448 status = smb2srv_session_lookup_global(xconn->client,
452 DEBUG(1, ("invalid session[%llu] in "
453 "SMB2_TRANSFORM header\n",
454 (unsigned long long)uid));
455 TALLOC_FREE(iov_alloc);
456 return NT_STATUS_USER_SESSION_DELETED;
459 tf_iov[0].iov_base = (void *)tf;
460 tf_iov[0].iov_len = tf_len;
461 tf_iov[1].iov_base = (void *)hdr;
462 tf_iov[1].iov_len = enc_len;
464 status = smb2_signing_decrypt_pdu(s->global->decryption_key,
466 if (!NT_STATUS_IS_OK(status)) {
467 TALLOC_FREE(iov_alloc);
471 verified_buflen = taken + enc_len;
476 * We need the header plus the body length field
479 if (len < SMB2_HDR_BODY + 2) {
482 (IVAL(hdr, 0) == SMB_SUICIDE_PACKET) &&
483 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
484 uint8_t exitcode = CVAL(hdr, 4);
485 DBG_WARNING("SUICIDE: Exiting immediately "
486 "with code %"PRIu8"\n",
491 DEBUG(10, ("%d bytes left, expected at least %d\n",
492 (int)len, SMB2_HDR_BODY));
495 if (IVAL(hdr, 0) != SMB2_MAGIC) {
496 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
500 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
501 DEBUG(10, ("Got HDR len %d, expected %d\n",
502 SVAL(hdr, 4), SMB2_HDR_BODY));
507 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
508 body_size = SVAL(hdr, SMB2_HDR_BODY);
510 if (next_command_ofs != 0) {
511 if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
514 if (next_command_ofs > full_size) {
517 full_size = next_command_ofs;
524 if (body_size > (full_size - SMB2_HDR_BODY)) {
526 * let the caller handle the error
528 body_size = full_size - SMB2_HDR_BODY;
530 body = hdr + SMB2_HDR_BODY;
531 dyn = body + body_size;
532 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
534 if (num_iov >= ARRAY_SIZE(req->in._vector)) {
535 struct iovec *iov_tmp = NULL;
537 iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
540 SMBD_SMB2_NUM_IOV_PER_REQ);
541 if (iov_tmp == NULL) {
542 TALLOC_FREE(iov_alloc);
543 return NT_STATUS_NO_MEMORY;
546 if (iov_alloc == NULL) {
549 sizeof(req->in._vector));
555 num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
557 cur[SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
558 cur[SMBD_SMB2_TF_IOV_OFS].iov_len = tf_len;
559 cur[SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
560 cur[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
561 cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
562 cur[SMBD_SMB2_BODY_IOV_OFS].iov_len = body_size;
563 cur[SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
564 cur[SMBD_SMB2_DYN_IOV_OFS].iov_len = dyn_size;
574 if (iov != req->in._vector) {
577 return NT_STATUS_INVALID_PARAMETER;
580 static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
581 const uint8_t *_inpdu, size_t size,
582 struct smbd_smb2_request **_req)
584 struct smbd_server_connection *sconn = xconn->client->sconn;
585 struct smbd_smb2_request *req;
586 uint32_t protocol_version;
587 uint8_t *inpdu = NULL;
588 const uint8_t *inhdr = NULL;
590 uint32_t next_command_ofs;
594 if (size < (SMB2_HDR_BODY + 2)) {
595 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
596 return NT_STATUS_INVALID_PARAMETER;
601 protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
602 if (protocol_version != SMB2_MAGIC) {
603 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
605 return NT_STATUS_INVALID_PARAMETER;
608 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
609 if (cmd != SMB2_OP_NEGPROT) {
610 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
612 return NT_STATUS_INVALID_PARAMETER;
615 next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
616 if (next_command_ofs != 0) {
617 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
619 return NT_STATUS_INVALID_PARAMETER;
622 req = smbd_smb2_request_allocate(xconn);
624 return NT_STATUS_NO_MEMORY;
629 inpdu = talloc_memdup(req, _inpdu, size);
631 return NT_STATUS_NO_MEMORY;
634 req->request_time = timeval_current();
635 now = timeval_to_nttime(&req->request_time);
637 status = smbd_smb2_inbuf_parse_compound(xconn,
641 req, &req->in.vector,
642 &req->in.vector_count);
643 if (!NT_STATUS_IS_OK(status)) {
648 req->current_idx = 1;
654 static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
655 uint64_t message_id, uint64_t seq_id)
657 struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
661 seq_tmp = xconn->smb2.credits.seq_low;
662 if (seq_id < seq_tmp) {
663 DBGC_ERR(DBGC_SMB2_CREDITS,
664 "smb2_validate_sequence_number: bad message_id "
665 "%llu (sequence id %llu) "
666 "(granted = %u, low = %llu, range = %u)\n",
667 (unsigned long long)message_id,
668 (unsigned long long)seq_id,
669 (unsigned int)xconn->smb2.credits.granted,
670 (unsigned long long)xconn->smb2.credits.seq_low,
671 (unsigned int)xconn->smb2.credits.seq_range);
675 seq_tmp += xconn->smb2.credits.seq_range;
676 if (seq_id >= seq_tmp) {
677 DBGC_ERR(DBGC_SMB2_CREDITS,
678 "smb2_validate_sequence_number: bad message_id "
679 "%llu (sequence id %llu) "
680 "(granted = %u, low = %llu, range = %u)\n",
681 (unsigned long long)message_id,
682 (unsigned long long)seq_id,
683 (unsigned int)xconn->smb2.credits.granted,
684 (unsigned long long)xconn->smb2.credits.seq_low,
685 (unsigned int)xconn->smb2.credits.seq_range);
689 offset = seq_id % xconn->smb2.credits.max;
691 if (bitmap_query(credits_bm, offset)) {
692 DBGC_ERR(DBGC_SMB2_CREDITS,
693 "smb2_validate_sequence_number: duplicate message_id "
694 "%llu (sequence id %llu) "
695 "(granted = %u, low = %llu, range = %u) "
697 (unsigned long long)message_id,
698 (unsigned long long)seq_id,
699 (unsigned int)xconn->smb2.credits.granted,
700 (unsigned long long)xconn->smb2.credits.seq_low,
701 (unsigned int)xconn->smb2.credits.seq_range,
706 /* Mark the message_ids as seen in the bitmap. */
707 bitmap_set(credits_bm, offset);
709 if (seq_id != xconn->smb2.credits.seq_low) {
714 * Move the window forward by all the message_id's
717 while (bitmap_query(credits_bm, offset)) {
718 DBGC_DEBUG(DBGC_SMB2_CREDITS,
719 "smb2_validate_sequence_number: clearing "
720 "id %llu (position %u) from bitmap\n",
721 (unsigned long long)(xconn->smb2.credits.seq_low),
723 bitmap_clear(credits_bm, offset);
725 xconn->smb2.credits.seq_low += 1;
726 xconn->smb2.credits.seq_range -= 1;
727 offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
733 static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
734 const uint8_t *inhdr)
736 uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
737 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
738 uint16_t credit_charge = 1;
741 if (opcode == SMB2_OP_CANCEL) {
742 /* SMB2_CANCEL requests by definition resend messageids. */
746 if (xconn->smb2.credits.multicredit) {
747 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
748 credit_charge = MAX(credit_charge, 1);
753 ("smb2_validate_message_id: mid %llu (charge %llu), "
754 "credits_granted %llu, "
755 "seqnum low/range: %llu/%llu\n",
756 (unsigned long long) message_id,
757 (unsigned long long) credit_charge,
758 (unsigned long long) xconn->smb2.credits.granted,
759 (unsigned long long) xconn->smb2.credits.seq_low,
760 (unsigned long long) xconn->smb2.credits.seq_range));
762 if (xconn->smb2.credits.granted < credit_charge) {
763 DBGC_ERR(DBGC_SMB2_CREDITS,
764 "smb2_validate_message_id: client used more "
765 "credits than granted, mid %llu, charge %llu, "
766 "credits_granted %llu, "
767 "seqnum low/range: %llu/%llu\n",
768 (unsigned long long) message_id,
769 (unsigned long long) credit_charge,
770 (unsigned long long) xconn->smb2.credits.granted,
771 (unsigned long long) xconn->smb2.credits.seq_low,
772 (unsigned long long) xconn->smb2.credits.seq_range);
777 * now check the message ids
779 * for multi-credit requests we need to check all current mid plus
780 * the implicit mids caused by the credit charge
781 * e.g. current mid = 15, charge 5 => mark 15-19 as used
784 for (i = 0; i <= (credit_charge-1); i++) {
785 uint64_t id = message_id + i;
790 ("Iterating mid %llu charge %u (sequence %llu)\n",
791 (unsigned long long)message_id,
793 (unsigned long long)id));
795 ok = smb2_validate_sequence_number(xconn, message_id, id);
801 /* substract used credits */
802 xconn->smb2.credits.granted -= credit_charge;
807 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
812 count = req->in.vector_count;
814 if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
815 /* It's not a SMB2 request */
816 return NT_STATUS_INVALID_PARAMETER;
819 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
820 struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
821 struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
822 const uint8_t *inhdr = NULL;
824 if (hdr->iov_len != SMB2_HDR_BODY) {
825 return NT_STATUS_INVALID_PARAMETER;
828 if (body->iov_len < 2) {
829 return NT_STATUS_INVALID_PARAMETER;
832 inhdr = (const uint8_t *)hdr->iov_base;
834 /* Check the SMB2 header */
835 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
836 return NT_STATUS_INVALID_PARAMETER;
839 if (!smb2_validate_message_id(req->xconn, inhdr)) {
840 return NT_STATUS_INVALID_PARAMETER;
847 static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
848 const struct iovec *in_vector,
849 struct iovec *out_vector)
851 const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
852 uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
853 uint16_t credit_charge = 1;
854 uint16_t credits_requested;
858 uint16_t credits_granted = 0;
859 uint64_t credits_possible;
860 uint16_t current_max_credits;
863 * first we grant only 1/16th of the max range.
865 * Windows also starts with the 1/16th and then grants
866 * more later. I was only able to trigger higher
867 * values, when using a very high credit charge.
869 * TODO: scale up depending on load, free memory
871 * Maybe also on the relationship between number
872 * of requests and the used sequence number.
873 * Which means we would grant more credits
874 * for client which use multi credit requests.
876 * The above is what Windows Server < 2016 is doing,
877 * but new servers use all credits (8192 by default).
879 current_max_credits = xconn->smb2.credits.max;
880 current_max_credits = MAX(current_max_credits, 1);
882 if (xconn->smb2.credits.multicredit) {
883 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
884 credit_charge = MAX(credit_charge, 1);
887 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
888 credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
889 credits_requested = MAX(credits_requested, 1);
890 out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
891 out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
893 SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
895 if (xconn->smb2.credits.max < credit_charge) {
896 smbd_server_connection_terminate(xconn,
897 "client error: credit charge > max credits\n");
901 if (out_flags & SMB2_HDR_FLAG_ASYNC) {
903 * In case we already send an async interim
904 * response, we should not grant
905 * credits on the final response.
909 uint16_t additional_possible =
910 xconn->smb2.credits.max - credit_charge;
911 uint16_t additional_max = 0;
912 uint16_t additional_credits = credits_requested - 1;
915 case SMB2_OP_NEGPROT:
917 case SMB2_OP_SESSSETUP:
919 * Windows 2012 RC1 starts to grant
921 * with a successful session setup
923 if (NT_STATUS_IS_OK(out_status)) {
924 additional_max = xconn->smb2.credits.max;
929 * Windows Server < 2016 and older Samba versions
930 * used to only grant additional credits in
931 * chunks of 32 credits.
933 * But we match Windows Server 2016 and grant
934 * all credits as requested.
936 additional_max = xconn->smb2.credits.max;
940 additional_max = MIN(additional_max, additional_possible);
941 additional_credits = MIN(additional_credits, additional_max);
943 credits_granted = credit_charge + additional_credits;
947 * sequence numbers should not wrap
949 * 1. calculate the possible credits until
950 * the sequence numbers start to wrap on 64-bit.
952 * 2. UINT64_MAX is used for Break Notifications.
954 * 2. truncate the possible credits to the maximum
955 * credits we want to grant to the client in total.
957 * 3. remove the range we'll already granted to the client
958 * this makes sure the client consumes the lowest sequence
959 * number, before we can grant additional credits.
961 credits_possible = UINT64_MAX - xconn->smb2.credits.seq_low;
962 if (credits_possible > 0) {
963 /* remove UINT64_MAX */
964 credits_possible -= 1;
966 credits_possible = MIN(credits_possible, current_max_credits);
967 credits_possible -= xconn->smb2.credits.seq_range;
969 credits_granted = MIN(credits_granted, credits_possible);
971 SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
972 xconn->smb2.credits.granted += credits_granted;
973 xconn->smb2.credits.seq_range += credits_granted;
975 DBGC_DEBUG(DBGC_SMB2_CREDITS,
976 "smb2_set_operation_credit: requested %u, charge %u, "
977 "granted %u, current possible/max %u/%u, "
978 "total granted/max/low/range %u/%u/%llu/%u\n",
979 (unsigned int)credits_requested,
980 (unsigned int)credit_charge,
981 (unsigned int)credits_granted,
982 (unsigned int)credits_possible,
983 (unsigned int)current_max_credits,
984 (unsigned int)xconn->smb2.credits.granted,
985 (unsigned int)xconn->smb2.credits.max,
986 (unsigned long long)xconn->smb2.credits.seq_low,
987 (unsigned int)xconn->smb2.credits.seq_range);
990 static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
991 struct smbd_smb2_request *outreq)
994 uint16_t total_credits = 0;
996 count = outreq->out.vector_count;
998 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
999 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
1000 struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
1001 uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
1003 smb2_set_operation_credit(outreq->xconn, inhdr_v, outhdr_v);
1005 /* To match Windows, count up what we
1007 total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
1008 /* Set to zero in all but the last reply. */
1009 if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
1010 SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
1012 SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
1017 DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size)
1019 if (req->current_idx <= 1) {
1020 if (size <= sizeof(req->out._body)) {
1021 return data_blob_const(req->out._body, size);
1025 return data_blob_talloc(req, NULL, size);
1028 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
1030 struct smbXsrv_connection *xconn = req->xconn;
1031 TALLOC_CTX *mem_ctx;
1032 struct iovec *vector;
1037 count = req->in.vector_count;
1038 if (count <= ARRAY_SIZE(req->out._vector)) {
1040 vector = req->out._vector;
1042 vector = talloc_zero_array(req, struct iovec, count);
1043 if (vector == NULL) {
1044 return NT_STATUS_NO_MEMORY;
1049 vector[0].iov_base = req->out.nbt_hdr;
1050 vector[0].iov_len = 4;
1051 SIVAL(req->out.nbt_hdr, 0, 0);
1053 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
1054 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
1055 const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
1056 uint8_t *outhdr = NULL;
1057 uint8_t *outbody = NULL;
1058 uint32_t next_command_ofs = 0;
1059 struct iovec *current = &vector[idx];
1061 if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
1062 /* we have a next command -
1063 * setup for the error case. */
1064 next_command_ofs = SMB2_HDR_BODY + 9;
1068 outhdr = req->out._hdr;
1070 outhdr = talloc_zero_array(mem_ctx, uint8_t,
1072 if (outhdr == NULL) {
1073 return NT_STATUS_NO_MEMORY;
1077 outbody = outhdr + SMB2_HDR_BODY;
1080 * SMBD_SMB2_TF_IOV_OFS might be used later
1082 current[SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
1083 current[SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
1085 current[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)outhdr;
1086 current[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1088 current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
1089 current[SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
1091 current[SMBD_SMB2_DYN_IOV_OFS].iov_base = NULL;
1092 current[SMBD_SMB2_DYN_IOV_OFS].iov_len = 0;
1094 /* setup the SMB2 header */
1095 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1096 SSVAL(outhdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1097 SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1098 SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1099 SIVAL(outhdr, SMB2_HDR_STATUS,
1100 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1101 SSVAL(outhdr, SMB2_HDR_OPCODE,
1102 SVAL(inhdr, SMB2_HDR_OPCODE));
1103 SIVAL(outhdr, SMB2_HDR_FLAGS,
1104 IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1105 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1106 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1107 BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1108 SIVAL(outhdr, SMB2_HDR_PID,
1109 IVAL(inhdr, SMB2_HDR_PID));
1110 SIVAL(outhdr, SMB2_HDR_TID,
1111 IVAL(inhdr, SMB2_HDR_TID));
1112 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1113 BVAL(inhdr, SMB2_HDR_SESSION_ID));
1114 memcpy(outhdr + SMB2_HDR_SIGNATURE,
1115 inhdr + SMB2_HDR_SIGNATURE, 16);
1117 /* setup error body header */
1118 SSVAL(outbody, 0x00, 0x08 + 1);
1119 SSVAL(outbody, 0x02, 0);
1120 SIVAL(outbody, 0x04, 0);
1123 req->out.vector = vector;
1124 req->out.vector_count = count;
1126 /* setup the length of the NBT packet */
1127 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1129 return NT_STATUS_INVALID_PARAMETER_MIX;
1132 DLIST_ADD_END(xconn->smb2.requests, req);
1134 return NT_STATUS_OK;
1137 bool smbXsrv_server_multi_channel_enabled(void)
1139 bool enabled = lp_server_multi_channel_support();
1140 #ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1141 bool forced = false;
1142 struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
1143 bool unspecified = lpcfg_parm_is_unspecified(lp_ctx, "server multi channel support");
1148 * If we don't have support from the kernel
1149 * to ask for the un-acked number of bytes
1150 * in the socket send queue, we better
1151 * don't support multi-channel.
1153 forced = lp_parm_bool(-1, "force", "server multi channel support", false);
1154 if (enabled && !forced) {
1155 D_NOTICE("'server multi channel support' enabled "
1156 "but not supported on %s (%s)\n",
1157 SYSTEM_UNAME_SYSNAME, SYSTEM_UNAME_RELEASE);
1158 DEBUGADD(DBGLVL_NOTICE, ("Please report this on "
1159 "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1162 TALLOC_FREE(lp_ctx);
1163 #endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1167 static NTSTATUS smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection *xconn,
1168 uint32_t *_rto_usecs)
1171 * Define an Retransmission Timeout
1172 * of 1 second, if there's no way for the
1173 * kernel to tell us the current value.
1175 uint32_t rto_usecs = 1000000;
1177 #ifdef __HAVE_TCP_INFO_RTO
1179 struct tcp_info info;
1180 socklen_t ilen = sizeof(info);
1184 ret = getsockopt(xconn->transport.sock,
1185 IPPROTO_TCP, TCP_INFO,
1186 (void *)&info, &ilen);
1188 int saved_errno = errno;
1189 NTSTATUS status = map_nt_error_from_unix(errno);
1190 DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1191 saved_errno, strerror(saved_errno),
1196 DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1197 (unsigned)info.tcpi_rto,
1198 (unsigned)info.tcpi_rtt,
1199 (unsigned)info.tcpi_rttvar);
1200 rto_usecs = info.tcpi_rto;
1202 #endif /* __HAVE_TCP_INFO_RTO */
1204 rto_usecs = MAX(rto_usecs, 200000); /* at least 0.2s */
1205 rto_usecs = MIN(rto_usecs, 1000000); /* at max 1.0s */
1206 *_rto_usecs = rto_usecs;
1207 return NT_STATUS_OK;
1210 static NTSTATUS smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection *xconn,
1211 uint64_t *_acked_bytes)
1214 * Unless the kernel has an interface
1215 * to reveal the number of un-acked bytes
1216 * in the socket send queue, we'll assume
1217 * everything is already acked.
1219 * But that would mean that we better don't
1220 * pretent to support multi-channel.
1222 uint64_t unacked_bytes = 0;
1226 if (xconn->ack.force_unacked_timeout) {
1228 * Smbtorture tries to test channel failures...
1229 * Just pretend nothing was acked...
1231 DBG_INFO("Simulating channel failure: "
1232 "xconn->ack.unacked_bytes[%llu]\n",
1233 (unsigned long long)xconn->ack.unacked_bytes);
1234 return NT_STATUS_OK;
1237 #ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1243 * If we have kernel support to get
1244 * the number of bytes waiting in
1245 * the socket's send queue, we
1246 * use that in order to find out
1247 * the number of unacked bytes.
1249 ret = ioctl(xconn->transport.sock,
1250 __IOCTL_SEND_QUEUE_SIZE_OPCODE,
1253 int saved_errno = errno;
1254 NTSTATUS status = map_nt_error_from_unix(saved_errno);
1255 DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1256 "errno %d (%s) - %s\n",
1257 saved_errno, strerror(saved_errno),
1263 DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1264 (unsigned long long)xconn->ack.unacked_bytes,
1266 return NT_STATUS_INTERNAL_ERROR;
1268 unacked_bytes = value;
1271 if (xconn->ack.unacked_bytes == 0) {
1272 xconn->ack.unacked_bytes = unacked_bytes;
1273 return NT_STATUS_OK;
1276 if (xconn->ack.unacked_bytes < unacked_bytes) {
1277 DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1278 (unsigned long long)xconn->ack.unacked_bytes,
1279 (unsigned long long)unacked_bytes);
1280 return NT_STATUS_INTERNAL_ERROR;
1283 *_acked_bytes = xconn->ack.unacked_bytes - unacked_bytes;
1284 xconn->ack.unacked_bytes = unacked_bytes;
1285 return NT_STATUS_OK;
1288 static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue **queue,
1291 struct smbd_smb2_send_queue *e = NULL;
1292 struct smbd_smb2_send_queue *n = NULL;
1294 for (e = *queue; e != NULL; e = n) {
1297 DLIST_REMOVE(*queue, e);
1298 if (e->ack.req != NULL) {
1299 tevent_req_nterror(e->ack.req, status);
1304 static NTSTATUS smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue **queue,
1305 uint64_t acked_bytes)
1307 struct smbd_smb2_send_queue *e = NULL;
1308 struct smbd_smb2_send_queue *n = NULL;
1310 for (e = *queue; e != NULL; e = n) {
1315 if (e->ack.req == NULL) {
1319 if (e->ack.required_acked_bytes <= acked_bytes) {
1320 e->ack.required_acked_bytes = 0;
1321 DLIST_REMOVE(*queue, e);
1322 tevent_req_done(e->ack.req);
1325 e->ack.required_acked_bytes -= acked_bytes;
1327 expired = timeval_expired(&e->ack.timeout);
1329 return NT_STATUS_IO_TIMEOUT;
1333 return NT_STATUS_OK;
1336 static NTSTATUS smbd_smb2_check_ack_queue(struct smbXsrv_connection *xconn)
1338 uint64_t acked_bytes = 0;
1341 status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1342 if (!NT_STATUS_IS_OK(status)) {
1346 status = smbd_smb2_send_queue_ack_bytes(&xconn->ack.queue, acked_bytes);
1347 if (!NT_STATUS_IS_OK(status)) {
1351 status = smbd_smb2_send_queue_ack_bytes(&xconn->smb2.send_queue, 0);
1352 if (!NT_STATUS_IS_OK(status)) {
1356 return NT_STATUS_OK;
1359 static void smbXsrv_connection_ack_checker(struct tevent_req *subreq)
1361 struct smbXsrv_connection *xconn =
1362 tevent_req_callback_data(subreq,
1363 struct smbXsrv_connection);
1364 struct smbXsrv_client *client = xconn->client;
1365 struct timeval next_check;
1369 xconn->ack.checker_subreq = NULL;
1371 ok = tevent_wakeup_recv(subreq);
1372 TALLOC_FREE(subreq);
1374 smbd_server_connection_terminate(xconn,
1375 "tevent_wakeup_recv() failed");
1379 status = smbd_smb2_check_ack_queue(xconn);
1380 if (!NT_STATUS_IS_OK(status)) {
1381 smbd_server_connection_terminate(xconn, nt_errstr(status));
1385 next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1386 xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1389 if (xconn->ack.checker_subreq == NULL) {
1390 smbd_server_connection_terminate(xconn,
1391 "tevent_wakeup_send() failed");
1394 tevent_req_set_callback(xconn->ack.checker_subreq,
1395 smbXsrv_connection_ack_checker,
1399 static NTSTATUS smbXsrv_client_pending_breaks_updated(struct smbXsrv_client *client)
1401 struct smbXsrv_connection *xconn = NULL;
1403 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1404 struct timeval next_check;
1405 uint64_t acked_bytes = 0;
1409 * A new 'pending break cycle' starts
1410 * with a first pending break and lasts until
1411 * all pending breaks are finished.
1413 * This is typically a very short time,
1414 * the value of one retransmission timeout.
1417 if (client->pending_breaks == NULL) {
1419 * No more pending breaks, remove a pending
1422 TALLOC_FREE(xconn->ack.checker_subreq);
1426 if (xconn->ack.checker_subreq != NULL) {
1428 * The cycle already started =>
1435 * Get the current retransmission timeout value.
1437 * It may change over time, but fetching it once
1438 * per 'pending break' cycled should be enough.
1440 status = smbXsrv_connection_get_rto_usecs(xconn,
1441 &xconn->ack.rto_usecs);
1442 if (!NT_STATUS_IS_OK(status)) {
1447 * At the start of the cycle we reset the
1448 * unacked_bytes counter (first to 0 and
1449 * within smbXsrv_connection_get_acked_bytes()
1450 * to the current value in the kernel
1453 xconn->ack.unacked_bytes = 0;
1454 status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1455 if (!NT_STATUS_IS_OK(status)) {
1460 * We setup a timer in order to check for
1461 * acked bytes after one retransmission timeout.
1463 * The code that sets up the send_queue.ack.timeout
1464 * uses a multiple of the retransmission timeout.
1466 next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1467 xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1470 if (xconn->ack.checker_subreq == NULL) {
1471 return NT_STATUS_NO_MEMORY;
1473 tevent_req_set_callback(xconn->ack.checker_subreq,
1474 smbXsrv_connection_ack_checker,
1478 return NT_STATUS_OK;
1481 void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
1484 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
1488 xconn->transport.status = status;
1489 TALLOC_FREE(xconn->transport.fde);
1490 if (xconn->transport.sock != -1) {
1491 xconn->transport.sock = -1;
1493 smbd_smb2_send_queue_ack_fail(&xconn->ack.queue, status);
1494 smbd_smb2_send_queue_ack_fail(&xconn->smb2.send_queue, status);
1495 xconn->smb2.send_queue_len = 0;
1496 DO_PROFILE_INC(disconnect);
1499 size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
1501 struct smbXsrv_connection *xconn = NULL;
1504 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1505 if (NT_STATUS_IS_OK(xconn->transport.status)) {
1513 struct smbXsrv_connection_shutdown_state {
1514 struct smbXsrv_connection *xconn;
1517 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
1519 static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
1520 struct tevent_context *ev,
1521 struct smbXsrv_connection *xconn)
1523 struct tevent_req *req = NULL;
1524 struct smbXsrv_connection_shutdown_state *state = NULL;
1525 struct tevent_req *subreq = NULL;
1527 struct smbd_smb2_request *preq = NULL;
1531 * The caller should have called
1532 * smbXsrv_connection_disconnect_transport() before.
1534 SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
1535 SMB_ASSERT(xconn->transport.terminating);
1536 SMB_ASSERT(xconn->transport.shutdown_wait_queue == NULL);
1538 req = tevent_req_create(mem_ctx, &state,
1539 struct smbXsrv_connection_shutdown_state);
1544 state->xconn = xconn;
1545 tevent_req_defer_callback(req, ev);
1547 xconn->transport.shutdown_wait_queue =
1548 tevent_queue_create(state, "smbXsrv_connection_shutdown_queue");
1549 if (tevent_req_nomem(xconn->transport.shutdown_wait_queue, req)) {
1550 return tevent_req_post(req, ev);
1553 for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next) {
1555 * Now wait until the request is finished.
1557 * We don't set a callback, as we just want to block the
1558 * wait queue and the talloc_free() of the request will
1559 * remove the item from the wait queue.
1561 * Note that we don't cancel the requests here
1562 * in order to keep the replay detection logic correct.
1564 * However if we teardown the last channel of
1565 * a connection, we'll call some logic via
1566 * smbXsrv_session_disconnect_xconn()
1567 * -> smbXsrv_session_disconnect_xconn_callback()
1568 * -> smbXsrv_session_remove_channel()
1569 * -> smb2srv_session_shutdown_send()
1570 * will indeed cancel the request.
1572 subreq = tevent_queue_wait_send(preq, ev,
1573 xconn->transport.shutdown_wait_queue);
1574 if (tevent_req_nomem(subreq, req)) {
1575 return tevent_req_post(req, ev);
1580 * This may attach sessions with num_channels == 0
1581 * to xconn->transport.shutdown_wait_queue.
1583 status = smbXsrv_session_disconnect_xconn(xconn);
1584 if (tevent_req_nterror(req, status)) {
1585 return tevent_req_post(req, ev);
1588 len = tevent_queue_length(xconn->transport.shutdown_wait_queue);
1590 tevent_req_done(req);
1591 return tevent_req_post(req, ev);
1595 * Now we add our own waiter to the end of the queue,
1596 * this way we get notified when all pending requests are finished
1597 * and send to the socket.
1599 subreq = tevent_queue_wait_send(state, ev, xconn->transport.shutdown_wait_queue);
1600 if (tevent_req_nomem(subreq, req)) {
1601 return tevent_req_post(req, ev);
1603 tevent_req_set_callback(subreq, smbXsrv_connection_shutdown_wait_done, req);
1608 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
1610 struct tevent_req *req =
1611 tevent_req_callback_data(subreq,
1613 struct smbXsrv_connection_shutdown_state *state =
1614 tevent_req_data(req,
1615 struct smbXsrv_connection_shutdown_state);
1616 struct smbXsrv_connection *xconn = state->xconn;
1618 tevent_queue_wait_recv(subreq);
1619 TALLOC_FREE(subreq);
1621 tevent_req_done(req);
1623 * make sure the xconn pointer is still valid,
1624 * it should as we used tevent_req_defer_callback()
1626 SMB_ASSERT(xconn->transport.terminating);
1629 static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
1631 struct smbXsrv_connection_shutdown_state *state =
1632 tevent_req_data(req,
1633 struct smbXsrv_connection_shutdown_state);
1634 struct smbXsrv_connection *xconn = state->xconn;
1636 * make sure the xconn pointer is still valid,
1637 * it should as we used tevent_req_defer_callback()
1639 SMB_ASSERT(xconn->transport.terminating);
1640 return tevent_req_simple_recv_ntstatus(req);
1643 static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
1645 struct smbXsrv_connection *xconn =
1646 tevent_req_callback_data(subreq,
1647 struct smbXsrv_connection);
1648 struct smbXsrv_client *client = xconn->client;
1651 status = smbXsrv_connection_shutdown_recv(subreq);
1652 TALLOC_FREE(subreq);
1653 if (!NT_STATUS_IS_OK(status)) {
1654 exit_server("smbXsrv_connection_shutdown_recv failed");
1657 DLIST_REMOVE(client->connections, xconn);
1661 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
1663 const char *location)
1665 struct smbXsrv_client *client = xconn->client;
1669 * Make sure that no new request will be able to use this session.
1671 * smbXsrv_connection_disconnect_transport() might be called already,
1672 * but calling it again is a no-op.
1674 smbXsrv_connection_disconnect_transport(xconn,
1675 NT_STATUS_CONNECTION_DISCONNECTED);
1677 num_ok = smbXsrv_client_valid_connections(client);
1679 if (xconn->transport.terminating) {
1680 DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1681 smbXsrv_connection_dbg(xconn), num_ok,
1685 xconn->transport.terminating = true;
1687 DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1688 smbXsrv_connection_dbg(xconn), num_ok,
1691 if (xconn->has_cluster_movable_ip) {
1693 * If the connection has a movable cluster public address
1694 * we disconnect all client connections,
1695 * as the public address might be moved to
1698 * In future we may recheck which node currently
1699 * holds this address, but for now we keep it simple.
1701 smbd_server_disconnect_client_ex(xconn->client,
1708 struct tevent_req *subreq = NULL;
1710 subreq = smbXsrv_connection_shutdown_send(client,
1713 if (subreq == NULL) {
1714 exit_server("smbXsrv_connection_shutdown_send failed");
1716 tevent_req_set_callback(subreq,
1717 smbd_server_connection_terminate_done,
1723 * The last connection was disconnected
1725 exit_server_cleanly(reason);
1728 void smbd_server_disconnect_client_ex(struct smbXsrv_client *client,
1730 const char *location)
1734 num_ok = smbXsrv_client_valid_connections(client);
1736 DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1737 client->global->remote_address, num_ok,
1741 * Something bad happened we need to disconnect all connections.
1743 exit_server_cleanly(reason);
1746 static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1747 struct iovec *outvec,
1748 const struct iovec *srcvec)
1750 const uint8_t *srctf;
1752 const uint8_t *srchdr;
1754 const uint8_t *srcbody;
1756 const uint8_t *expected_srcbody;
1757 const uint8_t *srcdyn;
1759 const uint8_t *expected_srcdyn;
1765 srctf = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1766 srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1767 srchdr = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1768 srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1769 srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1770 srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1771 expected_srcbody = srchdr + SMB2_HDR_BODY;
1772 srcdyn = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1773 srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1774 expected_srcdyn = srcbody + 8;
1776 if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1780 if (srchdr_len != SMB2_HDR_BODY) {
1784 if (srctf_len == SMB2_TF_HDR_SIZE) {
1785 dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1786 if (dsttf == NULL) {
1792 outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1793 outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1795 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1796 * be allocated with size OUTVEC_ALLOC_SIZE. */
1798 dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1799 if (dsthdr == NULL) {
1802 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1803 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1806 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1807 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1808 * then duplicate this. Else use talloc_memdup().
1811 if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1812 dstbody = dsthdr + SMB2_HDR_BODY;
1814 dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1815 if (dstbody == NULL) {
1819 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1820 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1823 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1825 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1826 * then duplicate this. Else use talloc_memdup().
1829 if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1830 dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1831 } else if (srcdyn == NULL) {
1834 dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1835 if (dstdyn == NULL) {
1839 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1840 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1845 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1847 struct smbd_smb2_request *newreq = NULL;
1848 struct iovec *outvec = NULL;
1849 int count = req->out.vector_count;
1853 newreq = smbd_smb2_request_allocate(req->xconn);
1858 newreq->sconn = req->sconn;
1859 newreq->xconn = req->xconn;
1860 newreq->session = req->session;
1861 newreq->do_encryption = req->do_encryption;
1862 newreq->do_signing = req->do_signing;
1863 newreq->current_idx = req->current_idx;
1865 outvec = talloc_zero_array(newreq, struct iovec, count);
1867 TALLOC_FREE(newreq);
1870 newreq->out.vector = outvec;
1871 newreq->out.vector_count = count;
1873 /* Setup the outvec's identically to req. */
1874 outvec[0].iov_base = newreq->out.nbt_hdr;
1875 outvec[0].iov_len = 4;
1876 memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1878 /* Setup the vectors identically to the ones in req. */
1879 for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1880 if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1887 TALLOC_FREE(newreq);
1891 ok = smb2_setup_nbt_length(newreq->out.vector,
1892 newreq->out.vector_count);
1894 TALLOC_FREE(newreq);
1901 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
1903 struct smbXsrv_connection *xconn = req->xconn;
1905 struct iovec *firsttf = NULL;
1906 struct iovec *outhdr_v = NULL;
1907 uint8_t *outhdr = NULL;
1908 struct smbd_smb2_request *nreq = NULL;
1912 /* Create a new smb2 request we'll use
1913 for the interim return. */
1914 nreq = dup_smb2_req(req);
1916 return NT_STATUS_NO_MEMORY;
1919 /* Lose the last X out vectors. They're the
1920 ones we'll be using for the async reply. */
1921 nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
1923 ok = smb2_setup_nbt_length(nreq->out.vector,
1924 nreq->out.vector_count);
1926 return NT_STATUS_INVALID_PARAMETER_MIX;
1929 /* Step back to the previous reply. */
1930 nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
1931 firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
1932 outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
1933 outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
1934 /* And end the chain. */
1935 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
1937 /* Calculate outgoing credits */
1938 smb2_calculate_credits(req, nreq);
1940 if (DEBUGLEVEL >= 10) {
1941 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1942 (unsigned int)nreq->current_idx );
1943 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1944 (unsigned int)nreq->out.vector_count );
1945 print_req_vectors(nreq);
1949 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1950 * we need to sign/encrypt here with the last/first key we remembered
1952 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
1953 status = smb2_signing_encrypt_pdu(req->first_enc_key,
1955 nreq->out.vector_count - first_idx);
1956 if (!NT_STATUS_IS_OK(status)) {
1959 } else if (smb2_signing_key_valid(req->last_sign_key)) {
1960 status = smb2_signing_sign_pdu(req->last_sign_key,
1962 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1963 if (!NT_STATUS_IS_OK(status)) {
1968 nreq->queue_entry.mem_ctx = nreq;
1969 nreq->queue_entry.vector = nreq->out.vector;
1970 nreq->queue_entry.count = nreq->out.vector_count;
1971 DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
1972 xconn->smb2.send_queue_len++;
1974 status = smbd_smb2_flush_send_queue(xconn);
1975 if (!NT_STATUS_IS_OK(status)) {
1979 return NT_STATUS_OK;
1982 struct smbd_smb2_request_pending_state {
1983 struct smbd_smb2_send_queue queue_entry;
1984 uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1985 struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1988 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1989 struct tevent_timer *te,
1990 struct timeval current_time,
1991 void *private_data);
1993 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1994 struct tevent_req *subreq,
1995 uint32_t defer_time)
1998 struct timeval defer_endtime;
1999 uint8_t *outhdr = NULL;
2002 if (!tevent_req_is_in_progress(subreq)) {
2004 * This is a performance optimization,
2005 * it avoids one tevent_loop iteration,
2006 * which means we avoid one
2007 * talloc_stackframe_pool/talloc_free pair.
2009 tevent_req_notify_callback(subreq);
2010 return NT_STATUS_OK;
2013 req->subreq = subreq;
2016 if (req->async_te) {
2017 /* We're already async. */
2018 return NT_STATUS_OK;
2021 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2022 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2023 if (flags & SMB2_HDR_FLAG_ASYNC) {
2024 /* We're already async. */
2025 return NT_STATUS_OK;
2028 if (req->async_internal || defer_time == 0) {
2030 * An SMB2 request implementation wants to handle the request
2031 * asynchronously "internally" while keeping synchronous
2032 * behaviour for the SMB2 request. This means we don't send an
2033 * interim response and we can allow processing of compound SMB2
2034 * requests (cf the subsequent check) for all cases.
2036 return NT_STATUS_OK;
2039 if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
2041 * We're trying to go async in a compound request
2042 * chain. This is only allowed for opens that cause an
2043 * oplock break or for the last operation in the
2044 * chain, otherwise it is not allowed. See
2045 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2047 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2049 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
2051 * Cancel the outstanding request.
2053 bool ok = tevent_req_cancel(req->subreq);
2055 return NT_STATUS_OK;
2057 TALLOC_FREE(req->subreq);
2058 return smbd_smb2_request_error(req,
2059 NT_STATUS_INTERNAL_ERROR);
2063 if (DEBUGLEVEL >= 10) {
2064 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2065 (unsigned int)req->current_idx );
2066 print_req_vectors(req);
2069 if (req->current_idx > 1) {
2071 * We're going async in a compound
2072 * chain after the first request has
2073 * already been processed. Send an
2074 * interim response containing the
2075 * set of replies already generated.
2077 int idx = req->current_idx;
2079 status = smb2_send_async_interim_response(req);
2080 if (!NT_STATUS_IS_OK(status)) {
2083 TALLOC_FREE(req->first_enc_key);
2085 req->current_idx = 1;
2088 * Re-arrange the in.vectors to remove what
2091 memmove(&req->in.vector[1],
2092 &req->in.vector[idx],
2093 sizeof(req->in.vector[0])*(req->in.vector_count - idx));
2094 req->in.vector_count = 1 + (req->in.vector_count - idx);
2096 /* Re-arrange the out.vectors to match. */
2097 memmove(&req->out.vector[1],
2098 &req->out.vector[idx],
2099 sizeof(req->out.vector[0])*(req->out.vector_count - idx));
2100 req->out.vector_count = 1 + (req->out.vector_count - idx);
2102 if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
2104 * We only have one remaining request as
2105 * we've processed everything else.
2106 * This is no longer a compound request.
2108 req->compound_related = false;
2109 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2110 flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
2111 SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
2114 TALLOC_FREE(req->last_sign_key);
2117 * smbd_smb2_request_pending_timer() just send a packet
2118 * to the client and doesn't need any impersonation.
2119 * So we use req->xconn->client->raw_ev_ctx instead
2120 * of req->ev_ctx here.
2122 defer_endtime = timeval_current_ofs_usec(defer_time);
2123 req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
2125 smbd_smb2_request_pending_timer,
2127 if (req->async_te == NULL) {
2128 return NT_STATUS_NO_MEMORY;
2131 return NT_STATUS_OK;
2135 struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
2136 struct smbXsrv_connection *xconn,
2139 struct smbXsrv_channel_global0 *c = NULL;
2141 struct smb2_signing_key *key = NULL;
2142 bool has_channel = false;
2144 status = smbXsrv_session_find_channel(session, xconn, &c);
2145 if (NT_STATUS_IS_OK(status)) {
2146 key = c->signing_key;
2150 if (!smb2_signing_key_valid(key)) {
2151 key = session->global->signing_key;
2152 has_channel = false;
2155 if (_has_channel != NULL) {
2156 *_has_channel = has_channel;
2162 static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
2163 uint64_t *new_nonce_high,
2164 uint64_t *new_nonce_low)
2166 uint64_t nonce_high;
2169 session->nonce_low += 1;
2170 if (session->nonce_low == 0) {
2171 session->nonce_low += 1;
2172 session->nonce_high += 1;
2176 * CCM and GCM algorithms must never have their
2177 * nonce wrap, or the security of the whole
2178 * communication and the keys is destroyed.
2179 * We must drop the connection once we have
2180 * transfered too much data.
2182 * NOTE: We assume nonces greater than 8 bytes.
2184 if (session->nonce_high >= session->nonce_high_max) {
2185 return NT_STATUS_ENCRYPTION_FAILED;
2188 nonce_high = session->nonce_high_random;
2189 nonce_high += session->nonce_high;
2190 nonce_low = session->nonce_low;
2192 *new_nonce_high = nonce_high;
2193 *new_nonce_low = nonce_low;
2194 return NT_STATUS_OK;
2197 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
2198 struct tevent_timer *te,
2199 struct timeval current_time,
2202 struct smbd_smb2_request *req =
2203 talloc_get_type_abort(private_data,
2204 struct smbd_smb2_request);
2205 struct smbXsrv_connection *xconn = req->xconn;
2206 struct smbd_smb2_request_pending_state *state = NULL;
2207 uint8_t *outhdr = NULL;
2208 const uint8_t *inhdr = NULL;
2210 uint8_t *hdr = NULL;
2211 uint8_t *body = NULL;
2212 uint8_t *dyn = NULL;
2214 uint64_t message_id = 0;
2215 uint64_t async_id = 0;
2219 TALLOC_FREE(req->async_te);
2221 /* Ensure our final reply matches the interim one. */
2222 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2223 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2224 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2225 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2227 async_id = message_id; /* keep it simple for now... */
2229 SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2230 SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
2232 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2234 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2235 (unsigned long long)async_id ));
2238 * What we send is identical to a smbd_smb2_request_error
2239 * packet with an error status of STATUS_PENDING. Make use
2240 * of this fact sometime when refactoring. JRA.
2243 state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
2244 if (state == NULL) {
2245 smbd_server_connection_terminate(xconn,
2246 nt_errstr(NT_STATUS_NO_MEMORY));
2250 tf = state->buf + NBT_HDR_SIZE;
2252 hdr = tf + SMB2_TF_HDR_SIZE;
2253 body = hdr + SMB2_HDR_BODY;
2256 if (req->do_encryption) {
2257 uint64_t nonce_high = 0;
2258 uint64_t nonce_low = 0;
2259 uint64_t session_id = req->session->global->session_wire_id;
2261 status = smb2_get_new_nonce(req->session,
2264 if (!NT_STATUS_IS_OK(status)) {
2265 smbd_server_connection_terminate(xconn,
2270 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2271 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2272 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2273 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2276 SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
2277 SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
2278 SSVAL(hdr, SMB2_HDR_EPOCH, 0);
2279 SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_PENDING));
2280 SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
2283 * The STATUS_PENDING response has SMB2_HDR_FLAG_SIGNED
2284 * clearedm, but echoes the signature field.
2286 flags &= ~SMB2_HDR_FLAG_SIGNED;
2287 SIVAL(hdr, SMB2_HDR_FLAGS, flags);
2288 SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
2289 SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
2290 SBVAL(hdr, SMB2_HDR_PID, async_id);
2291 SBVAL(hdr, SMB2_HDR_SESSION_ID,
2292 BVAL(outhdr, SMB2_HDR_SESSION_ID));
2293 memcpy(hdr+SMB2_HDR_SIGNATURE,
2294 outhdr+SMB2_HDR_SIGNATURE, 16);
2296 SSVAL(body, 0x00, 0x08 + 1);
2298 SCVAL(body, 0x02, 0);
2299 SCVAL(body, 0x03, 0);
2300 SIVAL(body, 0x04, 0);
2301 /* Match W2K8R2... */
2302 SCVAL(dyn, 0x00, 0x21);
2304 state->vector[0].iov_base = (void *)state->buf;
2305 state->vector[0].iov_len = NBT_HDR_SIZE;
2307 if (req->do_encryption) {
2308 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
2309 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len =
2312 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
2313 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
2316 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
2317 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
2319 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
2320 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
2322 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
2323 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len = 1;
2325 ok = smb2_setup_nbt_length(state->vector,
2326 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2328 smbd_server_connection_terminate(
2329 xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
2333 /* Ensure we correctly go through crediting. Grant
2334 the credits now, and zero credits on the final
2336 smb2_set_operation_credit(req->xconn,
2337 SMBD_SMB2_IN_HDR_IOV(req),
2338 &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
2341 * We add SMB2_HDR_FLAG_ASYNC after smb2_set_operation_credit()
2342 * as it reacts on it
2344 SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2349 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
2350 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2352 (unsigned int)ARRAY_SIZE(state->vector),
2353 (unsigned int)state->vector[i].iov_len);
2357 if (req->do_encryption) {
2358 struct smbXsrv_session *x = req->session;
2359 struct smb2_signing_key *encryption_key = x->global->encryption_key;
2361 status = smb2_signing_encrypt_pdu(encryption_key,
2362 &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2363 SMBD_SMB2_NUM_IOV_PER_REQ);
2364 if (!NT_STATUS_IS_OK(status)) {
2365 smbd_server_connection_terminate(xconn,
2371 state->queue_entry.mem_ctx = state;
2372 state->queue_entry.vector = state->vector;
2373 state->queue_entry.count = ARRAY_SIZE(state->vector);
2374 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
2375 xconn->smb2.send_queue_len++;
2377 status = smbd_smb2_flush_send_queue(xconn);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 smbd_server_connection_terminate(xconn,
2385 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
2387 struct smbXsrv_connection *xconn = req->xconn;
2388 struct smbd_smb2_request *cur;
2389 const uint8_t *inhdr;
2391 uint64_t search_message_id;
2392 uint64_t search_async_id;
2395 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2397 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2398 search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2399 search_async_id = BVAL(inhdr, SMB2_HDR_PID);
2402 * We don't need the request anymore cancel requests never
2405 * We defer the TALLOC_FREE(req) to the caller.
2407 DLIST_REMOVE(xconn->smb2.requests, req);
2409 for (cur = xconn->smb2.requests; cur; cur = cur->next) {
2410 const uint8_t *outhdr;
2411 uint64_t message_id;
2414 if (cur->session != req->session) {
2418 if (cur->compound_related) {
2420 * Never cancel anything in a compound request.
2421 * Way too hard to deal with the result.
2426 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
2428 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2429 async_id = BVAL(outhdr, SMB2_HDR_PID);
2431 if (flags & SMB2_HDR_FLAG_ASYNC) {
2432 if (search_async_id == async_id) {
2433 found_id = async_id;
2437 if (search_message_id == message_id) {
2438 found_id = message_id;
2444 if (cur && cur->subreq) {
2445 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
2446 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2447 "cancel opcode[%s] mid %llu\n",
2448 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2449 (unsigned long long)found_id ));
2450 tevent_req_cancel(cur->subreq);
2453 return NT_STATUS_OK;
2456 /*************************************************************
2457 Ensure an incoming tid is a valid one for us to access.
2458 Change to the associated uid credentials and chdir to the
2459 valid tid directory.
2460 *************************************************************/
2462 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
2464 const uint8_t *inhdr;
2467 struct smbXsrv_tcon *tcon;
2469 NTTIME now = timeval_to_nttime(&req->request_time);
2473 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2475 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2476 in_tid = IVAL(inhdr, SMB2_HDR_TID);
2478 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2479 in_tid = req->last_tid;
2484 status = smb2srv_tcon_lookup(req->session,
2485 in_tid, now, &tcon);
2486 if (!NT_STATUS_IS_OK(status)) {
2490 if (!change_to_user_and_service(
2492 req->session->global->session_wire_id))
2494 return NT_STATUS_ACCESS_DENIED;
2498 req->last_tid = in_tid;
2500 return NT_STATUS_OK;
2503 /*************************************************************
2504 Ensure an incoming session_id is a valid one for us to access.
2505 *************************************************************/
2507 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
2509 const uint8_t *inhdr;
2512 uint64_t in_session_id;
2513 struct smbXsrv_session *session = NULL;
2514 struct auth_session_info *session_info;
2516 NTTIME now = timeval_to_nttime(&req->request_time);
2518 req->session = NULL;
2521 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2523 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2524 in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2525 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
2527 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2528 in_session_id = req->last_session_id;
2531 req->last_session_id = 0;
2533 /* look an existing session up */
2534 switch (in_opcode) {
2535 case SMB2_OP_SESSSETUP:
2537 * For a session bind request, we don't have the
2538 * channel set up at this point yet, so we defer
2539 * the verification that the connection belongs
2540 * to the session to the session setup code, which
2541 * can look at the session binding flags.
2543 status = smb2srv_session_lookup_client(req->xconn->client,
2548 status = smb2srv_session_lookup_conn(req->xconn,
2554 req->session = session;
2555 req->last_session_id = in_session_id;
2557 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
2558 switch (in_opcode) {
2559 case SMB2_OP_SESSSETUP:
2560 status = smb2srv_session_lookup_global(req->xconn->client,
2564 if (NT_STATUS_IS_OK(status)) {
2566 * We fallback to a session of
2567 * another process in order to
2568 * get the signing correct.
2570 * We don't set req->last_session_id here.
2572 req->session = session;
2579 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
2580 switch (in_opcode) {
2581 case SMB2_OP_SESSSETUP:
2582 status = NT_STATUS_OK;
2584 case SMB2_OP_LOGOFF:
2587 case SMB2_OP_CANCEL:
2588 case SMB2_OP_KEEPALIVE:
2590 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2591 * specifies that LOGOFF, CLOSE and (UN)LOCK
2592 * should always be processed even on expired sessions.
2594 * Also see the logic in
2595 * smbd_smb2_request_process_lock().
2597 * The smb2.session.expire2 test shows that
2598 * CANCEL and KEEPALIVE/ECHO should also
2601 status = NT_STATUS_OK;
2607 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2608 switch (in_opcode) {
2610 case SMB2_OP_CREATE:
2611 case SMB2_OP_GETINFO:
2612 case SMB2_OP_SETINFO:
2613 return NT_STATUS_INVALID_HANDLE;
2616 * Notice the check for
2617 * (session_info == NULL)
2620 status = NT_STATUS_OK;
2624 if (!NT_STATUS_IS_OK(status)) {
2628 session_info = session->global->auth_session_info;
2629 if (session_info == NULL) {
2630 return NT_STATUS_INVALID_HANDLE;
2633 return NT_STATUS_OK;
2636 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
2637 uint32_t data_length)
2639 struct smbXsrv_connection *xconn = req->xconn;
2640 uint16_t needed_charge;
2641 uint16_t credit_charge = 1;
2642 const uint8_t *inhdr;
2644 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2646 if (xconn->smb2.credits.multicredit) {
2647 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
2648 credit_charge = MAX(credit_charge, 1);
2651 needed_charge = (data_length - 1)/ 65536 + 1;
2653 DBGC_DEBUG(DBGC_SMB2_CREDITS,
2654 "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2655 (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
2656 credit_charge, needed_charge);
2658 if (needed_charge > credit_charge) {
2659 DBGC_WARNING(DBGC_SMB2_CREDITS,
2660 "CreditCharge too low, given %d, needed %d\n",
2661 credit_charge, needed_charge);
2662 return NT_STATUS_INVALID_PARAMETER;
2665 return NT_STATUS_OK;
2668 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
2669 size_t expected_body_size)
2671 struct iovec *inhdr_v;
2672 const uint8_t *inhdr;
2674 const uint8_t *inbody;
2676 size_t min_dyn_size = expected_body_size & 0x00000001;
2677 int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2680 * The following should be checked already.
2682 if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2683 return NT_STATUS_INTERNAL_ERROR;
2685 if (req->current_idx > max_idx) {
2686 return NT_STATUS_INTERNAL_ERROR;
2689 inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2690 if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2691 return NT_STATUS_INTERNAL_ERROR;
2693 if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2694 return NT_STATUS_INTERNAL_ERROR;
2697 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2698 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2702 case SMB2_OP_GETINFO:
2709 * Now check the expected body size,
2710 * where the last byte might be in the
2713 if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2714 return NT_STATUS_INVALID_PARAMETER;
2716 if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2717 return NT_STATUS_INVALID_PARAMETER;
2720 inbody = SMBD_SMB2_IN_BODY_PTR(req);
2722 body_size = SVAL(inbody, 0x00);
2723 if (body_size != expected_body_size) {
2724 return NT_STATUS_INVALID_PARAMETER;
2727 return NT_STATUS_OK;
2730 bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2732 return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2734 (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2735 SMBXSRV_ENCRYPTION_DESIRED |
2736 SMBXSRV_ENCRYPTION_REQUIRED)));
2739 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2741 return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2742 (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2745 /* Set a flag if not already set, return true if set */
2746 bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2748 if ((flag == 0) || (*flags & flag)) {
2757 * Update encryption state tracking flags, this can be used to
2758 * determine whether whether the session or tcon is "encrypted".
2760 static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2762 bool *update_session_globalp,
2763 bool *update_tcon_globalp)
2765 /* Default: assume unecrypted and unsigned */
2766 struct smbXsrv_session *session = req->session;
2767 struct smbXsrv_tcon *tcon = req->tcon;
2768 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2769 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2770 bool update_session = false;
2771 bool update_tcon = false;
2773 if (session->table == NULL) {
2775 * sessions from smb2srv_session_lookup_global()
2776 * have NT_STATUS_BAD_LOGON_SESSION_STATE
2777 * and session->table == NULL.
2779 * They only used to give the correct error
2780 * status, we should not update any state.
2785 if (req->was_encrypted && req->do_encryption) {
2786 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2787 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2789 /* Unencrypted packet, can be signed */
2790 if (req->do_signing) {
2791 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2795 update_session |= smbXsrv_set_crypto_flag(
2796 &session->global->encryption_flags, encrypt_flag);
2797 update_session |= smbXsrv_set_crypto_flag(
2798 &session->global->signing_flags, sign_flag);
2801 update_tcon |= smbXsrv_set_crypto_flag(
2802 &tcon->global->encryption_flags, encrypt_flag);
2803 update_tcon |= smbXsrv_set_crypto_flag(
2804 &tcon->global->signing_flags, sign_flag);
2808 *update_session_globalp = update_session;
2809 *update_tcon_globalp = update_tcon;
2813 bool smbXsrv_is_signed(uint8_t signing_flags)
2816 * Signing is always enabled, so unless we got an unsigned
2817 * packet and at least one signed packet that was not
2818 * encrypted, the session or tcon is "signed".
2820 return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2821 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2824 bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2826 return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2827 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2830 static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2831 struct smbd_smb2_request *req,
2834 struct smbXsrv_connection *xconn = req->xconn;
2835 const uint8_t *inhdr;
2836 uint16_t channel_sequence;
2837 uint8_t generation_wrap = 0;
2840 struct smbXsrv_open *op;
2841 bool update_open = false;
2842 NTSTATUS status = NT_STATUS_OK;
2844 SMB_ASSERT(!req->request_counters_updated);
2846 if (xconn->protocol < PROTOCOL_SMB3_00) {
2847 return NT_STATUS_OK;
2850 if (req->compat_chain_fsp == NULL) {
2851 return NT_STATUS_OK;
2854 op = req->compat_chain_fsp->op;
2856 return NT_STATUS_OK;
2859 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2860 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2861 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2863 cmp = channel_sequence - op->global->channel_sequence;
2866 * csn wrap. We need to watch out for long-running
2867 * requests that are still sitting on a previously
2868 * used csn. SMB2_OP_NOTIFY can take VERY long.
2870 generation_wrap += 1;
2873 if (abs(cmp) > INT16_MAX) {
2875 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2877 * If the channel sequence number of the request and the one
2878 * known to the server are not equal, the channel sequence
2879 * number and outstanding request counts are only updated
2880 * "... if the unsigned difference using 16-bit arithmetic
2881 * between ChannelSequence and Open.ChannelSequence is less than
2882 * or equal to 0x7FFF ...".
2883 * Otherwise, an error is returned for the modifying
2884 * calls write, set_info, and ioctl.
2886 * There are currently two issues with the description:
2888 * * For the other calls, the document seems to imply
2889 * that processing continues without adapting the
2890 * counters (if the sequence numbers are not equal).
2892 * TODO: This needs clarification!
2894 * * Also, the behaviour if the difference is larger
2895 * than 0x7FFF is not clear. The document seems to
2896 * imply that if such a difference is reached,
2897 * the server starts to ignore the counters or
2898 * in the case of the modifying calls, return errors.
2900 * TODO: This needs clarification!
2902 * At this point Samba tries to be a little more
2903 * clever than the description in the MS-SMB2 document
2904 * by heuristically detecting and properly treating
2905 * a 16 bit overflow of the client-submitted sequence
2908 * If the stored channel sequence number is more than
2909 * 0x7FFF larger than the one from the request, then
2910 * the client-provided sequence number has likely
2911 * overflown. We treat this case as valid instead
2914 * The MS-SMB2 behaviour would be setting cmp = -1.
2919 if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2920 if (cmp == 0 && op->pre_request_count == 0) {
2921 op->request_count += 1;
2922 req->request_counters_updated = true;
2923 } else if (cmp > 0 && op->pre_request_count == 0) {
2924 op->pre_request_count += op->request_count;
2925 op->request_count = 1;
2926 op->global->channel_sequence = channel_sequence;
2927 op->global->channel_generation += generation_wrap;
2929 req->request_counters_updated = true;
2930 } else if (modify_call) {
2931 return NT_STATUS_FILE_NOT_AVAILABLE;
2935 op->request_count += 1;
2936 req->request_counters_updated = true;
2937 } else if (cmp > 0) {
2938 op->pre_request_count += op->request_count;
2939 op->request_count = 1;
2940 op->global->channel_sequence = channel_sequence;
2941 op->global->channel_generation += generation_wrap;
2943 req->request_counters_updated = true;
2944 } else if (modify_call) {
2945 return NT_STATUS_FILE_NOT_AVAILABLE;
2948 req->channel_generation = op->global->channel_generation;
2951 status = smbXsrv_open_update(op);
2957 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2959 struct smbXsrv_connection *xconn = req->xconn;
2960 const struct smbd_smb2_dispatch_table *call = NULL;
2961 const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2962 const uint8_t *inhdr;
2967 NTSTATUS session_status;
2968 uint32_t allowed_flags;
2969 NTSTATUS return_value;
2970 struct smbXsrv_session *x = NULL;
2971 bool signing_required = false;
2972 bool encryption_desired = false;
2973 bool encryption_required = false;
2975 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2977 DO_PROFILE_INC(request);
2979 SMB_ASSERT(!req->request_counters_updated);
2981 /* TODO: verify more things */
2983 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2984 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2985 mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2986 DBG_DEBUG("opcode[%s] mid = %"PRIu64"\n",
2987 smb2_opcode_name(opcode),
2990 if (xconn->protocol >= PROTOCOL_SMB2_02) {
2992 * once the protocol is negotiated
2993 * SMB2_OP_NEGPROT is not allowed anymore
2995 if (opcode == SMB2_OP_NEGPROT) {
2996 /* drop the connection */
2997 return NT_STATUS_INVALID_PARAMETER;
3001 * if the protocol is not negotiated yet
3002 * only SMB2_OP_NEGPROT is allowed.
3004 if (opcode != SMB2_OP_NEGPROT) {
3005 /* drop the connection */
3006 return NT_STATUS_INVALID_PARAMETER;
3011 * Check if the client provided a valid session id.
3013 * As some command don't require a valid session id
3014 * we defer the check of the session_status
3016 session_status = smbd_smb2_request_check_session(req);
3019 signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
3020 encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3021 encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
3024 req->async_internal = false;
3025 req->do_signing = false;
3026 if (opcode != SMB2_OP_SESSSETUP) {
3027 req->do_encryption = encryption_desired;
3029 req->do_encryption = false;
3031 req->was_encrypted = false;
3032 if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
3033 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
3034 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
3036 if (x != NULL && x->global->session_wire_id != tf_session_id) {
3037 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
3038 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
3039 (unsigned long long)x->global->session_wire_id,
3040 (unsigned long long)tf_session_id));
3042 * TODO: windows allows this...
3043 * should we drop the connection?
3045 * For now we just return ACCESS_DENIED
3046 * (Windows clients never trigger this)
3047 * and wait for an update of [MS-SMB2].
3049 return smbd_smb2_request_error(req,
3050 NT_STATUS_ACCESS_DENIED);
3053 req->was_encrypted = true;
3054 req->do_encryption = true;
3057 if (encryption_required && !req->was_encrypted) {
3058 req->do_encryption = true;
3059 return smbd_smb2_request_error(req,
3060 NT_STATUS_ACCESS_DENIED);
3063 call = smbd_smb2_call(opcode);
3065 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3068 allowed_flags = SMB2_HDR_FLAG_CHAINED |
3069 SMB2_HDR_FLAG_SIGNED |
3071 if (xconn->protocol >= PROTOCOL_SMB3_11) {
3072 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3074 if (opcode == SMB2_OP_NEGPROT) {
3075 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
3076 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3079 if (opcode == SMB2_OP_CANCEL) {
3080 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
3082 if (xconn->protocol >= PROTOCOL_SMB3_00) {
3083 allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3085 if ((flags & ~allowed_flags) != 0) {
3086 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3089 if (flags & SMB2_HDR_FLAG_CHAINED) {
3091 * This check is mostly for giving the correct error code
3092 * for compounded requests.
3094 if (!NT_STATUS_IS_OK(session_status)) {
3095 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3098 req->compat_chain_fsp = NULL;
3101 if (req->was_encrypted) {
3102 signing_required = false;
3103 } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
3104 struct smb2_signing_key *signing_key = NULL;
3105 bool has_channel = false;
3109 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3110 * If the SMB2 header of the SMB2 NEGOTIATE
3111 * request has the SMB2_FLAGS_SIGNED bit set in the
3112 * Flags field, the server MUST fail the request
3113 * with STATUS_INVALID_PARAMETER.
3115 * Microsoft test tool checks this.
3118 if ((opcode == SMB2_OP_NEGPROT) &&
3119 (flags & SMB2_HDR_FLAG_SIGNED)) {
3120 status = NT_STATUS_INVALID_PARAMETER;
3122 status = NT_STATUS_USER_SESSION_DELETED;
3124 return smbd_smb2_request_error(req, status);
3127 signing_key = smbd_smb2_signing_key(x, xconn, &has_channel);
3130 * If we have a signing key, we should
3133 if (smb2_signing_key_valid(signing_key) && opcode != SMB2_OP_CANCEL) {
3134 req->do_signing = true;
3137 status = smb2_signing_check_pdu(signing_key,
3138 SMBD_SMB2_IN_HDR_IOV(req),
3139 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3140 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
3141 opcode == SMB2_OP_SESSSETUP && !has_channel &&
3142 NT_STATUS_IS_OK(session_status))
3144 if (!NT_STATUS_EQUAL(x->status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
3145 struct smbXsrv_session *session = NULL;
3148 error = smb2srv_session_lookup_global(req->xconn->client,
3149 x->global->session_wire_id,
3152 if (!NT_STATUS_IS_OK(error)) {
3153 return smbd_smb2_request_error(req, error);
3157 * We fallback to a session of
3158 * another process in order to
3159 * get the signing correct.
3161 * We don't set req->last_session_id here.
3163 req->session = x = session;
3165 goto skipped_signing;
3167 if (!NT_STATUS_IS_OK(status)) {
3168 return smbd_smb2_request_error(req, status);
3172 * Now that we know the request was correctly signed
3173 * we have to sign the response too.
3175 if (opcode != SMB2_OP_CANCEL) {
3176 req->do_signing = true;
3179 if (!NT_STATUS_IS_OK(session_status)) {
3180 return smbd_smb2_request_error(req, session_status);
3184 if (opcode == SMB2_OP_IOCTL) {
3186 * Some special IOCTL calls don't require
3187 * file, tcon nor session.
3189 * They typically don't do any real action
3190 * on behalf of the client.
3192 * They are mainly used to alter the behavior
3193 * of the connection for testing. So we can
3194 * run as root and skip all file, tcon and session
3197 static const struct smbd_smb2_dispatch_table _root_ioctl_call = {
3201 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3202 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3203 uint32_t in_ctl_code;
3206 if (needed > body_size) {
3207 return smbd_smb2_request_error(req,
3208 NT_STATUS_INVALID_PARAMETER);
3211 in_ctl_code = IVAL(body, 0x04);
3213 * Only add trusted IOCTL codes here!
3215 switch (in_ctl_code) {
3216 case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
3217 call = &_root_ioctl_call;
3219 case FSCTL_VALIDATE_NEGOTIATE_INFO:
3220 call = &_root_ioctl_call;
3222 case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
3223 call = &_root_ioctl_call;
3230 if (flags & SMB2_HDR_FLAG_CHAINED) {
3231 req->compound_related = true;
3234 if (call->need_session) {
3235 if (!NT_STATUS_IS_OK(session_status)) {
3236 return smbd_smb2_request_error(req, session_status);
3240 if (call->need_tcon) {
3241 SMB_ASSERT(call->need_session);
3244 * This call needs to be run as user.
3246 * smbd_smb2_request_check_tcon()
3247 * calls change_to_user() on success.
3248 * Which implies set_current_user_info()
3249 * and chdir_current_service().
3251 status = smbd_smb2_request_check_tcon(req);
3252 if (!NT_STATUS_IS_OK(status)) {
3253 return smbd_smb2_request_error(req, status);
3255 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3256 encryption_desired = true;
3258 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
3259 encryption_required = true;
3261 if (encryption_required && !req->was_encrypted) {
3262 req->do_encryption = true;
3263 return smbd_smb2_request_error(req,
3264 NT_STATUS_ACCESS_DENIED);
3265 } else if (encryption_desired) {
3266 req->do_encryption = true;
3268 } else if (call->need_session) {
3269 struct auth_session_info *session_info = NULL;
3272 * Unless we also have need_tcon (see above),
3273 * we still need to call set_current_user_info().
3276 session_info = req->session->global->auth_session_info;
3277 if (session_info == NULL) {
3278 return NT_STATUS_INVALID_HANDLE;
3281 set_current_user_info(session_info->unix_info->sanitized_username,
3282 session_info->unix_info->unix_name,
3283 session_info->info->domain_name);
3287 bool update_session_global = false;
3288 bool update_tcon_global = false;
3290 smb2srv_update_crypto_flags(req, opcode,
3291 &update_session_global,
3292 &update_tcon_global);
3294 if (update_session_global) {
3295 status = smbXsrv_session_update(x);
3296 if (!NT_STATUS_IS_OK(status)) {
3297 return smbd_smb2_request_error(req, status);
3300 if (update_tcon_global) {
3301 status = smbXsrv_tcon_update(req->tcon);
3302 if (!NT_STATUS_IS_OK(status)) {
3303 return smbd_smb2_request_error(req, status);
3308 if (call->fileid_ofs != 0) {
3309 size_t needed = call->fileid_ofs + 16;
3310 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3311 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3312 uint64_t file_id_persistent;
3313 uint64_t file_id_volatile;
3314 struct files_struct *fsp;
3316 SMB_ASSERT(call->need_tcon);
3318 if (needed > body_size) {
3319 return smbd_smb2_request_error(req,
3320 NT_STATUS_INVALID_PARAMETER);
3323 file_id_persistent = BVAL(body, call->fileid_ofs + 0);
3324 file_id_volatile = BVAL(body, call->fileid_ofs + 8);
3326 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
3328 if (req->compound_related &&
3329 !NT_STATUS_IS_OK(req->compound_create_err))
3331 return smbd_smb2_request_error(req,
3332 req->compound_create_err);
3335 * smbd_smb2_request_process_ioctl()
3336 * has more checks in order to return more
3337 * detailed error codes...
3339 if (opcode != SMB2_OP_IOCTL) {
3340 return smbd_smb2_request_error(req,
3341 NT_STATUS_FILE_CLOSED);
3344 if (fsp->fsp_flags.encryption_required && !req->was_encrypted) {
3345 return smbd_smb2_request_error(req,
3346 NT_STATUS_ACCESS_DENIED);
3351 status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
3352 if (!NT_STATUS_IS_OK(status)) {
3353 return smbd_smb2_request_error(req, status);
3356 if (call->as_root) {
3357 SMB_ASSERT(call->fileid_ofs == 0);
3358 /* This call needs to be run as root */
3359 change_to_root_user();
3361 SMB_ASSERT(call->need_tcon);
3364 #define _INBYTES(_r) \
3365 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3368 case SMB2_OP_NEGPROT:
3369 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
3370 req->profile, _INBYTES(req));
3371 return_value = smbd_smb2_request_process_negprot(req);
3374 case SMB2_OP_SESSSETUP:
3375 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
3376 req->profile, _INBYTES(req));
3377 return_value = smbd_smb2_request_process_sesssetup(req);
3380 case SMB2_OP_LOGOFF:
3381 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
3382 req->profile, _INBYTES(req));
3383 return_value = smbd_smb2_request_process_logoff(req);
3387 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
3388 req->profile, _INBYTES(req));
3389 return_value = smbd_smb2_request_process_tcon(req);
3393 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
3394 req->profile, _INBYTES(req));
3395 return_value = smbd_smb2_request_process_tdis(req);
3398 case SMB2_OP_CREATE:
3399 if (req->subreq == NULL) {
3400 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
3401 req->profile, _INBYTES(req));
3403 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
3405 return_value = smbd_smb2_request_process_create(req);
3409 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
3410 req->profile, _INBYTES(req));
3411 return_value = smbd_smb2_request_process_close(req);
3415 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
3416 req->profile, _INBYTES(req));
3417 return_value = smbd_smb2_request_process_flush(req);
3421 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
3422 req->profile, _INBYTES(req));
3423 return_value = smbd_smb2_request_process_read(req);
3427 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
3428 req->profile, _INBYTES(req));
3429 return_value = smbd_smb2_request_process_write(req);
3433 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
3434 req->profile, _INBYTES(req));
3435 return_value = smbd_smb2_request_process_lock(req);
3439 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
3440 req->profile, _INBYTES(req));
3441 return_value = smbd_smb2_request_process_ioctl(req);
3444 case SMB2_OP_CANCEL:
3445 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
3446 req->profile, _INBYTES(req));
3447 return_value = smbd_smb2_request_process_cancel(req);
3448 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
3451 * We don't need the request anymore cancel requests never
3454 * smbd_smb2_request_process_cancel() already called
3455 * DLIST_REMOVE(xconn->smb2.requests, req);
3461 case SMB2_OP_KEEPALIVE:
3462 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
3463 req->profile, _INBYTES(req));
3464 return_value = smbd_smb2_request_process_keepalive(req);
3467 case SMB2_OP_QUERY_DIRECTORY:
3468 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
3469 req->profile, _INBYTES(req));
3470 return_value = smbd_smb2_request_process_query_directory(req);
3473 case SMB2_OP_NOTIFY:
3474 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
3475 req->profile, _INBYTES(req));
3476 return_value = smbd_smb2_request_process_notify(req);
3479 case SMB2_OP_GETINFO:
3480 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
3481 req->profile, _INBYTES(req));
3482 return_value = smbd_smb2_request_process_getinfo(req);
3485 case SMB2_OP_SETINFO:
3486 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
3487 req->profile, _INBYTES(req));
3488 return_value = smbd_smb2_request_process_setinfo(req);
3492 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
3493 req->profile, _INBYTES(req));
3494 return_value = smbd_smb2_request_process_break(req);
3498 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3501 return return_value;
3504 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
3506 struct smbXsrv_connection *xconn = req->xconn;
3507 const uint8_t *inhdr;
3508 uint16_t channel_sequence;
3509 struct smbXsrv_open *op;
3511 if (!req->request_counters_updated) {
3515 req->request_counters_updated = false;
3517 if (xconn->protocol < PROTOCOL_SMB3_00) {
3521 if (req->compat_chain_fsp == NULL) {
3525 op = req->compat_chain_fsp->op;
3530 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
3531 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
3533 if ((op->global->channel_sequence == channel_sequence) &&
3534 (op->global->channel_generation == req->channel_generation)) {
3535 SMB_ASSERT(op->request_count > 0);
3536 op->request_count -= 1;
3538 SMB_ASSERT(op->pre_request_count > 0);
3539 op->pre_request_count -= 1;
3543 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
3545 struct smbXsrv_connection *xconn = req->xconn;
3547 struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
3548 struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
3549 struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
3554 TALLOC_FREE(req->async_te);
3556 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3557 smbd_smb2_request_reply_update_counts(req);
3559 if (req->do_encryption &&
3560 (firsttf->iov_len == 0) &&
3561 (!smb2_signing_key_valid(req->first_enc_key)) &&
3562 (req->session != NULL) &&
3563 smb2_signing_key_valid(req->session->global->encryption_key))
3565 struct smb2_signing_key *encryption_key =
3566 req->session->global->encryption_key;
3568 uint64_t session_id = req->session->global->session_wire_id;
3569 uint64_t nonce_high;
3572 status = smb2_get_new_nonce(req->session,
3575 if (!NT_STATUS_IS_OK(status)) {
3580 * We need to place the SMB2_TRANSFORM header before the
3585 * we need to remember the encryption key
3586 * and defer the signing/encryption until
3587 * we are sure that we do not change
3590 status = smb2_signing_key_copy(req,
3592 &req->first_enc_key);
3593 if (!NT_STATUS_IS_OK(status)) {
3597 tf = talloc_zero_array(req, uint8_t,
3600 return NT_STATUS_NO_MEMORY;
3603 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3604 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
3605 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
3606 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
3608 firsttf->iov_base = (void *)tf;
3609 firsttf->iov_len = SMB2_TF_HDR_SIZE;
3612 if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
3613 (smb2_signing_key_valid(req->last_sign_key)) &&
3614 (firsttf->iov_len == 0))
3616 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
3617 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
3620 * As we are sure the header of the last request in the
3621 * compound chain will not change, we can to sign here
3622 * with the last signing key we remembered.
3624 status = smb2_signing_sign_pdu(req->last_sign_key,
3626 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3627 if (!NT_STATUS_IS_OK(status)) {
3631 TALLOC_FREE(req->last_sign_key);
3633 SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
3634 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
3636 req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
3638 if (req->current_idx < req->out.vector_count) {
3640 * We must process the remaining compound
3641 * SMB2 requests before any new incoming SMB2
3642 * requests. This is because incoming SMB2
3643 * requests may include a cancel for a
3644 * compound request we haven't processed
3647 struct tevent_immediate *im = tevent_create_immediate(req);
3649 return NT_STATUS_NO_MEMORY;
3652 if (req->do_signing && firsttf->iov_len == 0) {
3653 struct smbXsrv_session *x = req->session;
3654 struct smb2_signing_key *signing_key =
3655 smbd_smb2_signing_key(x, xconn, NULL);
3658 * we need to remember the signing key
3659 * and defer the signing until
3660 * we are sure that we do not change
3663 status = smb2_signing_key_copy(req,
3665 &req->last_sign_key);
3666 if (!NT_STATUS_IS_OK(status)) {
3672 * smbd_smb2_request_dispatch() will redo the impersonation.
3673 * So we use req->xconn->client->raw_ev_ctx instead
3674 * of req->ev_ctx here.
3676 tevent_schedule_immediate(im,
3677 req->xconn->client->raw_ev_ctx,
3678 smbd_smb2_request_dispatch_immediate,
3680 return NT_STATUS_OK;
3683 if (req->compound_related) {
3684 req->compound_related = false;
3687 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
3689 return NT_STATUS_INVALID_PARAMETER_MIX;
3692 /* Set credit for these operations (zero credits if this
3693 is a final reply for an async operation). */
3694 smb2_calculate_credits(req, req);
3697 * now check if we need to sign the current response
3699 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3700 status = smb2_signing_encrypt_pdu(req->first_enc_key,
3702 req->out.vector_count - first_idx);
3703 if (!NT_STATUS_IS_OK(status)) {
3706 } else if (req->do_signing) {
3707 struct smbXsrv_session *x = req->session;
3708 struct smb2_signing_key *signing_key =
3709 smbd_smb2_signing_key(x, xconn, NULL);
3711 status = smb2_signing_sign_pdu(signing_key,
3713 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3714 if (!NT_STATUS_IS_OK(status)) {
3718 TALLOC_FREE(req->first_enc_key);
3720 if (req->preauth != NULL) {
3721 gnutls_hash_hd_t hash_hnd = NULL;
3725 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3727 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3729 rc = gnutls_hash(hash_hnd,
3730 req->preauth->sha512_value,
3731 sizeof(req->preauth->sha512_value));
3733 gnutls_hash_deinit(hash_hnd, NULL);
3734 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3736 for (i = 1; i < req->in.vector_count; i++) {
3737 rc = gnutls_hash(hash_hnd,
3738 req->in.vector[i].iov_base,
3739 req->in.vector[i].iov_len);
3741 gnutls_hash_deinit(hash_hnd, NULL);
3742 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3746 gnutls_hash_deinit(hash_hnd, NULL);
3747 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3749 gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3751 rc = gnutls_hash(hash_hnd,
3752 req->preauth->sha512_value,
3753 sizeof(req->preauth->sha512_value));
3755 gnutls_hash_deinit(hash_hnd, NULL);
3756 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3758 for (i = 1; i < req->out.vector_count; i++) {
3759 rc = gnutls_hash(hash_hnd,
3760 req->out.vector[i].iov_base,
3761 req->out.vector[i].iov_len);
3763 gnutls_hash_deinit(hash_hnd, NULL);
3764 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3768 gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3770 req->preauth = NULL;
3773 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3774 if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3775 outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3776 /* Dynamic part is NULL. Chop it off,
3777 We're going to send it via sendfile. */
3778 req->out.vector_count -= 1;
3782 * We're done with this request -
3783 * move it off the "being processed" queue.
3785 DLIST_REMOVE(xconn->smb2.requests, req);
3787 req->queue_entry.mem_ctx = req;
3788 req->queue_entry.vector = req->out.vector;
3789 req->queue_entry.count = req->out.vector_count;
3790 DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3791 xconn->smb2.send_queue_len++;
3793 status = smbd_smb2_flush_send_queue(xconn);
3794 if (!NT_STATUS_IS_OK(status)) {
3798 return NT_STATUS_OK;
3801 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3803 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3804 struct tevent_immediate *im,
3807 struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3808 struct smbd_smb2_request);
3809 struct smbXsrv_connection *xconn = req->xconn;
3814 if (DEBUGLEVEL >= 10) {
3815 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3816 req->current_idx, req->in.vector_count));
3817 print_req_vectors(req);
3820 status = smbd_smb2_request_dispatch(req);
3821 if (!NT_STATUS_IS_OK(status)) {
3822 smbd_server_connection_terminate(xconn, nt_errstr(status));
3826 status = smbd_smb2_request_next_incoming(xconn);
3827 if (!NT_STATUS_IS_OK(status)) {
3828 smbd_server_connection_terminate(xconn, nt_errstr(status));
3833 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3835 DATA_BLOB body, DATA_BLOB *dyn,
3836 const char *location)
3839 struct iovec *outbody_v;
3840 struct iovec *outdyn_v;
3841 uint32_t next_command_ofs;
3844 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3845 mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
3847 DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
3848 "body[%u] dyn[%s:%u] at %s\n",
3852 (unsigned int)body.length,
3854 (unsigned int)(dyn ? dyn->length : 0),
3857 if (body.length < 2) {
3858 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3861 if ((body.length % 2) != 0) {
3862 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3865 outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3866 outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3868 next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3869 SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3871 outbody_v->iov_base = (void *)body.data;
3872 outbody_v->iov_len = body.length;
3875 outdyn_v->iov_base = (void *)dyn->data;
3876 outdyn_v->iov_len = dyn->length;
3878 outdyn_v->iov_base = NULL;
3879 outdyn_v->iov_len = 0;
3883 * See if we need to recalculate the offset to the next response
3885 * Note that all responses may require padding (including the very last
3888 if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3889 next_command_ofs = SMB2_HDR_BODY;
3890 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3891 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3894 if ((next_command_ofs % 8) != 0) {
3895 size_t pad_size = 8 - (next_command_ofs % 8);
3896 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3898 * if the dyn buffer is empty
3899 * we can use it to add padding
3903 pad = talloc_zero_array(req,
3906 return smbd_smb2_request_error(req,
3907 NT_STATUS_NO_MEMORY);
3910 outdyn_v->iov_base = (void *)pad;
3911 outdyn_v->iov_len = pad_size;
3914 * For now we copy the dynamic buffer
3915 * and add the padding to the new buffer
3922 old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3923 old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3925 new_size = old_size + pad_size;
3926 new_dyn = talloc_zero_array(req,
3928 if (new_dyn == NULL) {
3929 return smbd_smb2_request_error(req,
3930 NT_STATUS_NO_MEMORY);
3933 memcpy(new_dyn, old_dyn, old_size);
3934 memset(new_dyn + old_size, 0, pad_size);
3936 outdyn_v->iov_base = (void *)new_dyn;
3937 outdyn_v->iov_len = new_size;
3939 next_command_ofs += pad_size;
3942 if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3943 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3945 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3947 return smbd_smb2_request_reply(req);
3950 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3952 uint8_t error_context_count,
3954 const char *location)
3956 struct smbXsrv_connection *xconn = req->xconn;
3959 uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3960 size_t unread_bytes = smbd_smb2_unread_bytes(req);
3962 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3963 "at %s\n", req->current_idx, nt_errstr(status),
3964 info ? " +info" : "", location);
3967 /* Recvfile error. Drain incoming socket. */
3971 ret = drain_socket(xconn->transport.sock, unread_bytes);
3972 if (ret != unread_bytes) {
3976 error = NT_STATUS_IO_DEVICE_ERROR;
3978 error = map_nt_error_from_unix_common(errno);
3981 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3982 "ret[%u] errno[%d] => %s\n",
3983 (unsigned)unread_bytes,
3984 (unsigned)ret, errno, nt_errstr(error)));
3989 body.data = outhdr + SMB2_HDR_BODY;
3991 SSVAL(body.data, 0, 9);
3992 SCVAL(body.data, 2, error_context_count);
3995 SIVAL(body.data, 0x04, info->length);
3997 /* Allocated size of req->out.vector[i].iov_base
3998 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3999 * 1 byte without having to do an alloc.
4002 info->data = ((uint8_t *)outhdr) +
4003 OUTVEC_ALLOC_SIZE - 1;
4005 SCVAL(info->data, 0, 0);
4009 * Note: Even if there is an error, continue to process the request.
4013 return smbd_smb2_request_done_ex(req, status, body, info, __location__);
4016 struct smbd_smb2_break_state {
4017 struct tevent_req *req;
4018 struct smbd_smb2_send_queue queue_entry;
4019 uint8_t nbt_hdr[NBT_HDR_SIZE];
4020 uint8_t hdr[SMB2_HDR_BODY];
4021 struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
4024 static struct tevent_req *smbd_smb2_break_send(TALLOC_CTX *mem_ctx,
4025 struct tevent_context *ev,
4026 struct smbXsrv_connection *xconn,
4027 uint64_t session_id,
4028 const uint8_t *body,
4031 struct tevent_req *req = NULL;
4032 struct smbd_smb2_break_state *state = NULL;
4036 req = tevent_req_create(mem_ctx, &state,
4037 struct smbd_smb2_break_state);
4043 tevent_req_defer_callback(req, ev);
4045 SIVAL(state->hdr, 0, SMB2_MAGIC);
4046 SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
4047 SSVAL(state->hdr, SMB2_HDR_EPOCH, 0);
4048 SIVAL(state->hdr, SMB2_HDR_STATUS, 0);
4049 SSVAL(state->hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK);
4050 SSVAL(state->hdr, SMB2_HDR_CREDIT, 0);
4051 SIVAL(state->hdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
4052 SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, 0);
4053 SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
4054 SIVAL(state->hdr, SMB2_HDR_PID, 0);
4055 SIVAL(state->hdr, SMB2_HDR_TID, 0);
4056 SBVAL(state->hdr, SMB2_HDR_SESSION_ID, session_id);
4057 memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
4059 state->vector[0] = (struct iovec) {
4060 .iov_base = state->nbt_hdr,
4061 .iov_len = sizeof(state->nbt_hdr)
4064 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
4069 state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
4070 .iov_base = state->hdr,
4071 .iov_len = sizeof(state->hdr)
4074 state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
4075 .iov_base = discard_const_p(uint8_t, body),
4076 .iov_len = body_len,
4080 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4083 ok = smb2_setup_nbt_length(state->vector,
4084 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
4086 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4087 return tevent_req_post(req, ev);
4091 * We require TCP acks for this PDU to the client!
4092 * We want 5 retransmissions and timeout when the
4093 * retransmission timeout (rto) passed 6 times.
4095 * required_acked_bytes gets a dummy value of
4096 * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4097 * it'll get the real value when it's moved to
4100 * state->queue_entry.ack.req gets completed with
4101 * 1. tevent_req_done(), when all bytes are acked.
4102 * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4103 * the timeout expired before all bytes were acked.
4104 * 2b. tevent_req_nterror(transport_error), when the
4105 * connection got a disconnect from the kernel.
4107 state->queue_entry.ack.timeout =
4108 timeval_current_ofs_usec(xconn->ack.rto_usecs * 6);
4109 state->queue_entry.ack.required_acked_bytes = UINT64_MAX;
4110 state->queue_entry.ack.req = req;
4111 state->queue_entry.mem_ctx = state;
4112 state->queue_entry.vector = state->vector;
4113 state->queue_entry.count = ARRAY_SIZE(state->vector);
4114 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
4115 xconn->smb2.send_queue_len++;
4117 status = smbd_smb2_flush_send_queue(xconn);
4118 if (tevent_req_nterror(req, status)) {
4119 return tevent_req_post(req, ev);
4125 static NTSTATUS smbd_smb2_break_recv(struct tevent_req *req)
4127 return tevent_req_simple_recv_ntstatus(req);
4130 struct smbXsrv_pending_break {
4131 struct smbXsrv_pending_break *prev, *next;
4132 struct smbXsrv_client *client;
4133 bool disable_oplock_break_retries;
4134 uint64_t session_id;
4135 uint64_t last_channel_id;
4138 uint8_t oplock[0x18];
4139 uint8_t lease[0x2c];
4144 static void smbXsrv_pending_break_done(struct tevent_req *subreq);
4146 static struct smbXsrv_pending_break *smbXsrv_pending_break_create(
4147 struct smbXsrv_client *client,
4148 uint64_t session_id)
4150 struct smbXsrv_pending_break *pb = NULL;
4152 pb = talloc_zero(client, struct smbXsrv_pending_break);
4156 pb->client = client;
4157 pb->session_id = session_id;
4158 pb->disable_oplock_break_retries = lp_smb2_disable_oplock_break_retry();
4163 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb);
4165 static NTSTATUS smbXsrv_pending_break_schedule(struct smbXsrv_pending_break *pb)
4167 struct smbXsrv_client *client = pb->client;
4170 DLIST_ADD_END(client->pending_breaks, pb);
4171 status = smbXsrv_client_pending_breaks_updated(client);
4172 if (!NT_STATUS_IS_OK(status)) {
4176 status = smbXsrv_pending_break_submit(pb);
4177 if (!NT_STATUS_IS_OK(status)) {
4181 return NT_STATUS_OK;
4184 static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb)
4186 struct smbXsrv_client *client = pb->client;
4187 struct smbXsrv_session *session = NULL;
4188 struct smbXsrv_connection *xconn = NULL;
4189 struct smbXsrv_connection *oplock_xconn = NULL;
4190 struct tevent_req *subreq = NULL;
4193 if (pb->session_id != 0) {
4194 status = get_valid_smbXsrv_session(client,
4197 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
4198 return NT_STATUS_ABANDONED;
4200 if (!NT_STATUS_IS_OK(status)) {
4204 if (pb->last_channel_id != 0) {
4206 * This is what current Windows servers
4207 * do, they don't retry on all available
4208 * channels. They only use the last channel.
4210 * But it doesn't match the specification in
4211 * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4214 * Per default disable_oplock_break_retries is false
4215 * and we behave like the specification.
4217 if (pb->disable_oplock_break_retries) {
4218 return NT_STATUS_ABANDONED;
4223 for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
4224 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4228 if (xconn->channel_id == 0) {
4230 * non-multichannel case
4235 if (session != NULL) {
4236 struct smbXsrv_channel_global0 *c = NULL;
4239 * Having a session means we're handling
4240 * an oplock break and we only need to
4241 * use channels available on the
4244 status = smbXsrv_session_find_channel(session, xconn, &c);
4245 if (!NT_STATUS_IS_OK(status)) {
4250 * This is what current Windows servers
4251 * do, they don't retry on all available
4252 * channels. They only use the last channel.
4254 * But it doesn't match the specification
4255 * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4258 * Per default disable_oplock_break_retries is false
4259 * and we behave like the specification.
4261 if (pb->disable_oplock_break_retries) {
4262 oplock_xconn = xconn;
4267 if (xconn->channel_id > pb->last_channel_id) {
4275 if (xconn == NULL) {
4276 xconn = oplock_xconn;
4279 if (xconn == NULL) {
4281 * If there's no remaining connection available
4282 * tell the caller to stop...
4284 return NT_STATUS_ABANDONED;
4287 pb->last_channel_id = xconn->channel_id;
4289 subreq = smbd_smb2_break_send(pb,
4295 if (subreq == NULL) {
4296 return NT_STATUS_NO_MEMORY;
4298 tevent_req_set_callback(subreq,
4299 smbXsrv_pending_break_done,
4302 return NT_STATUS_OK;
4305 static void smbXsrv_pending_break_done(struct tevent_req *subreq)
4307 struct smbXsrv_pending_break *pb =
4308 tevent_req_callback_data(subreq,
4309 struct smbXsrv_pending_break);
4310 struct smbXsrv_client *client = pb->client;
4313 status = smbd_smb2_break_recv(subreq);
4314 TALLOC_FREE(subreq);
4315 if (!NT_STATUS_IS_OK(status)) {
4316 status = smbXsrv_pending_break_submit(pb);
4317 if (NT_STATUS_EQUAL(status, NT_STATUS_ABANDONED)) {
4319 * If there's no remaing connection
4320 * there's no need to send a break again.
4324 if (!NT_STATUS_IS_OK(status)) {
4325 smbd_server_disconnect_client(client, nt_errstr(status));
4332 DLIST_REMOVE(client->pending_breaks, pb);
4335 status = smbXsrv_client_pending_breaks_updated(client);
4336 if (!NT_STATUS_IS_OK(status)) {
4337 smbd_server_disconnect_client(client, nt_errstr(status));
4342 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_client *client,
4343 struct smbXsrv_open *op,
4344 uint8_t oplock_level)
4346 struct smbXsrv_pending_break *pb = NULL;
4347 uint8_t *body = NULL;
4349 pb = smbXsrv_pending_break_create(client,
4352 return NT_STATUS_NO_MEMORY;
4354 pb->body_len = sizeof(pb->body.oplock);
4355 body = pb->body.oplock;
4357 SSVAL(body, 0x00, pb->body_len);
4358 SCVAL(body, 0x02, oplock_level);
4359 SCVAL(body, 0x03, 0); /* reserved */
4360 SIVAL(body, 0x04, 0); /* reserved */
4361 SBVAL(body, 0x08, op->global->open_persistent_id);
4362 SBVAL(body, 0x10, op->global->open_volatile_id);
4364 return smbXsrv_pending_break_schedule(pb);
4367 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_client *client,
4369 uint32_t lease_flags,
4370 struct smb2_lease_key *lease_key,
4371 uint32_t current_lease_state,
4372 uint32_t new_lease_state)
4374 struct smbXsrv_pending_break *pb = NULL;
4375 uint8_t *body = NULL;
4377 pb = smbXsrv_pending_break_create(client,
4378 0); /* no session_id */
4380 return NT_STATUS_NO_MEMORY;
4382 pb->body_len = sizeof(pb->body.lease);
4383 body = pb->body.lease;
4385 SSVAL(body, 0x00, pb->body_len);
4386 SSVAL(body, 0x02, new_epoch);
4387 SIVAL(body, 0x04, lease_flags);
4388 SBVAL(body, 0x08, lease_key->data[0]);
4389 SBVAL(body, 0x10, lease_key->data[1]);
4390 SIVAL(body, 0x18, current_lease_state);
4391 SIVAL(body, 0x1c, new_lease_state);
4392 SIVAL(body, 0x20, 0); /* BreakReason, MUST be 0 */
4393 SIVAL(body, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4394 SIVAL(body, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4396 return smbXsrv_pending_break_schedule(pb);
4399 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
4403 uint64_t file_id_persistent;
4404 uint64_t file_id_volatile;
4405 struct smbXsrv_open *op = NULL;
4406 struct files_struct *fsp = NULL;
4407 const uint8_t *body = NULL;
4410 * This is only called with a pktbuf
4411 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4415 if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
4416 /* Transform header. Cannot recvfile. */
4419 if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
4420 /* Not SMB2. Normal error path will cope. */
4423 if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
4424 /* Not SMB2. Normal error path will cope. */
4427 if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
4428 /* Needs to be a WRITE. */
4431 if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
4432 /* Chained. Cannot recvfile. */
4435 flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
4436 if (flags & SMB2_HDR_FLAG_CHAINED) {
4437 /* Chained. Cannot recvfile. */
4440 if (flags & SMB2_HDR_FLAG_SIGNED) {
4441 /* Signed. Cannot recvfile. */
4445 body = &state->pktbuf[SMB2_HDR_BODY];
4447 file_id_persistent = BVAL(body, 0x10);
4448 file_id_volatile = BVAL(body, 0x18);
4450 status = smb2srv_open_lookup(state->req->xconn,
4455 if (!NT_STATUS_IS_OK(status)) {
4463 if (fsp->conn == NULL) {
4467 if (IS_IPC(fsp->conn)) {
4470 if (IS_PRINT(fsp->conn)) {
4473 if (fsp_is_alternate_stream(fsp)) {
4477 DEBUG(10,("Doing recvfile write len = %u\n",
4478 (unsigned int)(state->pktfull - state->pktlen)));
4483 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
4485 struct smbd_server_connection *sconn = xconn->client->sconn;
4486 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4487 size_t max_send_queue_len;
4488 size_t cur_send_queue_len;
4490 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4492 * we're not supposed to do any io
4494 return NT_STATUS_OK;
4497 if (state->req != NULL) {
4499 * if there is already a tstream_readv_pdu
4500 * pending, we are done.
4502 return NT_STATUS_OK;
4505 max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
4506 cur_send_queue_len = xconn->smb2.send_queue_len;
4508 if (cur_send_queue_len > max_send_queue_len) {
4510 * if we have a lot of requests to send,
4511 * we wait until they are on the wire until we
4512 * ask for the next request.
4514 return NT_STATUS_OK;
4517 /* ask for the next request */
4518 ZERO_STRUCTP(state);
4519 state->req = smbd_smb2_request_allocate(xconn);
4520 if (state->req == NULL) {
4521 return NT_STATUS_NO_MEMORY;
4523 state->req->sconn = sconn;
4524 state->req->xconn = xconn;
4525 state->min_recv_size = lp_min_receive_file_size();
4527 TEVENT_FD_READABLE(xconn->transport.fde);
4529 return NT_STATUS_OK;
4532 NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
4533 uint64_t expected_seq_low,
4534 const uint8_t *inpdu, size_t size)
4536 struct smbd_server_connection *sconn = xconn->client->sconn;
4538 struct smbd_smb2_request *req = NULL;
4540 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4541 (unsigned int)size));
4543 status = smbd_initialize_smb2(xconn, expected_seq_low);
4544 if (!NT_STATUS_IS_OK(status)) {
4545 smbd_server_connection_terminate(xconn, nt_errstr(status));
4550 * If a new connection joins the process, when we're
4551 * already in a "pending break cycle", we need to
4552 * turn on the ack checker on the new connection.
4554 status = smbXsrv_client_pending_breaks_updated(xconn->client);
4555 if (!NT_STATUS_IS_OK(status)) {
4557 * If there's a problem, we disconnect the whole
4558 * client with all connections here!
4560 * Instead of just the new connection.
4562 smbd_server_disconnect_client(xconn->client, nt_errstr(status));
4566 status = smbd_smb2_request_create(xconn, inpdu, size, &req);
4567 if (!NT_STATUS_IS_OK(status)) {
4568 smbd_server_connection_terminate(xconn, nt_errstr(status));
4572 status = smbd_smb2_request_validate(req);
4573 if (!NT_STATUS_IS_OK(status)) {
4574 smbd_server_connection_terminate(xconn, nt_errstr(status));
4578 status = smbd_smb2_request_setup_out(req);
4579 if (!NT_STATUS_IS_OK(status)) {
4580 smbd_server_connection_terminate(xconn, nt_errstr(status));
4586 * this was already counted at the SMB1 layer =>
4587 * smbd_smb2_request_dispatch() should not count it twice.
4589 if (profile_p->values.request_stats.count > 0) {
4590 profile_p->values.request_stats.count--;
4593 status = smbd_smb2_request_dispatch(req);
4594 if (!NT_STATUS_IS_OK(status)) {
4595 smbd_server_connection_terminate(xconn, nt_errstr(status));
4599 status = smbd_smb2_request_next_incoming(xconn);
4600 if (!NT_STATUS_IS_OK(status)) {
4601 smbd_server_connection_terminate(xconn, nt_errstr(status));
4605 sconn->num_requests++;
4606 return NT_STATUS_OK;
4609 static int socket_error_from_errno(int ret,
4623 if (sys_errno == 0) {
4627 if (sys_errno == EINTR) {
4632 if (sys_errno == EINPROGRESS) {
4637 if (sys_errno == EAGAIN) {
4642 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4643 if (sys_errno == ENOMEM) {
4649 #if EWOULDBLOCK != EAGAIN
4650 if (sys_errno == EWOULDBLOCK) {
4660 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
4667 if (xconn->smb2.send_queue == NULL) {
4668 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4669 return NT_STATUS_OK;
4672 while (xconn->smb2.send_queue != NULL) {
4673 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
4677 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4679 * we're not supposed to do any io
4680 * just flush all pending stuff.
4682 xconn->smb2.send_queue_len--;
4683 DLIST_REMOVE(xconn->smb2.send_queue, e);
4685 talloc_free(e->mem_ctx);
4689 if (e->sendfile_header != NULL) {
4694 status = NT_STATUS_INTERNAL_ERROR;
4696 for (i=0; i < e->count; i++) {
4697 size += e->vector[i].iov_len;
4700 if (size <= e->sendfile_header->length) {
4701 buf = e->sendfile_header->data;
4703 buf = talloc_array(e->mem_ctx, uint8_t, size);
4705 return NT_STATUS_NO_MEMORY;
4710 for (i=0; i < e->count; i++) {
4712 e->vector[i].iov_base,
4713 e->vector[i].iov_len);
4714 size += e->vector[i].iov_len;
4717 e->sendfile_header->data = buf;
4718 e->sendfile_header->length = size;
4719 e->sendfile_status = &status;
4722 xconn->smb2.send_queue_len--;
4723 DLIST_REMOVE(xconn->smb2.send_queue, e);
4725 size += e->sendfile_body_size;
4728 * This triggers the sendfile path via
4731 talloc_free(e->mem_ctx);
4733 if (!NT_STATUS_IS_OK(status)) {
4734 smbXsrv_connection_disconnect_transport(xconn,
4738 xconn->ack.unacked_bytes += size;
4742 msg = (struct msghdr) {
4743 .msg_iov = e->vector,
4744 .msg_iovlen = e->count,
4747 ret = sendmsg(xconn->transport.sock, &msg, 0);
4749 /* propagate end of file */
4750 return NT_STATUS_INTERNAL_ERROR;
4752 err = socket_error_from_errno(ret, errno, &retry);
4755 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4756 return NT_STATUS_OK;
4759 status = map_nt_error_from_unix_common(err);
4760 smbXsrv_connection_disconnect_transport(xconn,
4765 xconn->ack.unacked_bytes += ret;
4767 ok = iov_advance(&e->vector, &e->count, ret);
4769 return NT_STATUS_INTERNAL_ERROR;
4773 /* we have more to write */
4774 TEVENT_FD_WRITEABLE(xconn->transport.fde);
4775 return NT_STATUS_OK;
4778 xconn->smb2.send_queue_len--;
4779 DLIST_REMOVE(xconn->smb2.send_queue, e);
4781 if (e->ack.req == NULL) {
4782 talloc_free(e->mem_ctx);
4786 e->ack.required_acked_bytes = xconn->ack.unacked_bytes;
4787 DLIST_ADD_END(xconn->ack.queue, e);
4791 * Restart reads if we were blocked on
4792 * draining the send queue.
4795 status = smbd_smb2_request_next_incoming(xconn);
4796 if (!NT_STATUS_IS_OK(status)) {
4800 return NT_STATUS_OK;
4803 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
4806 struct smbd_server_connection *sconn = xconn->client->sconn;
4807 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4808 struct smbd_smb2_request *req = NULL;
4809 size_t min_recvfile_size = UINT32_MAX;
4817 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4819 * we're not supposed to do any io
4821 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4822 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4823 return NT_STATUS_OK;
4826 if (fde_flags & TEVENT_FD_WRITE) {
4827 status = smbd_smb2_flush_send_queue(xconn);
4828 if (!NT_STATUS_IS_OK(status)) {
4833 if (!(fde_flags & TEVENT_FD_READ)) {
4834 return NT_STATUS_OK;
4837 if (state->req == NULL) {
4838 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4839 return NT_STATUS_OK;
4843 if (!state->hdr.done) {
4844 state->hdr.done = true;
4846 state->vector.iov_base = (void *)state->hdr.nbt;
4847 state->vector.iov_len = NBT_HDR_SIZE;
4850 msg = (struct msghdr) {
4851 .msg_iov = &state->vector,
4855 ret = recvmsg(xconn->transport.sock, &msg, 0);
4857 /* propagate end of file */
4858 status = NT_STATUS_END_OF_FILE;
4859 smbXsrv_connection_disconnect_transport(xconn,
4863 err = socket_error_from_errno(ret, errno, &retry);
4866 TEVENT_FD_READABLE(xconn->transport.fde);
4867 return NT_STATUS_OK;
4870 status = map_nt_error_from_unix_common(err);
4871 smbXsrv_connection_disconnect_transport(xconn,
4876 if (ret < state->vector.iov_len) {
4878 base = (uint8_t *)state->vector.iov_base;
4880 state->vector.iov_base = (void *)base;
4881 state->vector.iov_len -= ret;
4882 /* we have more to read */
4883 TEVENT_FD_READABLE(xconn->transport.fde);
4884 return NT_STATUS_OK;
4887 if (state->pktlen > 0) {
4888 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
4890 * Not a possible receivefile write.
4891 * Read the rest of the data.
4893 state->doing_receivefile = false;
4895 state->pktbuf = talloc_realloc(state->req,
4899 if (state->pktbuf == NULL) {
4900 return NT_STATUS_NO_MEMORY;
4903 state->vector.iov_base = (void *)(state->pktbuf +
4905 state->vector.iov_len = (state->pktfull -
4908 state->pktlen = state->pktfull;
4913 * Either this is a receivefile write so we've
4914 * done a short read, or if not we have all the data.
4920 * Now we analyze the NBT header
4922 if (state->hdr.nbt[0] != 0x00) {
4923 state->min_recv_size = 0;
4925 state->pktfull = smb2_len(state->hdr.nbt);
4926 if (state->pktfull == 0) {
4930 if (state->min_recv_size != 0) {
4931 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4932 min_recvfile_size += state->min_recv_size;
4935 if (state->pktfull > min_recvfile_size) {
4937 * Might be a receivefile write. Read the SMB2 HEADER +
4938 * SMB2_WRITE header first. Set 'doing_receivefile'
4939 * as we're *attempting* receivefile write. If this
4940 * turns out not to be a SMB2_WRITE request or otherwise
4941 * not suitable then we'll just read the rest of the data
4942 * the next time this function is called.
4944 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4945 state->doing_receivefile = true;
4947 state->pktlen = state->pktfull;
4950 state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
4951 if (state->pktbuf == NULL) {
4952 return NT_STATUS_NO_MEMORY;
4955 state->vector.iov_base = (void *)state->pktbuf;
4956 state->vector.iov_len = state->pktlen;
4962 if (state->hdr.nbt[0] != 0x00) {
4963 DEBUG(1,("ignore NBT[0x%02X] msg\n",
4964 state->hdr.nbt[0]));
4967 ZERO_STRUCTP(state);
4969 state->min_recv_size = lp_min_receive_file_size();
4977 req->request_time = timeval_current();
4978 now = timeval_to_nttime(&req->request_time);
4980 status = smbd_smb2_inbuf_parse_compound(xconn,
4986 &req->in.vector_count);
4987 if (!NT_STATUS_IS_OK(status)) {
4991 if (state->doing_receivefile) {
4992 req->smb1req = talloc_zero(req, struct smb_request);
4993 if (req->smb1req == NULL) {
4994 return NT_STATUS_NO_MEMORY;
4996 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
4999 ZERO_STRUCTP(state);
5001 req->current_idx = 1;
5003 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
5004 req->current_idx, req->in.vector_count));
5006 status = smbd_smb2_request_validate(req);
5007 if (!NT_STATUS_IS_OK(status)) {
5011 status = smbd_smb2_request_setup_out(req);
5012 if (!NT_STATUS_IS_OK(status)) {
5016 status = smbd_smb2_request_dispatch(req);
5017 if (!NT_STATUS_IS_OK(status)) {
5021 sconn->num_requests++;
5023 /* The timeout_processing function isn't run nearly
5024 often enough to implement 'max log size' without
5025 overrunning the size of the file by many megabytes.
5026 This is especially true if we are running at debug
5027 level 10. Checking every 50 SMB2s is a nice
5028 tradeoff of performance vs log file size overrun. */
5030 if ((sconn->num_requests % 50) == 0 &&
5031 need_to_check_log_size()) {
5032 change_to_root_user();
5036 status = smbd_smb2_request_next_incoming(xconn);
5037 if (!NT_STATUS_IS_OK(status)) {
5041 return NT_STATUS_OK;
5044 static void smbd_smb2_connection_handler(struct tevent_context *ev,
5045 struct tevent_fd *fde,
5049 struct smbXsrv_connection *xconn =
5050 talloc_get_type_abort(private_data,
5051 struct smbXsrv_connection);
5054 status = smbd_smb2_io_handler(xconn, flags);
5055 if (!NT_STATUS_IS_OK(status)) {
5056 smbd_server_connection_terminate(xconn, nt_errstr(status));