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 "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30 #include "../librpc/gen_ndr/krb5pac.h"
31 #include "lib/util/iov_buf.h"
33 #include "lib/crypto/sha512.h"
35 static void smbd_smb2_connection_handler(struct tevent_context *ev,
36 struct tevent_fd *fde,
39 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
41 static const struct smbd_smb2_dispatch_table {
48 bool allow_invalid_fileid;
50 } smbd_smb2_table[] = {
51 #define _OP(o) .opcode = o, .name = #o
56 _OP(SMB2_OP_SESSSETUP),
66 * This call needs to be run as root.
68 * smbd_smb2_request_process_tcon()
69 * calls make_connection_snum(), which will call
70 * change_to_user(), when needed.
105 .need_session = true,
110 .need_session = true,
113 .allow_invalid_fileid = true,
119 _OP(SMB2_OP_KEEPALIVE),
122 _OP(SMB2_OP_QUERY_DIRECTORY),
123 .need_session = true,
128 .need_session = true,
132 _OP(SMB2_OP_GETINFO),
133 .need_session = true,
137 _OP(SMB2_OP_SETINFO),
138 .need_session = true,
144 .need_session = true,
149 * as LEASE breaks does not
155 const char *smb2_opcode_name(uint16_t opcode)
157 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
158 return "Bad SMB2 opcode";
160 return smbd_smb2_table[opcode].name;
163 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
165 const struct smbd_smb2_dispatch_table *ret = NULL;
167 if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
171 ret = &smbd_smb2_table[opcode];
173 SMB_ASSERT(ret->opcode == opcode);
178 static void print_req_vectors(const struct smbd_smb2_request *req)
182 for (i = 0; i < req->in.vector_count; i++) {
183 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
185 (unsigned int)req->in.vector[i].iov_len);
187 for (i = 0; i < req->out.vector_count; i++) {
188 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
190 (unsigned int)req->out.vector[i].iov_len);
194 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
196 if (size < (4 + SMB2_HDR_BODY)) {
200 if (IVAL(inbuf, 4) != SMB2_MAGIC) {
207 bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
209 return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
212 static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
213 uint64_t expected_seq_low)
215 TALLOC_FREE(xconn->transport.fde);
217 xconn->smb2.credits.seq_low = expected_seq_low;
218 xconn->smb2.credits.seq_range = 1;
219 xconn->smb2.credits.granted = 1;
220 xconn->smb2.credits.max = lp_smb2_max_credits();
221 xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
222 xconn->smb2.credits.max);
223 if (xconn->smb2.credits.bitmap == NULL) {
224 return NT_STATUS_NO_MEMORY;
227 xconn->transport.fde = tevent_add_fd(xconn->ev_ctx,
229 xconn->transport.sock,
231 smbd_smb2_connection_handler,
233 if (xconn->transport.fde == NULL) {
234 return NT_STATUS_NO_MEMORY;
237 /* Ensure child is set to non-blocking mode */
238 set_blocking(xconn->transport.sock, false);
242 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
243 #define _smb2_setlen(_buf,len) do { \
244 uint8_t *buf = (uint8_t *)_buf; \
246 buf[1] = ((len)&0xFF0000)>>16; \
247 buf[2] = ((len)&0xFF00)>>8; \
248 buf[3] = (len)&0xFF; \
251 static bool smb2_setup_nbt_length(struct iovec *vector, int count)
259 len = iov_buflen(vector+1, count-1);
261 if ((len == -1) || (len > 0xFFFFFF)) {
265 _smb2_setlen(vector[0].iov_base, len);
269 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
271 if (req->first_key.length > 0) {
272 data_blob_clear_free(&req->first_key);
274 if (req->last_key.length > 0) {
275 data_blob_clear_free(&req->last_key);
280 void smb2_request_set_async_internal(struct smbd_smb2_request *req,
283 req->async_internal = async_internal;
286 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
288 TALLOC_CTX *mem_pool;
289 struct smbd_smb2_request *req;
292 /* Enable this to find subtle valgrind errors. */
293 mem_pool = talloc_init("smbd_smb2_request_allocate");
295 mem_pool = talloc_tos();
297 if (mem_pool == NULL) {
301 req = talloc_zero(mem_pool, struct smbd_smb2_request);
303 talloc_free(mem_pool);
306 talloc_reparent(mem_pool, mem_ctx, req);
308 TALLOC_FREE(mem_pool);
311 req->last_session_id = UINT64_MAX;
312 req->last_tid = UINT32_MAX;
314 talloc_set_destructor(req, smbd_smb2_request_destructor);
319 static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
323 struct smbd_smb2_request *req,
327 TALLOC_CTX *mem_ctx = req;
331 uint8_t *first_hdr = buf;
332 size_t verified_buflen = 0;
337 * Note: index '0' is reserved for the transport protocol
339 iov = req->in._vector;
341 while (taken < buflen) {
342 size_t len = buflen - taken;
343 uint8_t *hdr = first_hdr + taken;
346 size_t next_command_ofs;
348 uint8_t *body = NULL;
351 struct iovec *iov_alloc = NULL;
353 if (iov != req->in._vector) {
357 if (verified_buflen > taken) {
358 len = verified_buflen - taken;
365 DEBUG(10, ("%d bytes left, expected at least %d\n",
369 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
370 struct smbXsrv_session *s = NULL;
372 struct iovec tf_iov[2];
376 if (xconn->protocol < PROTOCOL_SMB2_24) {
377 DEBUG(10, ("Got SMB2_TRANSFORM header, "
378 "but dialect[0x%04X] is used\n",
379 xconn->smb2.server.dialect));
383 if (xconn->smb2.server.cipher == 0) {
384 DEBUG(10, ("Got SMB2_TRANSFORM header, "
385 "but not negotiated "
386 "client[0x%08X] server[0x%08X]\n",
387 xconn->smb2.client.capabilities,
388 xconn->smb2.server.capabilities));
392 if (len < SMB2_TF_HDR_SIZE) {
393 DEBUG(1, ("%d bytes left, expected at least %d\n",
394 (int)len, SMB2_TF_HDR_SIZE));
398 tf_len = SMB2_TF_HDR_SIZE;
401 hdr = first_hdr + taken;
402 enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
403 uid = BVAL(tf, SMB2_TF_SESSION_ID);
405 if (len < SMB2_TF_HDR_SIZE + enc_len) {
406 DEBUG(1, ("%d bytes left, expected at least %d\n",
408 (int)(SMB2_TF_HDR_SIZE + enc_len)));
412 status = smb2srv_session_lookup_conn(xconn, uid, now,
415 DEBUG(1, ("invalid session[%llu] in "
416 "SMB2_TRANSFORM header\n",
417 (unsigned long long)uid));
418 TALLOC_FREE(iov_alloc);
419 return NT_STATUS_USER_SESSION_DELETED;
422 tf_iov[0].iov_base = (void *)tf;
423 tf_iov[0].iov_len = tf_len;
424 tf_iov[1].iov_base = (void *)hdr;
425 tf_iov[1].iov_len = enc_len;
427 status = smb2_signing_decrypt_pdu(s->global->decryption_key,
428 xconn->smb2.server.cipher,
430 if (!NT_STATUS_IS_OK(status)) {
431 TALLOC_FREE(iov_alloc);
435 verified_buflen = taken + enc_len;
440 * We need the header plus the body length field
443 if (len < SMB2_HDR_BODY + 2) {
444 DEBUG(10, ("%d bytes left, expected at least %d\n",
445 (int)len, SMB2_HDR_BODY));
448 if (IVAL(hdr, 0) != SMB2_MAGIC) {
449 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
453 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
454 DEBUG(10, ("Got HDR len %d, expected %d\n",
455 SVAL(hdr, 4), SMB2_HDR_BODY));
460 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
461 body_size = SVAL(hdr, SMB2_HDR_BODY);
463 if (next_command_ofs != 0) {
464 if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
467 if (next_command_ofs > full_size) {
470 full_size = next_command_ofs;
477 if (body_size > (full_size - SMB2_HDR_BODY)) {
479 * let the caller handle the error
481 body_size = full_size - SMB2_HDR_BODY;
483 body = hdr + SMB2_HDR_BODY;
484 dyn = body + body_size;
485 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
487 if (num_iov >= ARRAY_SIZE(req->in._vector)) {
488 struct iovec *iov_tmp = NULL;
490 iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
493 SMBD_SMB2_NUM_IOV_PER_REQ);
494 if (iov_tmp == NULL) {
495 TALLOC_FREE(iov_alloc);
496 return NT_STATUS_NO_MEMORY;
499 if (iov_alloc == NULL) {
502 sizeof(req->in._vector));
508 num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
510 cur[SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
511 cur[SMBD_SMB2_TF_IOV_OFS].iov_len = tf_len;
512 cur[SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
513 cur[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
514 cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
515 cur[SMBD_SMB2_BODY_IOV_OFS].iov_len = body_size;
516 cur[SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
517 cur[SMBD_SMB2_DYN_IOV_OFS].iov_len = dyn_size;
527 if (iov != req->in._vector) {
530 return NT_STATUS_INVALID_PARAMETER;
533 static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
534 const uint8_t *_inpdu, size_t size,
535 struct smbd_smb2_request **_req)
537 struct smbd_server_connection *sconn = xconn->client->sconn;
538 struct smbd_smb2_request *req;
539 uint32_t protocol_version;
540 uint8_t *inpdu = NULL;
541 const uint8_t *inhdr = NULL;
543 uint32_t next_command_ofs;
547 if (size < (SMB2_HDR_BODY + 2)) {
548 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
549 return NT_STATUS_INVALID_PARAMETER;
554 protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
555 if (protocol_version != SMB2_MAGIC) {
556 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
558 return NT_STATUS_INVALID_PARAMETER;
561 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
562 if (cmd != SMB2_OP_NEGPROT) {
563 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
565 return NT_STATUS_INVALID_PARAMETER;
568 next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
569 if (next_command_ofs != 0) {
570 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
572 return NT_STATUS_INVALID_PARAMETER;
575 req = smbd_smb2_request_allocate(xconn);
577 return NT_STATUS_NO_MEMORY;
582 inpdu = talloc_memdup(req, _inpdu, size);
584 return NT_STATUS_NO_MEMORY;
587 req->request_time = timeval_current();
588 now = timeval_to_nttime(&req->request_time);
590 status = smbd_smb2_inbuf_parse_compound(xconn,
594 req, &req->in.vector,
595 &req->in.vector_count);
596 if (!NT_STATUS_IS_OK(status)) {
601 req->current_idx = 1;
607 static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
608 uint64_t message_id, uint64_t seq_id)
610 struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
614 seq_tmp = xconn->smb2.credits.seq_low;
615 if (seq_id < seq_tmp) {
616 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
617 "%llu (sequence id %llu) "
618 "(granted = %u, low = %llu, range = %u)\n",
619 (unsigned long long)message_id,
620 (unsigned long long)seq_id,
621 (unsigned int)xconn->smb2.credits.granted,
622 (unsigned long long)xconn->smb2.credits.seq_low,
623 (unsigned int)xconn->smb2.credits.seq_range));
627 seq_tmp += xconn->smb2.credits.seq_range;
628 if (seq_id >= seq_tmp) {
629 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
630 "%llu (sequence id %llu) "
631 "(granted = %u, low = %llu, range = %u)\n",
632 (unsigned long long)message_id,
633 (unsigned long long)seq_id,
634 (unsigned int)xconn->smb2.credits.granted,
635 (unsigned long long)xconn->smb2.credits.seq_low,
636 (unsigned int)xconn->smb2.credits.seq_range));
640 offset = seq_id % xconn->smb2.credits.max;
642 if (bitmap_query(credits_bm, offset)) {
643 DEBUG(0,("smb2_validate_sequence_number: duplicate message_id "
644 "%llu (sequence id %llu) "
645 "(granted = %u, low = %llu, range = %u) "
647 (unsigned long long)message_id,
648 (unsigned long long)seq_id,
649 (unsigned int)xconn->smb2.credits.granted,
650 (unsigned long long)xconn->smb2.credits.seq_low,
651 (unsigned int)xconn->smb2.credits.seq_range,
656 /* Mark the message_ids as seen in the bitmap. */
657 bitmap_set(credits_bm, offset);
659 if (seq_id != xconn->smb2.credits.seq_low) {
664 * Move the window forward by all the message_id's
667 while (bitmap_query(credits_bm, offset)) {
668 DEBUG(10,("smb2_validate_sequence_number: clearing "
669 "id %llu (position %u) from bitmap\n",
670 (unsigned long long)(xconn->smb2.credits.seq_low),
672 bitmap_clear(credits_bm, offset);
674 xconn->smb2.credits.seq_low += 1;
675 xconn->smb2.credits.seq_range -= 1;
676 offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
682 static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
683 const uint8_t *inhdr)
685 uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
686 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
687 uint16_t credit_charge = 1;
690 if (opcode == SMB2_OP_CANCEL) {
691 /* SMB2_CANCEL requests by definition resend messageids. */
695 if (xconn->smb2.credits.multicredit) {
696 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
697 credit_charge = MAX(credit_charge, 1);
700 DEBUG(11, ("smb2_validate_message_id: mid %llu (charge %llu), "
701 "credits_granted %llu, "
702 "seqnum low/range: %llu/%llu\n",
703 (unsigned long long) message_id,
704 (unsigned long long) credit_charge,
705 (unsigned long long) xconn->smb2.credits.granted,
706 (unsigned long long) xconn->smb2.credits.seq_low,
707 (unsigned long long) xconn->smb2.credits.seq_range));
709 if (xconn->smb2.credits.granted < credit_charge) {
710 DEBUG(0, ("smb2_validate_message_id: client used more "
711 "credits than granted, mid %llu, charge %llu, "
712 "credits_granted %llu, "
713 "seqnum low/range: %llu/%llu\n",
714 (unsigned long long) message_id,
715 (unsigned long long) credit_charge,
716 (unsigned long long) xconn->smb2.credits.granted,
717 (unsigned long long) xconn->smb2.credits.seq_low,
718 (unsigned long long) xconn->smb2.credits.seq_range));
723 * now check the message ids
725 * for multi-credit requests we need to check all current mid plus
726 * the implicit mids caused by the credit charge
727 * e.g. current mid = 15, charge 5 => mark 15-19 as used
730 for (i = 0; i <= (credit_charge-1); i++) {
731 uint64_t id = message_id + i;
734 DEBUG(11, ("Iterating mid %llu charge %u (sequence %llu)\n",
735 (unsigned long long)message_id,
737 (unsigned long long)id));
739 ok = smb2_validate_sequence_number(xconn, message_id, id);
745 /* substract used credits */
746 xconn->smb2.credits.granted -= credit_charge;
751 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
756 count = req->in.vector_count;
758 if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
759 /* It's not a SMB2 request */
760 return NT_STATUS_INVALID_PARAMETER;
763 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
764 struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
765 struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
766 const uint8_t *inhdr = NULL;
768 if (hdr->iov_len != SMB2_HDR_BODY) {
769 return NT_STATUS_INVALID_PARAMETER;
772 if (body->iov_len < 2) {
773 return NT_STATUS_INVALID_PARAMETER;
776 inhdr = (const uint8_t *)hdr->iov_base;
778 /* Check the SMB2 header */
779 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
780 return NT_STATUS_INVALID_PARAMETER;
783 if (!smb2_validate_message_id(req->xconn, inhdr)) {
784 return NT_STATUS_INVALID_PARAMETER;
791 static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
792 const struct iovec *in_vector,
793 struct iovec *out_vector)
795 const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
796 uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
797 uint16_t credit_charge = 1;
798 uint16_t credits_requested;
802 uint16_t credits_granted = 0;
803 uint64_t credits_possible;
804 uint16_t current_max_credits;
807 * first we grant only 1/16th of the max range.
809 * Windows also starts with the 1/16th and then grants
810 * more later. I was only able to trigger higher
811 * values, when using a very high credit charge.
813 * TODO: scale up depending on load, free memory
815 * Maybe also on the relationship between number
816 * of requests and the used sequence number.
817 * Which means we would grant more credits
818 * for client which use multi credit requests.
820 current_max_credits = xconn->smb2.credits.max / 16;
821 current_max_credits = MAX(current_max_credits, 1);
823 if (xconn->smb2.credits.multicredit) {
824 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
825 credit_charge = MAX(credit_charge, 1);
828 cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
829 credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
830 credits_requested = MAX(credits_requested, 1);
831 out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
832 out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
834 SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
836 if (xconn->smb2.credits.max < credit_charge) {
837 smbd_server_connection_terminate(xconn,
838 "client error: credit charge > max credits\n");
842 if (out_flags & SMB2_HDR_FLAG_ASYNC) {
844 * In case we already send an async interim
845 * response, we should not grant
846 * credits on the final response.
850 uint16_t additional_possible =
851 xconn->smb2.credits.max - credit_charge;
852 uint16_t additional_max = 0;
853 uint16_t additional_credits = credits_requested - 1;
856 case SMB2_OP_NEGPROT:
858 case SMB2_OP_SESSSETUP:
860 * Windows 2012 RC1 starts to grant
862 * with a successful session setup
864 if (NT_STATUS_IS_OK(out_status)) {
870 * We match windows and only grant additional credits
877 additional_max = MIN(additional_max, additional_possible);
878 additional_credits = MIN(additional_credits, additional_max);
880 credits_granted = credit_charge + additional_credits;
884 * sequence numbers should not wrap
886 * 1. calculate the possible credits until
887 * the sequence numbers start to wrap on 64-bit.
889 * 2. UINT64_MAX is used for Break Notifications.
891 * 2. truncate the possible credits to the maximum
892 * credits we want to grant to the client in total.
894 * 3. remove the range we'll already granted to the client
895 * this makes sure the client consumes the lowest sequence
896 * number, before we can grant additional credits.
898 credits_possible = UINT64_MAX - xconn->smb2.credits.seq_low;
899 if (credits_possible > 0) {
900 /* remove UINT64_MAX */
901 credits_possible -= 1;
903 credits_possible = MIN(credits_possible, current_max_credits);
904 credits_possible -= xconn->smb2.credits.seq_range;
906 credits_granted = MIN(credits_granted, credits_possible);
908 SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
909 xconn->smb2.credits.granted += credits_granted;
910 xconn->smb2.credits.seq_range += credits_granted;
912 DEBUG(10,("smb2_set_operation_credit: requested %u, charge %u, "
913 "granted %u, current possible/max %u/%u, "
914 "total granted/max/low/range %u/%u/%llu/%u\n",
915 (unsigned int)credits_requested,
916 (unsigned int)credit_charge,
917 (unsigned int)credits_granted,
918 (unsigned int)credits_possible,
919 (unsigned int)current_max_credits,
920 (unsigned int)xconn->smb2.credits.granted,
921 (unsigned int)xconn->smb2.credits.max,
922 (unsigned long long)xconn->smb2.credits.seq_low,
923 (unsigned int)xconn->smb2.credits.seq_range));
926 static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
927 struct smbd_smb2_request *outreq)
930 uint16_t total_credits = 0;
932 count = outreq->out.vector_count;
934 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
935 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
936 struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
937 uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
939 smb2_set_operation_credit(outreq->xconn, inhdr_v, outhdr_v);
941 /* To match Windows, count up what we
943 total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
944 /* Set to zero in all but the last reply. */
945 if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
946 SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
948 SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
953 DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size)
955 if (req->current_idx <= 1) {
956 if (size <= sizeof(req->out._body)) {
957 return data_blob_const(req->out._body, size);
961 return data_blob_talloc(req, NULL, size);
964 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
966 struct smbXsrv_connection *xconn = req->xconn;
968 struct iovec *vector;
973 count = req->in.vector_count;
974 if (count <= ARRAY_SIZE(req->out._vector)) {
976 vector = req->out._vector;
978 vector = talloc_zero_array(req, struct iovec, count);
979 if (vector == NULL) {
980 return NT_STATUS_NO_MEMORY;
985 vector[0].iov_base = req->out.nbt_hdr;
986 vector[0].iov_len = 4;
987 SIVAL(req->out.nbt_hdr, 0, 0);
989 for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
990 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
991 const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
992 uint8_t *outhdr = NULL;
993 uint8_t *outbody = NULL;
994 uint32_t next_command_ofs = 0;
995 struct iovec *current = &vector[idx];
997 if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
998 /* we have a next command -
999 * setup for the error case. */
1000 next_command_ofs = SMB2_HDR_BODY + 9;
1004 outhdr = req->out._hdr;
1006 outhdr = talloc_zero_array(mem_ctx, uint8_t,
1008 if (outhdr == NULL) {
1009 return NT_STATUS_NO_MEMORY;
1013 outbody = outhdr + SMB2_HDR_BODY;
1016 * SMBD_SMB2_TF_IOV_OFS might be used later
1018 current[SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
1019 current[SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
1021 current[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)outhdr;
1022 current[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1024 current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
1025 current[SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
1027 current[SMBD_SMB2_DYN_IOV_OFS].iov_base = NULL;
1028 current[SMBD_SMB2_DYN_IOV_OFS].iov_len = 0;
1030 /* setup the SMB2 header */
1031 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1032 SSVAL(outhdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1033 SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1034 SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1035 SIVAL(outhdr, SMB2_HDR_STATUS,
1036 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1037 SSVAL(outhdr, SMB2_HDR_OPCODE,
1038 SVAL(inhdr, SMB2_HDR_OPCODE));
1039 SIVAL(outhdr, SMB2_HDR_FLAGS,
1040 IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1041 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1042 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1043 BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1044 SIVAL(outhdr, SMB2_HDR_PID,
1045 IVAL(inhdr, SMB2_HDR_PID));
1046 SIVAL(outhdr, SMB2_HDR_TID,
1047 IVAL(inhdr, SMB2_HDR_TID));
1048 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1049 BVAL(inhdr, SMB2_HDR_SESSION_ID));
1050 memcpy(outhdr + SMB2_HDR_SIGNATURE,
1051 inhdr + SMB2_HDR_SIGNATURE, 16);
1053 /* setup error body header */
1054 SSVAL(outbody, 0x00, 0x08 + 1);
1055 SSVAL(outbody, 0x02, 0);
1056 SIVAL(outbody, 0x04, 0);
1059 req->out.vector = vector;
1060 req->out.vector_count = count;
1062 /* setup the length of the NBT packet */
1063 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1065 return NT_STATUS_INVALID_PARAMETER_MIX;
1068 DLIST_ADD_END(xconn->smb2.requests, req);
1070 return NT_STATUS_OK;
1073 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
1075 const char *location)
1077 struct smbXsrv_client *client = xconn->client;
1079 DEBUG(10,("smbd_server_connection_terminate_ex: conn[%s] reason[%s] at %s\n",
1080 smbXsrv_connection_dbg(xconn), reason, location));
1082 if (client->connections->next != NULL) {
1083 /* TODO: cancel pending requests */
1084 DLIST_REMOVE(client->connections, xconn);
1090 * The last connection was disconnected
1092 exit_server_cleanly(reason);
1095 static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1096 struct iovec *outvec,
1097 const struct iovec *srcvec)
1099 const uint8_t *srctf;
1101 const uint8_t *srchdr;
1103 const uint8_t *srcbody;
1105 const uint8_t *expected_srcbody;
1106 const uint8_t *srcdyn;
1108 const uint8_t *expected_srcdyn;
1114 srctf = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1115 srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1116 srchdr = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1117 srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1118 srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1119 srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1120 expected_srcbody = srchdr + SMB2_HDR_BODY;
1121 srcdyn = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1122 srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1123 expected_srcdyn = srcbody + 8;
1125 if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1129 if (srchdr_len != SMB2_HDR_BODY) {
1133 if (srctf_len == SMB2_TF_HDR_SIZE) {
1134 dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1135 if (dsttf == NULL) {
1141 outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1142 outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1144 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1145 * be allocated with size OUTVEC_ALLOC_SIZE. */
1147 dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1148 if (dsthdr == NULL) {
1151 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1152 outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1155 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1156 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1157 * then duplicate this. Else use talloc_memdup().
1160 if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1161 dstbody = dsthdr + SMB2_HDR_BODY;
1163 dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1164 if (dstbody == NULL) {
1168 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1169 outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1172 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1174 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1175 * then duplicate this. Else use talloc_memdup().
1178 if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1179 dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1180 } else if (srcdyn == NULL) {
1183 dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1184 if (dstdyn == NULL) {
1188 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1189 outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1194 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1196 struct smbd_smb2_request *newreq = NULL;
1197 struct iovec *outvec = NULL;
1198 int count = req->out.vector_count;
1202 newreq = smbd_smb2_request_allocate(req->xconn);
1207 newreq->sconn = req->sconn;
1208 newreq->xconn = req->xconn;
1209 newreq->session = req->session;
1210 newreq->do_encryption = req->do_encryption;
1211 newreq->do_signing = req->do_signing;
1212 newreq->current_idx = req->current_idx;
1214 outvec = talloc_zero_array(newreq, struct iovec, count);
1216 TALLOC_FREE(newreq);
1219 newreq->out.vector = outvec;
1220 newreq->out.vector_count = count;
1222 /* Setup the outvec's identically to req. */
1223 outvec[0].iov_base = newreq->out.nbt_hdr;
1224 outvec[0].iov_len = 4;
1225 memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1227 /* Setup the vectors identically to the ones in req. */
1228 for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1229 if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1236 TALLOC_FREE(newreq);
1240 ok = smb2_setup_nbt_length(newreq->out.vector,
1241 newreq->out.vector_count);
1243 TALLOC_FREE(newreq);
1250 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
1252 struct smbXsrv_connection *xconn = req->xconn;
1254 struct iovec *firsttf = NULL;
1255 struct iovec *outhdr_v = NULL;
1256 uint8_t *outhdr = NULL;
1257 struct smbd_smb2_request *nreq = NULL;
1261 /* Create a new smb2 request we'll use
1262 for the interim return. */
1263 nreq = dup_smb2_req(req);
1265 return NT_STATUS_NO_MEMORY;
1268 /* Lose the last X out vectors. They're the
1269 ones we'll be using for the async reply. */
1270 nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
1272 ok = smb2_setup_nbt_length(nreq->out.vector,
1273 nreq->out.vector_count);
1275 return NT_STATUS_INVALID_PARAMETER_MIX;
1278 /* Step back to the previous reply. */
1279 nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
1280 firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
1281 outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
1282 outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
1283 /* And end the chain. */
1284 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
1286 /* Calculate outgoing credits */
1287 smb2_calculate_credits(req, nreq);
1289 if (DEBUGLEVEL >= 10) {
1290 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1291 (unsigned int)nreq->current_idx );
1292 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1293 (unsigned int)nreq->out.vector_count );
1294 print_req_vectors(nreq);
1298 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1299 * we need to sign/encrypt here with the last/first key we remembered
1301 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
1302 status = smb2_signing_encrypt_pdu(req->first_key,
1303 xconn->smb2.server.cipher,
1305 nreq->out.vector_count - first_idx);
1306 if (!NT_STATUS_IS_OK(status)) {
1309 } else if (req->last_key.length > 0) {
1310 status = smb2_signing_sign_pdu(req->last_key,
1313 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1314 if (!NT_STATUS_IS_OK(status)) {
1319 nreq->queue_entry.mem_ctx = nreq;
1320 nreq->queue_entry.vector = nreq->out.vector;
1321 nreq->queue_entry.count = nreq->out.vector_count;
1322 DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
1323 xconn->smb2.send_queue_len++;
1325 status = smbd_smb2_flush_send_queue(xconn);
1326 if (!NT_STATUS_IS_OK(status)) {
1330 return NT_STATUS_OK;
1333 struct smbd_smb2_request_pending_state {
1334 struct smbd_smb2_send_queue queue_entry;
1335 uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1336 struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1339 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1340 struct tevent_timer *te,
1341 struct timeval current_time,
1342 void *private_data);
1344 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1345 struct tevent_req *subreq,
1346 uint32_t defer_time)
1349 struct timeval defer_endtime;
1350 uint8_t *outhdr = NULL;
1353 if (!tevent_req_is_in_progress(subreq)) {
1355 * This is a performance optimization,
1356 * it avoids one tevent_loop iteration,
1357 * which means we avoid one
1358 * talloc_stackframe_pool/talloc_free pair.
1360 tevent_req_notify_callback(subreq);
1361 return NT_STATUS_OK;
1364 req->subreq = subreq;
1367 if (req->async_te) {
1368 /* We're already async. */
1369 return NT_STATUS_OK;
1372 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1373 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1374 if (flags & SMB2_HDR_FLAG_ASYNC) {
1375 /* We're already async. */
1376 return NT_STATUS_OK;
1379 if (req->async_internal) {
1381 * An SMB2 request implementation wants to handle the request
1382 * asynchronously "internally" while keeping synchronous
1383 * behaviour for the SMB2 request. This means we don't send an
1384 * interim response and we can allow processing of compound SMB2
1385 * requests (cf the subsequent check) for all cases.
1387 return NT_STATUS_OK;
1390 if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
1392 * We're trying to go async in a compound request
1393 * chain. This is only allowed for opens that cause an
1394 * oplock break or for the last operation in the
1395 * chain, otherwise it is not allowed. See
1396 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
1398 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1400 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
1402 * Cancel the outstanding request.
1404 bool ok = tevent_req_cancel(req->subreq);
1406 return NT_STATUS_OK;
1408 TALLOC_FREE(req->subreq);
1409 return smbd_smb2_request_error(req,
1410 NT_STATUS_INTERNAL_ERROR);
1414 if (DEBUGLEVEL >= 10) {
1415 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1416 (unsigned int)req->current_idx );
1417 print_req_vectors(req);
1420 if (req->current_idx > 1) {
1422 * We're going async in a compound
1423 * chain after the first request has
1424 * already been processed. Send an
1425 * interim response containing the
1426 * set of replies already generated.
1428 int idx = req->current_idx;
1430 status = smb2_send_async_interim_response(req);
1431 if (!NT_STATUS_IS_OK(status)) {
1434 if (req->first_key.length > 0) {
1435 data_blob_clear_free(&req->first_key);
1438 req->current_idx = 1;
1441 * Re-arrange the in.vectors to remove what
1444 memmove(&req->in.vector[1],
1445 &req->in.vector[idx],
1446 sizeof(req->in.vector[0])*(req->in.vector_count - idx));
1447 req->in.vector_count = 1 + (req->in.vector_count - idx);
1449 /* Re-arrange the out.vectors to match. */
1450 memmove(&req->out.vector[1],
1451 &req->out.vector[idx],
1452 sizeof(req->out.vector[0])*(req->out.vector_count - idx));
1453 req->out.vector_count = 1 + (req->out.vector_count - idx);
1455 if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
1457 * We only have one remaining request as
1458 * we've processed everything else.
1459 * This is no longer a compound request.
1461 req->compound_related = false;
1462 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1463 flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
1464 SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
1467 if (req->last_key.length > 0) {
1468 data_blob_clear_free(&req->last_key);
1471 defer_endtime = timeval_current_ofs_usec(defer_time);
1472 req->async_te = tevent_add_timer(req->sconn->ev_ctx,
1474 smbd_smb2_request_pending_timer,
1476 if (req->async_te == NULL) {
1477 return NT_STATUS_NO_MEMORY;
1480 return NT_STATUS_OK;
1483 static DATA_BLOB smbd_smb2_signing_key(struct smbXsrv_session *session,
1484 struct smbXsrv_connection *xconn)
1486 struct smbXsrv_channel_global0 *c = NULL;
1488 DATA_BLOB key = data_blob_null;
1490 status = smbXsrv_session_find_channel(session, xconn, &c);
1491 if (NT_STATUS_IS_OK(status)) {
1492 key = c->signing_key;
1495 if (key.length == 0) {
1496 key = session->global->signing_key;
1502 static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
1503 uint64_t *new_nonce_high,
1504 uint64_t *new_nonce_low)
1506 uint64_t nonce_high;
1509 session->nonce_low += 1;
1510 if (session->nonce_low == 0) {
1511 session->nonce_low += 1;
1512 session->nonce_high += 1;
1516 * CCM and GCM algorithms must never have their
1517 * nonce wrap, or the security of the whole
1518 * communication and the keys is destroyed.
1519 * We must drop the connection once we have
1520 * transfered too much data.
1522 * NOTE: We assume nonces greater than 8 bytes.
1524 if (session->nonce_high >= session->nonce_high_max) {
1525 return NT_STATUS_ENCRYPTION_FAILED;
1528 nonce_high = session->nonce_high_random;
1529 nonce_high += session->nonce_high;
1530 nonce_low = session->nonce_low;
1532 *new_nonce_high = nonce_high;
1533 *new_nonce_low = nonce_low;
1534 return NT_STATUS_OK;
1537 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1538 struct tevent_timer *te,
1539 struct timeval current_time,
1542 struct smbd_smb2_request *req =
1543 talloc_get_type_abort(private_data,
1544 struct smbd_smb2_request);
1545 struct smbXsrv_connection *xconn = req->xconn;
1546 struct smbd_smb2_request_pending_state *state = NULL;
1547 uint8_t *outhdr = NULL;
1548 const uint8_t *inhdr = NULL;
1551 uint8_t *hdr = NULL;
1552 uint8_t *body = NULL;
1553 uint8_t *dyn = NULL;
1555 uint64_t session_id = 0;
1556 uint64_t message_id = 0;
1557 uint64_t nonce_high = 0;
1558 uint64_t nonce_low = 0;
1559 uint64_t async_id = 0;
1563 TALLOC_FREE(req->async_te);
1565 /* Ensure our final reply matches the interim one. */
1566 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1567 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1568 flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1569 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1570 session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
1572 async_id = message_id; /* keep it simple for now... */
1574 SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1575 SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
1577 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1579 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
1580 (unsigned long long)async_id ));
1583 * What we send is identical to a smbd_smb2_request_error
1584 * packet with an error status of STATUS_PENDING. Make use
1585 * of this fact sometime when refactoring. JRA.
1588 state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
1589 if (state == NULL) {
1590 smbd_server_connection_terminate(xconn,
1591 nt_errstr(NT_STATUS_NO_MEMORY));
1595 tf = state->buf + NBT_HDR_SIZE;
1596 tf_len = SMB2_TF_HDR_SIZE;
1598 hdr = tf + SMB2_TF_HDR_SIZE;
1599 body = hdr + SMB2_HDR_BODY;
1602 if (req->do_encryption) {
1603 status = smb2_get_new_nonce(req->session,
1606 if (!NT_STATUS_IS_OK(status)) {
1607 smbd_server_connection_terminate(xconn,
1613 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
1614 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
1615 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
1616 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
1618 SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1619 SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1620 SSVAL(hdr, SMB2_HDR_EPOCH, 0);
1621 SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
1622 SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
1624 SIVAL(hdr, SMB2_HDR_FLAGS, flags);
1625 SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
1626 SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
1627 SBVAL(hdr, SMB2_HDR_PID, async_id);
1628 SBVAL(hdr, SMB2_HDR_SESSION_ID,
1629 BVAL(outhdr, SMB2_HDR_SESSION_ID));
1630 memcpy(hdr+SMB2_HDR_SIGNATURE,
1631 outhdr+SMB2_HDR_SIGNATURE, 16);
1633 SSVAL(body, 0x00, 0x08 + 1);
1635 SCVAL(body, 0x02, 0);
1636 SCVAL(body, 0x03, 0);
1637 SIVAL(body, 0x04, 0);
1638 /* Match W2K8R2... */
1639 SCVAL(dyn, 0x00, 0x21);
1641 state->vector[0].iov_base = (void *)state->buf;
1642 state->vector[0].iov_len = NBT_HDR_SIZE;
1644 if (req->do_encryption) {
1645 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
1646 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len = tf_len;
1648 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
1649 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
1652 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
1653 state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1655 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
1656 state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
1658 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
1659 state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len = 1;
1661 ok = smb2_setup_nbt_length(state->vector,
1662 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
1664 smbd_server_connection_terminate(
1665 xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
1669 /* Ensure we correctly go through crediting. Grant
1670 the credits now, and zero credits on the final
1672 smb2_set_operation_credit(req->xconn,
1673 SMBD_SMB2_IN_HDR_IOV(req),
1674 &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
1676 SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1681 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
1682 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1684 (unsigned int)ARRAY_SIZE(state->vector),
1685 (unsigned int)state->vector[i].iov_len);
1689 if (req->do_encryption) {
1690 struct smbXsrv_session *x = req->session;
1691 DATA_BLOB encryption_key = x->global->encryption_key;
1693 status = smb2_signing_encrypt_pdu(encryption_key,
1694 xconn->smb2.server.cipher,
1695 &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
1696 SMBD_SMB2_NUM_IOV_PER_REQ);
1697 if (!NT_STATUS_IS_OK(status)) {
1698 smbd_server_connection_terminate(xconn,
1702 } else if (req->do_signing) {
1703 struct smbXsrv_session *x = req->session;
1704 DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
1706 status = smb2_signing_sign_pdu(signing_key,
1708 &state->vector[1+SMBD_SMB2_HDR_IOV_OFS],
1709 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1710 if (!NT_STATUS_IS_OK(status)) {
1711 smbd_server_connection_terminate(xconn,
1717 state->queue_entry.mem_ctx = state;
1718 state->queue_entry.vector = state->vector;
1719 state->queue_entry.count = ARRAY_SIZE(state->vector);
1720 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
1721 xconn->smb2.send_queue_len++;
1723 status = smbd_smb2_flush_send_queue(xconn);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 smbd_server_connection_terminate(xconn,
1731 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
1733 struct smbXsrv_connection *xconn = req->xconn;
1734 struct smbd_smb2_request *cur;
1735 const uint8_t *inhdr;
1737 uint64_t search_message_id;
1738 uint64_t search_async_id;
1741 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1743 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1744 search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1745 search_async_id = BVAL(inhdr, SMB2_HDR_PID);
1748 * We don't need the request anymore cancel requests never
1751 * We defer the TALLOC_FREE(req) to the caller.
1753 DLIST_REMOVE(xconn->smb2.requests, req);
1755 for (cur = xconn->smb2.requests; cur; cur = cur->next) {
1756 const uint8_t *outhdr;
1757 uint64_t message_id;
1760 if (cur->compound_related) {
1762 * Never cancel anything in a compound request.
1763 * Way too hard to deal with the result.
1768 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
1770 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1771 async_id = BVAL(outhdr, SMB2_HDR_PID);
1773 if (flags & SMB2_HDR_FLAG_ASYNC) {
1774 if (search_async_id == async_id) {
1775 found_id = async_id;
1779 if (search_message_id == message_id) {
1780 found_id = message_id;
1786 if (cur && cur->subreq) {
1787 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
1788 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1789 "cancel opcode[%s] mid %llu\n",
1790 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
1791 (unsigned long long)found_id ));
1792 tevent_req_cancel(cur->subreq);
1795 return NT_STATUS_OK;
1798 /*************************************************************
1799 Ensure an incoming tid is a valid one for us to access.
1800 Change to the associated uid credentials and chdir to the
1801 valid tid directory.
1802 *************************************************************/
1804 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
1806 const uint8_t *inhdr;
1809 struct smbXsrv_tcon *tcon;
1811 NTTIME now = timeval_to_nttime(&req->request_time);
1815 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1817 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1818 in_tid = IVAL(inhdr, SMB2_HDR_TID);
1820 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1821 in_tid = req->last_tid;
1826 status = smb2srv_tcon_lookup(req->session,
1827 in_tid, now, &tcon);
1828 if (!NT_STATUS_IS_OK(status)) {
1832 if (!change_to_user(tcon->compat, req->session->compat->vuid)) {
1833 return NT_STATUS_ACCESS_DENIED;
1836 if (!set_current_service(tcon->compat, 0, true)) {
1837 return NT_STATUS_ACCESS_DENIED;
1841 req->last_tid = in_tid;
1843 return NT_STATUS_OK;
1846 /*************************************************************
1847 Ensure an incoming session_id is a valid one for us to access.
1848 *************************************************************/
1850 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
1852 const uint8_t *inhdr;
1855 uint64_t in_session_id;
1856 struct smbXsrv_session *session = NULL;
1857 struct auth_session_info *session_info;
1859 NTTIME now = timeval_to_nttime(&req->request_time);
1861 req->session = NULL;
1864 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1866 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1867 in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
1868 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
1870 if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1871 in_session_id = req->last_session_id;
1874 req->last_session_id = 0;
1876 /* look an existing session up */
1877 switch (in_opcode) {
1878 case SMB2_OP_SESSSETUP:
1880 * For a session bind request, we don't have the
1881 * channel set up at this point yet, so we defer
1882 * the verification that the connection belongs
1883 * to the session to the session setup code, which
1884 * can look at the session binding flags.
1886 status = smb2srv_session_lookup_client(req->xconn->client,
1891 status = smb2srv_session_lookup_conn(req->xconn,
1897 req->session = session;
1898 req->last_session_id = in_session_id;
1900 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1901 switch (in_opcode) {
1902 case SMB2_OP_SESSSETUP:
1903 status = NT_STATUS_OK;
1905 case SMB2_OP_LOGOFF:
1908 case SMB2_OP_CANCEL:
1909 case SMB2_OP_KEEPALIVE:
1911 * [MS-SMB2] 3.3.5.2.9 Verifying the Session
1912 * specifies that LOGOFF, CLOSE and (UN)LOCK
1913 * should always be processed even on expired sessions.
1915 * Also see the logic in
1916 * smbd_smb2_request_process_lock().
1918 * The smb2.session.expire2 test shows that
1919 * CANCEL and KEEPALIVE/ECHO should also
1922 status = NT_STATUS_OK;
1928 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1929 switch (in_opcode) {
1931 case SMB2_OP_CREATE:
1932 case SMB2_OP_GETINFO:
1933 case SMB2_OP_SETINFO:
1934 return NT_STATUS_INVALID_HANDLE;
1937 * Notice the check for
1938 * (session_info == NULL)
1941 status = NT_STATUS_OK;
1945 if (!NT_STATUS_IS_OK(status)) {
1949 session_info = session->global->auth_session_info;
1950 if (session_info == NULL) {
1951 return NT_STATUS_INVALID_HANDLE;
1954 if (in_session_id != req->xconn->client->last_session_id) {
1955 req->xconn->client->last_session_id = in_session_id;
1956 set_current_user_info(session_info->unix_info->sanitized_username,
1957 session_info->unix_info->unix_name,
1958 session_info->info->domain_name);
1961 return NT_STATUS_OK;
1964 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
1965 uint32_t data_length)
1967 struct smbXsrv_connection *xconn = req->xconn;
1968 uint16_t needed_charge;
1969 uint16_t credit_charge = 1;
1970 const uint8_t *inhdr;
1972 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1974 if (xconn->smb2.credits.multicredit) {
1975 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
1976 credit_charge = MAX(credit_charge, 1);
1979 needed_charge = (data_length - 1)/ 65536 + 1;
1981 DEBUG(10, ("mid %llu, CreditCharge: %d, NeededCharge: %d\n",
1982 (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
1983 credit_charge, needed_charge));
1985 if (needed_charge > credit_charge) {
1986 DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
1987 credit_charge, needed_charge));
1988 return NT_STATUS_INVALID_PARAMETER;
1991 return NT_STATUS_OK;
1994 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
1995 size_t expected_body_size)
1997 struct iovec *inhdr_v;
1998 const uint8_t *inhdr;
2000 const uint8_t *inbody;
2002 size_t min_dyn_size = expected_body_size & 0x00000001;
2003 int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2006 * The following should be checked already.
2008 if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2009 return NT_STATUS_INTERNAL_ERROR;
2011 if (req->current_idx > max_idx) {
2012 return NT_STATUS_INTERNAL_ERROR;
2015 inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2016 if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2017 return NT_STATUS_INTERNAL_ERROR;
2019 if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2020 return NT_STATUS_INTERNAL_ERROR;
2023 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2024 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2028 case SMB2_OP_GETINFO:
2032 if (req->smb1req != NULL && req->smb1req->unread_bytes > 0) {
2033 if (req->smb1req->unread_bytes < min_dyn_size) {
2034 return NT_STATUS_INVALID_PARAMETER;
2043 * Now check the expected body size,
2044 * where the last byte might be in the
2047 if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2048 return NT_STATUS_INVALID_PARAMETER;
2050 if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2051 return NT_STATUS_INVALID_PARAMETER;
2054 inbody = SMBD_SMB2_IN_BODY_PTR(req);
2056 body_size = SVAL(inbody, 0x00);
2057 if (body_size != expected_body_size) {
2058 return NT_STATUS_INVALID_PARAMETER;
2061 return NT_STATUS_OK;
2064 bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2066 return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2068 (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2069 SMBXSRV_ENCRYPTION_DESIRED |
2070 SMBXSRV_ENCRYPTION_REQUIRED)));
2073 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2075 return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2076 (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2079 /* Set a flag if not already set, return true if set */
2080 bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2082 if ((flag == 0) || (*flags & flag)) {
2091 * Update encryption state tracking flags, this can be used to
2092 * determine whether whether the session or tcon is "encrypted".
2094 static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2096 bool *update_session_globalp,
2097 bool *update_tcon_globalp)
2099 /* Default: assume unecrypted and unsigned */
2100 struct smbXsrv_session *session = req->session;
2101 struct smbXsrv_tcon *tcon = req->tcon;
2102 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2103 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2104 bool update_session = false;
2105 bool update_tcon = false;
2107 if (req->was_encrypted && req->do_encryption) {
2108 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2109 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2111 /* Unencrypted packet, can be signed */
2112 if (req->do_signing) {
2113 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2114 } else if (opcode == SMB2_OP_CANCEL) {
2115 /* Cancel requests are allowed to skip signing */
2116 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2120 update_session |= smbXsrv_set_crypto_flag(
2121 &session->global->encryption_flags, encrypt_flag);
2122 update_session |= smbXsrv_set_crypto_flag(
2123 &session->global->signing_flags, sign_flag);
2126 update_tcon |= smbXsrv_set_crypto_flag(
2127 &tcon->global->encryption_flags, encrypt_flag);
2128 update_tcon |= smbXsrv_set_crypto_flag(
2129 &tcon->global->signing_flags, sign_flag);
2132 *update_session_globalp = update_session;
2133 *update_tcon_globalp = update_tcon;
2137 bool smbXsrv_is_signed(uint8_t signing_flags)
2140 * Signing is always enabled, so unless we got an unsigned
2141 * packet and at least one signed packet that was not
2142 * encrypted, the session or tcon is "signed".
2144 return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2145 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2148 bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2150 return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2151 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2154 static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2155 struct smbd_smb2_request *req,
2158 struct smbXsrv_connection *xconn = req->xconn;
2159 const uint8_t *inhdr;
2160 uint16_t channel_sequence;
2163 struct smbXsrv_open *op;
2164 bool update_open = false;
2165 NTSTATUS status = NT_STATUS_OK;
2167 req->request_counters_updated = false;
2169 if (xconn->protocol < PROTOCOL_SMB2_22) {
2170 return NT_STATUS_OK;
2173 if (req->compat_chain_fsp == NULL) {
2174 return NT_STATUS_OK;
2177 op = req->compat_chain_fsp->op;
2179 return NT_STATUS_OK;
2182 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2183 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2184 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2186 cmp = channel_sequence - op->global->channel_sequence;
2188 if (abs(cmp) > INT16_MAX) {
2190 * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2192 * If the channel sequence number of the request and the one
2193 * known to the server are not equal, the channel sequence
2194 * number and outstanding request counts are only updated
2195 * "... if the unsigned difference using 16-bit arithmetic
2196 * between ChannelSequence and Open.ChannelSequence is less than
2197 * or equal to 0x7FFF ...".
2198 * Otherwise, an error is returned for the modifying
2199 * calls write, set_info, and ioctl.
2201 * There are currently two issues with the description:
2203 * * For the other calls, the document seems to imply
2204 * that processing continues without adapting the
2205 * counters (if the sequence numbers are not equal).
2207 * TODO: This needs clarification!
2209 * * Also, the behaviour if the difference is larger
2210 * than 0x7FFF is not clear. The document seems to
2211 * imply that if such a difference is reached,
2212 * the server starts to ignore the counters or
2213 * in the case of the modifying calls, return errors.
2215 * TODO: This needs clarification!
2217 * At this point Samba tries to be a little more
2218 * clever than the description in the MS-SMB2 document
2219 * by heuristically detecting and properly treating
2220 * a 16 bit overflow of the client-submitted sequence
2223 * If the stored channel sequence number is more than
2224 * 0x7FFF larger than the one from the request, then
2225 * the client-provided sequence number has likely
2226 * overflown. We treat this case as valid instead
2229 * The MS-SMB2 behaviour would be setting cmp = -1.
2234 if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2235 if (cmp == 0 && op->pre_request_count == 0) {
2236 op->request_count += 1;
2237 req->request_counters_updated = true;
2238 } else if (cmp > 0 && op->pre_request_count == 0) {
2239 op->pre_request_count += op->request_count;
2240 op->request_count = 1;
2241 op->global->channel_sequence = channel_sequence;
2243 req->request_counters_updated = true;
2244 } else if (modify_call) {
2245 return NT_STATUS_FILE_NOT_AVAILABLE;
2249 op->request_count += 1;
2250 req->request_counters_updated = true;
2251 } else if (cmp > 0) {
2252 op->pre_request_count += op->request_count;
2253 op->request_count = 1;
2254 op->global->channel_sequence = channel_sequence;
2256 req->request_counters_updated = true;
2257 } else if (modify_call) {
2258 return NT_STATUS_FILE_NOT_AVAILABLE;
2263 status = smbXsrv_open_update(op);
2269 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2271 struct smbXsrv_connection *xconn = req->xconn;
2272 const struct smbd_smb2_dispatch_table *call = NULL;
2273 const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2274 const uint8_t *inhdr;
2279 NTSTATUS session_status;
2280 uint32_t allowed_flags;
2281 NTSTATUS return_value;
2282 struct smbXsrv_session *x = NULL;
2283 bool signing_required = false;
2284 bool encryption_desired = false;
2285 bool encryption_required = false;
2287 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2289 DO_PROFILE_INC(request);
2291 /* TODO: verify more things */
2293 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2294 opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2295 mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2296 DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2297 smb2_opcode_name(opcode),
2298 (unsigned long long)mid));
2300 if (xconn->protocol >= PROTOCOL_SMB2_02) {
2302 * once the protocol is negotiated
2303 * SMB2_OP_NEGPROT is not allowed anymore
2305 if (opcode == SMB2_OP_NEGPROT) {
2306 /* drop the connection */
2307 return NT_STATUS_INVALID_PARAMETER;
2311 * if the protocol is not negotiated yet
2312 * only SMB2_OP_NEGPROT is allowed.
2314 if (opcode != SMB2_OP_NEGPROT) {
2315 /* drop the connection */
2316 return NT_STATUS_INVALID_PARAMETER;
2321 * Check if the client provided a valid session id,
2322 * if so smbd_smb2_request_check_session() calls
2323 * set_current_user_info().
2325 * As some command don't require a valid session id
2326 * we defer the check of the session_status
2328 session_status = smbd_smb2_request_check_session(req);
2331 signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
2332 encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
2333 encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
2336 req->async_internal = false;
2337 req->do_signing = false;
2338 req->do_encryption = false;
2339 req->was_encrypted = false;
2340 if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
2341 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
2342 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
2344 if (x != NULL && x->global->session_wire_id != tf_session_id) {
2345 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2346 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2347 (unsigned long long)x->global->session_wire_id,
2348 (unsigned long long)tf_session_id));
2350 * TODO: windows allows this...
2351 * should we drop the connection?
2353 * For now we just return ACCESS_DENIED
2354 * (Windows clients never trigger this)
2355 * and wait for an update of [MS-SMB2].
2357 return smbd_smb2_request_error(req,
2358 NT_STATUS_ACCESS_DENIED);
2361 req->was_encrypted = true;
2364 if (encryption_required && !req->was_encrypted) {
2365 return smbd_smb2_request_error(req,
2366 NT_STATUS_ACCESS_DENIED);
2369 call = smbd_smb2_call(opcode);
2371 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2374 allowed_flags = SMB2_HDR_FLAG_CHAINED |
2375 SMB2_HDR_FLAG_SIGNED |
2377 if (xconn->protocol >= PROTOCOL_SMB3_11) {
2378 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2380 if (opcode == SMB2_OP_NEGPROT) {
2381 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
2382 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2385 if (opcode == SMB2_OP_CANCEL) {
2386 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
2388 if (xconn->protocol >= PROTOCOL_SMB2_22) {
2389 allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
2391 if ((flags & ~allowed_flags) != 0) {
2392 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2395 if (flags & SMB2_HDR_FLAG_CHAINED) {
2397 * This check is mostly for giving the correct error code
2398 * for compounded requests.
2400 if (!NT_STATUS_IS_OK(session_status)) {
2401 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2404 req->compat_chain_fsp = NULL;
2407 if (req->was_encrypted) {
2408 signing_required = false;
2409 } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
2410 DATA_BLOB signing_key = data_blob_null;
2414 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2415 * If the SMB2 header of the SMB2 NEGOTIATE
2416 * request has the SMB2_FLAGS_SIGNED bit set in the
2417 * Flags field, the server MUST fail the request
2418 * with STATUS_INVALID_PARAMETER.
2420 * Microsoft test tool checks this.
2423 if ((opcode == SMB2_OP_NEGPROT) &&
2424 (flags & SMB2_HDR_FLAG_SIGNED)) {
2425 status = NT_STATUS_INVALID_PARAMETER;
2427 status = NT_STATUS_USER_SESSION_DELETED;
2429 return smbd_smb2_request_error(req, status);
2432 signing_key = smbd_smb2_signing_key(x, xconn);
2435 * If we have a signing key, we should
2438 if (signing_key.length > 0) {
2439 req->do_signing = true;
2442 status = smb2_signing_check_pdu(signing_key,
2444 SMBD_SMB2_IN_HDR_IOV(req),
2445 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2446 if (!NT_STATUS_IS_OK(status)) {
2447 return smbd_smb2_request_error(req, status);
2451 * Now that we know the request was correctly signed
2452 * we have to sign the response too.
2454 req->do_signing = true;
2456 if (!NT_STATUS_IS_OK(session_status)) {
2457 return smbd_smb2_request_error(req, session_status);
2459 } else if (opcode == SMB2_OP_CANCEL) {
2460 /* Cancel requests are allowed to skip the signing */
2461 } else if (signing_required) {
2463 * If signing is required we try to sign
2464 * a possible error response
2466 req->do_signing = true;
2467 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
2470 if (flags & SMB2_HDR_FLAG_CHAINED) {
2471 req->compound_related = true;
2474 if (call->need_session) {
2475 if (!NT_STATUS_IS_OK(session_status)) {
2476 return smbd_smb2_request_error(req, session_status);
2480 if (call->need_tcon) {
2481 SMB_ASSERT(call->need_session);
2484 * This call needs to be run as user.
2486 * smbd_smb2_request_check_tcon()
2487 * calls change_to_user() on success.
2489 status = smbd_smb2_request_check_tcon(req);
2490 if (!NT_STATUS_IS_OK(status)) {
2491 return smbd_smb2_request_error(req, status);
2493 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
2494 encryption_desired = true;
2496 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
2497 encryption_required = true;
2499 if (encryption_required && !req->was_encrypted) {
2500 return smbd_smb2_request_error(req,
2501 NT_STATUS_ACCESS_DENIED);
2505 if (req->was_encrypted || encryption_desired) {
2506 req->do_encryption = true;
2510 bool update_session_global = false;
2511 bool update_tcon_global = false;
2513 smb2srv_update_crypto_flags(req, opcode,
2514 &update_session_global,
2515 &update_tcon_global);
2517 if (update_session_global) {
2518 status = smbXsrv_session_update(x);
2519 if (!NT_STATUS_IS_OK(status)) {
2520 return smbd_smb2_request_error(req, status);
2523 if (update_tcon_global) {
2524 status = smbXsrv_tcon_update(req->tcon);
2525 if (!NT_STATUS_IS_OK(status)) {
2526 return smbd_smb2_request_error(req, status);
2531 if (call->fileid_ofs != 0) {
2532 size_t needed = call->fileid_ofs + 16;
2533 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2534 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2535 uint64_t file_id_persistent;
2536 uint64_t file_id_volatile;
2537 struct files_struct *fsp;
2539 SMB_ASSERT(call->need_tcon);
2541 if (needed > body_size) {
2542 return smbd_smb2_request_error(req,
2543 NT_STATUS_INVALID_PARAMETER);
2546 file_id_persistent = BVAL(body, call->fileid_ofs + 0);
2547 file_id_volatile = BVAL(body, call->fileid_ofs + 8);
2549 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2551 if (!call->allow_invalid_fileid) {
2552 return smbd_smb2_request_error(req,
2553 NT_STATUS_FILE_CLOSED);
2556 if (file_id_persistent != UINT64_MAX) {
2557 return smbd_smb2_request_error(req,
2558 NT_STATUS_FILE_CLOSED);
2560 if (file_id_volatile != UINT64_MAX) {
2561 return smbd_smb2_request_error(req,
2562 NT_STATUS_FILE_CLOSED);
2567 status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
2568 if (!NT_STATUS_IS_OK(status)) {
2569 return smbd_smb2_request_error(req, status);
2572 if (call->as_root) {
2573 SMB_ASSERT(call->fileid_ofs == 0);
2574 /* This call needs to be run as root */
2575 change_to_root_user();
2577 SMB_ASSERT(call->need_tcon);
2580 #define _INBYTES(_r) \
2581 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2584 case SMB2_OP_NEGPROT:
2585 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
2586 req->profile, _INBYTES(req));
2587 return_value = smbd_smb2_request_process_negprot(req);
2590 case SMB2_OP_SESSSETUP:
2591 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
2592 req->profile, _INBYTES(req));
2593 return_value = smbd_smb2_request_process_sesssetup(req);
2596 case SMB2_OP_LOGOFF:
2597 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
2598 req->profile, _INBYTES(req));
2599 return_value = smbd_smb2_request_process_logoff(req);
2603 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
2604 req->profile, _INBYTES(req));
2605 return_value = smbd_smb2_request_process_tcon(req);
2609 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
2610 req->profile, _INBYTES(req));
2611 return_value = smbd_smb2_request_process_tdis(req);
2614 case SMB2_OP_CREATE:
2615 if (req->subreq == NULL) {
2616 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
2617 req->profile, _INBYTES(req));
2619 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
2621 return_value = smbd_smb2_request_process_create(req);
2625 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
2626 req->profile, _INBYTES(req));
2627 return_value = smbd_smb2_request_process_close(req);
2631 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
2632 req->profile, _INBYTES(req));
2633 return_value = smbd_smb2_request_process_flush(req);
2637 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
2638 req->profile, _INBYTES(req));
2639 return_value = smbd_smb2_request_process_read(req);
2643 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
2644 req->profile, _INBYTES(req));
2645 return_value = smbd_smb2_request_process_write(req);
2649 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
2650 req->profile, _INBYTES(req));
2651 return_value = smbd_smb2_request_process_lock(req);
2655 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
2656 req->profile, _INBYTES(req));
2657 return_value = smbd_smb2_request_process_ioctl(req);
2660 case SMB2_OP_CANCEL:
2661 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
2662 req->profile, _INBYTES(req));
2663 return_value = smbd_smb2_request_process_cancel(req);
2664 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
2667 * We don't need the request anymore cancel requests never
2670 * smbd_smb2_request_process_cancel() already called
2671 * DLIST_REMOVE(xconn->smb2.requests, req);
2677 case SMB2_OP_KEEPALIVE:
2678 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
2679 req->profile, _INBYTES(req));
2680 return_value = smbd_smb2_request_process_keepalive(req);
2683 case SMB2_OP_QUERY_DIRECTORY:
2684 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
2685 req->profile, _INBYTES(req));
2686 return_value = smbd_smb2_request_process_query_directory(req);
2689 case SMB2_OP_NOTIFY:
2690 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
2691 req->profile, _INBYTES(req));
2692 return_value = smbd_smb2_request_process_notify(req);
2695 case SMB2_OP_GETINFO:
2696 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
2697 req->profile, _INBYTES(req));
2698 return_value = smbd_smb2_request_process_getinfo(req);
2701 case SMB2_OP_SETINFO:
2702 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
2703 req->profile, _INBYTES(req));
2704 return_value = smbd_smb2_request_process_setinfo(req);
2708 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
2709 req->profile, _INBYTES(req));
2710 return_value = smbd_smb2_request_process_break(req);
2714 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2717 return return_value;
2720 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
2722 struct smbXsrv_connection *xconn = req->xconn;
2723 const uint8_t *inhdr;
2724 uint16_t channel_sequence;
2725 struct smbXsrv_open *op;
2727 if (!req->request_counters_updated) {
2731 if (xconn->protocol < PROTOCOL_SMB2_22) {
2735 if (req->compat_chain_fsp == NULL) {
2739 op = req->compat_chain_fsp->op;
2744 inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2745 channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2747 if (op->global->channel_sequence == channel_sequence) {
2748 SMB_ASSERT(op->request_count > 0);
2749 op->request_count -= 1;
2751 SMB_ASSERT(op->pre_request_count > 0);
2752 op->pre_request_count -= 1;
2756 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
2758 struct smbXsrv_connection *xconn = req->xconn;
2760 struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
2761 struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
2762 struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
2767 TALLOC_FREE(req->async_te);
2769 /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
2770 smbd_smb2_request_reply_update_counts(req);
2772 if (req->do_encryption &&
2773 (firsttf->iov_len == 0) &&
2774 (req->first_key.length == 0) &&
2775 (req->session != NULL) &&
2776 (req->session->global->encryption_key.length != 0))
2778 DATA_BLOB encryption_key = req->session->global->encryption_key;
2780 uint64_t session_id = req->session->global->session_wire_id;
2781 uint64_t nonce_high;
2784 status = smb2_get_new_nonce(req->session,
2787 if (!NT_STATUS_IS_OK(status)) {
2792 * We need to place the SMB2_TRANSFORM header before the
2797 * we need to remember the encryption key
2798 * and defer the signing/encryption until
2799 * we are sure that we do not change
2802 req->first_key = data_blob_dup_talloc(req, encryption_key);
2803 if (req->first_key.data == NULL) {
2804 return NT_STATUS_NO_MEMORY;
2807 tf = talloc_zero_array(req, uint8_t,
2810 return NT_STATUS_NO_MEMORY;
2813 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2814 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2815 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2816 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2818 firsttf->iov_base = (void *)tf;
2819 firsttf->iov_len = SMB2_TF_HDR_SIZE;
2822 if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
2823 (req->last_key.length > 0) &&
2824 (firsttf->iov_len == 0))
2826 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
2827 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
2830 * As we are sure the header of the last request in the
2831 * compound chain will not change, we can to sign here
2832 * with the last signing key we remembered.
2834 status = smb2_signing_sign_pdu(req->last_key,
2837 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2838 if (!NT_STATUS_IS_OK(status)) {
2842 if (req->last_key.length > 0) {
2843 data_blob_clear_free(&req->last_key);
2846 SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
2847 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
2849 req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
2851 if (req->current_idx < req->out.vector_count) {
2853 * We must process the remaining compound
2854 * SMB2 requests before any new incoming SMB2
2855 * requests. This is because incoming SMB2
2856 * requests may include a cancel for a
2857 * compound request we haven't processed
2860 struct tevent_immediate *im = tevent_create_immediate(req);
2862 return NT_STATUS_NO_MEMORY;
2865 if (req->do_signing && firsttf->iov_len == 0) {
2866 struct smbXsrv_session *x = req->session;
2867 DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2870 * we need to remember the signing key
2871 * and defer the signing until
2872 * we are sure that we do not change
2875 req->last_key = data_blob_dup_talloc(req, signing_key);
2876 if (req->last_key.data == NULL) {
2877 return NT_STATUS_NO_MEMORY;
2881 tevent_schedule_immediate(im,
2883 smbd_smb2_request_dispatch_immediate,
2885 return NT_STATUS_OK;
2888 if (req->compound_related) {
2889 req->compound_related = false;
2892 ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
2894 return NT_STATUS_INVALID_PARAMETER_MIX;
2897 /* Set credit for these operations (zero credits if this
2898 is a final reply for an async operation). */
2899 smb2_calculate_credits(req, req);
2902 * now check if we need to sign the current response
2904 if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
2905 status = smb2_signing_encrypt_pdu(req->first_key,
2906 xconn->smb2.server.cipher,
2908 req->out.vector_count - first_idx);
2909 if (!NT_STATUS_IS_OK(status)) {
2912 } else if (req->do_signing) {
2913 struct smbXsrv_session *x = req->session;
2914 DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2916 status = smb2_signing_sign_pdu(signing_key,
2919 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2920 if (!NT_STATUS_IS_OK(status)) {
2924 if (req->first_key.length > 0) {
2925 data_blob_clear_free(&req->first_key);
2928 if (req->preauth != NULL) {
2929 struct hc_sha512state sctx;
2932 samba_SHA512_Init(&sctx);
2933 samba_SHA512_Update(&sctx, req->preauth->sha512_value,
2934 sizeof(req->preauth->sha512_value));
2935 for (i = 1; i < req->in.vector_count; i++) {
2936 samba_SHA512_Update(&sctx,
2937 req->in.vector[i].iov_base,
2938 req->in.vector[i].iov_len);
2940 samba_SHA512_Final(req->preauth->sha512_value, &sctx);
2942 samba_SHA512_Init(&sctx);
2943 samba_SHA512_Update(&sctx, req->preauth->sha512_value,
2944 sizeof(req->preauth->sha512_value));
2945 for (i = 1; i < req->out.vector_count; i++) {
2946 samba_SHA512_Update(&sctx,
2947 req->out.vector[i].iov_base,
2948 req->out.vector[i].iov_len);
2950 samba_SHA512_Final(req->preauth->sha512_value, &sctx);
2952 req->preauth = NULL;
2955 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2956 if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
2957 outdyn->iov_base == NULL && outdyn->iov_len != 0) {
2958 /* Dynamic part is NULL. Chop it off,
2959 We're going to send it via sendfile. */
2960 req->out.vector_count -= 1;
2964 * We're done with this request -
2965 * move it off the "being processed" queue.
2967 DLIST_REMOVE(xconn->smb2.requests, req);
2969 req->queue_entry.mem_ctx = req;
2970 req->queue_entry.vector = req->out.vector;
2971 req->queue_entry.count = req->out.vector_count;
2972 DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
2973 xconn->smb2.send_queue_len++;
2975 status = smbd_smb2_flush_send_queue(xconn);
2976 if (!NT_STATUS_IS_OK(status)) {
2980 return NT_STATUS_OK;
2983 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
2985 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
2986 struct tevent_immediate *im,
2989 struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
2990 struct smbd_smb2_request);
2991 struct smbXsrv_connection *xconn = req->xconn;
2996 if (DEBUGLEVEL >= 10) {
2997 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2998 req->current_idx, req->in.vector_count));
2999 print_req_vectors(req);
3002 status = smbd_smb2_request_dispatch(req);
3003 if (!NT_STATUS_IS_OK(status)) {
3004 smbd_server_connection_terminate(xconn, nt_errstr(status));
3008 status = smbd_smb2_request_next_incoming(xconn);
3009 if (!NT_STATUS_IS_OK(status)) {
3010 smbd_server_connection_terminate(xconn, nt_errstr(status));
3015 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3017 DATA_BLOB body, DATA_BLOB *dyn,
3018 const char *location)
3021 struct iovec *outbody_v;
3022 struct iovec *outdyn_v;
3023 uint32_t next_command_ofs;
3025 DEBUG(10,("smbd_smb2_request_done_ex: "
3026 "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
3027 req->current_idx, nt_errstr(status), (unsigned int)body.length,
3029 (unsigned int)(dyn ? dyn->length : 0),
3032 if (body.length < 2) {
3033 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3036 if ((body.length % 2) != 0) {
3037 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3040 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3041 outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3042 outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3044 next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3045 SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3047 outbody_v->iov_base = (void *)body.data;
3048 outbody_v->iov_len = body.length;
3051 outdyn_v->iov_base = (void *)dyn->data;
3052 outdyn_v->iov_len = dyn->length;
3054 outdyn_v->iov_base = NULL;
3055 outdyn_v->iov_len = 0;
3059 * See if we need to recalculate the offset to the next response
3061 * Note that all responses may require padding (including the very last
3064 if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3065 next_command_ofs = SMB2_HDR_BODY;
3066 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3067 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3070 if ((next_command_ofs % 8) != 0) {
3071 size_t pad_size = 8 - (next_command_ofs % 8);
3072 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3074 * if the dyn buffer is empty
3075 * we can use it to add padding
3079 pad = talloc_zero_array(req,
3082 return smbd_smb2_request_error(req,
3083 NT_STATUS_NO_MEMORY);
3086 outdyn_v->iov_base = (void *)pad;
3087 outdyn_v->iov_len = pad_size;
3090 * For now we copy the dynamic buffer
3091 * and add the padding to the new buffer
3098 old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3099 old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3101 new_size = old_size + pad_size;
3102 new_dyn = talloc_zero_array(req,
3104 if (new_dyn == NULL) {
3105 return smbd_smb2_request_error(req,
3106 NT_STATUS_NO_MEMORY);
3109 memcpy(new_dyn, old_dyn, old_size);
3110 memset(new_dyn + old_size, 0, pad_size);
3112 outdyn_v->iov_base = (void *)new_dyn;
3113 outdyn_v->iov_len = new_size;
3115 next_command_ofs += pad_size;
3118 if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3119 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3121 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3123 return smbd_smb2_request_reply(req);
3126 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3129 const char *location)
3131 struct smbXsrv_connection *xconn = req->xconn;
3134 uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3135 size_t unread_bytes = smbd_smb2_unread_bytes(req);
3137 DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3138 "at %s\n", req->current_idx, nt_errstr(status),
3139 info ? " +info" : "", location);
3142 /* Recvfile error. Drain incoming socket. */
3146 ret = drain_socket(xconn->transport.sock, unread_bytes);
3147 if (ret != unread_bytes) {
3151 error = NT_STATUS_IO_DEVICE_ERROR;
3153 error = map_nt_error_from_unix_common(errno);
3156 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3157 "ret[%u] errno[%d] => %s\n",
3158 (unsigned)unread_bytes,
3159 (unsigned)ret, errno, nt_errstr(error)));
3164 body.data = outhdr + SMB2_HDR_BODY;
3166 SSVAL(body.data, 0, 9);
3169 SIVAL(body.data, 0x04, info->length);
3171 /* Allocated size of req->out.vector[i].iov_base
3172 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3173 * 1 byte without having to do an alloc.
3176 info->data = ((uint8_t *)outhdr) +
3177 OUTVEC_ALLOC_SIZE - 1;
3179 SCVAL(info->data, 0, 0);
3183 * Note: Even if there is an error, continue to process the request.
3187 return smbd_smb2_request_done_ex(req, status, body, info, __location__);
3191 struct smbd_smb2_send_break_state {
3192 struct smbd_smb2_send_queue queue_entry;
3193 uint8_t nbt_hdr[NBT_HDR_SIZE];
3194 uint8_t tf[SMB2_TF_HDR_SIZE];
3195 uint8_t hdr[SMB2_HDR_BODY];
3196 struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
3200 static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
3201 struct smbXsrv_session *session,
3202 struct smbXsrv_tcon *tcon,
3203 const uint8_t *body,
3206 struct smbd_smb2_send_break_state *state;
3207 bool do_encryption = false;
3208 uint64_t session_wire_id = 0;
3209 uint64_t nonce_high = 0;
3210 uint64_t nonce_low = 0;
3215 if (session != NULL) {
3216 session_wire_id = session->global->session_wire_id;
3217 do_encryption = session->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3218 if (tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3219 do_encryption = true;
3223 statelen = offsetof(struct smbd_smb2_send_break_state, body) +
3226 state = talloc_zero_size(xconn, statelen);
3227 if (state == NULL) {
3228 return NT_STATUS_NO_MEMORY;
3230 talloc_set_name_const(state, "struct smbd_smb2_send_break_state");
3232 if (do_encryption) {
3233 status = smb2_get_new_nonce(session,
3236 if (!NT_STATUS_IS_OK(status)) {
3241 SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3242 SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
3243 SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
3244 SBVAL(state->tf, SMB2_TF_SESSION_ID, session_wire_id);
3246 SIVAL(state->hdr, 0, SMB2_MAGIC);
3247 SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
3248 SSVAL(state->hdr, SMB2_HDR_EPOCH, 0);
3249 SIVAL(state->hdr, SMB2_HDR_STATUS, 0);
3250 SSVAL(state->hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK);
3251 SSVAL(state->hdr, SMB2_HDR_CREDIT, 0);
3252 SIVAL(state->hdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
3253 SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, 0);
3254 SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
3255 SIVAL(state->hdr, SMB2_HDR_PID, 0);
3256 SIVAL(state->hdr, SMB2_HDR_TID, 0);
3257 SBVAL(state->hdr, SMB2_HDR_SESSION_ID, 0);
3258 memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
3260 state->vector[0] = (struct iovec) {
3261 .iov_base = state->nbt_hdr,
3262 .iov_len = sizeof(state->nbt_hdr)
3265 if (do_encryption) {
3266 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3267 .iov_base = state->tf,
3268 .iov_len = sizeof(state->tf)
3271 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3277 state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
3278 .iov_base = state->hdr,
3279 .iov_len = sizeof(state->hdr)
3282 memcpy(state->body, body, body_len);
3284 state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
3285 .iov_base = state->body,
3286 .iov_len = body_len /* no sizeof(state->body) .. :-) */
3290 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
3293 ok = smb2_setup_nbt_length(state->vector,
3294 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
3296 return NT_STATUS_INVALID_PARAMETER_MIX;
3299 if (do_encryption) {
3300 DATA_BLOB encryption_key = session->global->encryption_key;
3302 status = smb2_signing_encrypt_pdu(encryption_key,
3303 xconn->smb2.server.cipher,
3304 &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
3305 SMBD_SMB2_NUM_IOV_PER_REQ);
3306 if (!NT_STATUS_IS_OK(status)) {
3311 state->queue_entry.mem_ctx = state;
3312 state->queue_entry.vector = state->vector;
3313 state->queue_entry.count = ARRAY_SIZE(state->vector);
3314 DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
3315 xconn->smb2.send_queue_len++;
3317 status = smbd_smb2_flush_send_queue(xconn);
3318 if (!NT_STATUS_IS_OK(status)) {
3322 return NT_STATUS_OK;
3325 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
3326 struct smbXsrv_session *session,
3327 struct smbXsrv_tcon *tcon,
3328 struct smbXsrv_open *op,
3329 uint8_t oplock_level)
3333 SSVAL(body, 0x00, sizeof(body));
3334 SCVAL(body, 0x02, oplock_level);
3335 SCVAL(body, 0x03, 0); /* reserved */
3336 SIVAL(body, 0x04, 0); /* reserved */
3337 SBVAL(body, 0x08, op->global->open_persistent_id);
3338 SBVAL(body, 0x10, op->global->open_volatile_id);
3340 return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3343 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
3345 uint32_t lease_flags,
3346 struct smb2_lease_key *lease_key,
3347 uint32_t current_lease_state,
3348 uint32_t new_lease_state)
3352 SSVAL(body, 0x00, sizeof(body));
3353 SSVAL(body, 0x02, new_epoch);
3354 SIVAL(body, 0x04, lease_flags);
3355 SBVAL(body, 0x08, lease_key->data[0]);
3356 SBVAL(body, 0x10, lease_key->data[1]);
3357 SIVAL(body, 0x18, current_lease_state);
3358 SIVAL(body, 0x1c, new_lease_state);
3359 SIVAL(body, 0x20, 0); /* BreakReason, MUST be 0 */
3360 SIVAL(body, 0x24, 0); /* AccessMaskHint, MUST be 0 */
3361 SIVAL(body, 0x28, 0); /* ShareMaskHint, MUST be 0 */
3363 return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3366 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
3370 uint64_t file_id_persistent;
3371 uint64_t file_id_volatile;
3372 struct smbXsrv_open *op = NULL;
3373 struct files_struct *fsp = NULL;
3374 const uint8_t *body = NULL;
3377 * This is only called with a pktbuf
3378 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
3382 if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
3383 /* Transform header. Cannot recvfile. */
3386 if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
3387 /* Not SMB2. Normal error path will cope. */
3390 if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
3391 /* Not SMB2. Normal error path will cope. */
3394 if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
3395 /* Needs to be a WRITE. */
3398 if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
3399 /* Chained. Cannot recvfile. */
3402 flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
3403 if (flags & SMB2_HDR_FLAG_CHAINED) {
3404 /* Chained. Cannot recvfile. */
3407 if (flags & SMB2_HDR_FLAG_SIGNED) {
3408 /* Signed. Cannot recvfile. */
3412 body = &state->pktbuf[SMB2_HDR_BODY];
3414 file_id_persistent = BVAL(body, 0x10);
3415 file_id_volatile = BVAL(body, 0x18);
3417 status = smb2srv_open_lookup(state->req->xconn,
3422 if (!NT_STATUS_IS_OK(status)) {
3430 if (fsp->conn == NULL) {
3434 if (IS_IPC(fsp->conn)) {
3437 if (IS_PRINT(fsp->conn)) {
3441 DEBUG(10,("Doing recvfile write len = %u\n",
3442 (unsigned int)(state->pktfull - state->pktlen)));
3447 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
3449 struct smbd_server_connection *sconn = xconn->client->sconn;
3450 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3451 size_t max_send_queue_len;
3452 size_t cur_send_queue_len;
3454 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3456 * we're not supposed to do any io
3458 return NT_STATUS_OK;
3461 if (state->req != NULL) {
3463 * if there is already a tstream_readv_pdu
3464 * pending, we are done.
3466 return NT_STATUS_OK;
3469 max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
3470 cur_send_queue_len = xconn->smb2.send_queue_len;
3472 if (cur_send_queue_len > max_send_queue_len) {
3474 * if we have a lot of requests to send,
3475 * we wait until they are on the wire until we
3476 * ask for the next request.
3478 return NT_STATUS_OK;
3481 /* ask for the next request */
3482 ZERO_STRUCTP(state);
3483 state->req = smbd_smb2_request_allocate(xconn);
3484 if (state->req == NULL) {
3485 return NT_STATUS_NO_MEMORY;
3487 state->req->sconn = sconn;
3488 state->req->xconn = xconn;
3489 state->min_recv_size = lp_min_receive_file_size();
3491 TEVENT_FD_READABLE(xconn->transport.fde);
3493 return NT_STATUS_OK;
3496 void smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
3497 uint64_t expected_seq_low,
3498 const uint8_t *inpdu, size_t size)
3500 struct smbd_server_connection *sconn = xconn->client->sconn;
3502 struct smbd_smb2_request *req = NULL;
3504 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3505 (unsigned int)size));
3507 status = smbd_initialize_smb2(xconn, expected_seq_low);
3508 if (!NT_STATUS_IS_OK(status)) {
3509 smbd_server_connection_terminate(xconn, nt_errstr(status));
3513 status = smbd_smb2_request_create(xconn, inpdu, size, &req);
3514 if (!NT_STATUS_IS_OK(status)) {
3515 smbd_server_connection_terminate(xconn, nt_errstr(status));
3519 status = smbd_smb2_request_validate(req);
3520 if (!NT_STATUS_IS_OK(status)) {
3521 smbd_server_connection_terminate(xconn, nt_errstr(status));
3525 status = smbd_smb2_request_setup_out(req);
3526 if (!NT_STATUS_IS_OK(status)) {
3527 smbd_server_connection_terminate(xconn, nt_errstr(status));
3533 * this was already counted at the SMB1 layer =>
3534 * smbd_smb2_request_dispatch() should not count it twice.
3536 if (profile_p->values.request_stats.count > 0) {
3537 profile_p->values.request_stats.count--;
3540 status = smbd_smb2_request_dispatch(req);
3541 if (!NT_STATUS_IS_OK(status)) {
3542 smbd_server_connection_terminate(xconn, nt_errstr(status));
3546 status = smbd_smb2_request_next_incoming(xconn);
3547 if (!NT_STATUS_IS_OK(status)) {
3548 smbd_server_connection_terminate(xconn, nt_errstr(status));
3552 sconn->num_requests++;
3555 static int socket_error_from_errno(int ret,
3569 if (sys_errno == 0) {
3573 if (sys_errno == EINTR) {
3578 if (sys_errno == EINPROGRESS) {
3583 if (sys_errno == EAGAIN) {
3588 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3589 if (sys_errno == ENOMEM) {
3595 #if EWOULDBLOCK != EAGAIN
3596 if (sys_errno == EWOULDBLOCK) {
3606 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
3613 if (xconn->smb2.send_queue == NULL) {
3614 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3615 return NT_STATUS_OK;
3618 while (xconn->smb2.send_queue != NULL) {
3619 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
3622 if (e->sendfile_header != NULL) {
3627 status = NT_STATUS_INTERNAL_ERROR;
3629 for (i=0; i < e->count; i++) {
3630 size += e->vector[i].iov_len;
3633 if (size <= e->sendfile_header->length) {
3634 buf = e->sendfile_header->data;
3636 buf = talloc_array(e->mem_ctx, uint8_t, size);
3638 return NT_STATUS_NO_MEMORY;
3643 for (i=0; i < e->count; i++) {
3645 e->vector[i].iov_base,
3646 e->vector[i].iov_len);
3647 size += e->vector[i].iov_len;
3650 e->sendfile_header->data = buf;
3651 e->sendfile_header->length = size;
3652 e->sendfile_status = &status;
3655 xconn->smb2.send_queue_len--;
3656 DLIST_REMOVE(xconn->smb2.send_queue, e);
3658 * This triggers the sendfile path via
3661 talloc_free(e->mem_ctx);
3663 if (!NT_STATUS_IS_OK(status)) {
3669 ret = writev(xconn->transport.sock, e->vector, e->count);
3671 /* propagate end of file */
3672 return NT_STATUS_INTERNAL_ERROR;
3674 err = socket_error_from_errno(ret, errno, &retry);
3677 TEVENT_FD_WRITEABLE(xconn->transport.fde);
3678 return NT_STATUS_OK;
3681 return map_nt_error_from_unix_common(err);
3684 ok = iov_advance(&e->vector, &e->count, ret);
3686 return NT_STATUS_INTERNAL_ERROR;
3690 /* we have more to write */
3691 TEVENT_FD_WRITEABLE(xconn->transport.fde);
3692 return NT_STATUS_OK;
3695 xconn->smb2.send_queue_len--;
3696 DLIST_REMOVE(xconn->smb2.send_queue, e);
3697 talloc_free(e->mem_ctx);
3701 * Restart reads if we were blocked on
3702 * draining the send queue.
3705 status = smbd_smb2_request_next_incoming(xconn);
3706 if (!NT_STATUS_IS_OK(status)) {
3710 return NT_STATUS_OK;
3713 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
3716 struct smbd_server_connection *sconn = xconn->client->sconn;
3717 struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3718 struct smbd_smb2_request *req = NULL;
3719 size_t min_recvfile_size = UINT32_MAX;
3726 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3728 * we're not supposed to do any io
3730 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3731 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3732 return NT_STATUS_OK;
3735 if (fde_flags & TEVENT_FD_WRITE) {
3736 status = smbd_smb2_flush_send_queue(xconn);
3737 if (!NT_STATUS_IS_OK(status)) {
3742 if (!(fde_flags & TEVENT_FD_READ)) {
3743 return NT_STATUS_OK;
3746 if (state->req == NULL) {
3747 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3748 return NT_STATUS_OK;
3752 if (!state->hdr.done) {
3753 state->hdr.done = true;
3755 state->vector.iov_base = (void *)state->hdr.nbt;
3756 state->vector.iov_len = NBT_HDR_SIZE;
3759 ret = readv(xconn->transport.sock, &state->vector, 1);
3761 /* propagate end of file */
3762 return NT_STATUS_END_OF_FILE;
3764 err = socket_error_from_errno(ret, errno, &retry);
3767 TEVENT_FD_READABLE(xconn->transport.fde);
3768 return NT_STATUS_OK;
3771 return map_nt_error_from_unix_common(err);
3774 if (ret < state->vector.iov_len) {
3776 base = (uint8_t *)state->vector.iov_base;
3778 state->vector.iov_base = (void *)base;
3779 state->vector.iov_len -= ret;
3780 /* we have more to read */
3781 TEVENT_FD_READABLE(xconn->transport.fde);
3782 return NT_STATUS_OK;
3785 if (state->pktlen > 0) {
3786 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
3788 * Not a possible receivefile write.
3789 * Read the rest of the data.
3791 state->doing_receivefile = false;
3793 state->pktbuf = talloc_realloc(state->req,
3797 if (state->pktbuf == NULL) {
3798 return NT_STATUS_NO_MEMORY;
3801 state->vector.iov_base = (void *)(state->pktbuf +
3803 state->vector.iov_len = (state->pktfull -
3806 state->pktlen = state->pktfull;
3811 * Either this is a receivefile write so we've
3812 * done a short read, or if not we have all the data.
3818 * Now we analyze the NBT header
3820 if (state->hdr.nbt[0] != 0x00) {
3821 state->min_recv_size = 0;
3823 state->pktfull = smb2_len(state->hdr.nbt);
3824 if (state->pktfull == 0) {
3828 if (state->min_recv_size != 0) {
3829 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3830 min_recvfile_size += state->min_recv_size;
3833 if (state->pktfull > min_recvfile_size) {
3835 * Might be a receivefile write. Read the SMB2 HEADER +
3836 * SMB2_WRITE header first. Set 'doing_receivefile'
3837 * as we're *attempting* receivefile write. If this
3838 * turns out not to be a SMB2_WRITE request or otherwise
3839 * not suitable then we'll just read the rest of the data
3840 * the next time this function is called.
3842 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3843 state->doing_receivefile = true;
3845 state->pktlen = state->pktfull;
3848 state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
3849 if (state->pktbuf == NULL) {
3850 return NT_STATUS_NO_MEMORY;
3853 state->vector.iov_base = (void *)state->pktbuf;
3854 state->vector.iov_len = state->pktlen;
3860 if (state->hdr.nbt[0] != 0x00) {
3861 DEBUG(1,("ignore NBT[0x%02X] msg\n",
3862 state->hdr.nbt[0]));
3865 ZERO_STRUCTP(state);
3867 state->min_recv_size = lp_min_receive_file_size();
3875 req->request_time = timeval_current();
3876 now = timeval_to_nttime(&req->request_time);
3878 status = smbd_smb2_inbuf_parse_compound(xconn,
3884 &req->in.vector_count);
3885 if (!NT_STATUS_IS_OK(status)) {
3889 if (state->doing_receivefile) {
3890 req->smb1req = talloc_zero(req, struct smb_request);
3891 if (req->smb1req == NULL) {
3892 return NT_STATUS_NO_MEMORY;
3894 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
3897 ZERO_STRUCTP(state);
3899 req->current_idx = 1;
3901 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
3902 req->current_idx, req->in.vector_count));
3904 status = smbd_smb2_request_validate(req);
3905 if (!NT_STATUS_IS_OK(status)) {
3909 status = smbd_smb2_request_setup_out(req);
3910 if (!NT_STATUS_IS_OK(status)) {
3914 status = smbd_smb2_request_dispatch(req);
3915 if (!NT_STATUS_IS_OK(status)) {
3919 sconn->num_requests++;
3921 /* The timeout_processing function isn't run nearly
3922 often enough to implement 'max log size' without
3923 overrunning the size of the file by many megabytes.
3924 This is especially true if we are running at debug
3925 level 10. Checking every 50 SMB2s is a nice
3926 tradeoff of performance vs log file size overrun. */
3928 if ((sconn->num_requests % 50) == 0 &&
3929 need_to_check_log_size()) {
3930 change_to_root_user();
3934 status = smbd_smb2_request_next_incoming(xconn);
3935 if (!NT_STATUS_IS_OK(status)) {
3939 return NT_STATUS_OK;
3942 static void smbd_smb2_connection_handler(struct tevent_context *ev,
3943 struct tevent_fd *fde,
3947 struct smbXsrv_connection *xconn =
3948 talloc_get_type_abort(private_data,
3949 struct smbXsrv_connection);
3952 status = smbd_smb2_io_handler(xconn, flags);
3953 if (!NT_STATUS_IS_OK(status)) {
3954 smbd_server_connection_terminate(xconn, nt_errstr(status));