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
;
49 } smbd_smb2_table
[] = {
50 #define _OP(o) .opcode = o, .name = #o
55 _OP(SMB2_OP_SESSSETUP
),
65 * This call needs to be run as root.
67 * smbd_smb2_request_process_tcon()
68 * calls make_connection_snum(), which will call
69 * change_to_user(), when needed.
103 .need_session
= true,
108 .need_session
= true,
111 .allow_invalid_fileid
= true,
116 _OP(SMB2_OP_KEEPALIVE
),
119 _OP(SMB2_OP_QUERY_DIRECTORY
),
120 .need_session
= true,
125 .need_session
= true,
129 _OP(SMB2_OP_GETINFO
),
130 .need_session
= true,
134 _OP(SMB2_OP_SETINFO
),
135 .need_session
= true,
140 .need_session
= true,
145 * as LEASE breaks does not
151 const char *smb2_opcode_name(uint16_t opcode
)
153 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
154 return "Bad SMB2 opcode";
156 return smbd_smb2_table
[opcode
].name
;
159 static const struct smbd_smb2_dispatch_table
*smbd_smb2_call(uint16_t opcode
)
161 const struct smbd_smb2_dispatch_table
*ret
= NULL
;
163 if (opcode
>= ARRAY_SIZE(smbd_smb2_table
)) {
167 ret
= &smbd_smb2_table
[opcode
];
169 SMB_ASSERT(ret
->opcode
== opcode
);
174 static void print_req_vectors(const struct smbd_smb2_request
*req
)
178 for (i
= 0; i
< req
->in
.vector_count
; i
++) {
179 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
181 (unsigned int)req
->in
.vector
[i
].iov_len
);
183 for (i
= 0; i
< req
->out
.vector_count
; i
++) {
184 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
186 (unsigned int)req
->out
.vector
[i
].iov_len
);
190 bool smbd_is_smb2_header(const uint8_t *inbuf
, size_t size
)
192 if (size
< (4 + SMB2_HDR_BODY
)) {
196 if (IVAL(inbuf
, 4) != SMB2_MAGIC
) {
203 static NTSTATUS
smbd_initialize_smb2(struct smbXsrv_connection
*xconn
)
205 TALLOC_FREE(xconn
->transport
.fde
);
207 xconn
->smb2
.credits
.seq_low
= 0;
208 xconn
->smb2
.credits
.seq_range
= 1;
209 xconn
->smb2
.credits
.granted
= 1;
210 xconn
->smb2
.credits
.max
= lp_smb2_max_credits();
211 xconn
->smb2
.credits
.bitmap
= bitmap_talloc(xconn
,
212 xconn
->smb2
.credits
.max
);
213 if (xconn
->smb2
.credits
.bitmap
== NULL
) {
214 return NT_STATUS_NO_MEMORY
;
217 xconn
->transport
.fde
= tevent_add_fd(xconn
->ev_ctx
,
219 xconn
->transport
.sock
,
221 smbd_smb2_connection_handler
,
223 if (xconn
->transport
.fde
== NULL
) {
224 return NT_STATUS_NO_MEMORY
;
227 /* Ensure child is set to non-blocking mode */
228 set_blocking(xconn
->transport
.sock
, false);
232 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
233 #define _smb2_setlen(_buf,len) do { \
234 uint8_t *buf = (uint8_t *)_buf; \
236 buf[1] = ((len)&0xFF0000)>>16; \
237 buf[2] = ((len)&0xFF00)>>8; \
238 buf[3] = (len)&0xFF; \
241 static bool smb2_setup_nbt_length(struct iovec
*vector
, int count
)
249 len
= iov_buflen(vector
+1, count
-1);
251 if ((len
== -1) || (len
> 0xFFFFFF)) {
255 _smb2_setlen(vector
[0].iov_base
, len
);
259 static int smbd_smb2_request_destructor(struct smbd_smb2_request
*req
)
261 if (req
->first_key
.length
> 0) {
262 data_blob_clear_free(&req
->first_key
);
264 if (req
->last_key
.length
> 0) {
265 data_blob_clear_free(&req
->last_key
);
270 static struct smbd_smb2_request
*smbd_smb2_request_allocate(TALLOC_CTX
*mem_ctx
)
272 TALLOC_CTX
*mem_pool
;
273 struct smbd_smb2_request
*req
;
276 /* Enable this to find subtle valgrind errors. */
277 mem_pool
= talloc_init("smbd_smb2_request_allocate");
279 mem_pool
= talloc_tos();
281 if (mem_pool
== NULL
) {
285 req
= talloc_zero(mem_pool
, struct smbd_smb2_request
);
287 talloc_free(mem_pool
);
290 talloc_reparent(mem_pool
, mem_ctx
, req
);
292 TALLOC_FREE(mem_pool
);
295 req
->last_session_id
= UINT64_MAX
;
296 req
->last_tid
= UINT32_MAX
;
298 talloc_set_destructor(req
, smbd_smb2_request_destructor
);
303 static NTSTATUS
smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection
*xconn
,
307 struct smbd_smb2_request
*req
,
311 TALLOC_CTX
*mem_ctx
= req
;
315 uint8_t *first_hdr
= buf
;
316 size_t verified_buflen
= 0;
321 * Note: index '0' is reserved for the transport protocol
323 iov
= req
->in
._vector
;
325 while (taken
< buflen
) {
326 size_t len
= buflen
- taken
;
327 uint8_t *hdr
= first_hdr
+ taken
;
330 size_t next_command_ofs
;
332 uint8_t *body
= NULL
;
335 struct iovec
*iov_alloc
= NULL
;
337 if (iov
!= req
->in
._vector
) {
341 if (verified_buflen
> taken
) {
342 len
= verified_buflen
- taken
;
349 DEBUG(10, ("%d bytes left, expected at least %d\n",
353 if (IVAL(hdr
, 0) == SMB2_TF_MAGIC
) {
354 struct smbXsrv_session
*s
= NULL
;
356 struct iovec tf_iov
[2];
360 if (xconn
->protocol
< PROTOCOL_SMB2_24
) {
361 DEBUG(10, ("Got SMB2_TRANSFORM header, "
362 "but dialect[0x%04X] is used\n",
363 xconn
->smb2
.server
.dialect
));
367 if (xconn
->smb2
.server
.cipher
== 0) {
368 DEBUG(10, ("Got SMB2_TRANSFORM header, "
369 "but not negotiated "
370 "client[0x%08X] server[0x%08X]\n",
371 xconn
->smb2
.client
.capabilities
,
372 xconn
->smb2
.server
.capabilities
));
376 if (len
< SMB2_TF_HDR_SIZE
) {
377 DEBUG(1, ("%d bytes left, expected at least %d\n",
378 (int)len
, SMB2_TF_HDR_SIZE
));
382 tf_len
= SMB2_TF_HDR_SIZE
;
385 hdr
= first_hdr
+ taken
;
386 enc_len
= IVAL(tf
, SMB2_TF_MSG_SIZE
);
387 uid
= BVAL(tf
, SMB2_TF_SESSION_ID
);
389 if (len
< SMB2_TF_HDR_SIZE
+ enc_len
) {
390 DEBUG(1, ("%d bytes left, expected at least %d\n",
392 (int)(SMB2_TF_HDR_SIZE
+ enc_len
)));
396 status
= smb2srv_session_lookup(xconn
, uid
, now
, &s
);
398 DEBUG(1, ("invalid session[%llu] in "
399 "SMB2_TRANSFORM header\n",
400 (unsigned long long)uid
));
401 TALLOC_FREE(iov_alloc
);
402 return NT_STATUS_USER_SESSION_DELETED
;
405 tf_iov
[0].iov_base
= (void *)tf
;
406 tf_iov
[0].iov_len
= tf_len
;
407 tf_iov
[1].iov_base
= (void *)hdr
;
408 tf_iov
[1].iov_len
= enc_len
;
410 status
= smb2_signing_decrypt_pdu(s
->global
->decryption_key
,
411 xconn
->smb2
.server
.cipher
,
413 if (!NT_STATUS_IS_OK(status
)) {
414 TALLOC_FREE(iov_alloc
);
418 verified_buflen
= taken
+ enc_len
;
423 * We need the header plus the body length field
426 if (len
< SMB2_HDR_BODY
+ 2) {
427 DEBUG(10, ("%d bytes left, expected at least %d\n",
428 (int)len
, SMB2_HDR_BODY
));
431 if (IVAL(hdr
, 0) != SMB2_MAGIC
) {
432 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
436 if (SVAL(hdr
, 4) != SMB2_HDR_BODY
) {
437 DEBUG(10, ("Got HDR len %d, expected %d\n",
438 SVAL(hdr
, 4), SMB2_HDR_BODY
));
443 next_command_ofs
= IVAL(hdr
, SMB2_HDR_NEXT_COMMAND
);
444 body_size
= SVAL(hdr
, SMB2_HDR_BODY
);
446 if (next_command_ofs
!= 0) {
447 if (next_command_ofs
< (SMB2_HDR_BODY
+ 2)) {
450 if (next_command_ofs
> full_size
) {
453 full_size
= next_command_ofs
;
460 if (body_size
> (full_size
- SMB2_HDR_BODY
)) {
462 * let the caller handle the error
464 body_size
= full_size
- SMB2_HDR_BODY
;
466 body
= hdr
+ SMB2_HDR_BODY
;
467 dyn
= body
+ body_size
;
468 dyn_size
= full_size
- (SMB2_HDR_BODY
+ body_size
);
470 if (num_iov
>= ARRAY_SIZE(req
->in
._vector
)) {
471 struct iovec
*iov_tmp
= NULL
;
473 iov_tmp
= talloc_realloc(mem_ctx
, iov_alloc
,
476 SMBD_SMB2_NUM_IOV_PER_REQ
);
477 if (iov_tmp
== NULL
) {
478 TALLOC_FREE(iov_alloc
);
479 return NT_STATUS_NO_MEMORY
;
482 if (iov_alloc
== NULL
) {
485 sizeof(req
->in
._vector
));
491 num_iov
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
493 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
494 cur
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
495 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
496 cur
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
497 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
498 cur
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= body_size
;
499 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
500 cur
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= dyn_size
;
510 if (iov
!= req
->in
._vector
) {
513 return NT_STATUS_INVALID_PARAMETER
;
516 static NTSTATUS
smbd_smb2_request_create(struct smbXsrv_connection
*xconn
,
517 const uint8_t *_inpdu
, size_t size
,
518 struct smbd_smb2_request
**_req
)
520 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
521 struct smbd_smb2_request
*req
;
522 uint32_t protocol_version
;
523 uint8_t *inpdu
= NULL
;
524 const uint8_t *inhdr
= NULL
;
526 uint32_t next_command_ofs
;
530 if (size
< (SMB2_HDR_BODY
+ 2)) {
531 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size
));
532 return NT_STATUS_INVALID_PARAMETER
;
537 protocol_version
= IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
);
538 if (protocol_version
!= SMB2_MAGIC
) {
539 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
541 return NT_STATUS_INVALID_PARAMETER
;
544 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
545 if (cmd
!= SMB2_OP_NEGPROT
) {
546 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
548 return NT_STATUS_INVALID_PARAMETER
;
551 next_command_ofs
= IVAL(inhdr
, SMB2_HDR_NEXT_COMMAND
);
552 if (next_command_ofs
!= 0) {
553 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
555 return NT_STATUS_INVALID_PARAMETER
;
558 req
= smbd_smb2_request_allocate(xconn
);
560 return NT_STATUS_NO_MEMORY
;
565 inpdu
= talloc_memdup(req
, _inpdu
, size
);
567 return NT_STATUS_NO_MEMORY
;
570 req
->request_time
= timeval_current();
571 now
= timeval_to_nttime(&req
->request_time
);
573 status
= smbd_smb2_inbuf_parse_compound(xconn
,
577 req
, &req
->in
.vector
,
578 &req
->in
.vector_count
);
579 if (!NT_STATUS_IS_OK(status
)) {
584 req
->current_idx
= 1;
590 static bool smb2_validate_sequence_number(struct smbXsrv_connection
*xconn
,
591 uint64_t message_id
, uint64_t seq_id
)
593 struct bitmap
*credits_bm
= xconn
->smb2
.credits
.bitmap
;
597 seq_tmp
= xconn
->smb2
.credits
.seq_low
;
598 if (seq_id
< seq_tmp
) {
599 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
600 "%llu (sequence id %llu) "
601 "(granted = %u, low = %llu, range = %u)\n",
602 (unsigned long long)message_id
,
603 (unsigned long long)seq_id
,
604 (unsigned int)xconn
->smb2
.credits
.granted
,
605 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
606 (unsigned int)xconn
->smb2
.credits
.seq_range
));
610 seq_tmp
+= xconn
->smb2
.credits
.seq_range
;
611 if (seq_id
>= seq_tmp
) {
612 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
613 "%llu (sequence id %llu) "
614 "(granted = %u, low = %llu, range = %u)\n",
615 (unsigned long long)message_id
,
616 (unsigned long long)seq_id
,
617 (unsigned int)xconn
->smb2
.credits
.granted
,
618 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
619 (unsigned int)xconn
->smb2
.credits
.seq_range
));
623 offset
= seq_id
% xconn
->smb2
.credits
.max
;
625 if (bitmap_query(credits_bm
, offset
)) {
626 DEBUG(0,("smb2_validate_sequence_number: duplicate message_id "
627 "%llu (sequence id %llu) "
628 "(granted = %u, low = %llu, range = %u) "
630 (unsigned long long)message_id
,
631 (unsigned long long)seq_id
,
632 (unsigned int)xconn
->smb2
.credits
.granted
,
633 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
634 (unsigned int)xconn
->smb2
.credits
.seq_range
,
639 /* Mark the message_ids as seen in the bitmap. */
640 bitmap_set(credits_bm
, offset
);
642 if (seq_id
!= xconn
->smb2
.credits
.seq_low
) {
647 * Move the window forward by all the message_id's
650 while (bitmap_query(credits_bm
, offset
)) {
651 DEBUG(10,("smb2_validate_sequence_number: clearing "
652 "id %llu (position %u) from bitmap\n",
653 (unsigned long long)(xconn
->smb2
.credits
.seq_low
),
655 bitmap_clear(credits_bm
, offset
);
657 xconn
->smb2
.credits
.seq_low
+= 1;
658 xconn
->smb2
.credits
.seq_range
-= 1;
659 offset
= xconn
->smb2
.credits
.seq_low
% xconn
->smb2
.credits
.max
;
665 static bool smb2_validate_message_id(struct smbXsrv_connection
*xconn
,
666 const uint8_t *inhdr
)
668 uint64_t message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
669 uint16_t opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
670 uint16_t credit_charge
= 1;
673 if (opcode
== SMB2_OP_CANCEL
) {
674 /* SMB2_CANCEL requests by definition resend messageids. */
678 if (xconn
->smb2
.credits
.multicredit
) {
679 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
680 credit_charge
= MAX(credit_charge
, 1);
683 DEBUG(11, ("smb2_validate_message_id: mid %llu (charge %llu), "
684 "credits_granted %llu, "
685 "seqnum low/range: %llu/%llu\n",
686 (unsigned long long) message_id
,
687 (unsigned long long) credit_charge
,
688 (unsigned long long) xconn
->smb2
.credits
.granted
,
689 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
690 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
692 if (xconn
->smb2
.credits
.granted
< credit_charge
) {
693 DEBUG(0, ("smb2_validate_message_id: client used more "
694 "credits than granted, mid %llu, charge %llu, "
695 "credits_granted %llu, "
696 "seqnum low/range: %llu/%llu\n",
697 (unsigned long long) message_id
,
698 (unsigned long long) credit_charge
,
699 (unsigned long long) xconn
->smb2
.credits
.granted
,
700 (unsigned long long) xconn
->smb2
.credits
.seq_low
,
701 (unsigned long long) xconn
->smb2
.credits
.seq_range
));
706 * now check the message ids
708 * for multi-credit requests we need to check all current mid plus
709 * the implicit mids caused by the credit charge
710 * e.g. current mid = 15, charge 5 => mark 15-19 as used
713 for (i
= 0; i
<= (credit_charge
-1); i
++) {
714 uint64_t id
= message_id
+ i
;
717 DEBUG(11, ("Iterating mid %llu charge %u (sequence %llu)\n",
718 (unsigned long long)message_id
,
720 (unsigned long long)id
));
722 ok
= smb2_validate_sequence_number(xconn
, message_id
, id
);
728 /* substract used credits */
729 xconn
->smb2
.credits
.granted
-= credit_charge
;
734 static NTSTATUS
smbd_smb2_request_validate(struct smbd_smb2_request
*req
)
739 count
= req
->in
.vector_count
;
741 if (count
< 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
742 /* It's not a SMB2 request */
743 return NT_STATUS_INVALID_PARAMETER
;
746 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
747 struct iovec
*hdr
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
748 struct iovec
*body
= SMBD_SMB2_IDX_BODY_IOV(req
,in
,idx
);
749 const uint8_t *inhdr
= NULL
;
751 if (hdr
->iov_len
!= SMB2_HDR_BODY
) {
752 return NT_STATUS_INVALID_PARAMETER
;
755 if (body
->iov_len
< 2) {
756 return NT_STATUS_INVALID_PARAMETER
;
759 inhdr
= (const uint8_t *)hdr
->iov_base
;
761 /* Check the SMB2 header */
762 if (IVAL(inhdr
, SMB2_HDR_PROTOCOL_ID
) != SMB2_MAGIC
) {
763 return NT_STATUS_INVALID_PARAMETER
;
766 if (!smb2_validate_message_id(req
->xconn
, inhdr
)) {
767 return NT_STATUS_INVALID_PARAMETER
;
774 static void smb2_set_operation_credit(struct smbXsrv_connection
*xconn
,
775 const struct iovec
*in_vector
,
776 struct iovec
*out_vector
)
778 const uint8_t *inhdr
= (const uint8_t *)in_vector
->iov_base
;
779 uint8_t *outhdr
= (uint8_t *)out_vector
->iov_base
;
780 uint16_t credit_charge
= 1;
781 uint16_t credits_requested
;
785 uint16_t credits_granted
= 0;
786 uint64_t credits_possible
;
787 uint16_t current_max_credits
;
790 * first we grant only 1/16th of the max range.
792 * Windows also starts with the 1/16th and then grants
793 * more later. I was only able to trigger higher
794 * values, when using a very high credit charge.
796 * TODO: scale up depending on load, free memory
798 * Maybe also on the relationship between number
799 * of requests and the used sequence number.
800 * Which means we would grant more credits
801 * for client which use multi credit requests.
803 current_max_credits
= xconn
->smb2
.credits
.max
/ 16;
804 current_max_credits
= MAX(current_max_credits
, 1);
806 if (xconn
->smb2
.credits
.multicredit
) {
807 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
808 credit_charge
= MAX(credit_charge
, 1);
811 cmd
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
812 credits_requested
= SVAL(inhdr
, SMB2_HDR_CREDIT
);
813 credits_requested
= MAX(credits_requested
, 1);
814 out_flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
815 out_status
= NT_STATUS(IVAL(outhdr
, SMB2_HDR_STATUS
));
817 SMB_ASSERT(xconn
->smb2
.credits
.max
>= xconn
->smb2
.credits
.granted
);
819 if (xconn
->smb2
.credits
.max
< credit_charge
) {
820 smbd_server_connection_terminate(xconn
,
821 "client error: credit charge > max credits\n");
825 if (out_flags
& SMB2_HDR_FLAG_ASYNC
) {
827 * In case we already send an async interim
828 * response, we should not grant
829 * credits on the final response.
833 uint16_t additional_possible
=
834 xconn
->smb2
.credits
.max
- credit_charge
;
835 uint16_t additional_max
= 0;
836 uint16_t additional_credits
= credits_requested
- 1;
839 case SMB2_OP_NEGPROT
:
841 case SMB2_OP_SESSSETUP
:
843 * Windows 2012 RC1 starts to grant
845 * with a successful session setup
847 if (NT_STATUS_IS_OK(out_status
)) {
853 * We match windows and only grant additional credits
860 additional_max
= MIN(additional_max
, additional_possible
);
861 additional_credits
= MIN(additional_credits
, additional_max
);
863 credits_granted
= credit_charge
+ additional_credits
;
867 * sequence numbers should not wrap
869 * 1. calculate the possible credits until
870 * the sequence numbers start to wrap on 64-bit.
872 * 2. UINT64_MAX is used for Break Notifications.
874 * 2. truncate the possible credits to the maximum
875 * credits we want to grant to the client in total.
877 * 3. remove the range we'll already granted to the client
878 * this makes sure the client consumes the lowest sequence
879 * number, before we can grant additional credits.
881 credits_possible
= UINT64_MAX
- xconn
->smb2
.credits
.seq_low
;
882 if (credits_possible
> 0) {
883 /* remove UINT64_MAX */
884 credits_possible
-= 1;
886 credits_possible
= MIN(credits_possible
, current_max_credits
);
887 credits_possible
-= xconn
->smb2
.credits
.seq_range
;
889 credits_granted
= MIN(credits_granted
, credits_possible
);
891 SSVAL(outhdr
, SMB2_HDR_CREDIT
, credits_granted
);
892 xconn
->smb2
.credits
.granted
+= credits_granted
;
893 xconn
->smb2
.credits
.seq_range
+= credits_granted
;
895 DEBUG(10,("smb2_set_operation_credit: requested %u, charge %u, "
896 "granted %u, current possible/max %u/%u, "
897 "total granted/max/low/range %u/%u/%llu/%u\n",
898 (unsigned int)credits_requested
,
899 (unsigned int)credit_charge
,
900 (unsigned int)credits_granted
,
901 (unsigned int)credits_possible
,
902 (unsigned int)current_max_credits
,
903 (unsigned int)xconn
->smb2
.credits
.granted
,
904 (unsigned int)xconn
->smb2
.credits
.max
,
905 (unsigned long long)xconn
->smb2
.credits
.seq_low
,
906 (unsigned int)xconn
->smb2
.credits
.seq_range
));
909 static void smb2_calculate_credits(const struct smbd_smb2_request
*inreq
,
910 struct smbd_smb2_request
*outreq
)
913 uint16_t total_credits
= 0;
915 count
= outreq
->out
.vector_count
;
917 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
918 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(inreq
,in
,idx
);
919 struct iovec
*outhdr_v
= SMBD_SMB2_IDX_HDR_IOV(outreq
,out
,idx
);
920 uint8_t *outhdr
= (uint8_t *)outhdr_v
->iov_base
;
922 smb2_set_operation_credit(outreq
->xconn
, inhdr_v
, outhdr_v
);
924 /* To match Windows, count up what we
926 total_credits
+= SVAL(outhdr
, SMB2_HDR_CREDIT
);
927 /* Set to zero in all but the last reply. */
928 if (idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
< count
) {
929 SSVAL(outhdr
, SMB2_HDR_CREDIT
, 0);
931 SSVAL(outhdr
, SMB2_HDR_CREDIT
, total_credits
);
936 DATA_BLOB
smbd_smb2_generate_outbody(struct smbd_smb2_request
*req
, size_t size
)
938 if (req
->current_idx
<= 1) {
939 if (size
<= sizeof(req
->out
._body
)) {
940 return data_blob_const(req
->out
._body
, size
);
944 return data_blob_talloc(req
, NULL
, size
);
947 static NTSTATUS
smbd_smb2_request_setup_out(struct smbd_smb2_request
*req
)
949 struct smbXsrv_connection
*xconn
= req
->xconn
;
951 struct iovec
*vector
;
956 count
= req
->in
.vector_count
;
957 if (count
<= ARRAY_SIZE(req
->out
._vector
)) {
959 vector
= req
->out
._vector
;
961 vector
= talloc_zero_array(req
, struct iovec
, count
);
962 if (vector
== NULL
) {
963 return NT_STATUS_NO_MEMORY
;
968 vector
[0].iov_base
= req
->out
.nbt_hdr
;
969 vector
[0].iov_len
= 4;
970 SIVAL(req
->out
.nbt_hdr
, 0, 0);
972 for (idx
=1; idx
< count
; idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
973 struct iovec
*inhdr_v
= SMBD_SMB2_IDX_HDR_IOV(req
,in
,idx
);
974 const uint8_t *inhdr
= (const uint8_t *)inhdr_v
->iov_base
;
975 uint8_t *outhdr
= NULL
;
976 uint8_t *outbody
= NULL
;
977 uint32_t next_command_ofs
= 0;
978 struct iovec
*current
= &vector
[idx
];
980 if ((idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) < count
) {
981 /* we have a next command -
982 * setup for the error case. */
983 next_command_ofs
= SMB2_HDR_BODY
+ 9;
987 outhdr
= req
->out
._hdr
;
989 outhdr
= talloc_zero_array(mem_ctx
, uint8_t,
991 if (outhdr
== NULL
) {
992 return NT_STATUS_NO_MEMORY
;
996 outbody
= outhdr
+ SMB2_HDR_BODY
;
999 * SMBD_SMB2_TF_IOV_OFS might be used later
1001 current
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1002 current
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1004 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)outhdr
;
1005 current
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1007 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)outbody
;
1008 current
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1010 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= NULL
;
1011 current
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 0;
1013 /* setup the SMB2 header */
1014 SIVAL(outhdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1015 SSVAL(outhdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1016 SSVAL(outhdr
, SMB2_HDR_CREDIT_CHARGE
,
1017 SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
));
1018 SIVAL(outhdr
, SMB2_HDR_STATUS
,
1019 NT_STATUS_V(NT_STATUS_INTERNAL_ERROR
));
1020 SSVAL(outhdr
, SMB2_HDR_OPCODE
,
1021 SVAL(inhdr
, SMB2_HDR_OPCODE
));
1022 SIVAL(outhdr
, SMB2_HDR_FLAGS
,
1023 IVAL(inhdr
, SMB2_HDR_FLAGS
) | SMB2_HDR_FLAG_REDIRECT
);
1024 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
1025 SBVAL(outhdr
, SMB2_HDR_MESSAGE_ID
,
1026 BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
));
1027 SIVAL(outhdr
, SMB2_HDR_PID
,
1028 IVAL(inhdr
, SMB2_HDR_PID
));
1029 SIVAL(outhdr
, SMB2_HDR_TID
,
1030 IVAL(inhdr
, SMB2_HDR_TID
));
1031 SBVAL(outhdr
, SMB2_HDR_SESSION_ID
,
1032 BVAL(inhdr
, SMB2_HDR_SESSION_ID
));
1033 memcpy(outhdr
+ SMB2_HDR_SIGNATURE
,
1034 inhdr
+ SMB2_HDR_SIGNATURE
, 16);
1036 /* setup error body header */
1037 SSVAL(outbody
, 0x00, 0x08 + 1);
1038 SSVAL(outbody
, 0x02, 0);
1039 SIVAL(outbody
, 0x04, 0);
1042 req
->out
.vector
= vector
;
1043 req
->out
.vector_count
= count
;
1045 /* setup the length of the NBT packet */
1046 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
1048 return NT_STATUS_INVALID_PARAMETER_MIX
;
1051 DLIST_ADD_END(xconn
->smb2
.requests
, req
, struct smbd_smb2_request
*);
1053 return NT_STATUS_OK
;
1056 void smbd_server_connection_terminate_ex(struct smbXsrv_connection
*xconn
,
1058 const char *location
)
1060 DEBUG(10,("smbd_server_connection_terminate_ex: reason[%s] at %s\n",
1062 exit_server_cleanly(reason
);
1065 static bool dup_smb2_vec4(TALLOC_CTX
*ctx
,
1066 struct iovec
*outvec
,
1067 const struct iovec
*srcvec
)
1069 const uint8_t *srctf
;
1071 const uint8_t *srchdr
;
1073 const uint8_t *srcbody
;
1075 const uint8_t *expected_srcbody
;
1076 const uint8_t *srcdyn
;
1078 const uint8_t *expected_srcdyn
;
1084 srctf
= (const uint8_t *)srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
;
1085 srctf_len
= srcvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
;
1086 srchdr
= (const uint8_t *)srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
;
1087 srchdr_len
= srcvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
;
1088 srcbody
= (const uint8_t *)srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
;
1089 srcbody_len
= srcvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
;
1090 expected_srcbody
= srchdr
+ SMB2_HDR_BODY
;
1091 srcdyn
= (const uint8_t *)srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
;
1092 srcdyn_len
= srcvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
;
1093 expected_srcdyn
= srcbody
+ 8;
1095 if ((srctf_len
!= SMB2_TF_HDR_SIZE
) && (srctf_len
!= 0)) {
1099 if (srchdr_len
!= SMB2_HDR_BODY
) {
1103 if (srctf_len
== SMB2_TF_HDR_SIZE
) {
1104 dsttf
= talloc_memdup(ctx
, srctf
, SMB2_TF_HDR_SIZE
);
1105 if (dsttf
== NULL
) {
1111 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_base
= (void *)dsttf
;
1112 outvec
[SMBD_SMB2_TF_IOV_OFS
].iov_len
= srctf_len
;
1114 /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1115 * be allocated with size OUTVEC_ALLOC_SIZE. */
1117 dsthdr
= talloc_memdup(ctx
, srchdr
, OUTVEC_ALLOC_SIZE
);
1118 if (dsthdr
== NULL
) {
1121 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_base
= (void *)dsthdr
;
1122 outvec
[SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1125 * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1126 * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1127 * then duplicate this. Else use talloc_memdup().
1130 if ((srcbody
== expected_srcbody
) && (srcbody_len
== 8)) {
1131 dstbody
= dsthdr
+ SMB2_HDR_BODY
;
1133 dstbody
= talloc_memdup(ctx
, srcbody
, srcbody_len
);
1134 if (dstbody
== NULL
) {
1138 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_base
= (void *)dstbody
;
1139 outvec
[SMBD_SMB2_BODY_IOV_OFS
].iov_len
= srcbody_len
;
1142 * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1144 * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1145 * then duplicate this. Else use talloc_memdup().
1148 if ((srcdyn
== expected_srcdyn
) && (srcdyn_len
== 1)) {
1149 dstdyn
= dsthdr
+ SMB2_HDR_BODY
+ 8;
1150 } else if (srcdyn
== NULL
) {
1153 dstdyn
= talloc_memdup(ctx
, srcdyn
, srcdyn_len
);
1154 if (dstdyn
== NULL
) {
1158 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_base
= (void *)dstdyn
;
1159 outvec
[SMBD_SMB2_DYN_IOV_OFS
].iov_len
= srcdyn_len
;
1164 static struct smbd_smb2_request
*dup_smb2_req(const struct smbd_smb2_request
*req
)
1166 struct smbd_smb2_request
*newreq
= NULL
;
1167 struct iovec
*outvec
= NULL
;
1168 int count
= req
->out
.vector_count
;
1172 newreq
= smbd_smb2_request_allocate(req
->xconn
);
1177 newreq
->sconn
= req
->sconn
;
1178 newreq
->xconn
= req
->xconn
;
1179 newreq
->session
= req
->session
;
1180 newreq
->do_encryption
= req
->do_encryption
;
1181 newreq
->do_signing
= req
->do_signing
;
1182 newreq
->current_idx
= req
->current_idx
;
1184 outvec
= talloc_zero_array(newreq
, struct iovec
, count
);
1186 TALLOC_FREE(newreq
);
1189 newreq
->out
.vector
= outvec
;
1190 newreq
->out
.vector_count
= count
;
1192 /* Setup the outvec's identically to req. */
1193 outvec
[0].iov_base
= newreq
->out
.nbt_hdr
;
1194 outvec
[0].iov_len
= 4;
1195 memcpy(newreq
->out
.nbt_hdr
, req
->out
.nbt_hdr
, 4);
1197 /* Setup the vectors identically to the ones in req. */
1198 for (i
= 1; i
< count
; i
+= SMBD_SMB2_NUM_IOV_PER_REQ
) {
1199 if (!dup_smb2_vec4(outvec
, &outvec
[i
], &req
->out
.vector
[i
])) {
1206 TALLOC_FREE(newreq
);
1210 ok
= smb2_setup_nbt_length(newreq
->out
.vector
,
1211 newreq
->out
.vector_count
);
1213 TALLOC_FREE(newreq
);
1220 static NTSTATUS
smb2_send_async_interim_response(const struct smbd_smb2_request
*req
)
1222 struct smbXsrv_connection
*xconn
= req
->xconn
;
1224 struct iovec
*firsttf
= NULL
;
1225 struct iovec
*outhdr_v
= NULL
;
1226 uint8_t *outhdr
= NULL
;
1227 struct smbd_smb2_request
*nreq
= NULL
;
1231 /* Create a new smb2 request we'll use
1232 for the interim return. */
1233 nreq
= dup_smb2_req(req
);
1235 return NT_STATUS_NO_MEMORY
;
1238 /* Lose the last X out vectors. They're the
1239 ones we'll be using for the async reply. */
1240 nreq
->out
.vector_count
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1242 ok
= smb2_setup_nbt_length(nreq
->out
.vector
,
1243 nreq
->out
.vector_count
);
1245 return NT_STATUS_INVALID_PARAMETER_MIX
;
1248 /* Step back to the previous reply. */
1249 nreq
->current_idx
-= SMBD_SMB2_NUM_IOV_PER_REQ
;
1250 firsttf
= SMBD_SMB2_IDX_TF_IOV(nreq
,out
,first_idx
);
1251 outhdr_v
= SMBD_SMB2_OUT_HDR_IOV(nreq
);
1252 outhdr
= SMBD_SMB2_OUT_HDR_PTR(nreq
);
1253 /* And end the chain. */
1254 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
1256 /* Calculate outgoing credits */
1257 smb2_calculate_credits(req
, nreq
);
1259 if (DEBUGLEVEL
>= 10) {
1260 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1261 (unsigned int)nreq
->current_idx
);
1262 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1263 (unsigned int)nreq
->out
.vector_count
);
1264 print_req_vectors(nreq
);
1268 * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1269 * we need to sign/encrypt here with the last/first key we remembered
1271 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
1272 status
= smb2_signing_encrypt_pdu(req
->first_key
,
1273 xconn
->smb2
.server
.cipher
,
1275 nreq
->out
.vector_count
- first_idx
);
1276 if (!NT_STATUS_IS_OK(status
)) {
1279 } else if (req
->last_key
.length
> 0) {
1280 status
= smb2_signing_sign_pdu(req
->last_key
,
1283 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
1284 if (!NT_STATUS_IS_OK(status
)) {
1289 nreq
->queue_entry
.mem_ctx
= nreq
;
1290 nreq
->queue_entry
.vector
= nreq
->out
.vector
;
1291 nreq
->queue_entry
.count
= nreq
->out
.vector_count
;
1292 DLIST_ADD_END(xconn
->smb2
.send_queue
, &nreq
->queue_entry
, NULL
);
1293 xconn
->smb2
.send_queue_len
++;
1295 status
= smbd_smb2_flush_send_queue(xconn
);
1296 if (!NT_STATUS_IS_OK(status
)) {
1300 return NT_STATUS_OK
;
1303 struct smbd_smb2_request_pending_state
{
1304 struct smbd_smb2_send_queue queue_entry
;
1305 uint8_t buf
[NBT_HDR_SIZE
+ SMB2_TF_HDR_SIZE
+ SMB2_HDR_BODY
+ 0x08 + 1];
1306 struct iovec vector
[1 + SMBD_SMB2_NUM_IOV_PER_REQ
];
1309 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
1310 struct tevent_timer
*te
,
1311 struct timeval current_time
,
1312 void *private_data
);
1314 NTSTATUS
smbd_smb2_request_pending_queue(struct smbd_smb2_request
*req
,
1315 struct tevent_req
*subreq
,
1316 uint32_t defer_time
)
1319 struct timeval defer_endtime
;
1320 uint8_t *outhdr
= NULL
;
1323 if (!tevent_req_is_in_progress(subreq
)) {
1325 * This is a performance optimization,
1326 * it avoids one tevent_loop iteration,
1327 * which means we avoid one
1328 * talloc_stackframe_pool/talloc_free pair.
1330 tevent_req_notify_callback(subreq
);
1331 return NT_STATUS_OK
;
1334 req
->subreq
= subreq
;
1337 if (req
->async_te
) {
1338 /* We're already async. */
1339 return NT_STATUS_OK
;
1342 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1343 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
1344 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
1345 /* We're already async. */
1346 return NT_STATUS_OK
;
1349 if (req
->in
.vector_count
> req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) {
1351 * We're trying to go async in a compound request
1352 * chain. This is only allowed for opens that cause an
1353 * oplock break or for the last operation in the
1354 * chain, otherwise it is not allowed. See
1355 * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
1357 const uint8_t *inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1359 if (SVAL(inhdr
, SMB2_HDR_OPCODE
) != SMB2_OP_CREATE
) {
1361 * Cancel the outstanding request.
1363 bool ok
= tevent_req_cancel(req
->subreq
);
1365 return NT_STATUS_OK
;
1367 TALLOC_FREE(req
->subreq
);
1368 return smbd_smb2_request_error(req
,
1369 NT_STATUS_INTERNAL_ERROR
);
1373 if (DEBUGLEVEL
>= 10) {
1374 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1375 (unsigned int)req
->current_idx
);
1376 print_req_vectors(req
);
1379 if (req
->current_idx
> 1) {
1381 * We're going async in a compound
1382 * chain after the first request has
1383 * already been processed. Send an
1384 * interim response containing the
1385 * set of replies already generated.
1387 int idx
= req
->current_idx
;
1389 status
= smb2_send_async_interim_response(req
);
1390 if (!NT_STATUS_IS_OK(status
)) {
1393 if (req
->first_key
.length
> 0) {
1394 data_blob_clear_free(&req
->first_key
);
1397 req
->current_idx
= 1;
1400 * Re-arrange the in.vectors to remove what
1403 memmove(&req
->in
.vector
[1],
1404 &req
->in
.vector
[idx
],
1405 sizeof(req
->in
.vector
[0])*(req
->in
.vector_count
- idx
));
1406 req
->in
.vector_count
= 1 + (req
->in
.vector_count
- idx
);
1408 /* Re-arrange the out.vectors to match. */
1409 memmove(&req
->out
.vector
[1],
1410 &req
->out
.vector
[idx
],
1411 sizeof(req
->out
.vector
[0])*(req
->out
.vector_count
- idx
));
1412 req
->out
.vector_count
= 1 + (req
->out
.vector_count
- idx
);
1414 if (req
->in
.vector_count
== 1 + SMBD_SMB2_NUM_IOV_PER_REQ
) {
1416 * We only have one remaining request as
1417 * we've processed everything else.
1418 * This is no longer a compound request.
1420 req
->compound_related
= false;
1421 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1422 flags
= (IVAL(outhdr
, SMB2_HDR_FLAGS
) & ~SMB2_HDR_FLAG_CHAINED
);
1423 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
);
1426 if (req
->last_key
.length
> 0) {
1427 data_blob_clear_free(&req
->last_key
);
1430 defer_endtime
= timeval_current_ofs_usec(defer_time
);
1431 req
->async_te
= tevent_add_timer(req
->sconn
->ev_ctx
,
1433 smbd_smb2_request_pending_timer
,
1435 if (req
->async_te
== NULL
) {
1436 return NT_STATUS_NO_MEMORY
;
1439 return NT_STATUS_OK
;
1442 static DATA_BLOB
smbd_smb2_signing_key(struct smbXsrv_session
*session
,
1443 struct smbXsrv_connection
*xconn
)
1445 struct smbXsrv_channel_global0
*c
= NULL
;
1447 DATA_BLOB key
= data_blob_null
;
1449 status
= smbXsrv_session_find_channel(session
, xconn
, &c
);
1450 if (NT_STATUS_IS_OK(status
)) {
1451 key
= c
->signing_key
;
1454 if (key
.length
== 0) {
1455 key
= session
->global
->signing_key
;
1461 static NTSTATUS
smb2_get_new_nonce(struct smbXsrv_session
*session
,
1462 uint64_t *new_nonce_high
,
1463 uint64_t *new_nonce_low
)
1465 uint64_t nonce_high
;
1468 session
->nonce_low
+= 1;
1469 if (session
->nonce_low
== 0) {
1470 session
->nonce_low
+= 1;
1471 session
->nonce_high
+= 1;
1475 * CCM and GCM algorithms must never have their
1476 * nonce wrap, or the security of the whole
1477 * communication and the keys is destroyed.
1478 * We must drop the connection once we have
1479 * transfered too much data.
1481 * NOTE: We assume nonces greater than 8 bytes.
1483 if (session
->nonce_high
>= session
->nonce_high_max
) {
1484 return NT_STATUS_ENCRYPTION_FAILED
;
1487 nonce_high
= session
->nonce_high_random
;
1488 nonce_high
+= session
->nonce_high
;
1489 nonce_low
= session
->nonce_low
;
1491 *new_nonce_high
= nonce_high
;
1492 *new_nonce_low
= nonce_low
;
1493 return NT_STATUS_OK
;
1496 static void smbd_smb2_request_pending_timer(struct tevent_context
*ev
,
1497 struct tevent_timer
*te
,
1498 struct timeval current_time
,
1501 struct smbd_smb2_request
*req
=
1502 talloc_get_type_abort(private_data
,
1503 struct smbd_smb2_request
);
1504 struct smbXsrv_connection
*xconn
= req
->xconn
;
1505 struct smbd_smb2_request_pending_state
*state
= NULL
;
1506 uint8_t *outhdr
= NULL
;
1507 const uint8_t *inhdr
= NULL
;
1510 uint8_t *hdr
= NULL
;
1511 uint8_t *body
= NULL
;
1512 uint8_t *dyn
= NULL
;
1514 uint64_t session_id
= 0;
1515 uint64_t message_id
= 0;
1516 uint64_t nonce_high
= 0;
1517 uint64_t nonce_low
= 0;
1518 uint64_t async_id
= 0;
1522 TALLOC_FREE(req
->async_te
);
1524 /* Ensure our final reply matches the interim one. */
1525 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1526 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
1527 flags
= IVAL(outhdr
, SMB2_HDR_FLAGS
);
1528 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
1529 session_id
= BVAL(outhdr
, SMB2_HDR_SESSION_ID
);
1531 async_id
= message_id
; /* keep it simple for now... */
1533 SIVAL(outhdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
1534 SBVAL(outhdr
, SMB2_HDR_ASYNC_ID
, async_id
);
1536 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1538 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
1539 (unsigned long long)async_id
));
1542 * What we send is identical to a smbd_smb2_request_error
1543 * packet with an error status of STATUS_PENDING. Make use
1544 * of this fact sometime when refactoring. JRA.
1547 state
= talloc_zero(req
->xconn
, struct smbd_smb2_request_pending_state
);
1548 if (state
== NULL
) {
1549 smbd_server_connection_terminate(xconn
,
1550 nt_errstr(NT_STATUS_NO_MEMORY
));
1554 tf
= state
->buf
+ NBT_HDR_SIZE
;
1555 tf_len
= SMB2_TF_HDR_SIZE
;
1557 hdr
= tf
+ SMB2_TF_HDR_SIZE
;
1558 body
= hdr
+ SMB2_HDR_BODY
;
1561 if (req
->do_encryption
) {
1562 status
= smb2_get_new_nonce(req
->session
,
1565 if (!NT_STATUS_IS_OK(status
)) {
1566 smbd_server_connection_terminate(xconn
,
1572 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
1573 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
1574 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
1575 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
1577 SIVAL(hdr
, SMB2_HDR_PROTOCOL_ID
, SMB2_MAGIC
);
1578 SSVAL(hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
1579 SSVAL(hdr
, SMB2_HDR_EPOCH
, 0);
1580 SIVAL(hdr
, SMB2_HDR_STATUS
, NT_STATUS_V(STATUS_PENDING
));
1581 SSVAL(hdr
, SMB2_HDR_OPCODE
, SVAL(outhdr
, SMB2_HDR_OPCODE
));
1583 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
);
1584 SIVAL(hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
1585 SBVAL(hdr
, SMB2_HDR_MESSAGE_ID
, message_id
);
1586 SBVAL(hdr
, SMB2_HDR_PID
, async_id
);
1587 SBVAL(hdr
, SMB2_HDR_SESSION_ID
,
1588 BVAL(outhdr
, SMB2_HDR_SESSION_ID
));
1589 memcpy(hdr
+SMB2_HDR_SIGNATURE
,
1590 outhdr
+SMB2_HDR_SIGNATURE
, 16);
1592 SSVAL(body
, 0x00, 0x08 + 1);
1594 SCVAL(body
, 0x02, 0);
1595 SCVAL(body
, 0x03, 0);
1596 SIVAL(body
, 0x04, 0);
1597 /* Match W2K8R2... */
1598 SCVAL(dyn
, 0x00, 0x21);
1600 state
->vector
[0].iov_base
= (void *)state
->buf
;
1601 state
->vector
[0].iov_len
= NBT_HDR_SIZE
;
1603 if (req
->do_encryption
) {
1604 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= tf
;
1605 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= tf_len
;
1607 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_base
= NULL
;
1608 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
].iov_len
= 0;
1611 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_base
= hdr
;
1612 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
].iov_len
= SMB2_HDR_BODY
;
1614 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_base
= body
;
1615 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
].iov_len
= 8;
1617 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_base
= dyn
;
1618 state
->vector
[1+SMBD_SMB2_DYN_IOV_OFS
].iov_len
= 1;
1620 ok
= smb2_setup_nbt_length(state
->vector
,
1621 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
1623 smbd_server_connection_terminate(
1624 xconn
, nt_errstr(NT_STATUS_INTERNAL_ERROR
));
1628 /* Ensure we correctly go through crediting. Grant
1629 the credits now, and zero credits on the final
1631 smb2_set_operation_credit(req
->xconn
,
1632 SMBD_SMB2_IN_HDR_IOV(req
),
1633 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
]);
1635 SIVAL(hdr
, SMB2_HDR_FLAGS
, flags
| SMB2_HDR_FLAG_ASYNC
);
1640 for (i
= 0; i
< ARRAY_SIZE(state
->vector
); i
++) {
1641 dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1643 (unsigned int)ARRAY_SIZE(state
->vector
),
1644 (unsigned int)state
->vector
[i
].iov_len
);
1648 if (req
->do_encryption
) {
1649 struct smbXsrv_session
*x
= req
->session
;
1650 DATA_BLOB encryption_key
= x
->global
->encryption_key
;
1652 status
= smb2_signing_encrypt_pdu(encryption_key
,
1653 xconn
->smb2
.server
.cipher
,
1654 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
1655 SMBD_SMB2_NUM_IOV_PER_REQ
);
1656 if (!NT_STATUS_IS_OK(status
)) {
1657 smbd_server_connection_terminate(xconn
,
1661 } else if (req
->do_signing
) {
1662 struct smbXsrv_session
*x
= req
->session
;
1663 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
1665 status
= smb2_signing_sign_pdu(signing_key
,
1667 &state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
],
1668 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
1669 if (!NT_STATUS_IS_OK(status
)) {
1670 smbd_server_connection_terminate(xconn
,
1676 state
->queue_entry
.mem_ctx
= state
;
1677 state
->queue_entry
.vector
= state
->vector
;
1678 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
1679 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
, NULL
);
1680 xconn
->smb2
.send_queue_len
++;
1682 status
= smbd_smb2_flush_send_queue(xconn
);
1683 if (!NT_STATUS_IS_OK(status
)) {
1684 smbd_server_connection_terminate(xconn
,
1690 static NTSTATUS
smbd_smb2_request_process_cancel(struct smbd_smb2_request
*req
)
1692 struct smbXsrv_connection
*xconn
= req
->xconn
;
1693 struct smbd_smb2_request
*cur
;
1694 const uint8_t *inhdr
;
1696 uint64_t search_message_id
;
1697 uint64_t search_async_id
;
1700 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1702 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1703 search_message_id
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
1704 search_async_id
= BVAL(inhdr
, SMB2_HDR_PID
);
1707 * we don't need the request anymore
1708 * cancel requests never have a response
1710 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
1713 for (cur
= xconn
->smb2
.requests
; cur
; cur
= cur
->next
) {
1714 const uint8_t *outhdr
;
1715 uint64_t message_id
;
1718 if (cur
->compound_related
) {
1720 * Never cancel anything in a compound request.
1721 * Way too hard to deal with the result.
1726 outhdr
= SMBD_SMB2_OUT_HDR_PTR(cur
);
1728 message_id
= BVAL(outhdr
, SMB2_HDR_MESSAGE_ID
);
1729 async_id
= BVAL(outhdr
, SMB2_HDR_PID
);
1731 if (flags
& SMB2_HDR_FLAG_ASYNC
) {
1732 if (search_async_id
== async_id
) {
1733 found_id
= async_id
;
1737 if (search_message_id
== message_id
) {
1738 found_id
= message_id
;
1744 if (cur
&& cur
->subreq
) {
1745 inhdr
= SMBD_SMB2_IN_HDR_PTR(cur
);
1746 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1747 "cancel opcode[%s] mid %llu\n",
1748 smb2_opcode_name(SVAL(inhdr
, SMB2_HDR_OPCODE
)),
1749 (unsigned long long)found_id
));
1750 tevent_req_cancel(cur
->subreq
);
1753 return NT_STATUS_OK
;
1756 /*************************************************************
1757 Ensure an incoming tid is a valid one for us to access.
1758 Change to the associated uid credentials and chdir to the
1759 valid tid directory.
1760 *************************************************************/
1762 static NTSTATUS
smbd_smb2_request_check_tcon(struct smbd_smb2_request
*req
)
1764 const uint8_t *inhdr
;
1767 struct smbXsrv_tcon
*tcon
;
1769 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1773 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1775 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1776 in_tid
= IVAL(inhdr
, SMB2_HDR_TID
);
1778 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
1779 in_tid
= req
->last_tid
;
1784 status
= smb2srv_tcon_lookup(req
->session
,
1785 in_tid
, now
, &tcon
);
1786 if (!NT_STATUS_IS_OK(status
)) {
1790 if (!change_to_user(tcon
->compat
, req
->session
->compat
->vuid
)) {
1791 return NT_STATUS_ACCESS_DENIED
;
1794 /* should we pass FLAG_CASELESS_PATHNAMES here? */
1795 if (!set_current_service(tcon
->compat
, 0, true)) {
1796 return NT_STATUS_ACCESS_DENIED
;
1800 req
->last_tid
= in_tid
;
1802 return NT_STATUS_OK
;
1805 /*************************************************************
1806 Ensure an incoming session_id is a valid one for us to access.
1807 *************************************************************/
1809 static NTSTATUS
smbd_smb2_request_check_session(struct smbd_smb2_request
*req
)
1811 const uint8_t *inhdr
;
1814 uint64_t in_session_id
;
1815 struct smbXsrv_session
*session
= NULL
;
1816 struct auth_session_info
*session_info
;
1818 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1820 req
->session
= NULL
;
1823 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1825 in_flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
1826 in_opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
1827 in_session_id
= BVAL(inhdr
, SMB2_HDR_SESSION_ID
);
1829 if (in_flags
& SMB2_HDR_FLAG_CHAINED
) {
1830 in_session_id
= req
->last_session_id
;
1833 req
->last_session_id
= 0;
1835 /* lookup an existing session */
1836 status
= smb2srv_session_lookup(req
->xconn
,
1840 req
->session
= session
;
1841 req
->last_session_id
= in_session_id
;
1843 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1844 switch (in_opcode
) {
1845 case SMB2_OP_SESSSETUP
:
1846 status
= NT_STATUS_OK
;
1852 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1853 switch (in_opcode
) {
1855 case SMB2_OP_CREATE
:
1856 case SMB2_OP_GETINFO
:
1857 case SMB2_OP_SETINFO
:
1858 return NT_STATUS_INVALID_HANDLE
;
1861 * Notice the check for
1862 * (session_info == NULL)
1865 status
= NT_STATUS_OK
;
1869 if (!NT_STATUS_IS_OK(status
)) {
1873 session_info
= session
->global
->auth_session_info
;
1874 if (session_info
== NULL
) {
1875 return NT_STATUS_INVALID_HANDLE
;
1878 if (in_session_id
!= req
->xconn
->client
->last_session_id
) {
1879 req
->xconn
->client
->last_session_id
= in_session_id
;
1880 set_current_user_info(session_info
->unix_info
->sanitized_username
,
1881 session_info
->unix_info
->unix_name
,
1882 session_info
->info
->domain_name
);
1885 return NT_STATUS_OK
;
1888 NTSTATUS
smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request
*req
,
1889 uint32_t data_length
)
1891 struct smbXsrv_connection
*xconn
= req
->xconn
;
1892 uint16_t needed_charge
;
1893 uint16_t credit_charge
= 1;
1894 const uint8_t *inhdr
;
1896 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1898 if (xconn
->smb2
.credits
.multicredit
) {
1899 credit_charge
= SVAL(inhdr
, SMB2_HDR_CREDIT_CHARGE
);
1900 credit_charge
= MAX(credit_charge
, 1);
1903 needed_charge
= (data_length
- 1)/ 65536 + 1;
1905 DEBUG(10, ("mid %llu, CreditCharge: %d, NeededCharge: %d\n",
1906 (unsigned long long) BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
),
1907 credit_charge
, needed_charge
));
1909 if (needed_charge
> credit_charge
) {
1910 DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
1911 credit_charge
, needed_charge
));
1912 return NT_STATUS_INVALID_PARAMETER
;
1915 return NT_STATUS_OK
;
1918 NTSTATUS
smbd_smb2_request_verify_sizes(struct smbd_smb2_request
*req
,
1919 size_t expected_body_size
)
1921 struct iovec
*inhdr_v
;
1922 const uint8_t *inhdr
;
1924 const uint8_t *inbody
;
1926 size_t min_dyn_size
= expected_body_size
& 0x00000001;
1927 int max_idx
= req
->in
.vector_count
- SMBD_SMB2_NUM_IOV_PER_REQ
;
1930 * The following should be checked already.
1932 if (req
->in
.vector_count
< SMBD_SMB2_NUM_IOV_PER_REQ
) {
1933 return NT_STATUS_INTERNAL_ERROR
;
1935 if (req
->current_idx
> max_idx
) {
1936 return NT_STATUS_INTERNAL_ERROR
;
1939 inhdr_v
= SMBD_SMB2_IN_HDR_IOV(req
);
1940 if (inhdr_v
->iov_len
!= SMB2_HDR_BODY
) {
1941 return NT_STATUS_INTERNAL_ERROR
;
1943 if (SMBD_SMB2_IN_BODY_LEN(req
) < 2) {
1944 return NT_STATUS_INTERNAL_ERROR
;
1947 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
1948 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
1952 case SMB2_OP_GETINFO
:
1956 if (req
->smb1req
!= NULL
&& req
->smb1req
->unread_bytes
> 0) {
1957 if (req
->smb1req
->unread_bytes
< min_dyn_size
) {
1958 return NT_STATUS_INVALID_PARAMETER
;
1967 * Now check the expected body size,
1968 * where the last byte might be in the
1971 if (SMBD_SMB2_IN_BODY_LEN(req
) != (expected_body_size
& 0xFFFFFFFE)) {
1972 return NT_STATUS_INVALID_PARAMETER
;
1974 if (SMBD_SMB2_IN_DYN_LEN(req
) < min_dyn_size
) {
1975 return NT_STATUS_INVALID_PARAMETER
;
1978 inbody
= SMBD_SMB2_IN_BODY_PTR(req
);
1980 body_size
= SVAL(inbody
, 0x00);
1981 if (body_size
!= expected_body_size
) {
1982 return NT_STATUS_INVALID_PARAMETER
;
1985 return NT_STATUS_OK
;
1988 NTSTATUS
smbd_smb2_request_dispatch(struct smbd_smb2_request
*req
)
1990 struct smbXsrv_connection
*xconn
= req
->xconn
;
1991 const struct smbd_smb2_dispatch_table
*call
= NULL
;
1992 const struct iovec
*intf_v
= SMBD_SMB2_IN_TF_IOV(req
);
1993 const uint8_t *inhdr
;
1998 NTSTATUS session_status
;
1999 uint32_t allowed_flags
;
2000 NTSTATUS return_value
;
2001 struct smbXsrv_session
*x
= NULL
;
2002 bool signing_required
= false;
2003 bool encryption_desired
= false;
2004 bool encryption_required
= false;
2006 inhdr
= SMBD_SMB2_IN_HDR_PTR(req
);
2008 DO_PROFILE_INC(request
);
2010 /* TODO: verify more things */
2012 flags
= IVAL(inhdr
, SMB2_HDR_FLAGS
);
2013 opcode
= SVAL(inhdr
, SMB2_HDR_OPCODE
);
2014 mid
= BVAL(inhdr
, SMB2_HDR_MESSAGE_ID
);
2015 DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2016 smb2_opcode_name(opcode
),
2017 (unsigned long long)mid
));
2019 if (xconn
->protocol
>= PROTOCOL_SMB2_02
) {
2021 * once the protocol is negotiated
2022 * SMB2_OP_NEGPROT is not allowed anymore
2024 if (opcode
== SMB2_OP_NEGPROT
) {
2025 /* drop the connection */
2026 return NT_STATUS_INVALID_PARAMETER
;
2030 * if the protocol is not negotiated yet
2031 * only SMB2_OP_NEGPROT is allowed.
2033 if (opcode
!= SMB2_OP_NEGPROT
) {
2034 /* drop the connection */
2035 return NT_STATUS_INVALID_PARAMETER
;
2040 * Check if the client provided a valid session id,
2041 * if so smbd_smb2_request_check_session() calls
2042 * set_current_user_info().
2044 * As some command don't require a valid session id
2045 * we defer the check of the session_status
2047 session_status
= smbd_smb2_request_check_session(req
);
2050 signing_required
= x
->global
->signing_required
;
2051 encryption_desired
= x
->encryption_desired
;
2052 encryption_required
= x
->global
->encryption_required
;
2055 req
->do_signing
= false;
2056 req
->do_encryption
= false;
2057 req
->was_encrypted
= false;
2058 if (intf_v
->iov_len
== SMB2_TF_HDR_SIZE
) {
2059 const uint8_t *intf
= SMBD_SMB2_IN_TF_PTR(req
);
2060 uint64_t tf_session_id
= BVAL(intf
, SMB2_TF_SESSION_ID
);
2062 if (x
!= NULL
&& x
->global
->session_wire_id
!= tf_session_id
) {
2063 DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2064 "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2065 (unsigned long long)x
->global
->session_wire_id
,
2066 (unsigned long long)tf_session_id
));
2068 * TODO: windows allows this...
2069 * should we drop the connection?
2071 * For now we just return ACCESS_DENIED
2072 * (Windows clients never trigger this)
2073 * and wait for an update of [MS-SMB2].
2075 return smbd_smb2_request_error(req
,
2076 NT_STATUS_ACCESS_DENIED
);
2079 req
->was_encrypted
= true;
2082 if (encryption_required
&& !req
->was_encrypted
) {
2083 return smbd_smb2_request_error(req
,
2084 NT_STATUS_ACCESS_DENIED
);
2087 call
= smbd_smb2_call(opcode
);
2089 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2092 allowed_flags
= SMB2_HDR_FLAG_CHAINED
|
2093 SMB2_HDR_FLAG_SIGNED
|
2095 if (xconn
->protocol
>= PROTOCOL_SMB3_11
) {
2096 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
2098 if (opcode
== SMB2_OP_NEGPROT
) {
2099 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11
) {
2100 allowed_flags
|= SMB2_HDR_FLAG_PRIORITY_MASK
;
2103 if (opcode
== SMB2_OP_CANCEL
) {
2104 allowed_flags
|= SMB2_HDR_FLAG_ASYNC
;
2106 if ((flags
& ~allowed_flags
) != 0) {
2107 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2110 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
2112 * This check is mostly for giving the correct error code
2113 * for compounded requests.
2115 if (!NT_STATUS_IS_OK(session_status
)) {
2116 return smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2119 req
->compat_chain_fsp
= NULL
;
2122 if (req
->was_encrypted
) {
2123 signing_required
= false;
2124 } else if (signing_required
|| (flags
& SMB2_HDR_FLAG_SIGNED
)) {
2125 DATA_BLOB signing_key
= data_blob_null
;
2129 * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2130 * If the SMB2 header of the SMB2 NEGOTIATE
2131 * request has the SMB2_FLAGS_SIGNED bit set in the
2132 * Flags field, the server MUST fail the request
2133 * with STATUS_INVALID_PARAMETER.
2135 * Microsoft test tool checks this.
2138 if ((opcode
== SMB2_OP_NEGPROT
) &&
2139 (flags
& SMB2_HDR_FLAG_SIGNED
)) {
2140 status
= NT_STATUS_INVALID_PARAMETER
;
2142 status
= NT_STATUS_USER_SESSION_DELETED
;
2144 return smbd_smb2_request_error(req
, status
);
2147 signing_key
= smbd_smb2_signing_key(x
, xconn
);
2150 * If we have a signing key, we should
2153 if (signing_key
.length
> 0) {
2154 req
->do_signing
= true;
2157 status
= smb2_signing_check_pdu(signing_key
,
2159 SMBD_SMB2_IN_HDR_IOV(req
),
2160 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2161 if (!NT_STATUS_IS_OK(status
)) {
2162 return smbd_smb2_request_error(req
, status
);
2166 * Now that we know the request was correctly signed
2167 * we have to sign the response too.
2169 req
->do_signing
= true;
2171 if (!NT_STATUS_IS_OK(session_status
)) {
2172 return smbd_smb2_request_error(req
, session_status
);
2174 } else if (opcode
== SMB2_OP_CANCEL
) {
2175 /* Cancel requests are allowed to skip the signing */
2176 } else if (signing_required
) {
2178 * If signing is required we try to sign
2179 * a possible error response
2181 req
->do_signing
= true;
2182 return smbd_smb2_request_error(req
, NT_STATUS_ACCESS_DENIED
);
2185 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
2186 req
->compound_related
= true;
2189 if (call
->need_session
) {
2190 if (!NT_STATUS_IS_OK(session_status
)) {
2191 return smbd_smb2_request_error(req
, session_status
);
2195 if (call
->need_tcon
) {
2196 SMB_ASSERT(call
->need_session
);
2199 * This call needs to be run as user.
2201 * smbd_smb2_request_check_tcon()
2202 * calls change_to_user() on success.
2204 status
= smbd_smb2_request_check_tcon(req
);
2205 if (!NT_STATUS_IS_OK(status
)) {
2206 return smbd_smb2_request_error(req
, status
);
2208 if (req
->tcon
->encryption_desired
) {
2209 encryption_desired
= true;
2211 if (req
->tcon
->global
->encryption_required
) {
2212 encryption_required
= true;
2214 if (encryption_required
&& !req
->was_encrypted
) {
2215 return smbd_smb2_request_error(req
,
2216 NT_STATUS_ACCESS_DENIED
);
2220 if (req
->was_encrypted
|| encryption_desired
) {
2221 req
->do_encryption
= true;
2224 if (call
->fileid_ofs
!= 0) {
2225 size_t needed
= call
->fileid_ofs
+ 16;
2226 const uint8_t *body
= SMBD_SMB2_IN_BODY_PTR(req
);
2227 size_t body_size
= SMBD_SMB2_IN_BODY_LEN(req
);
2228 uint64_t file_id_persistent
;
2229 uint64_t file_id_volatile
;
2230 struct files_struct
*fsp
;
2232 SMB_ASSERT(call
->need_tcon
);
2234 if (needed
> body_size
) {
2235 return smbd_smb2_request_error(req
,
2236 NT_STATUS_INVALID_PARAMETER
);
2239 file_id_persistent
= BVAL(body
, call
->fileid_ofs
+ 0);
2240 file_id_volatile
= BVAL(body
, call
->fileid_ofs
+ 8);
2242 fsp
= file_fsp_smb2(req
, file_id_persistent
, file_id_volatile
);
2244 if (!call
->allow_invalid_fileid
) {
2245 return smbd_smb2_request_error(req
,
2246 NT_STATUS_FILE_CLOSED
);
2249 if (file_id_persistent
!= UINT64_MAX
) {
2250 return smbd_smb2_request_error(req
,
2251 NT_STATUS_FILE_CLOSED
);
2253 if (file_id_volatile
!= UINT64_MAX
) {
2254 return smbd_smb2_request_error(req
,
2255 NT_STATUS_FILE_CLOSED
);
2260 if (call
->as_root
) {
2261 SMB_ASSERT(call
->fileid_ofs
== 0);
2262 /* This call needs to be run as root */
2263 change_to_root_user();
2265 SMB_ASSERT(call
->need_tcon
);
2268 #define _INBYTES(_r) \
2269 iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2272 case SMB2_OP_NEGPROT
:
2273 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot
, profile_p
,
2274 req
->profile
, _INBYTES(req
));
2275 return_value
= smbd_smb2_request_process_negprot(req
);
2278 case SMB2_OP_SESSSETUP
:
2279 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup
, profile_p
,
2280 req
->profile
, _INBYTES(req
));
2281 return_value
= smbd_smb2_request_process_sesssetup(req
);
2284 case SMB2_OP_LOGOFF
:
2285 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff
, profile_p
,
2286 req
->profile
, _INBYTES(req
));
2287 return_value
= smbd_smb2_request_process_logoff(req
);
2291 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon
, profile_p
,
2292 req
->profile
, _INBYTES(req
));
2293 return_value
= smbd_smb2_request_process_tcon(req
);
2297 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis
, profile_p
,
2298 req
->profile
, _INBYTES(req
));
2299 return_value
= smbd_smb2_request_process_tdis(req
);
2302 case SMB2_OP_CREATE
:
2303 if (req
->subreq
== NULL
) {
2304 SMBPROFILE_IOBYTES_ASYNC_START(smb2_create
, profile_p
,
2305 req
->profile
, _INBYTES(req
));
2307 SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req
->profile
);
2309 return_value
= smbd_smb2_request_process_create(req
);
2313 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close
, profile_p
,
2314 req
->profile
, _INBYTES(req
));
2315 return_value
= smbd_smb2_request_process_close(req
);
2319 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush
, profile_p
,
2320 req
->profile
, _INBYTES(req
));
2321 return_value
= smbd_smb2_request_process_flush(req
);
2325 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read
, profile_p
,
2326 req
->profile
, _INBYTES(req
));
2327 return_value
= smbd_smb2_request_process_read(req
);
2331 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write
, profile_p
,
2332 req
->profile
, _INBYTES(req
));
2333 return_value
= smbd_smb2_request_process_write(req
);
2337 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock
, profile_p
,
2338 req
->profile
, _INBYTES(req
));
2339 return_value
= smbd_smb2_request_process_lock(req
);
2343 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl
, profile_p
,
2344 req
->profile
, _INBYTES(req
));
2345 return_value
= smbd_smb2_request_process_ioctl(req
);
2348 case SMB2_OP_CANCEL
:
2349 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel
, profile_p
,
2350 req
->profile
, _INBYTES(req
));
2351 return_value
= smbd_smb2_request_process_cancel(req
);
2352 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
, 0);
2355 case SMB2_OP_KEEPALIVE
:
2356 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive
, profile_p
,
2357 req
->profile
, _INBYTES(req
));
2358 return_value
= smbd_smb2_request_process_keepalive(req
);
2361 case SMB2_OP_QUERY_DIRECTORY
:
2362 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find
, profile_p
,
2363 req
->profile
, _INBYTES(req
));
2364 return_value
= smbd_smb2_request_process_query_directory(req
);
2367 case SMB2_OP_NOTIFY
:
2368 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify
, profile_p
,
2369 req
->profile
, _INBYTES(req
));
2370 return_value
= smbd_smb2_request_process_notify(req
);
2373 case SMB2_OP_GETINFO
:
2374 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo
, profile_p
,
2375 req
->profile
, _INBYTES(req
));
2376 return_value
= smbd_smb2_request_process_getinfo(req
);
2379 case SMB2_OP_SETINFO
:
2380 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo
, profile_p
,
2381 req
->profile
, _INBYTES(req
));
2382 return_value
= smbd_smb2_request_process_setinfo(req
);
2386 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break
, profile_p
,
2387 req
->profile
, _INBYTES(req
));
2388 return_value
= smbd_smb2_request_process_break(req
);
2392 return_value
= smbd_smb2_request_error(req
, NT_STATUS_INVALID_PARAMETER
);
2395 return return_value
;
2398 static NTSTATUS
smbd_smb2_request_reply(struct smbd_smb2_request
*req
)
2400 struct smbXsrv_connection
*xconn
= req
->xconn
;
2402 struct iovec
*firsttf
= SMBD_SMB2_IDX_TF_IOV(req
,out
,first_idx
);
2403 struct iovec
*outhdr
= SMBD_SMB2_OUT_HDR_IOV(req
);
2404 struct iovec
*outdyn
= SMBD_SMB2_OUT_DYN_IOV(req
);
2409 TALLOC_FREE(req
->async_te
);
2411 if (req
->do_encryption
&&
2412 (firsttf
->iov_len
== 0) &&
2413 (req
->first_key
.length
== 0) &&
2414 (req
->session
!= NULL
) &&
2415 (req
->session
->global
->encryption_key
.length
!= 0))
2417 DATA_BLOB encryption_key
= req
->session
->global
->encryption_key
;
2419 uint64_t session_id
= req
->session
->global
->session_wire_id
;
2420 uint64_t nonce_high
;
2423 status
= smb2_get_new_nonce(req
->session
,
2426 if (!NT_STATUS_IS_OK(status
)) {
2431 * We need to place the SMB2_TRANSFORM header before the
2436 * we need to remember the encryption key
2437 * and defer the signing/encryption until
2438 * we are sure that we do not change
2441 req
->first_key
= data_blob_dup_talloc(req
, encryption_key
);
2442 if (req
->first_key
.data
== NULL
) {
2443 return NT_STATUS_NO_MEMORY
;
2446 tf
= talloc_zero_array(req
, uint8_t,
2449 return NT_STATUS_NO_MEMORY
;
2452 SIVAL(tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2453 SBVAL(tf
, SMB2_TF_NONCE
+0, nonce_low
);
2454 SBVAL(tf
, SMB2_TF_NONCE
+8, nonce_high
);
2455 SBVAL(tf
, SMB2_TF_SESSION_ID
, session_id
);
2457 firsttf
->iov_base
= (void *)tf
;
2458 firsttf
->iov_len
= SMB2_TF_HDR_SIZE
;
2461 if ((req
->current_idx
> SMBD_SMB2_NUM_IOV_PER_REQ
) &&
2462 (req
->last_key
.length
> 0) &&
2463 (firsttf
->iov_len
== 0))
2465 int last_idx
= req
->current_idx
- SMBD_SMB2_NUM_IOV_PER_REQ
;
2466 struct iovec
*lasthdr
= SMBD_SMB2_IDX_HDR_IOV(req
,out
,last_idx
);
2469 * As we are sure the header of the last request in the
2470 * compound chain will not change, we can to sign here
2471 * with the last signing key we remembered.
2473 status
= smb2_signing_sign_pdu(req
->last_key
,
2476 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2477 if (!NT_STATUS_IS_OK(status
)) {
2481 if (req
->last_key
.length
> 0) {
2482 data_blob_clear_free(&req
->last_key
);
2485 SMBPROFILE_IOBYTES_ASYNC_END(req
->profile
,
2486 iov_buflen(outhdr
, SMBD_SMB2_NUM_IOV_PER_REQ
-1));
2488 req
->current_idx
+= SMBD_SMB2_NUM_IOV_PER_REQ
;
2490 if (req
->current_idx
< req
->out
.vector_count
) {
2492 * We must process the remaining compound
2493 * SMB2 requests before any new incoming SMB2
2494 * requests. This is because incoming SMB2
2495 * requests may include a cancel for a
2496 * compound request we haven't processed
2499 struct tevent_immediate
*im
= tevent_create_immediate(req
);
2501 return NT_STATUS_NO_MEMORY
;
2504 if (req
->do_signing
&& firsttf
->iov_len
== 0) {
2505 struct smbXsrv_session
*x
= req
->session
;
2506 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
2509 * we need to remember the signing key
2510 * and defer the signing until
2511 * we are sure that we do not change
2514 req
->last_key
= data_blob_dup_talloc(req
, signing_key
);
2515 if (req
->last_key
.data
== NULL
) {
2516 return NT_STATUS_NO_MEMORY
;
2520 tevent_schedule_immediate(im
,
2522 smbd_smb2_request_dispatch_immediate
,
2524 return NT_STATUS_OK
;
2527 if (req
->compound_related
) {
2528 req
->compound_related
= false;
2531 ok
= smb2_setup_nbt_length(req
->out
.vector
, req
->out
.vector_count
);
2533 return NT_STATUS_INVALID_PARAMETER_MIX
;
2536 /* Set credit for these operations (zero credits if this
2537 is a final reply for an async operation). */
2538 smb2_calculate_credits(req
, req
);
2541 * now check if we need to sign the current response
2543 if (firsttf
->iov_len
== SMB2_TF_HDR_SIZE
) {
2544 status
= smb2_signing_encrypt_pdu(req
->first_key
,
2545 xconn
->smb2
.server
.cipher
,
2547 req
->out
.vector_count
- first_idx
);
2548 if (!NT_STATUS_IS_OK(status
)) {
2551 } else if (req
->do_signing
) {
2552 struct smbXsrv_session
*x
= req
->session
;
2553 DATA_BLOB signing_key
= smbd_smb2_signing_key(x
, xconn
);
2555 status
= smb2_signing_sign_pdu(signing_key
,
2558 SMBD_SMB2_NUM_IOV_PER_REQ
- 1);
2559 if (!NT_STATUS_IS_OK(status
)) {
2563 if (req
->first_key
.length
> 0) {
2564 data_blob_clear_free(&req
->first_key
);
2567 if (req
->preauth
!= NULL
) {
2568 struct hc_sha512state sctx
;
2571 samba_SHA512_Init(&sctx
);
2572 samba_SHA512_Update(&sctx
, req
->preauth
->sha512_value
,
2573 sizeof(req
->preauth
->sha512_value
));
2574 for (i
= 1; i
< req
->in
.vector_count
; i
++) {
2575 samba_SHA512_Update(&sctx
,
2576 req
->in
.vector
[i
].iov_base
,
2577 req
->in
.vector
[i
].iov_len
);
2579 samba_SHA512_Final(req
->preauth
->sha512_value
, &sctx
);
2581 samba_SHA512_Init(&sctx
);
2582 samba_SHA512_Update(&sctx
, req
->preauth
->sha512_value
,
2583 sizeof(req
->preauth
->sha512_value
));
2584 for (i
= 1; i
< req
->out
.vector_count
; i
++) {
2585 samba_SHA512_Update(&sctx
,
2586 req
->out
.vector
[i
].iov_base
,
2587 req
->out
.vector
[i
].iov_len
);
2589 samba_SHA512_Final(req
->preauth
->sha512_value
, &sctx
);
2591 req
->preauth
= NULL
;
2594 /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2595 if (req
->out
.vector_count
< (2*SMBD_SMB2_NUM_IOV_PER_REQ
) &&
2596 outdyn
->iov_base
== NULL
&& outdyn
->iov_len
!= 0) {
2597 /* Dynamic part is NULL. Chop it off,
2598 We're going to send it via sendfile. */
2599 req
->out
.vector_count
-= 1;
2603 * We're done with this request -
2604 * move it off the "being processed" queue.
2606 DLIST_REMOVE(xconn
->smb2
.requests
, req
);
2608 req
->queue_entry
.mem_ctx
= req
;
2609 req
->queue_entry
.vector
= req
->out
.vector
;
2610 req
->queue_entry
.count
= req
->out
.vector_count
;
2611 DLIST_ADD_END(xconn
->smb2
.send_queue
, &req
->queue_entry
, NULL
);
2612 xconn
->smb2
.send_queue_len
++;
2614 status
= smbd_smb2_flush_send_queue(xconn
);
2615 if (!NT_STATUS_IS_OK(status
)) {
2619 return NT_STATUS_OK
;
2622 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
);
2624 void smbd_smb2_request_dispatch_immediate(struct tevent_context
*ctx
,
2625 struct tevent_immediate
*im
,
2628 struct smbd_smb2_request
*req
= talloc_get_type_abort(private_data
,
2629 struct smbd_smb2_request
);
2630 struct smbXsrv_connection
*xconn
= req
->xconn
;
2635 if (DEBUGLEVEL
>= 10) {
2636 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2637 req
->current_idx
, req
->in
.vector_count
));
2638 print_req_vectors(req
);
2641 status
= smbd_smb2_request_dispatch(req
);
2642 if (!NT_STATUS_IS_OK(status
)) {
2643 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
2647 status
= smbd_smb2_request_next_incoming(xconn
);
2648 if (!NT_STATUS_IS_OK(status
)) {
2649 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
2654 NTSTATUS
smbd_smb2_request_done_ex(struct smbd_smb2_request
*req
,
2656 DATA_BLOB body
, DATA_BLOB
*dyn
,
2657 const char *location
)
2660 struct iovec
*outbody_v
;
2661 struct iovec
*outdyn_v
;
2662 uint32_t next_command_ofs
;
2664 DEBUG(10,("smbd_smb2_request_done_ex: "
2665 "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
2666 req
->current_idx
, nt_errstr(status
), (unsigned int)body
.length
,
2668 (unsigned int)(dyn
? dyn
->length
: 0),
2671 if (body
.length
< 2) {
2672 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
2675 if ((body
.length
% 2) != 0) {
2676 return smbd_smb2_request_error(req
, NT_STATUS_INTERNAL_ERROR
);
2679 outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2680 outbody_v
= SMBD_SMB2_OUT_BODY_IOV(req
);
2681 outdyn_v
= SMBD_SMB2_OUT_DYN_IOV(req
);
2683 next_command_ofs
= IVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
);
2684 SIVAL(outhdr
, SMB2_HDR_STATUS
, NT_STATUS_V(status
));
2686 outbody_v
->iov_base
= (void *)body
.data
;
2687 outbody_v
->iov_len
= body
.length
;
2690 outdyn_v
->iov_base
= (void *)dyn
->data
;
2691 outdyn_v
->iov_len
= dyn
->length
;
2693 outdyn_v
->iov_base
= NULL
;
2694 outdyn_v
->iov_len
= 0;
2698 * See if we need to recalculate the offset to the next response
2700 * Note that all responses may require padding (including the very last
2703 if (req
->out
.vector_count
>= (2 * SMBD_SMB2_NUM_IOV_PER_REQ
)) {
2704 next_command_ofs
= SMB2_HDR_BODY
;
2705 next_command_ofs
+= SMBD_SMB2_OUT_BODY_LEN(req
);
2706 next_command_ofs
+= SMBD_SMB2_OUT_DYN_LEN(req
);
2709 if ((next_command_ofs
% 8) != 0) {
2710 size_t pad_size
= 8 - (next_command_ofs
% 8);
2711 if (SMBD_SMB2_OUT_DYN_LEN(req
) == 0) {
2713 * if the dyn buffer is empty
2714 * we can use it to add padding
2718 pad
= talloc_zero_array(req
,
2721 return smbd_smb2_request_error(req
,
2722 NT_STATUS_NO_MEMORY
);
2725 outdyn_v
->iov_base
= (void *)pad
;
2726 outdyn_v
->iov_len
= pad_size
;
2729 * For now we copy the dynamic buffer
2730 * and add the padding to the new buffer
2737 old_size
= SMBD_SMB2_OUT_DYN_LEN(req
);
2738 old_dyn
= SMBD_SMB2_OUT_DYN_PTR(req
);
2740 new_size
= old_size
+ pad_size
;
2741 new_dyn
= talloc_zero_array(req
,
2743 if (new_dyn
== NULL
) {
2744 return smbd_smb2_request_error(req
,
2745 NT_STATUS_NO_MEMORY
);
2748 memcpy(new_dyn
, old_dyn
, old_size
);
2749 memset(new_dyn
+ old_size
, 0, pad_size
);
2751 outdyn_v
->iov_base
= (void *)new_dyn
;
2752 outdyn_v
->iov_len
= new_size
;
2754 next_command_ofs
+= pad_size
;
2757 if ((req
->current_idx
+ SMBD_SMB2_NUM_IOV_PER_REQ
) >= req
->out
.vector_count
) {
2758 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2760 SIVAL(outhdr
, SMB2_HDR_NEXT_COMMAND
, next_command_ofs
);
2762 return smbd_smb2_request_reply(req
);
2765 NTSTATUS
smbd_smb2_request_error_ex(struct smbd_smb2_request
*req
,
2768 const char *location
)
2770 struct smbXsrv_connection
*xconn
= req
->xconn
;
2773 uint8_t *outhdr
= SMBD_SMB2_OUT_HDR_PTR(req
);
2774 size_t unread_bytes
= smbd_smb2_unread_bytes(req
);
2776 DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n",
2777 req
->current_idx
, nt_errstr(status
), info
? " +info" : "",
2781 /* Recvfile error. Drain incoming socket. */
2785 ret
= drain_socket(xconn
->transport
.sock
, unread_bytes
);
2786 if (ret
!= unread_bytes
) {
2790 error
= NT_STATUS_IO_DEVICE_ERROR
;
2792 error
= map_nt_error_from_unix_common(errno
);
2795 DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
2796 "ret[%u] errno[%d] => %s\n",
2797 (unsigned)unread_bytes
,
2798 (unsigned)ret
, errno
, nt_errstr(error
)));
2803 body
.data
= outhdr
+ SMB2_HDR_BODY
;
2805 SSVAL(body
.data
, 0, 9);
2808 SIVAL(body
.data
, 0x04, info
->length
);
2810 /* Allocated size of req->out.vector[i].iov_base
2811 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
2812 * 1 byte without having to do an alloc.
2815 info
->data
= ((uint8_t *)outhdr
) +
2816 OUTVEC_ALLOC_SIZE
- 1;
2818 SCVAL(info
->data
, 0, 0);
2822 * Note: Even if there is an error, continue to process the request.
2826 return smbd_smb2_request_done_ex(req
, status
, body
, info
, __location__
);
2830 struct smbd_smb2_send_break_state
{
2831 struct smbd_smb2_send_queue queue_entry
;
2832 uint8_t nbt_hdr
[NBT_HDR_SIZE
];
2833 uint8_t tf
[SMB2_TF_HDR_SIZE
];
2834 uint8_t hdr
[SMB2_HDR_BODY
];
2835 struct iovec vector
[1+SMBD_SMB2_NUM_IOV_PER_REQ
];
2839 static NTSTATUS
smbd_smb2_send_break(struct smbXsrv_connection
*xconn
,
2840 struct smbXsrv_session
*session
,
2841 struct smbXsrv_tcon
*tcon
,
2842 const uint8_t *body
,
2845 struct smbd_smb2_send_break_state
*state
;
2846 bool do_encryption
= false;
2847 uint64_t session_wire_id
= 0;
2848 uint64_t nonce_high
= 0;
2849 uint64_t nonce_low
= 0;
2854 if (session
!= NULL
) {
2855 session_wire_id
= session
->global
->session_wire_id
;
2856 do_encryption
= session
->encryption_desired
;
2857 if (tcon
->encryption_desired
) {
2858 do_encryption
= true;
2862 statelen
= offsetof(struct smbd_smb2_send_break_state
, body
) +
2865 state
= talloc_zero_size(xconn
, statelen
);
2866 if (state
== NULL
) {
2867 return NT_STATUS_NO_MEMORY
;
2869 talloc_set_name_const(state
, "struct smbd_smb2_send_break_state");
2871 if (do_encryption
) {
2872 status
= smb2_get_new_nonce(session
,
2875 if (!NT_STATUS_IS_OK(status
)) {
2880 SIVAL(state
->tf
, SMB2_TF_PROTOCOL_ID
, SMB2_TF_MAGIC
);
2881 SBVAL(state
->tf
, SMB2_TF_NONCE
+0, nonce_low
);
2882 SBVAL(state
->tf
, SMB2_TF_NONCE
+8, nonce_high
);
2883 SBVAL(state
->tf
, SMB2_TF_SESSION_ID
, session_wire_id
);
2885 SIVAL(state
->hdr
, 0, SMB2_MAGIC
);
2886 SSVAL(state
->hdr
, SMB2_HDR_LENGTH
, SMB2_HDR_BODY
);
2887 SSVAL(state
->hdr
, SMB2_HDR_EPOCH
, 0);
2888 SIVAL(state
->hdr
, SMB2_HDR_STATUS
, 0);
2889 SSVAL(state
->hdr
, SMB2_HDR_OPCODE
, SMB2_OP_BREAK
);
2890 SSVAL(state
->hdr
, SMB2_HDR_CREDIT
, 0);
2891 SIVAL(state
->hdr
, SMB2_HDR_FLAGS
, SMB2_HDR_FLAG_REDIRECT
);
2892 SIVAL(state
->hdr
, SMB2_HDR_NEXT_COMMAND
, 0);
2893 SBVAL(state
->hdr
, SMB2_HDR_MESSAGE_ID
, UINT64_MAX
);
2894 SIVAL(state
->hdr
, SMB2_HDR_PID
, 0);
2895 SIVAL(state
->hdr
, SMB2_HDR_TID
, 0);
2896 SBVAL(state
->hdr
, SMB2_HDR_SESSION_ID
, 0);
2897 memset(state
->hdr
+SMB2_HDR_SIGNATURE
, 0, 16);
2899 state
->vector
[0] = (struct iovec
) {
2900 .iov_base
= state
->nbt_hdr
,
2901 .iov_len
= sizeof(state
->nbt_hdr
)
2904 if (do_encryption
) {
2905 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
2906 .iov_base
= state
->tf
,
2907 .iov_len
= sizeof(state
->tf
)
2910 state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
] = (struct iovec
) {
2916 state
->vector
[1+SMBD_SMB2_HDR_IOV_OFS
] = (struct iovec
) {
2917 .iov_base
= state
->hdr
,
2918 .iov_len
= sizeof(state
->hdr
)
2921 memcpy(state
->body
, body
, body_len
);
2923 state
->vector
[1+SMBD_SMB2_BODY_IOV_OFS
] = (struct iovec
) {
2924 .iov_base
= state
->body
,
2925 .iov_len
= body_len
/* no sizeof(state->body) .. :-) */
2929 * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
2932 ok
= smb2_setup_nbt_length(state
->vector
,
2933 1 + SMBD_SMB2_NUM_IOV_PER_REQ
);
2935 return NT_STATUS_INVALID_PARAMETER_MIX
;
2938 if (do_encryption
) {
2939 DATA_BLOB encryption_key
= session
->global
->encryption_key
;
2941 status
= smb2_signing_encrypt_pdu(encryption_key
,
2942 xconn
->smb2
.server
.cipher
,
2943 &state
->vector
[1+SMBD_SMB2_TF_IOV_OFS
],
2944 SMBD_SMB2_NUM_IOV_PER_REQ
);
2945 if (!NT_STATUS_IS_OK(status
)) {
2950 state
->queue_entry
.mem_ctx
= state
;
2951 state
->queue_entry
.vector
= state
->vector
;
2952 state
->queue_entry
.count
= ARRAY_SIZE(state
->vector
);
2953 DLIST_ADD_END(xconn
->smb2
.send_queue
, &state
->queue_entry
, NULL
);
2954 xconn
->smb2
.send_queue_len
++;
2956 status
= smbd_smb2_flush_send_queue(xconn
);
2957 if (!NT_STATUS_IS_OK(status
)) {
2961 return NT_STATUS_OK
;
2964 NTSTATUS
smbd_smb2_send_oplock_break(struct smbXsrv_connection
*xconn
,
2965 struct smbXsrv_session
*session
,
2966 struct smbXsrv_tcon
*tcon
,
2967 struct smbXsrv_open
*op
,
2968 uint8_t oplock_level
)
2972 SSVAL(body
, 0x00, sizeof(body
));
2973 SCVAL(body
, 0x02, oplock_level
);
2974 SCVAL(body
, 0x03, 0); /* reserved */
2975 SIVAL(body
, 0x04, 0); /* reserved */
2976 SBVAL(body
, 0x08, op
->global
->open_persistent_id
);
2977 SBVAL(body
, 0x10, op
->global
->open_volatile_id
);
2979 return smbd_smb2_send_break(xconn
, session
, tcon
, body
, sizeof(body
));
2982 NTSTATUS
smbd_smb2_send_lease_break(struct smbXsrv_connection
*xconn
,
2984 uint32_t lease_flags
,
2985 struct smb2_lease_key
*lease_key
,
2986 uint32_t current_lease_state
,
2987 uint32_t new_lease_state
)
2991 SSVAL(body
, 0x00, sizeof(body
));
2992 SSVAL(body
, 0x02, new_epoch
);
2993 SIVAL(body
, 0x04, lease_flags
);
2994 SBVAL(body
, 0x08, lease_key
->data
[0]);
2995 SBVAL(body
, 0x10, lease_key
->data
[1]);
2996 SIVAL(body
, 0x18, current_lease_state
);
2997 SIVAL(body
, 0x1c, new_lease_state
);
2998 SIVAL(body
, 0x20, 0); /* BreakReason, MUST be 0 */
2999 SIVAL(body
, 0x24, 0); /* AccessMaskHint, MUST be 0 */
3000 SIVAL(body
, 0x28, 0); /* ShareMaskHint, MUST be 0 */
3002 return smbd_smb2_send_break(xconn
, NULL
, NULL
, body
, sizeof(body
));
3005 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state
*state
)
3009 uint64_t file_id_persistent
;
3010 uint64_t file_id_volatile
;
3011 struct smbXsrv_open
*op
= NULL
;
3012 struct files_struct
*fsp
= NULL
;
3013 const uint8_t *body
= NULL
;
3016 * This is only called with a pktbuf
3017 * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
3021 if (IVAL(state
->pktbuf
, 0) == SMB2_TF_MAGIC
) {
3022 /* Transform header. Cannot recvfile. */
3025 if (IVAL(state
->pktbuf
, 0) != SMB2_MAGIC
) {
3026 /* Not SMB2. Normal error path will cope. */
3029 if (SVAL(state
->pktbuf
, 4) != SMB2_HDR_BODY
) {
3030 /* Not SMB2. Normal error path will cope. */
3033 if (SVAL(state
->pktbuf
, SMB2_HDR_OPCODE
) != SMB2_OP_WRITE
) {
3034 /* Needs to be a WRITE. */
3037 if (IVAL(state
->pktbuf
, SMB2_HDR_NEXT_COMMAND
) != 0) {
3038 /* Chained. Cannot recvfile. */
3041 flags
= IVAL(state
->pktbuf
, SMB2_HDR_FLAGS
);
3042 if (flags
& SMB2_HDR_FLAG_CHAINED
) {
3043 /* Chained. Cannot recvfile. */
3046 if (flags
& SMB2_HDR_FLAG_SIGNED
) {
3047 /* Signed. Cannot recvfile. */
3051 body
= &state
->pktbuf
[SMB2_HDR_BODY
];
3053 file_id_persistent
= BVAL(body
, 0x10);
3054 file_id_volatile
= BVAL(body
, 0x18);
3056 status
= smb2srv_open_lookup(state
->req
->xconn
,
3061 if (!NT_STATUS_IS_OK(status
)) {
3069 if (fsp
->conn
== NULL
) {
3073 if (IS_IPC(fsp
->conn
)) {
3076 if (IS_PRINT(fsp
->conn
)) {
3080 DEBUG(10,("Doing recvfile write len = %u\n",
3081 (unsigned int)(state
->pktfull
- state
->pktlen
)));
3086 static NTSTATUS
smbd_smb2_request_next_incoming(struct smbXsrv_connection
*xconn
)
3088 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3089 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
3090 size_t max_send_queue_len
;
3091 size_t cur_send_queue_len
;
3093 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
3095 * we're not supposed to do any io
3097 return NT_STATUS_OK
;
3100 if (state
->req
!= NULL
) {
3102 * if there is already a tstream_readv_pdu
3103 * pending, we are done.
3105 return NT_STATUS_OK
;
3108 max_send_queue_len
= MAX(1, xconn
->smb2
.credits
.max
/16);
3109 cur_send_queue_len
= xconn
->smb2
.send_queue_len
;
3111 if (cur_send_queue_len
> max_send_queue_len
) {
3113 * if we have a lot of requests to send,
3114 * we wait until they are on the wire until we
3115 * ask for the next request.
3117 return NT_STATUS_OK
;
3120 /* ask for the next request */
3121 ZERO_STRUCTP(state
);
3122 state
->req
= smbd_smb2_request_allocate(xconn
);
3123 if (state
->req
== NULL
) {
3124 return NT_STATUS_NO_MEMORY
;
3126 state
->req
->sconn
= sconn
;
3127 state
->req
->xconn
= xconn
;
3128 state
->min_recv_size
= lp_min_receive_file_size();
3130 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3132 return NT_STATUS_OK
;
3135 void smbd_smb2_first_negprot(struct smbXsrv_connection
*xconn
,
3136 const uint8_t *inpdu
, size_t size
)
3138 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3140 struct smbd_smb2_request
*req
= NULL
;
3142 DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3143 (unsigned int)size
));
3145 status
= smbd_initialize_smb2(xconn
);
3146 if (!NT_STATUS_IS_OK(status
)) {
3147 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3151 status
= smbd_smb2_request_create(xconn
, inpdu
, size
, &req
);
3152 if (!NT_STATUS_IS_OK(status
)) {
3153 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3157 status
= smbd_smb2_request_validate(req
);
3158 if (!NT_STATUS_IS_OK(status
)) {
3159 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3163 status
= smbd_smb2_request_setup_out(req
);
3164 if (!NT_STATUS_IS_OK(status
)) {
3165 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3171 * this was already counted at the SMB1 layer =>
3172 * smbd_smb2_request_dispatch() should not count it twice.
3174 if (profile_p
->values
.request_stats
.count
> 0) {
3175 profile_p
->values
.request_stats
.count
--;
3178 status
= smbd_smb2_request_dispatch(req
);
3179 if (!NT_STATUS_IS_OK(status
)) {
3180 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3184 status
= smbd_smb2_request_next_incoming(xconn
);
3185 if (!NT_STATUS_IS_OK(status
)) {
3186 smbd_server_connection_terminate(xconn
, nt_errstr(status
));
3190 sconn
->num_requests
++;
3193 static int socket_error_from_errno(int ret
,
3207 if (sys_errno
== 0) {
3211 if (sys_errno
== EINTR
) {
3216 if (sys_errno
== EINPROGRESS
) {
3221 if (sys_errno
== EAGAIN
) {
3226 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3227 if (sys_errno
== ENOMEM
) {
3233 #if EWOULDBLOCK != EAGAIN
3234 if (sys_errno
== EWOULDBLOCK
) {
3244 static NTSTATUS
smbd_smb2_flush_send_queue(struct smbXsrv_connection
*xconn
)
3250 if (xconn
->smb2
.send_queue
== NULL
) {
3251 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
3252 return NT_STATUS_OK
;
3255 while (xconn
->smb2
.send_queue
!= NULL
) {
3256 struct smbd_smb2_send_queue
*e
= xconn
->smb2
.send_queue
;
3259 if (e
->sendfile_header
!= NULL
) {
3260 NTSTATUS status
= NT_STATUS_INTERNAL_ERROR
;
3265 for (i
=0; i
< e
->count
; i
++) {
3266 size
+= e
->vector
[i
].iov_len
;
3269 if (size
<= e
->sendfile_header
->length
) {
3270 buf
= e
->sendfile_header
->data
;
3272 buf
= talloc_array(e
->mem_ctx
, uint8_t, size
);
3274 return NT_STATUS_NO_MEMORY
;
3279 for (i
=0; i
< e
->count
; i
++) {
3281 e
->vector
[i
].iov_base
,
3282 e
->vector
[i
].iov_len
);
3283 size
+= e
->vector
[i
].iov_len
;
3286 e
->sendfile_header
->data
= buf
;
3287 e
->sendfile_header
->length
= size
;
3288 e
->sendfile_status
= &status
;
3291 xconn
->smb2
.send_queue_len
--;
3292 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
3294 * This triggers the sendfile path via
3297 talloc_free(e
->mem_ctx
);
3299 if (!NT_STATUS_IS_OK(status
)) {
3305 ret
= writev(xconn
->transport
.sock
, e
->vector
, e
->count
);
3307 /* propagate end of file */
3308 return NT_STATUS_INTERNAL_ERROR
;
3310 err
= socket_error_from_errno(ret
, errno
, &retry
);
3313 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
3314 return NT_STATUS_OK
;
3317 return map_nt_error_from_unix_common(err
);
3320 ok
= iov_advance(&e
->vector
, &e
->count
, ret
);
3322 return NT_STATUS_INTERNAL_ERROR
;
3326 /* we have more to write */
3327 TEVENT_FD_WRITEABLE(xconn
->transport
.fde
);
3328 return NT_STATUS_OK
;
3331 xconn
->smb2
.send_queue_len
--;
3332 DLIST_REMOVE(xconn
->smb2
.send_queue
, e
);
3333 talloc_free(e
->mem_ctx
);
3336 return NT_STATUS_OK
;
3339 static NTSTATUS
smbd_smb2_io_handler(struct smbXsrv_connection
*xconn
,
3342 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
3343 struct smbd_smb2_request_read_state
*state
= &xconn
->smb2
.request_read_state
;
3344 struct smbd_smb2_request
*req
= NULL
;
3345 size_t min_recvfile_size
= UINT32_MAX
;
3352 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
3354 * we're not supposed to do any io
3356 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
3357 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
3358 return NT_STATUS_OK
;
3361 if (fde_flags
& TEVENT_FD_WRITE
) {
3362 status
= smbd_smb2_flush_send_queue(xconn
);
3363 if (!NT_STATUS_IS_OK(status
)) {
3368 if (!(fde_flags
& TEVENT_FD_READ
)) {
3369 return NT_STATUS_OK
;
3372 if (state
->req
== NULL
) {
3373 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
3374 return NT_STATUS_OK
;
3378 if (!state
->hdr
.done
) {
3379 state
->hdr
.done
= true;
3381 state
->vector
.iov_base
= (void *)state
->hdr
.nbt
;
3382 state
->vector
.iov_len
= NBT_HDR_SIZE
;
3385 ret
= readv(xconn
->transport
.sock
, &state
->vector
, 1);
3387 /* propagate end of file */
3388 return NT_STATUS_END_OF_FILE
;
3390 err
= socket_error_from_errno(ret
, errno
, &retry
);
3393 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3394 return NT_STATUS_OK
;
3397 return map_nt_error_from_unix_common(err
);
3400 if (ret
< state
->vector
.iov_len
) {
3402 base
= (uint8_t *)state
->vector
.iov_base
;
3404 state
->vector
.iov_base
= (void *)base
;
3405 state
->vector
.iov_len
-= ret
;
3406 /* we have more to read */
3407 TEVENT_FD_READABLE(xconn
->transport
.fde
);
3408 return NT_STATUS_OK
;
3411 if (state
->pktlen
> 0) {
3412 if (state
->doing_receivefile
&& !is_smb2_recvfile_write(state
)) {
3414 * Not a possible receivefile write.
3415 * Read the rest of the data.
3417 state
->doing_receivefile
= false;
3419 state
->pktbuf
= talloc_realloc(state
->req
,
3423 if (state
->pktbuf
== NULL
) {
3424 return NT_STATUS_NO_MEMORY
;
3427 state
->vector
.iov_base
= (void *)(state
->pktbuf
+
3429 state
->vector
.iov_len
= (state
->pktfull
-
3432 state
->pktlen
= state
->pktfull
;
3437 * Either this is a receivefile write so we've
3438 * done a short read, or if not we have all the data.
3444 * Now we analyze the NBT header
3446 if (state
->hdr
.nbt
[0] != 0x00) {
3447 state
->min_recv_size
= 0;
3449 state
->pktfull
= smb2_len(state
->hdr
.nbt
);
3450 if (state
->pktfull
== 0) {
3454 if (state
->min_recv_size
!= 0) {
3455 min_recvfile_size
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
3456 min_recvfile_size
+= state
->min_recv_size
;
3459 if (state
->pktfull
> min_recvfile_size
) {
3461 * Might be a receivefile write. Read the SMB2 HEADER +
3462 * SMB2_WRITE header first. Set 'doing_receivefile'
3463 * as we're *attempting* receivefile write. If this
3464 * turns out not to be a SMB2_WRITE request or otherwise
3465 * not suitable then we'll just read the rest of the data
3466 * the next time this function is called.
3468 state
->pktlen
= SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
;
3469 state
->doing_receivefile
= true;
3471 state
->pktlen
= state
->pktfull
;
3474 state
->pktbuf
= talloc_array(state
->req
, uint8_t, state
->pktlen
);
3475 if (state
->pktbuf
== NULL
) {
3476 return NT_STATUS_NO_MEMORY
;
3479 state
->vector
.iov_base
= (void *)state
->pktbuf
;
3480 state
->vector
.iov_len
= state
->pktlen
;
3486 if (state
->hdr
.nbt
[0] != 0x00) {
3487 DEBUG(1,("ignore NBT[0x%02X] msg\n",
3488 state
->hdr
.nbt
[0]));
3491 ZERO_STRUCTP(state
);
3493 state
->min_recv_size
= lp_min_receive_file_size();
3501 req
->request_time
= timeval_current();
3502 now
= timeval_to_nttime(&req
->request_time
);
3504 status
= smbd_smb2_inbuf_parse_compound(xconn
,
3510 &req
->in
.vector_count
);
3511 if (!NT_STATUS_IS_OK(status
)) {
3515 if (state
->doing_receivefile
) {
3516 req
->smb1req
= talloc_zero(req
, struct smb_request
);
3517 if (req
->smb1req
== NULL
) {
3518 return NT_STATUS_NO_MEMORY
;
3520 req
->smb1req
->unread_bytes
= state
->pktfull
- state
->pktlen
;
3523 ZERO_STRUCTP(state
);
3525 req
->current_idx
= 1;
3527 DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
3528 req
->current_idx
, req
->in
.vector_count
));
3530 status
= smbd_smb2_request_validate(req
);
3531 if (!NT_STATUS_IS_OK(status
)) {
3535 status
= smbd_smb2_request_setup_out(req
);
3536 if (!NT_STATUS_IS_OK(status
)) {
3540 status
= smbd_smb2_request_dispatch(req
);
3541 if (!NT_STATUS_IS_OK(status
)) {
3545 sconn
->num_requests
++;
3547 /* The timeout_processing function isn't run nearly
3548 often enough to implement 'max log size' without
3549 overrunning the size of the file by many megabytes.
3550 This is especially true if we are running at debug
3551 level 10. Checking every 50 SMB2s is a nice
3552 tradeoff of performance vs log file size overrun. */
3554 if ((sconn
->num_requests
% 50) == 0 &&
3555 need_to_check_log_size()) {
3556 change_to_root_user();
3560 status
= smbd_smb2_request_next_incoming(xconn
);
3561 if (!NT_STATUS_IS_OK(status
)) {
3565 return NT_STATUS_OK
;
3568 static void smbd_smb2_connection_handler(struct tevent_context
*ev
,
3569 struct tevent_fd
*fde
,
3573 struct smbXsrv_connection
*xconn
=
3574 talloc_get_type_abort(private_data
,
3575 struct smbXsrv_connection
);
3578 status
= smbd_smb2_io_handler(xconn
, flags
);
3579 if (!NT_STATUS_IS_OK(status
)) {
3580 smbd_server_connection_terminate(xconn
, nt_errstr(status
));