2 Unix SMB/CIFS implementation.
3 Infrastructure for async SMB client requests
4 Copyright (C) Volker Lendecke 2008
5 Copyright (C) Stefan Metzmacher 2011
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/network.h"
23 #include "../lib/async_req/async_sock.h"
24 #include "../lib/util/tevent_ntstatus.h"
25 #include "../lib/util/tevent_unix.h"
26 #include "lib/util/util_net.h"
27 #include "lib/util/dlinklist.h"
28 #include "lib/util/iov_buf.h"
29 #include "../libcli/smb/smb_common.h"
30 #include "../libcli/smb/smb_seal.h"
31 #include "../libcli/smb/smb_signing.h"
32 #include "../libcli/smb/read_smb.h"
33 #include "smbXcli_base.h"
34 #include "librpc/ndr/libndr.h"
35 #include "libcli/smb/smb2_negotiate_context.h"
36 #include "lib/crypto/sha512.h"
37 #include "lib/crypto/aes.h"
38 #include "lib/crypto/aes_ccm_128.h"
39 #include "lib/crypto/aes_gcm_128.h"
43 struct smbXcli_session;
48 struct sockaddr_storage local_ss;
49 struct sockaddr_storage remote_ss;
50 const char *remote_name;
52 struct tevent_queue *outgoing;
53 struct tevent_req **pending;
54 struct tevent_req *read_smb_req;
55 struct tevent_req *suicide_req;
57 enum protocol_types min_protocol;
58 enum protocol_types max_protocol;
59 enum protocol_types protocol;
62 bool mandatory_signing;
65 * The incoming dispatch function should return:
66 * - NT_STATUS_RETRY, if more incoming PDUs are expected.
67 * - NT_STATUS_OK, if no more processing is desired, e.g.
68 * the dispatch function called
70 * - All other return values disconnect the connection.
72 NTSTATUS (*dispatch_incoming)(struct smbXcli_conn *conn,
78 uint32_t capabilities;
83 uint32_t capabilities;
86 uint16_t security_mode;
95 const char *workgroup;
101 uint32_t capabilities;
106 struct smb_signing_state *signing;
107 struct smb_trans_enc_state *trans_enc;
109 struct tevent_req *read_braw_req;
114 uint32_t capabilities;
115 uint16_t security_mode;
120 uint32_t capabilities;
121 uint16_t security_mode;
123 uint32_t max_trans_size;
124 uint32_t max_read_size;
125 uint32_t max_write_size;
133 uint16_t cur_credits;
134 uint16_t max_credits;
136 uint32_t cc_chunk_len;
137 uint32_t cc_max_chunks;
141 uint8_t preauth_sha512[64];
144 struct smbXcli_session *sessions;
147 struct smb2cli_session {
149 uint16_t session_flags;
150 DATA_BLOB application_key;
151 DATA_BLOB signing_key;
154 DATA_BLOB encryption_key;
155 DATA_BLOB decryption_key;
156 uint64_t nonce_high_random;
157 uint64_t nonce_high_max;
160 uint16_t channel_sequence;
164 struct smbXcli_session {
165 struct smbXcli_session *prev, *next;
166 struct smbXcli_conn *conn;
170 DATA_BLOB application_key;
174 struct smb2cli_session *smb2;
177 DATA_BLOB signing_key;
178 uint8_t preauth_sha512[64];
182 * this should be a short term hack
183 * until the upper layers have implemented
186 bool disconnect_expired;
189 struct smbXcli_tcon {
191 uint32_t fs_attributes;
195 uint16_t optional_support;
196 uint32_t maximal_access;
197 uint32_t guest_maximal_access;
206 uint32_t capabilities;
207 uint32_t maximal_access;
213 struct smbXcli_req_state {
214 struct tevent_context *ev;
215 struct smbXcli_conn *conn;
216 struct smbXcli_session *session; /* maybe NULL */
217 struct smbXcli_tcon *tcon; /* maybe NULL */
219 uint8_t length_hdr[4];
226 /* Space for the header including the wct */
227 uint8_t hdr[HDR_VWV];
230 * For normal requests, smb1cli_req_send chooses a mid.
231 * SecondaryV trans requests need to use the mid of the primary
232 * request, so we need a place to store it.
233 * Assume it is set if != 0.
238 uint8_t bytecount_buf[2];
240 #define MAX_SMB_IOV 10
241 /* length_hdr, hdr, words, byte_count, buffers */
242 struct iovec iov[1 + 3 + MAX_SMB_IOV];
247 struct tevent_req **chained_requests;
250 NTSTATUS recv_status;
251 /* always an array of 3 talloc elements */
252 struct iovec *recv_iov;
256 const uint8_t *fixed;
261 uint8_t transform[SMB2_TF_HDR_SIZE];
262 uint8_t hdr[SMB2_HDR_BODY];
263 uint8_t pad[7]; /* padding space for compounding */
266 * always an array of 3 talloc elements
267 * (without a SMB2_TRANSFORM header!)
271 struct iovec *recv_iov;
274 * the expected max for the response dyn_len
276 uint32_t max_dyn_len;
278 uint16_t credit_charge;
282 uint64_t encryption_session_id;
284 bool signing_skipped;
287 uint16_t cancel_flags;
293 static int smbXcli_conn_destructor(struct smbXcli_conn *conn)
296 * NT_STATUS_OK, means we do not notify the callers
298 smbXcli_conn_disconnect(conn, NT_STATUS_OK);
300 while (conn->sessions) {
301 conn->sessions->conn = NULL;
302 DLIST_REMOVE(conn->sessions, conn->sessions);
305 if (conn->smb1.trans_enc) {
306 TALLOC_FREE(conn->smb1.trans_enc);
312 struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
314 const char *remote_name,
315 enum smb_signing_setting signing_state,
316 uint32_t smb1_capabilities,
317 struct GUID *client_guid,
318 uint32_t smb2_capabilities)
320 struct smbXcli_conn *conn = NULL;
322 struct sockaddr *sa = NULL;
326 conn = talloc_zero(mem_ctx, struct smbXcli_conn);
333 conn->remote_name = talloc_strdup(conn, remote_name);
334 if (conn->remote_name == NULL) {
338 ss = (void *)&conn->local_ss;
339 sa = (struct sockaddr *)ss;
340 sa_length = sizeof(conn->local_ss);
341 ret = getsockname(fd, sa, &sa_length);
345 ss = (void *)&conn->remote_ss;
346 sa = (struct sockaddr *)ss;
347 sa_length = sizeof(conn->remote_ss);
348 ret = getpeername(fd, sa, &sa_length);
353 conn->outgoing = tevent_queue_create(conn, "smbXcli_outgoing");
354 if (conn->outgoing == NULL) {
357 conn->pending = NULL;
359 conn->min_protocol = PROTOCOL_NONE;
360 conn->max_protocol = PROTOCOL_NONE;
361 conn->protocol = PROTOCOL_NONE;
363 switch (signing_state) {
364 case SMB_SIGNING_OFF:
366 conn->allow_signing = false;
367 conn->desire_signing = false;
368 conn->mandatory_signing = false;
370 case SMB_SIGNING_DEFAULT:
371 case SMB_SIGNING_IF_REQUIRED:
372 /* if the server requires it */
373 conn->allow_signing = true;
374 conn->desire_signing = false;
375 conn->mandatory_signing = false;
377 case SMB_SIGNING_REQUIRED:
379 conn->allow_signing = true;
380 conn->desire_signing = true;
381 conn->mandatory_signing = true;
385 conn->smb1.client.capabilities = smb1_capabilities;
386 conn->smb1.client.max_xmit = UINT16_MAX;
388 conn->smb1.capabilities = conn->smb1.client.capabilities;
389 conn->smb1.max_xmit = 1024;
393 /* initialise signing */
394 conn->smb1.signing = smb_signing_init(conn,
396 conn->desire_signing,
397 conn->mandatory_signing);
398 if (!conn->smb1.signing) {
402 conn->smb2.client.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
403 if (conn->mandatory_signing) {
404 conn->smb2.client.security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
407 conn->smb2.client.guid = *client_guid;
409 conn->smb2.client.capabilities = smb2_capabilities;
411 conn->smb2.cur_credits = 1;
412 conn->smb2.max_credits = 0;
413 conn->smb2.io_priority = 1;
416 * Samba and Windows servers accept a maximum of 16 MiB with a maximum
417 * chunk length of 1 MiB.
419 conn->smb2.cc_chunk_len = 1024 * 1024;
420 conn->smb2.cc_max_chunks = 16;
422 talloc_set_destructor(conn, smbXcli_conn_destructor);
430 bool smbXcli_conn_is_connected(struct smbXcli_conn *conn)
436 if (conn->sock_fd == -1) {
443 enum protocol_types smbXcli_conn_protocol(struct smbXcli_conn *conn)
445 return conn->protocol;
448 bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn)
450 if (conn->protocol >= PROTOCOL_SMB2_02) {
454 if (conn->smb1.capabilities & CAP_UNICODE) {
461 void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options)
463 set_socket_options(conn->sock_fd, options);
466 const struct sockaddr_storage *smbXcli_conn_local_sockaddr(struct smbXcli_conn *conn)
468 return &conn->local_ss;
471 const struct sockaddr_storage *smbXcli_conn_remote_sockaddr(struct smbXcli_conn *conn)
473 return &conn->remote_ss;
476 const char *smbXcli_conn_remote_name(struct smbXcli_conn *conn)
478 return conn->remote_name;
481 uint16_t smbXcli_conn_max_requests(struct smbXcli_conn *conn)
483 if (conn->protocol >= PROTOCOL_SMB2_02) {
490 return conn->smb1.server.max_mux;
493 NTTIME smbXcli_conn_server_system_time(struct smbXcli_conn *conn)
495 if (conn->protocol >= PROTOCOL_SMB2_02) {
496 return conn->smb2.server.system_time;
499 return conn->smb1.server.system_time;
502 const DATA_BLOB *smbXcli_conn_server_gss_blob(struct smbXcli_conn *conn)
504 if (conn->protocol >= PROTOCOL_SMB2_02) {
505 return &conn->smb2.server.gss_blob;
508 return &conn->smb1.server.gss_blob;
511 const struct GUID *smbXcli_conn_server_guid(struct smbXcli_conn *conn)
513 if (conn->protocol >= PROTOCOL_SMB2_02) {
514 return &conn->smb2.server.guid;
517 return &conn->smb1.server.guid;
520 struct smbXcli_conn_samba_suicide_state {
521 struct smbXcli_conn *conn;
524 struct tevent_req *write_req;
527 static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
528 enum tevent_req_state req_state);
529 static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq);
531 struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx,
532 struct tevent_context *ev,
533 struct smbXcli_conn *conn,
536 struct tevent_req *req, *subreq;
537 struct smbXcli_conn_samba_suicide_state *state;
539 req = tevent_req_create(mem_ctx, &state,
540 struct smbXcli_conn_samba_suicide_state);
545 SIVAL(state->buf, 4, 0x74697865);
546 SCVAL(state->buf, 8, exitcode);
547 _smb_setlen_nbt(state->buf, sizeof(state->buf)-4);
549 if (conn->suicide_req != NULL) {
550 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
551 return tevent_req_post(req, ev);
554 state->iov.iov_base = state->buf;
555 state->iov.iov_len = sizeof(state->buf);
557 subreq = writev_send(state, ev, conn->outgoing, conn->sock_fd,
558 false, &state->iov, 1);
559 if (tevent_req_nomem(subreq, req)) {
560 return tevent_req_post(req, ev);
562 tevent_req_set_callback(subreq, smbXcli_conn_samba_suicide_done, req);
563 state->write_req = subreq;
565 tevent_req_set_cleanup_fn(req, smbXcli_conn_samba_suicide_cleanup);
568 * We need to use tevent_req_defer_callback()
569 * in order to allow smbXcli_conn_disconnect()
570 * to do a safe cleanup.
572 tevent_req_defer_callback(req, ev);
573 conn->suicide_req = req;
578 static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
579 enum tevent_req_state req_state)
581 struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
582 req, struct smbXcli_conn_samba_suicide_state);
584 TALLOC_FREE(state->write_req);
586 if (state->conn == NULL) {
590 if (state->conn->suicide_req == req) {
591 state->conn->suicide_req = NULL;
596 static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq)
598 struct tevent_req *req = tevent_req_callback_data(
599 subreq, struct tevent_req);
600 struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
601 req, struct smbXcli_conn_samba_suicide_state);
605 state->write_req = NULL;
607 nwritten = writev_recv(subreq, &err);
609 if (nwritten == -1) {
610 /* here, we need to notify all pending requests */
611 NTSTATUS status = map_nt_error_from_unix_common(err);
612 smbXcli_conn_disconnect(state->conn, status);
615 tevent_req_done(req);
618 NTSTATUS smbXcli_conn_samba_suicide_recv(struct tevent_req *req)
620 return tevent_req_simple_recv_ntstatus(req);
623 NTSTATUS smbXcli_conn_samba_suicide(struct smbXcli_conn *conn,
626 TALLOC_CTX *frame = talloc_stackframe();
627 struct tevent_context *ev;
628 struct tevent_req *req;
629 NTSTATUS status = NT_STATUS_NO_MEMORY;
632 if (smbXcli_conn_has_async_calls(conn)) {
634 * Can't use sync call while an async call is in flight
636 status = NT_STATUS_INVALID_PARAMETER_MIX;
639 ev = samba_tevent_context_init(frame);
643 req = smbXcli_conn_samba_suicide_send(frame, ev, conn, exitcode);
647 ok = tevent_req_poll_ntstatus(req, ev, &status);
651 status = smbXcli_conn_samba_suicide_recv(req);
657 uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn)
659 return conn->smb1.capabilities;
662 uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn)
664 return conn->smb1.max_xmit;
667 bool smb1cli_conn_req_possible(struct smbXcli_conn *conn)
669 size_t pending = talloc_array_length(conn->pending);
670 uint16_t possible = conn->smb1.server.max_mux;
672 if (pending >= possible) {
679 uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn)
681 return conn->smb1.server.session_key;
684 const uint8_t *smb1cli_conn_server_challenge(struct smbXcli_conn *conn)
686 return conn->smb1.server.challenge;
689 uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn)
691 return conn->smb1.server.security_mode;
694 bool smb1cli_conn_server_readbraw(struct smbXcli_conn *conn)
696 return conn->smb1.server.readbraw;
699 bool smb1cli_conn_server_writebraw(struct smbXcli_conn *conn)
701 return conn->smb1.server.writebraw;
704 bool smb1cli_conn_server_lockread(struct smbXcli_conn *conn)
706 return conn->smb1.server.lockread;
709 bool smb1cli_conn_server_writeunlock(struct smbXcli_conn *conn)
711 return conn->smb1.server.writeunlock;
714 int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn)
716 return conn->smb1.server.time_zone;
719 bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
720 const DATA_BLOB user_session_key,
721 const DATA_BLOB response)
723 return smb_signing_activate(conn->smb1.signing,
728 bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
729 const uint8_t *buf, uint32_t seqnum)
731 const uint8_t *hdr = buf + NBT_HDR_SIZE;
732 size_t len = smb_len_nbt(buf);
734 return smb_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
737 bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
739 return smb_signing_is_active(conn->smb1.signing);
742 void smb1cli_conn_set_encryption(struct smbXcli_conn *conn,
743 struct smb_trans_enc_state *es)
745 /* Replace the old state, if any. */
746 if (conn->smb1.trans_enc) {
747 TALLOC_FREE(conn->smb1.trans_enc);
749 conn->smb1.trans_enc = es;
752 bool smb1cli_conn_encryption_on(struct smbXcli_conn *conn)
754 return common_encryption_on(conn->smb1.trans_enc);
758 static NTSTATUS smb1cli_pull_raw_error(const uint8_t *hdr)
760 uint32_t flags2 = SVAL(hdr, HDR_FLG2);
761 NTSTATUS status = NT_STATUS(IVAL(hdr, HDR_RCLS));
763 if (NT_STATUS_IS_OK(status)) {
767 if (flags2 & FLAGS2_32_BIT_ERROR_CODES) {
771 return NT_STATUS_DOS(CVAL(hdr, HDR_RCLS), SVAL(hdr, HDR_ERR));
775 * Is the SMB command able to hold an AND_X successor
776 * @param[in] cmd The SMB command in question
777 * @retval Can we add a chained request after "cmd"?
779 bool smb1cli_is_andx_req(uint8_t cmd)
799 static uint16_t smb1cli_alloc_mid(struct smbXcli_conn *conn)
801 size_t num_pending = talloc_array_length(conn->pending);
804 if (conn->protocol == PROTOCOL_NONE) {
806 * This is what windows sends on the SMB1 Negprot request
807 * and some vendors reuse the SMB1 MID as SMB2 sequence number.
815 result = conn->smb1.mid++;
816 if ((result == 0) || (result == 0xffff)) {
820 for (i=0; i<num_pending; i++) {
821 if (result == smb1cli_req_mid(conn->pending[i])) {
826 if (i == num_pending) {
832 void smbXcli_req_unset_pending(struct tevent_req *req)
834 struct smbXcli_req_state *state =
836 struct smbXcli_req_state);
837 struct smbXcli_conn *conn = state->conn;
838 size_t num_pending = talloc_array_length(conn->pending);
841 if (state->smb1.mid != 0) {
843 * This is a [nt]trans[2] request which waits
844 * for more than one reply.
849 tevent_req_set_cleanup_fn(req, NULL);
851 if (num_pending == 1) {
853 * The pending read_smb tevent_req is a child of
854 * conn->pending. So if nothing is pending anymore, we need to
855 * delete the socket read fde.
857 TALLOC_FREE(conn->pending);
858 conn->read_smb_req = NULL;
862 for (i=0; i<num_pending; i++) {
863 if (req == conn->pending[i]) {
867 if (i == num_pending) {
869 * Something's seriously broken. Just returning here is the
870 * right thing nevertheless, the point of this routine is to
871 * remove ourselves from conn->pending.
877 * Remove ourselves from the conn->pending array
879 for (; i < (num_pending - 1); i++) {
880 conn->pending[i] = conn->pending[i+1];
884 * No NULL check here, we're shrinking by sizeof(void *), and
885 * talloc_realloc just adjusts the size for this.
887 conn->pending = talloc_realloc(NULL, conn->pending, struct tevent_req *,
892 static void smbXcli_req_cleanup(struct tevent_req *req,
893 enum tevent_req_state req_state)
895 struct smbXcli_req_state *state =
897 struct smbXcli_req_state);
900 case TEVENT_REQ_RECEIVED:
902 * Make sure we really remove it from
903 * the pending array on destruction.
906 smbXcli_req_unset_pending(req);
913 static bool smb1cli_req_cancel(struct tevent_req *req);
914 static bool smb2cli_req_cancel(struct tevent_req *req);
916 static bool smbXcli_req_cancel(struct tevent_req *req)
918 struct smbXcli_req_state *state =
920 struct smbXcli_req_state);
922 if (!smbXcli_conn_is_connected(state->conn)) {
926 if (state->conn->protocol == PROTOCOL_NONE) {
930 if (state->conn->protocol >= PROTOCOL_SMB2_02) {
931 return smb2cli_req_cancel(req);
934 return smb1cli_req_cancel(req);
937 static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
939 bool smbXcli_req_set_pending(struct tevent_req *req)
941 struct smbXcli_req_state *state =
943 struct smbXcli_req_state);
944 struct smbXcli_conn *conn;
945 struct tevent_req **pending;
950 if (!smbXcli_conn_is_connected(conn)) {
954 num_pending = talloc_array_length(conn->pending);
956 pending = talloc_realloc(conn, conn->pending, struct tevent_req *,
958 if (pending == NULL) {
961 pending[num_pending] = req;
962 conn->pending = pending;
963 tevent_req_set_cleanup_fn(req, smbXcli_req_cleanup);
964 tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
966 if (!smbXcli_conn_receive_next(conn)) {
968 * the caller should notify the current request
970 * And all other pending requests get notified
971 * by smbXcli_conn_disconnect().
973 smbXcli_req_unset_pending(req);
974 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
981 static void smbXcli_conn_received(struct tevent_req *subreq);
983 static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
985 size_t num_pending = talloc_array_length(conn->pending);
986 struct tevent_req *req;
987 struct smbXcli_req_state *state;
989 if (conn->read_smb_req != NULL) {
993 if (num_pending == 0) {
994 if (conn->smb2.mid < UINT64_MAX) {
995 /* no more pending requests, so we are done for now */
1000 * If there are no more SMB2 requests possible,
1001 * because we are out of message ids,
1002 * we need to disconnect.
1004 smbXcli_conn_disconnect(conn, NT_STATUS_CONNECTION_ABORTED);
1008 req = conn->pending[0];
1009 state = tevent_req_data(req, struct smbXcli_req_state);
1012 * We're the first ones, add the read_smb request that waits for the
1013 * answer from the server
1015 conn->read_smb_req = read_smb_send(conn->pending,
1018 if (conn->read_smb_req == NULL) {
1021 tevent_req_set_callback(conn->read_smb_req, smbXcli_conn_received, conn);
1025 void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
1027 struct smbXcli_session *session;
1028 int sock_fd = conn->sock_fd;
1030 tevent_queue_stop(conn->outgoing);
1034 session = conn->sessions;
1035 if (talloc_array_length(conn->pending) == 0) {
1037 * if we do not have pending requests
1038 * there is no need to update the channel_sequence
1042 for (; session; session = session->next) {
1043 smb2cli_session_increment_channel_sequence(session);
1046 if (conn->suicide_req != NULL) {
1048 * smbXcli_conn_samba_suicide_send()
1049 * used tevent_req_defer_callback() already.
1051 if (!NT_STATUS_IS_OK(status)) {
1052 tevent_req_nterror(conn->suicide_req, status);
1054 conn->suicide_req = NULL;
1058 * Cancel all pending requests. We do not do a for-loop walking
1059 * conn->pending because that array changes in
1060 * smbXcli_req_unset_pending.
1062 while (talloc_array_length(conn->pending) > 0) {
1063 struct tevent_req *req;
1064 struct smbXcli_req_state *state;
1065 struct tevent_req **chain;
1069 req = conn->pending[0];
1070 state = tevent_req_data(req, struct smbXcli_req_state);
1072 if (state->smb1.chained_requests == NULL) {
1074 * We're dead. No point waiting for trans2
1077 state->smb1.mid = 0;
1079 smbXcli_req_unset_pending(req);
1081 if (NT_STATUS_IS_OK(status)) {
1082 /* do not notify the callers */
1087 * we need to defer the callback, because we may notify
1088 * more then one caller.
1090 tevent_req_defer_callback(req, state->ev);
1091 tevent_req_nterror(req, status);
1095 chain = talloc_move(conn, &state->smb1.chained_requests);
1096 num_chained = talloc_array_length(chain);
1098 for (i=0; i<num_chained; i++) {
1100 state = tevent_req_data(req, struct smbXcli_req_state);
1103 * We're dead. No point waiting for trans2
1106 state->smb1.mid = 0;
1108 smbXcli_req_unset_pending(req);
1110 if (NT_STATUS_IS_OK(status)) {
1111 /* do not notify the callers */
1116 * we need to defer the callback, because we may notify
1117 * more than one caller.
1119 tevent_req_defer_callback(req, state->ev);
1120 tevent_req_nterror(req, status);
1125 if (sock_fd != -1) {
1131 * Fetch a smb request's mid. Only valid after the request has been sent by
1132 * smb1cli_req_send().
1134 uint16_t smb1cli_req_mid(struct tevent_req *req)
1136 struct smbXcli_req_state *state =
1137 tevent_req_data(req,
1138 struct smbXcli_req_state);
1140 if (state->smb1.mid != 0) {
1141 return state->smb1.mid;
1144 return SVAL(state->smb1.hdr, HDR_MID);
1147 void smb1cli_req_set_mid(struct tevent_req *req, uint16_t mid)
1149 struct smbXcli_req_state *state =
1150 tevent_req_data(req,
1151 struct smbXcli_req_state);
1153 state->smb1.mid = mid;
1156 uint32_t smb1cli_req_seqnum(struct tevent_req *req)
1158 struct smbXcli_req_state *state =
1159 tevent_req_data(req,
1160 struct smbXcli_req_state);
1162 return state->smb1.seqnum;
1165 void smb1cli_req_set_seqnum(struct tevent_req *req, uint32_t seqnum)
1167 struct smbXcli_req_state *state =
1168 tevent_req_data(req,
1169 struct smbXcli_req_state);
1171 state->smb1.seqnum = seqnum;
1174 static size_t smbXcli_iov_len(const struct iovec *iov, int count)
1176 ssize_t ret = iov_buflen(iov, count);
1178 /* Ignore the overflow case for now ... */
1182 static uint8_t *smbXcli_iov_concat(TALLOC_CTX *mem_ctx,
1183 const struct iovec *iov,
1189 buflen = iov_buflen(iov, count);
1194 buf = talloc_array(mem_ctx, uint8_t, buflen);
1199 iov_buf(iov, count, buf, buflen);
1204 static void smb1cli_req_flags(enum protocol_types protocol,
1205 uint32_t smb1_capabilities,
1206 uint8_t smb_command,
1207 uint8_t additional_flags,
1208 uint8_t clear_flags,
1210 uint16_t additional_flags2,
1211 uint16_t clear_flags2,
1215 uint16_t flags2 = 0;
1217 if (protocol >= PROTOCOL_LANMAN1) {
1218 flags |= FLAG_CASELESS_PATHNAMES;
1219 flags |= FLAG_CANONICAL_PATHNAMES;
1222 if (protocol >= PROTOCOL_LANMAN2) {
1223 flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
1224 flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
1227 if (protocol >= PROTOCOL_NT1) {
1228 flags2 |= FLAGS2_IS_LONG_NAME;
1230 if (smb1_capabilities & CAP_UNICODE) {
1231 flags2 |= FLAGS2_UNICODE_STRINGS;
1233 if (smb1_capabilities & CAP_STATUS32) {
1234 flags2 |= FLAGS2_32_BIT_ERROR_CODES;
1236 if (smb1_capabilities & CAP_EXTENDED_SECURITY) {
1237 flags2 |= FLAGS2_EXTENDED_SECURITY;
1241 flags |= additional_flags;
1242 flags &= ~clear_flags;
1243 flags2 |= additional_flags2;
1244 flags2 &= ~clear_flags2;
1250 static void smb1cli_req_cancel_done(struct tevent_req *subreq);
1252 static bool smb1cli_req_cancel(struct tevent_req *req)
1254 struct smbXcli_req_state *state =
1255 tevent_req_data(req,
1256 struct smbXcli_req_state);
1261 struct tevent_req *subreq;
1264 flags = CVAL(state->smb1.hdr, HDR_FLG);
1265 flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
1266 pid = SVAL(state->smb1.hdr, HDR_PID);
1267 pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
1268 mid = SVAL(state->smb1.hdr, HDR_MID);
1270 subreq = smb1cli_req_create(state, state->ev,
1280 0, NULL); /* bytes */
1281 if (subreq == NULL) {
1284 smb1cli_req_set_mid(subreq, mid);
1286 status = smb1cli_req_chain_submit(&subreq, 1);
1287 if (!NT_STATUS_IS_OK(status)) {
1288 TALLOC_FREE(subreq);
1291 smb1cli_req_set_mid(subreq, 0);
1293 tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
1298 static void smb1cli_req_cancel_done(struct tevent_req *subreq)
1300 /* we do not care about the result */
1301 TALLOC_FREE(subreq);
1304 struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
1305 struct tevent_context *ev,
1306 struct smbXcli_conn *conn,
1307 uint8_t smb_command,
1308 uint8_t additional_flags,
1309 uint8_t clear_flags,
1310 uint16_t additional_flags2,
1311 uint16_t clear_flags2,
1312 uint32_t timeout_msec,
1314 struct smbXcli_tcon *tcon,
1315 struct smbXcli_session *session,
1316 uint8_t wct, uint16_t *vwv,
1318 struct iovec *bytes_iov)
1320 struct tevent_req *req;
1321 struct smbXcli_req_state *state;
1323 uint16_t flags2 = 0;
1328 if (iov_count > MAX_SMB_IOV) {
1330 * Should not happen :-)
1335 req = tevent_req_create(mem_ctx, &state,
1336 struct smbXcli_req_state);
1342 state->session = session;
1346 uid = session->smb1.session_id;
1350 tid = tcon->smb1.tcon_id;
1352 if (tcon->fs_attributes & FILE_CASE_SENSITIVE_SEARCH) {
1353 clear_flags |= FLAG_CASELESS_PATHNAMES;
1355 /* Default setting, case insensitive. */
1356 additional_flags |= FLAG_CASELESS_PATHNAMES;
1359 if (smbXcli_conn_dfs_supported(conn) &&
1360 smbXcli_tcon_is_dfs_share(tcon))
1362 additional_flags2 |= FLAGS2_DFS_PATHNAMES;
1366 state->smb1.recv_cmd = 0xFF;
1367 state->smb1.recv_status = NT_STATUS_INTERNAL_ERROR;
1368 state->smb1.recv_iov = talloc_zero_array(state, struct iovec, 3);
1369 if (state->smb1.recv_iov == NULL) {
1374 smb1cli_req_flags(conn->protocol,
1375 conn->smb1.capabilities,
1384 SIVAL(state->smb1.hdr, 0, SMB_MAGIC);
1385 SCVAL(state->smb1.hdr, HDR_COM, smb_command);
1386 SIVAL(state->smb1.hdr, HDR_RCLS, NT_STATUS_V(NT_STATUS_OK));
1387 SCVAL(state->smb1.hdr, HDR_FLG, flags);
1388 SSVAL(state->smb1.hdr, HDR_FLG2, flags2);
1389 SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);
1390 SSVAL(state->smb1.hdr, HDR_TID, tid);
1391 SSVAL(state->smb1.hdr, HDR_PID, pid);
1392 SSVAL(state->smb1.hdr, HDR_UID, uid);
1393 SSVAL(state->smb1.hdr, HDR_MID, 0); /* this comes later */
1394 SCVAL(state->smb1.hdr, HDR_WCT, wct);
1396 state->smb1.vwv = vwv;
1398 num_bytes = iov_buflen(bytes_iov, iov_count);
1399 if (num_bytes == -1) {
1401 * I'd love to add a check for num_bytes<=UINT16_MAX here, but
1402 * the smbclient->samba connections can lie and transfer more.
1408 SSVAL(state->smb1.bytecount_buf, 0, num_bytes);
1410 state->smb1.iov[0].iov_base = (void *)state->length_hdr;
1411 state->smb1.iov[0].iov_len = sizeof(state->length_hdr);
1412 state->smb1.iov[1].iov_base = (void *)state->smb1.hdr;
1413 state->smb1.iov[1].iov_len = sizeof(state->smb1.hdr);
1414 state->smb1.iov[2].iov_base = (void *)state->smb1.vwv;
1415 state->smb1.iov[2].iov_len = wct * sizeof(uint16_t);
1416 state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;
1417 state->smb1.iov[3].iov_len = sizeof(uint16_t);
1419 if (iov_count != 0) {
1420 memcpy(&state->smb1.iov[4], bytes_iov,
1421 iov_count * sizeof(*bytes_iov));
1423 state->smb1.iov_count = iov_count + 4;
1425 if (timeout_msec > 0) {
1426 struct timeval endtime;
1428 endtime = timeval_current_ofs_msec(timeout_msec);
1429 if (!tevent_req_set_endtime(req, ev, endtime)) {
1434 switch (smb_command) {
1438 state->one_way = true;
1441 state->one_way = true;
1442 state->smb1.one_way_seqnum = true;
1446 (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
1447 state->one_way = true;
1455 static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
1456 struct iovec *iov, int iov_count,
1458 bool one_way_seqnum)
1460 TALLOC_CTX *frame = NULL;
1464 * Obvious optimization: Make cli_calculate_sign_mac work with struct
1465 * iovec directly. MD5Update would do that just fine.
1468 if (iov_count < 4) {
1469 return NT_STATUS_INVALID_PARAMETER_MIX;
1471 if (iov[0].iov_len != NBT_HDR_SIZE) {
1472 return NT_STATUS_INVALID_PARAMETER_MIX;
1474 if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1475 return NT_STATUS_INVALID_PARAMETER_MIX;
1477 if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1478 return NT_STATUS_INVALID_PARAMETER_MIX;
1480 if (iov[3].iov_len != sizeof(uint16_t)) {
1481 return NT_STATUS_INVALID_PARAMETER_MIX;
1484 frame = talloc_stackframe();
1486 buf = smbXcli_iov_concat(frame, &iov[1], iov_count - 1);
1488 return NT_STATUS_NO_MEMORY;
1491 *seqnum = smb_signing_next_seqnum(conn->smb1.signing,
1493 smb_signing_sign_pdu(conn->smb1.signing,
1494 buf, talloc_get_size(buf),
1496 memcpy(iov[1].iov_base, buf, iov[1].iov_len);
1499 return NT_STATUS_OK;
1502 static void smb1cli_req_writev_done(struct tevent_req *subreq);
1503 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1504 TALLOC_CTX *tmp_mem,
1507 static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
1508 struct smbXcli_req_state *state,
1509 struct iovec *iov, int iov_count)
1511 struct tevent_req *subreq;
1517 if (!smbXcli_conn_is_connected(state->conn)) {
1518 return NT_STATUS_CONNECTION_DISCONNECTED;
1521 if (state->conn->protocol > PROTOCOL_NT1) {
1522 return NT_STATUS_REVISION_MISMATCH;
1525 if (iov_count < 4) {
1526 return NT_STATUS_INVALID_PARAMETER_MIX;
1528 if (iov[0].iov_len != NBT_HDR_SIZE) {
1529 return NT_STATUS_INVALID_PARAMETER_MIX;
1531 if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1532 return NT_STATUS_INVALID_PARAMETER_MIX;
1534 if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1535 return NT_STATUS_INVALID_PARAMETER_MIX;
1537 if (iov[3].iov_len != sizeof(uint16_t)) {
1538 return NT_STATUS_INVALID_PARAMETER_MIX;
1541 cmd = CVAL(iov[1].iov_base, HDR_COM);
1542 if (cmd == SMBreadBraw) {
1543 if (smbXcli_conn_has_async_calls(state->conn)) {
1544 return NT_STATUS_INVALID_PARAMETER_MIX;
1546 state->conn->smb1.read_braw_req = req;
1549 if (state->smb1.mid != 0) {
1550 mid = state->smb1.mid;
1552 mid = smb1cli_alloc_mid(state->conn);
1554 SSVAL(iov[1].iov_base, HDR_MID, mid);
1556 nbtlen = iov_buflen(&iov[1], iov_count-1);
1557 if ((nbtlen == -1) || (nbtlen > 0x1FFFF)) {
1558 return NT_STATUS_INVALID_PARAMETER_MIX;
1561 _smb_setlen_nbt(iov[0].iov_base, nbtlen);
1563 status = smb1cli_conn_signv(state->conn, iov, iov_count,
1564 &state->smb1.seqnum,
1565 state->smb1.one_way_seqnum);
1567 if (!NT_STATUS_IS_OK(status)) {
1572 * If we supported multiple encrytion contexts
1573 * here we'd look up based on tid.
1575 if (common_encryption_on(state->conn->smb1.trans_enc)) {
1576 char *buf, *enc_buf;
1578 buf = (char *)smbXcli_iov_concat(talloc_tos(), iov, iov_count);
1580 return NT_STATUS_NO_MEMORY;
1582 status = common_encrypt_buffer(state->conn->smb1.trans_enc,
1583 (char *)buf, &enc_buf);
1585 if (!NT_STATUS_IS_OK(status)) {
1586 DEBUG(0, ("Error in encrypting client message: %s\n",
1587 nt_errstr(status)));
1590 buf = (char *)talloc_memdup(state, enc_buf,
1591 smb_len_nbt(enc_buf)+4);
1594 return NT_STATUS_NO_MEMORY;
1596 iov[0].iov_base = (void *)buf;
1597 iov[0].iov_len = talloc_get_size(buf);
1601 if (state->conn->dispatch_incoming == NULL) {
1602 state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
1605 if (!smbXcli_req_set_pending(req)) {
1606 return NT_STATUS_NO_MEMORY;
1609 tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1611 subreq = writev_send(state, state->ev, state->conn->outgoing,
1612 state->conn->sock_fd, false, iov, iov_count);
1613 if (subreq == NULL) {
1614 return NT_STATUS_NO_MEMORY;
1616 tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
1617 return NT_STATUS_OK;
1620 struct tevent_req *smb1cli_req_send(TALLOC_CTX *mem_ctx,
1621 struct tevent_context *ev,
1622 struct smbXcli_conn *conn,
1623 uint8_t smb_command,
1624 uint8_t additional_flags,
1625 uint8_t clear_flags,
1626 uint16_t additional_flags2,
1627 uint16_t clear_flags2,
1628 uint32_t timeout_msec,
1630 struct smbXcli_tcon *tcon,
1631 struct smbXcli_session *session,
1632 uint8_t wct, uint16_t *vwv,
1634 const uint8_t *bytes)
1636 struct tevent_req *req;
1640 iov.iov_base = discard_const_p(void, bytes);
1641 iov.iov_len = num_bytes;
1643 req = smb1cli_req_create(mem_ctx, ev, conn, smb_command,
1644 additional_flags, clear_flags,
1645 additional_flags2, clear_flags2,
1652 if (!tevent_req_is_in_progress(req)) {
1653 return tevent_req_post(req, ev);
1655 status = smb1cli_req_chain_submit(&req, 1);
1656 if (tevent_req_nterror(req, status)) {
1657 return tevent_req_post(req, ev);
1662 static void smb1cli_req_writev_done(struct tevent_req *subreq)
1664 struct tevent_req *req =
1665 tevent_req_callback_data(subreq,
1667 struct smbXcli_req_state *state =
1668 tevent_req_data(req,
1669 struct smbXcli_req_state);
1673 nwritten = writev_recv(subreq, &err);
1674 TALLOC_FREE(subreq);
1675 if (nwritten == -1) {
1676 /* here, we need to notify all pending requests */
1677 NTSTATUS status = map_nt_error_from_unix_common(err);
1678 smbXcli_conn_disconnect(state->conn, status);
1682 if (state->one_way) {
1683 state->inbuf = NULL;
1684 tevent_req_done(req);
1689 static void smbXcli_conn_received(struct tevent_req *subreq)
1691 struct smbXcli_conn *conn =
1692 tevent_req_callback_data(subreq,
1693 struct smbXcli_conn);
1694 TALLOC_CTX *frame = talloc_stackframe();
1700 if (subreq != conn->read_smb_req) {
1701 DEBUG(1, ("Internal error: cli_smb_received called with "
1702 "unexpected subreq\n"));
1703 smbXcli_conn_disconnect(conn, NT_STATUS_INTERNAL_ERROR);
1707 conn->read_smb_req = NULL;
1709 received = read_smb_recv(subreq, frame, &inbuf, &err);
1710 TALLOC_FREE(subreq);
1711 if (received == -1) {
1712 status = map_nt_error_from_unix_common(err);
1713 smbXcli_conn_disconnect(conn, status);
1718 status = conn->dispatch_incoming(conn, frame, inbuf);
1720 if (NT_STATUS_IS_OK(status)) {
1722 * We should not do any more processing
1723 * as the dispatch function called
1724 * tevent_req_done().
1729 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1731 * We got an error, so notify all pending requests
1733 smbXcli_conn_disconnect(conn, status);
1738 * We got NT_STATUS_RETRY, so we may ask for a
1739 * next incoming pdu.
1741 if (!smbXcli_conn_receive_next(conn)) {
1742 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1746 static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
1747 struct iovec **piov, int *pnum_iov)
1758 size_t min_size = MIN_SMB_SIZE;
1760 buflen = smb_len_tcp(buf);
1763 hdr = buf + NBT_HDR_SIZE;
1765 status = smb1cli_pull_raw_error(hdr);
1766 if (NT_STATUS_IS_ERR(status)) {
1768 * This is an ugly hack to support OS/2
1769 * which skips the byte_count in the DATA block
1770 * on some error responses.
1774 min_size -= sizeof(uint16_t);
1777 if (buflen < min_size) {
1778 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1782 * This returns iovec elements in the following order:
1797 iov = talloc_array(mem_ctx, struct iovec, num_iov);
1799 return NT_STATUS_NO_MEMORY;
1801 iov[0].iov_base = hdr;
1802 iov[0].iov_len = HDR_WCT;
1805 cmd = CVAL(hdr, HDR_COM);
1809 size_t len = buflen - taken;
1811 struct iovec *iov_tmp;
1818 * we need at least WCT
1820 needed = sizeof(uint8_t);
1822 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1823 __location__, (int)len, (int)needed));
1828 * Now we check if the specified words are there
1830 wct = CVAL(hdr, wct_ofs);
1831 needed += wct * sizeof(uint16_t);
1833 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1834 __location__, (int)len, (int)needed));
1838 if ((num_iov == 1) &&
1840 NT_STATUS_IS_ERR(status))
1843 * This is an ugly hack to support OS/2
1844 * which skips the byte_count in the DATA block
1845 * on some error responses.
1849 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
1851 if (iov_tmp == NULL) {
1853 return NT_STATUS_NO_MEMORY;
1856 cur = &iov[num_iov];
1860 cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
1862 cur[1].iov_base = cur[0].iov_base;
1869 * we need at least BCC
1871 needed += sizeof(uint16_t);
1873 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1874 __location__, (int)len, (int)needed));
1879 * Now we check if the specified bytes are there
1881 bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
1882 bcc = SVAL(hdr, bcc_ofs);
1883 needed += bcc * sizeof(uint8_t);
1885 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1886 __location__, (int)len, (int)needed));
1891 * we allocate 2 iovec structures for words and bytes
1893 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
1895 if (iov_tmp == NULL) {
1897 return NT_STATUS_NO_MEMORY;
1900 cur = &iov[num_iov];
1903 cur[0].iov_len = wct * sizeof(uint16_t);
1904 cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
1905 cur[1].iov_len = bcc * sizeof(uint8_t);
1906 cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
1910 if (!smb1cli_is_andx_req(cmd)) {
1912 * If the current command does not have AndX chanining
1918 if (wct == 0 && bcc == 0) {
1920 * An empty response also ends the chain,
1921 * most likely with an error.
1927 DEBUG(10, ("%s: wct[%d] < 2 for cmd[0x%02X]\n",
1928 __location__, (int)wct, (int)cmd));
1931 cmd = CVAL(cur[0].iov_base, 0);
1934 * If it is the end of the chain we are also done.
1938 wct_ofs = SVAL(cur[0].iov_base, 2);
1940 if (wct_ofs < taken) {
1941 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1943 if (wct_ofs > buflen) {
1944 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1948 * we consumed everything up to the start of the next
1954 remaining = buflen - taken;
1956 if (remaining > 0 && num_iov >= 3) {
1958 * The last DATA block gets the remaining
1959 * bytes, this is needed to support
1960 * CAP_LARGE_WRITEX and CAP_LARGE_READX.
1962 iov[num_iov-1].iov_len += remaining;
1966 *pnum_iov = num_iov;
1967 return NT_STATUS_OK;
1971 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1974 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1975 TALLOC_CTX *tmp_mem,
1978 struct tevent_req *req;
1979 struct smbXcli_req_state *state;
1986 uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
1987 size_t len = smb_len_tcp(inbuf);
1988 struct iovec *iov = NULL;
1990 struct tevent_req **chain = NULL;
1991 size_t num_chained = 0;
1992 size_t num_responses = 0;
1994 if (conn->smb1.read_braw_req != NULL) {
1995 req = conn->smb1.read_braw_req;
1996 conn->smb1.read_braw_req = NULL;
1997 state = tevent_req_data(req, struct smbXcli_req_state);
1999 smbXcli_req_unset_pending(req);
2001 if (state->smb1.recv_iov == NULL) {
2003 * For requests with more than
2004 * one response, we have to readd the
2007 state->smb1.recv_iov = talloc_zero_array(state,
2010 if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2011 return NT_STATUS_OK;
2015 state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
2016 state->smb1.recv_iov[0].iov_len = len;
2017 ZERO_STRUCT(state->smb1.recv_iov[1]);
2018 ZERO_STRUCT(state->smb1.recv_iov[2]);
2020 state->smb1.recv_cmd = SMBreadBraw;
2021 state->smb1.recv_status = NT_STATUS_OK;
2022 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2024 tevent_req_done(req);
2025 return NT_STATUS_OK;
2028 if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
2029 && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
2030 DEBUG(10, ("Got non-SMB PDU\n"));
2031 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2035 * If we supported multiple encrytion contexts
2036 * here we'd look up based on tid.
2038 if (common_encryption_on(conn->smb1.trans_enc)
2039 && (CVAL(inbuf, 0) == 0)) {
2040 uint16_t enc_ctx_num;
2042 status = get_enc_ctx_num(inbuf, &enc_ctx_num);
2043 if (!NT_STATUS_IS_OK(status)) {
2044 DEBUG(10, ("get_enc_ctx_num returned %s\n",
2045 nt_errstr(status)));
2049 if (enc_ctx_num != conn->smb1.trans_enc->enc_ctx_num) {
2050 DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
2052 conn->smb1.trans_enc->enc_ctx_num));
2053 return NT_STATUS_INVALID_HANDLE;
2056 status = common_decrypt_buffer(conn->smb1.trans_enc,
2058 if (!NT_STATUS_IS_OK(status)) {
2059 DEBUG(10, ("common_decrypt_buffer returned %s\n",
2060 nt_errstr(status)));
2063 inhdr = inbuf + NBT_HDR_SIZE;
2064 len = smb_len_nbt(inbuf);
2067 mid = SVAL(inhdr, HDR_MID);
2068 num_pending = talloc_array_length(conn->pending);
2070 for (i=0; i<num_pending; i++) {
2071 if (mid == smb1cli_req_mid(conn->pending[i])) {
2075 if (i == num_pending) {
2076 /* Dump unexpected reply */
2077 return NT_STATUS_RETRY;
2080 oplock_break = false;
2082 if (mid == 0xffff) {
2084 * Paranoia checks that this is really an oplock break request.
2086 oplock_break = (len == 51); /* hdr + 8 words */
2087 oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
2088 oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
2089 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
2090 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
2092 if (!oplock_break) {
2093 /* Dump unexpected reply */
2094 return NT_STATUS_RETRY;
2098 req = conn->pending[i];
2099 state = tevent_req_data(req, struct smbXcli_req_state);
2101 if (!oplock_break /* oplock breaks are not signed */
2102 && !smb_signing_check_pdu(conn->smb1.signing,
2103 inhdr, len, state->smb1.seqnum+1)) {
2104 DEBUG(10, ("cli_check_sign_mac failed\n"));
2105 return NT_STATUS_ACCESS_DENIED;
2108 status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
2110 if (!NT_STATUS_IS_OK(status)) {
2111 DEBUG(10,("smb1cli_inbuf_parse_chain - %s\n",
2112 nt_errstr(status)));
2116 cmd = CVAL(inhdr, HDR_COM);
2117 status = smb1cli_pull_raw_error(inhdr);
2119 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
2120 (state->session != NULL) && state->session->disconnect_expired)
2123 * this should be a short term hack
2124 * until the upper layers have implemented
2125 * re-authentication.
2130 if (state->smb1.chained_requests == NULL) {
2132 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2135 smbXcli_req_unset_pending(req);
2137 if (state->smb1.recv_iov == NULL) {
2139 * For requests with more than
2140 * one response, we have to readd the
2143 state->smb1.recv_iov = talloc_zero_array(state,
2146 if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2147 return NT_STATUS_OK;
2151 state->smb1.recv_cmd = cmd;
2152 state->smb1.recv_status = status;
2153 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2155 state->smb1.recv_iov[0] = iov[0];
2156 state->smb1.recv_iov[1] = iov[1];
2157 state->smb1.recv_iov[2] = iov[2];
2159 if (talloc_array_length(conn->pending) == 0) {
2160 tevent_req_done(req);
2161 return NT_STATUS_OK;
2164 tevent_req_defer_callback(req, state->ev);
2165 tevent_req_done(req);
2166 return NT_STATUS_RETRY;
2169 chain = talloc_move(tmp_mem, &state->smb1.chained_requests);
2170 num_chained = talloc_array_length(chain);
2171 num_responses = (num_iov - 1)/2;
2173 if (num_responses > num_chained) {
2174 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2177 for (i=0; i<num_chained; i++) {
2178 size_t iov_idx = 1 + (i*2);
2179 struct iovec *cur = &iov[iov_idx];
2183 state = tevent_req_data(req, struct smbXcli_req_state);
2185 smbXcli_req_unset_pending(req);
2188 * as we finish multiple requests here
2189 * we need to defer the callbacks as
2190 * they could destroy our current stack state.
2192 tevent_req_defer_callback(req, state->ev);
2194 if (i >= num_responses) {
2195 tevent_req_nterror(req, NT_STATUS_REQUEST_ABORTED);
2199 if (state->smb1.recv_iov == NULL) {
2201 * For requests with more than
2202 * one response, we have to readd the
2205 state->smb1.recv_iov = talloc_zero_array(state,
2208 if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2213 state->smb1.recv_cmd = cmd;
2215 if (i == (num_responses - 1)) {
2217 * The last request in the chain gets the status
2219 state->smb1.recv_status = status;
2221 cmd = CVAL(cur[0].iov_base, 0);
2222 state->smb1.recv_status = NT_STATUS_OK;
2225 state->inbuf = inbuf;
2228 * Note: here we use talloc_reference() in a way
2229 * that does not expose it to the caller.
2231 inbuf_ref = talloc_reference(state->smb1.recv_iov, inbuf);
2232 if (tevent_req_nomem(inbuf_ref, req)) {
2236 /* copy the related buffers */
2237 state->smb1.recv_iov[0] = iov[0];
2238 state->smb1.recv_iov[1] = cur[0];
2239 state->smb1.recv_iov[2] = cur[1];
2241 tevent_req_done(req);
2244 return NT_STATUS_RETRY;
2247 NTSTATUS smb1cli_req_recv(struct tevent_req *req,
2248 TALLOC_CTX *mem_ctx,
2249 struct iovec **piov,
2253 uint32_t *pvwv_offset,
2254 uint32_t *pnum_bytes,
2256 uint32_t *pbytes_offset,
2258 const struct smb1cli_req_expected_response *expected,
2259 size_t num_expected)
2261 struct smbXcli_req_state *state =
2262 tevent_req_data(req,
2263 struct smbXcli_req_state);
2264 NTSTATUS status = NT_STATUS_OK;
2265 struct iovec *recv_iov = NULL;
2266 uint8_t *hdr = NULL;
2268 uint32_t vwv_offset = 0;
2269 uint16_t *vwv = NULL;
2270 uint32_t num_bytes = 0;
2271 uint32_t bytes_offset = 0;
2272 uint8_t *bytes = NULL;
2274 bool found_status = false;
2275 bool found_size = false;
2289 if (pvwv_offset != NULL) {
2292 if (pnum_bytes != NULL) {
2295 if (pbytes != NULL) {
2298 if (pbytes_offset != NULL) {
2301 if (pinbuf != NULL) {
2305 if (state->inbuf != NULL) {
2306 recv_iov = state->smb1.recv_iov;
2307 state->smb1.recv_iov = NULL;
2308 if (state->smb1.recv_cmd != SMBreadBraw) {
2309 hdr = (uint8_t *)recv_iov[0].iov_base;
2310 wct = recv_iov[1].iov_len/2;
2311 vwv = (uint16_t *)recv_iov[1].iov_base;
2312 vwv_offset = PTR_DIFF(vwv, hdr);
2313 num_bytes = recv_iov[2].iov_len;
2314 bytes = (uint8_t *)recv_iov[2].iov_base;
2315 bytes_offset = PTR_DIFF(bytes, hdr);
2319 if (tevent_req_is_nterror(req, &status)) {
2320 for (i=0; i < num_expected; i++) {
2321 if (NT_STATUS_EQUAL(status, expected[i].status)) {
2322 found_status = true;
2328 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2334 if (num_expected == 0) {
2335 found_status = true;
2339 status = state->smb1.recv_status;
2341 for (i=0; i < num_expected; i++) {
2342 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
2346 found_status = true;
2347 if (expected[i].wct == 0) {
2352 if (expected[i].wct == wct) {
2358 if (!found_status) {
2363 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2367 *piov = talloc_move(mem_ctx, &recv_iov);
2379 if (pvwv_offset != NULL) {
2380 *pvwv_offset = vwv_offset;
2382 if (pnum_bytes != NULL) {
2383 *pnum_bytes = num_bytes;
2385 if (pbytes != NULL) {
2388 if (pbytes_offset != NULL) {
2389 *pbytes_offset = bytes_offset;
2391 if (pinbuf != NULL) {
2392 *pinbuf = state->inbuf;
2398 size_t smb1cli_req_wct_ofs(struct tevent_req **reqs, int num_reqs)
2405 for (i=0; i<num_reqs; i++) {
2406 struct smbXcli_req_state *state;
2407 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2408 wct_ofs += smbXcli_iov_len(state->smb1.iov+2,
2409 state->smb1.iov_count-2);
2410 wct_ofs = (wct_ofs + 3) & ~3;
2415 NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
2417 struct smbXcli_req_state *first_state =
2418 tevent_req_data(reqs[0],
2419 struct smbXcli_req_state);
2420 struct smbXcli_req_state *state;
2422 size_t chain_padding = 0;
2424 struct iovec *iov = NULL;
2425 struct iovec *this_iov;
2429 if (num_reqs == 1) {
2430 return smb1cli_req_writev_submit(reqs[0], first_state,
2431 first_state->smb1.iov,
2432 first_state->smb1.iov_count);
2436 for (i=0; i<num_reqs; i++) {
2437 if (!tevent_req_is_in_progress(reqs[i])) {
2438 return NT_STATUS_INTERNAL_ERROR;
2441 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2443 if (state->smb1.iov_count < 4) {
2444 return NT_STATUS_INVALID_PARAMETER_MIX;
2449 * The NBT and SMB header
2462 iovlen += state->smb1.iov_count - 2;
2465 iov = talloc_zero_array(first_state, struct iovec, iovlen);
2467 return NT_STATUS_NO_MEMORY;
2470 first_state->smb1.chained_requests = (struct tevent_req **)talloc_memdup(
2471 first_state, reqs, sizeof(*reqs) * num_reqs);
2472 if (first_state->smb1.chained_requests == NULL) {
2474 return NT_STATUS_NO_MEMORY;
2477 wct_offset = HDR_WCT;
2480 for (i=0; i<num_reqs; i++) {
2481 size_t next_padding = 0;
2484 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2486 if (i < num_reqs-1) {
2487 if (!smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))
2488 || CVAL(state->smb1.hdr, HDR_WCT) < 2) {
2490 TALLOC_FREE(first_state->smb1.chained_requests);
2491 return NT_STATUS_INVALID_PARAMETER_MIX;
2495 wct_offset += smbXcli_iov_len(state->smb1.iov+2,
2496 state->smb1.iov_count-2) + 1;
2497 if ((wct_offset % 4) != 0) {
2498 next_padding = 4 - (wct_offset % 4);
2500 wct_offset += next_padding;
2501 vwv = state->smb1.vwv;
2503 if (i < num_reqs-1) {
2504 struct smbXcli_req_state *next_state =
2505 tevent_req_data(reqs[i+1],
2506 struct smbXcli_req_state);
2507 SCVAL(vwv+0, 0, CVAL(next_state->smb1.hdr, HDR_COM));
2509 SSVAL(vwv+1, 0, wct_offset);
2510 } else if (smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))) {
2511 /* properly end the chain */
2512 SCVAL(vwv+0, 0, 0xff);
2513 SCVAL(vwv+0, 1, 0xff);
2519 * The NBT and SMB header
2521 this_iov[0] = state->smb1.iov[0];
2522 this_iov[1] = state->smb1.iov[1];
2526 * This one is a bit subtle. We have to add
2527 * chain_padding bytes between the requests, and we
2528 * have to also include the wct field of the
2529 * subsequent requests. We use the subsequent header
2530 * for the padding, it contains the wct field in its
2533 this_iov[0].iov_len = chain_padding+1;
2534 this_iov[0].iov_base = (void *)&state->smb1.hdr[
2535 sizeof(state->smb1.hdr) - this_iov[0].iov_len];
2536 memset(this_iov[0].iov_base, 0, this_iov[0].iov_len-1);
2541 * copy the words and bytes
2543 memcpy(this_iov, state->smb1.iov+2,
2544 sizeof(struct iovec) * (state->smb1.iov_count-2));
2545 this_iov += state->smb1.iov_count - 2;
2546 chain_padding = next_padding;
2549 nbt_len = iov_buflen(&iov[1], iovlen-1);
2550 if ((nbt_len == -1) || (nbt_len > first_state->conn->smb1.max_xmit)) {
2552 TALLOC_FREE(first_state->smb1.chained_requests);
2553 return NT_STATUS_INVALID_PARAMETER_MIX;
2556 status = smb1cli_req_writev_submit(reqs[0], first_state, iov, iovlen);
2557 if (!NT_STATUS_IS_OK(status)) {
2559 TALLOC_FREE(first_state->smb1.chained_requests);
2563 return NT_STATUS_OK;
2566 bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
2568 return ((tevent_queue_length(conn->outgoing) != 0)
2569 || (talloc_array_length(conn->pending) != 0));
2572 bool smbXcli_conn_dfs_supported(struct smbXcli_conn *conn)
2574 if (conn->protocol >= PROTOCOL_SMB2_02) {
2575 return (smb2cli_conn_server_capabilities(conn) & SMB2_CAP_DFS);
2578 return (smb1cli_conn_capabilities(conn) & CAP_DFS);
2581 bool smb2cli_conn_req_possible(struct smbXcli_conn *conn, uint32_t *max_dyn_len)
2583 uint16_t credits = 1;
2585 if (conn->smb2.cur_credits == 0) {
2586 if (max_dyn_len != NULL) {
2592 if (conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2593 credits = conn->smb2.cur_credits;
2596 if (max_dyn_len != NULL) {
2597 *max_dyn_len = credits * 65536;
2603 uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
2605 return conn->smb2.server.capabilities;
2608 uint16_t smb2cli_conn_server_security_mode(struct smbXcli_conn *conn)
2610 return conn->smb2.server.security_mode;
2613 uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
2615 return conn->smb2.server.max_trans_size;
2618 uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
2620 return conn->smb2.server.max_read_size;
2623 uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
2625 return conn->smb2.server.max_write_size;
2628 void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
2629 uint16_t max_credits)
2631 conn->smb2.max_credits = max_credits;
2634 uint8_t smb2cli_conn_get_io_priority(struct smbXcli_conn *conn)
2636 if (conn->protocol < PROTOCOL_SMB3_11) {
2640 return conn->smb2.io_priority;
2643 void smb2cli_conn_set_io_priority(struct smbXcli_conn *conn,
2644 uint8_t io_priority)
2646 conn->smb2.io_priority = io_priority;
2649 uint32_t smb2cli_conn_cc_chunk_len(struct smbXcli_conn *conn)
2651 return conn->smb2.cc_chunk_len;
2654 void smb2cli_conn_set_cc_chunk_len(struct smbXcli_conn *conn,
2657 conn->smb2.cc_chunk_len = chunk_len;
2660 uint32_t smb2cli_conn_cc_max_chunks(struct smbXcli_conn *conn)
2662 return conn->smb2.cc_max_chunks;
2665 void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
2666 uint32_t max_chunks)
2668 conn->smb2.cc_max_chunks = max_chunks;
2671 static void smb2cli_req_cancel_done(struct tevent_req *subreq);
2673 static bool smb2cli_req_cancel(struct tevent_req *req)
2675 struct smbXcli_req_state *state =
2676 tevent_req_data(req,
2677 struct smbXcli_req_state);
2678 struct smbXcli_tcon *tcon = state->tcon;
2679 struct smbXcli_session *session = state->session;
2680 uint8_t *fixed = state->smb2.pad;
2681 uint16_t fixed_len = 4;
2682 struct tevent_req *subreq;
2683 struct smbXcli_req_state *substate;
2686 SSVAL(fixed, 0, 0x04);
2689 subreq = smb2cli_req_create(state, state->ev,
2697 if (subreq == NULL) {
2700 substate = tevent_req_data(subreq, struct smbXcli_req_state);
2702 SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, state->smb2.cancel_flags);
2703 SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, state->smb2.cancel_mid);
2704 SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, state->smb2.cancel_aid);
2706 status = smb2cli_req_compound_submit(&subreq, 1);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 TALLOC_FREE(subreq);
2712 tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2717 static void smb2cli_req_cancel_done(struct tevent_req *subreq)
2719 /* we do not care about the result */
2720 TALLOC_FREE(subreq);
2723 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
2724 struct tevent_context *ev,
2725 struct smbXcli_conn *conn,
2727 uint32_t additional_flags,
2728 uint32_t clear_flags,
2729 uint32_t timeout_msec,
2730 struct smbXcli_tcon *tcon,
2731 struct smbXcli_session *session,
2732 const uint8_t *fixed,
2736 uint32_t max_dyn_len)
2738 struct tevent_req *req;
2739 struct smbXcli_req_state *state;
2743 bool use_channel_sequence = false;
2744 uint16_t channel_sequence = 0;
2745 bool use_replay_flag = false;
2747 req = tevent_req_create(mem_ctx, &state,
2748 struct smbXcli_req_state);
2755 state->session = session;
2758 if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
2759 use_channel_sequence = true;
2760 } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
2761 use_channel_sequence = true;
2764 if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_00) {
2765 use_replay_flag = true;
2768 if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
2769 flags |= SMB2_PRIORITY_VALUE_TO_MASK(conn->smb2.io_priority);
2773 uid = session->smb2->session_id;
2775 if (use_channel_sequence) {
2776 channel_sequence = session->smb2->channel_sequence;
2779 if (use_replay_flag && session->smb2->replay_active) {
2780 additional_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
2783 state->smb2.should_sign = session->smb2->should_sign;
2784 state->smb2.should_encrypt = session->smb2->should_encrypt;
2786 if (cmd == SMB2_OP_SESSSETUP &&
2787 session->smb2_channel.signing_key.length == 0 &&
2788 session->smb2->signing_key.length != 0)
2791 * a session bind needs to be signed
2793 state->smb2.should_sign = true;
2796 if (cmd == SMB2_OP_SESSSETUP &&
2797 session->smb2_channel.signing_key.length == 0) {
2798 state->smb2.should_encrypt = false;
2801 if (additional_flags & SMB2_HDR_FLAG_SIGNED) {
2802 if (session->smb2_channel.signing_key.length == 0) {
2803 tevent_req_nterror(req, NT_STATUS_NO_USER_SESSION_KEY);
2807 additional_flags &= ~SMB2_HDR_FLAG_SIGNED;
2808 state->smb2.should_sign = true;
2813 tid = tcon->smb2.tcon_id;
2815 if (tcon->smb2.should_sign) {
2816 state->smb2.should_sign = true;
2818 if (tcon->smb2.should_encrypt) {
2819 state->smb2.should_encrypt = true;
2823 if (state->smb2.should_encrypt) {
2824 state->smb2.should_sign = false;
2827 state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
2828 if (state->smb2.recv_iov == NULL) {
2833 flags |= additional_flags;
2834 flags &= ~clear_flags;
2836 state->smb2.fixed = fixed;
2837 state->smb2.fixed_len = fixed_len;
2838 state->smb2.dyn = dyn;
2839 state->smb2.dyn_len = dyn_len;
2840 state->smb2.max_dyn_len = max_dyn_len;
2842 if (state->smb2.should_encrypt) {
2843 SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2844 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
2847 SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
2848 SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
2849 SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE, cmd);
2850 SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
2851 SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS, flags);
2852 SIVAL(state->smb2.hdr, SMB2_HDR_PID, 0); /* reserved */
2853 SIVAL(state->smb2.hdr, SMB2_HDR_TID, tid);
2854 SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID, uid);
2857 case SMB2_OP_CANCEL:
2858 state->one_way = true;
2862 * If this is a dummy request, it will have
2863 * UINT64_MAX as message id.
2864 * If we send on break acknowledgement,
2865 * this gets overwritten later.
2867 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
2871 if (timeout_msec > 0) {
2872 struct timeval endtime;
2874 endtime = timeval_current_ofs_msec(timeout_msec);
2875 if (!tevent_req_set_endtime(req, ev, endtime)) {
2883 void smb2cli_req_set_notify_async(struct tevent_req *req)
2885 struct smbXcli_req_state *state =
2886 tevent_req_data(req,
2887 struct smbXcli_req_state);
2889 state->smb2.notify_async = true;
2892 static void smb2cli_req_writev_done(struct tevent_req *subreq);
2893 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2894 TALLOC_CTX *tmp_mem,
2897 NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
2900 struct smbXcli_req_state *state;
2901 struct tevent_req *subreq;
2903 int i, num_iov, nbt_len;
2905 const DATA_BLOB *encryption_key = NULL;
2906 uint64_t encryption_session_id = 0;
2907 uint64_t nonce_high = UINT64_MAX;
2908 uint64_t nonce_low = UINT64_MAX;
2911 * 1 for the nbt length, optional TRANSFORM
2912 * per request: HDR, fixed, dyn, padding
2913 * -1 because the last one does not need padding
2916 iov = talloc_array(reqs[0], struct iovec, 1 + 1 + 4*num_reqs - 1);
2918 return NT_STATUS_NO_MEMORY;
2925 * the session of the first request that requires encryption
2926 * specifies the encryption key.
2928 for (i=0; i<num_reqs; i++) {
2929 if (!tevent_req_is_in_progress(reqs[i])) {
2930 return NT_STATUS_INTERNAL_ERROR;
2933 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2935 if (!smbXcli_conn_is_connected(state->conn)) {
2936 return NT_STATUS_CONNECTION_DISCONNECTED;
2939 if ((state->conn->protocol != PROTOCOL_NONE) &&
2940 (state->conn->protocol < PROTOCOL_SMB2_02)) {
2941 return NT_STATUS_REVISION_MISMATCH;
2944 if (state->session == NULL) {
2948 if (!state->smb2.should_encrypt) {
2952 encryption_key = &state->session->smb2->encryption_key;
2953 if (encryption_key->length == 0) {
2954 return NT_STATUS_INVALID_PARAMETER_MIX;
2957 encryption_session_id = state->session->smb2->session_id;
2959 state->session->smb2->nonce_low += 1;
2960 if (state->session->smb2->nonce_low == 0) {
2961 state->session->smb2->nonce_high += 1;
2962 state->session->smb2->nonce_low += 1;
2966 * CCM and GCM algorithms must never have their
2967 * nonce wrap, or the security of the whole
2968 * communication and the keys is destroyed.
2969 * We must drop the connection once we have
2970 * transfered too much data.
2972 * NOTE: We assume nonces greater than 8 bytes.
2974 if (state->session->smb2->nonce_high >=
2975 state->session->smb2->nonce_high_max)
2977 return NT_STATUS_ENCRYPTION_FAILED;
2980 nonce_high = state->session->smb2->nonce_high_random;
2981 nonce_high += state->session->smb2->nonce_high;
2982 nonce_low = state->session->smb2->nonce_low;
2985 iov[num_iov].iov_base = state->smb2.transform;
2986 iov[num_iov].iov_len = sizeof(state->smb2.transform);
2989 SBVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2990 SBVAL(state->smb2.transform, SMB2_TF_NONCE,
2992 SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
2994 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID,
2995 encryption_session_id);
2997 nbt_len += SMB2_TF_HDR_SIZE;
3001 for (i=0; i<num_reqs; i++) {
3010 const DATA_BLOB *signing_key = NULL;
3012 if (!tevent_req_is_in_progress(reqs[i])) {
3013 return NT_STATUS_INTERNAL_ERROR;
3016 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3018 if (!smbXcli_conn_is_connected(state->conn)) {
3019 return NT_STATUS_CONNECTION_DISCONNECTED;
3022 if ((state->conn->protocol != PROTOCOL_NONE) &&
3023 (state->conn->protocol < PROTOCOL_SMB2_02)) {
3024 return NT_STATUS_REVISION_MISMATCH;
3027 opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3028 if (opcode == SMB2_OP_CANCEL) {
3032 avail = UINT64_MAX - state->conn->smb2.mid;
3034 return NT_STATUS_CONNECTION_ABORTED;
3037 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3038 uint32_t max_dyn_len = 1;
3040 max_dyn_len = MAX(max_dyn_len, state->smb2.dyn_len);
3041 max_dyn_len = MAX(max_dyn_len, state->smb2.max_dyn_len);
3043 charge = (max_dyn_len - 1)/ 65536 + 1;
3048 charge = MAX(state->smb2.credit_charge, charge);
3050 avail = MIN(avail, state->conn->smb2.cur_credits);
3051 if (avail < charge) {
3052 return NT_STATUS_INTERNAL_ERROR;
3056 if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
3057 credits = state->conn->smb2.max_credits -
3058 state->conn->smb2.cur_credits;
3060 if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
3064 mid = state->conn->smb2.mid;
3065 state->conn->smb2.mid += charge;
3066 state->conn->smb2.cur_credits -= charge;
3068 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3069 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
3071 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
3072 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
3074 state->smb2.cancel_flags = 0;
3075 state->smb2.cancel_mid = mid;
3076 state->smb2.cancel_aid = 0;
3079 if (state->session && encryption_key == NULL) {
3081 * We prefer the channel signing key if it is
3084 if (state->smb2.should_sign) {
3085 signing_key = &state->session->smb2_channel.signing_key;
3089 * If it is a channel binding, we already have the main
3090 * signing key and try that one.
3092 if (signing_key && signing_key->length == 0) {
3093 signing_key = &state->session->smb2->signing_key;
3097 * If we do not have any session key yet, we skip the
3098 * signing of SMB2_OP_SESSSETUP requests.
3100 if (signing_key && signing_key->length == 0) {
3106 iov[num_iov].iov_base = state->smb2.hdr;
3107 iov[num_iov].iov_len = sizeof(state->smb2.hdr);
3110 iov[num_iov].iov_base = discard_const(state->smb2.fixed);
3111 iov[num_iov].iov_len = state->smb2.fixed_len;
3114 if (state->smb2.dyn != NULL) {
3115 iov[num_iov].iov_base = discard_const(state->smb2.dyn);
3116 iov[num_iov].iov_len = state->smb2.dyn_len;
3120 reqlen = sizeof(state->smb2.hdr);
3121 reqlen += state->smb2.fixed_len;
3122 reqlen += state->smb2.dyn_len;
3124 if (i < num_reqs-1) {
3125 if ((reqlen % 8) > 0) {
3126 uint8_t pad = 8 - (reqlen % 8);
3127 iov[num_iov].iov_base = state->smb2.pad;
3128 iov[num_iov].iov_len = pad;
3132 SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
3135 state->smb2.encryption_session_id = encryption_session_id;
3137 if (signing_key != NULL) {
3140 status = smb2_signing_sign_pdu(*signing_key,
3141 state->session->conn->protocol,
3142 &iov[hdr_iov], num_iov - hdr_iov);
3143 if (!NT_STATUS_IS_OK(status)) {
3150 ret = smbXcli_req_set_pending(reqs[i]);
3152 return NT_STATUS_NO_MEMORY;
3156 state = tevent_req_data(reqs[0], struct smbXcli_req_state);
3157 _smb_setlen_tcp(state->length_hdr, nbt_len);
3158 iov[0].iov_base = state->length_hdr;
3159 iov[0].iov_len = sizeof(state->length_hdr);
3161 if (encryption_key != NULL) {
3163 size_t buflen = nbt_len - SMB2_TF_HDR_SIZE;
3167 buf = talloc_array(iov, uint8_t, buflen);
3169 return NT_STATUS_NO_MEMORY;
3173 * We copy the buffers before encrypting them,
3174 * this is at least currently needed for the
3175 * to keep state->smb2.hdr.
3177 * Also the callers may expect there buffers
3180 for (vi = tf_iov + 1; vi < num_iov; vi++) {
3181 struct iovec *v = &iov[vi];
3182 const uint8_t *o = (const uint8_t *)v->iov_base;
3184 memcpy(buf, o, v->iov_len);
3185 v->iov_base = (void *)buf;
3189 status = smb2_signing_encrypt_pdu(*encryption_key,
3190 state->conn->smb2.server.cipher,
3191 &iov[tf_iov], num_iov - tf_iov);
3192 if (!NT_STATUS_IS_OK(status)) {
3197 if (state->conn->dispatch_incoming == NULL) {
3198 state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3201 subreq = writev_send(state, state->ev, state->conn->outgoing,
3202 state->conn->sock_fd, false, iov, num_iov);
3203 if (subreq == NULL) {
3204 return NT_STATUS_NO_MEMORY;
3206 tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
3207 return NT_STATUS_OK;
3210 void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
3212 struct smbXcli_req_state *state =
3213 tevent_req_data(req,
3214 struct smbXcli_req_state);
3216 state->smb2.credit_charge = charge;
3219 struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
3220 struct tevent_context *ev,
3221 struct smbXcli_conn *conn,
3223 uint32_t additional_flags,
3224 uint32_t clear_flags,
3225 uint32_t timeout_msec,
3226 struct smbXcli_tcon *tcon,
3227 struct smbXcli_session *session,
3228 const uint8_t *fixed,
3232 uint32_t max_dyn_len)
3234 struct tevent_req *req;
3237 req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
3238 additional_flags, clear_flags,
3247 if (!tevent_req_is_in_progress(req)) {
3248 return tevent_req_post(req, ev);
3250 status = smb2cli_req_compound_submit(&req, 1);
3251 if (tevent_req_nterror(req, status)) {
3252 return tevent_req_post(req, ev);
3257 static void smb2cli_req_writev_done(struct tevent_req *subreq)
3259 struct tevent_req *req =
3260 tevent_req_callback_data(subreq,
3262 struct smbXcli_req_state *state =
3263 tevent_req_data(req,
3264 struct smbXcli_req_state);
3268 nwritten = writev_recv(subreq, &err);
3269 TALLOC_FREE(subreq);
3270 if (nwritten == -1) {
3271 /* here, we need to notify all pending requests */
3272 NTSTATUS status = map_nt_error_from_unix_common(err);
3273 smbXcli_conn_disconnect(state->conn, status);
3278 static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
3281 TALLOC_CTX *mem_ctx,
3282 struct iovec **piov, int *pnum_iov)
3287 uint8_t *first_hdr = buf;
3288 size_t verified_buflen = 0;
3292 iov = talloc_array(mem_ctx, struct iovec, num_iov);
3294 return NT_STATUS_NO_MEMORY;
3297 while (taken < buflen) {
3298 size_t len = buflen - taken;
3299 uint8_t *hdr = first_hdr + taken;
3302 size_t next_command_ofs;
3304 struct iovec *iov_tmp;
3306 if (verified_buflen > taken) {
3307 len = verified_buflen - taken;
3314 DEBUG(10, ("%d bytes left, expected at least %d\n",
3318 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
3319 struct smbXcli_session *s;
3321 struct iovec tf_iov[2];
3325 if (len < SMB2_TF_HDR_SIZE) {
3326 DEBUG(10, ("%d bytes left, expected at least %d\n",
3327 (int)len, SMB2_TF_HDR_SIZE));
3331 tf_len = SMB2_TF_HDR_SIZE;
3334 hdr = first_hdr + taken;
3335 enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
3336 uid = BVAL(tf, SMB2_TF_SESSION_ID);
3338 if (len < SMB2_TF_HDR_SIZE + enc_len) {
3339 DEBUG(10, ("%d bytes left, expected at least %d\n",
3341 (int)(SMB2_TF_HDR_SIZE + enc_len)));
3346 for (; s; s = s->next) {
3347 if (s->smb2->session_id != uid) {
3354 DEBUG(10, ("unknown session_id %llu\n",
3355 (unsigned long long)uid));
3359 tf_iov[0].iov_base = (void *)tf;
3360 tf_iov[0].iov_len = tf_len;
3361 tf_iov[1].iov_base = (void *)hdr;
3362 tf_iov[1].iov_len = enc_len;
3364 status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
3365 conn->smb2.server.cipher,
3367 if (!NT_STATUS_IS_OK(status)) {
3372 verified_buflen = taken + enc_len;
3377 * We need the header plus the body length field
3380 if (len < SMB2_HDR_BODY + 2) {
3381 DEBUG(10, ("%d bytes left, expected at least %d\n",
3382 (int)len, SMB2_HDR_BODY));
3385 if (IVAL(hdr, 0) != SMB2_MAGIC) {
3386 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
3390 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
3391 DEBUG(10, ("Got HDR len %d, expected %d\n",
3392 SVAL(hdr, 4), SMB2_HDR_BODY));
3397 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
3398 body_size = SVAL(hdr, SMB2_HDR_BODY);
3400 if (next_command_ofs != 0) {
3401 if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
3404 if (next_command_ofs > full_size) {
3407 full_size = next_command_ofs;
3409 if (body_size < 2) {
3412 body_size &= 0xfffe;
3414 if (body_size > (full_size - SMB2_HDR_BODY)) {
3418 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
3420 if (iov_tmp == NULL) {
3422 return NT_STATUS_NO_MEMORY;
3425 cur = &iov[num_iov];
3428 cur[0].iov_base = tf;
3429 cur[0].iov_len = tf_len;
3430 cur[1].iov_base = hdr;
3431 cur[1].iov_len = SMB2_HDR_BODY;
3432 cur[2].iov_base = hdr + SMB2_HDR_BODY;
3433 cur[2].iov_len = body_size;
3434 cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
3435 cur[3].iov_len = full_size - (SMB2_HDR_BODY + body_size);
3441 *pnum_iov = num_iov;
3442 return NT_STATUS_OK;
3446 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3449 static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
3452 size_t num_pending = talloc_array_length(conn->pending);
3455 for (i=0; i<num_pending; i++) {
3456 struct tevent_req *req = conn->pending[i];
3457 struct smbXcli_req_state *state =
3458 tevent_req_data(req,
3459 struct smbXcli_req_state);
3461 if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
3468 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3469 TALLOC_CTX *tmp_mem,
3472 struct tevent_req *req;
3473 struct smbXcli_req_state *state = NULL;
3478 struct smbXcli_session *last_session = NULL;
3479 size_t inbuf_len = smb_len_tcp(inbuf);
3481 status = smb2cli_inbuf_parse_compound(conn,
3482 inbuf + NBT_HDR_SIZE,
3486 if (!NT_STATUS_IS_OK(status)) {
3490 for (i=0; i<num_iov; i+=4) {
3491 uint8_t *inbuf_ref = NULL;
3492 struct iovec *cur = &iov[i];
3493 uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
3494 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3495 uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3496 uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3497 uint16_t req_opcode;
3499 uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
3500 uint32_t new_credits;
3501 struct smbXcli_session *session = NULL;
3502 const DATA_BLOB *signing_key = NULL;
3503 bool was_encrypted = false;
3505 new_credits = conn->smb2.cur_credits;
3506 new_credits += credits;
3507 if (new_credits > UINT16_MAX) {
3508 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3510 conn->smb2.cur_credits += credits;
3512 req = smb2cli_conn_find_pending(conn, mid);
3514 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3516 state = tevent_req_data(req, struct smbXcli_req_state);
3518 req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3519 if (opcode != req_opcode) {
3520 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3522 req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3524 if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
3525 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3528 status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
3529 if ((flags & SMB2_HDR_FLAG_ASYNC) &&
3530 NT_STATUS_EQUAL(status, STATUS_PENDING)) {
3531 uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
3533 if (state->smb2.got_async) {
3534 /* We only expect one STATUS_PENDING response */
3535 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3537 state->smb2.got_async = true;
3540 * async interim responses are not signed,
3541 * even if the SMB2_HDR_FLAG_SIGNED flag
3544 state->smb2.cancel_flags = SMB2_HDR_FLAG_ASYNC;
3545 state->smb2.cancel_mid = 0;
3546 state->smb2.cancel_aid = async_id;
3548 if (state->smb2.notify_async) {
3549 tevent_req_defer_callback(req, state->ev);
3550 tevent_req_notify_callback(req);
3555 session = state->session;
3556 if (req_flags & SMB2_HDR_FLAG_CHAINED) {
3557 session = last_session;
3559 last_session = session;
3561 if (state->smb2.should_sign) {
3562 if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
3563 return NT_STATUS_ACCESS_DENIED;
3567 if (flags & SMB2_HDR_FLAG_SIGNED) {
3568 uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
3570 if (session == NULL) {
3571 struct smbXcli_session *s;
3573 s = state->conn->sessions;
3574 for (; s; s = s->next) {
3575 if (s->smb2->session_id != uid) {
3584 if (session == NULL) {
3585 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3588 last_session = session;
3589 signing_key = &session->smb2_channel.signing_key;
3592 if (opcode == SMB2_OP_SESSSETUP) {
3594 * We prefer the channel signing key, if it is
3597 * If we do not have a channel signing key yet,
3598 * we try the main signing key, if it is not
3599 * the final response.
3601 if (signing_key && signing_key->length == 0 &&
3602 !NT_STATUS_IS_OK(status)) {
3603 signing_key = &session->smb2->signing_key;
3606 if (signing_key && signing_key->length == 0) {
3608 * If we do not have a session key to
3609 * verify the signature, we defer the
3610 * signing check to the caller.
3612 * The caller gets NT_STATUS_OK, it
3614 * smb2cli_session_set_session_key()
3616 * smb2cli_session_set_channel_key()
3617 * which will check the signature
3618 * with the channel signing key.
3624 if (cur[0].iov_len == SMB2_TF_HDR_SIZE) {
3625 const uint8_t *tf = (const uint8_t *)cur[0].iov_base;
3626 uint64_t uid = BVAL(tf, SMB2_TF_SESSION_ID);
3629 * If the response was encrypted in a SMB2_TRANSFORM
3630 * pdu, which belongs to the correct session,
3631 * we do not need to do signing checks
3633 * It could be the session the response belongs to
3634 * or the session that was used to encrypt the
3635 * SMB2_TRANSFORM request.
3637 if ((session && session->smb2->session_id == uid) ||
3638 (state->smb2.encryption_session_id == uid)) {
3640 was_encrypted = true;
3644 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
3646 * if the server returns NT_STATUS_USER_SESSION_DELETED
3647 * the response is not signed and we should
3648 * propagate the NT_STATUS_USER_SESSION_DELETED
3649 * status to the caller.
3651 state->smb2.signing_skipped = true;
3655 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3657 * if the server returns
3658 * NT_STATUS_INVALID_PARAMETER
3659 * the response might not be encrypted.
3661 if (state->smb2.should_encrypt && !was_encrypted) {
3662 state->smb2.signing_skipped = true;
3667 if (state->smb2.should_encrypt && !was_encrypted) {
3668 if (!state->smb2.signing_skipped) {
3669 return NT_STATUS_ACCESS_DENIED;
3673 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
3674 NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
3675 NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3677 * if the server returns
3678 * NT_STATUS_NETWORK_NAME_DELETED
3679 * NT_STATUS_FILE_CLOSED
3680 * NT_STATUS_INVALID_PARAMETER
3681 * the response might not be signed
3682 * as this happens before the signing checks.
3684 * If server echos the signature (or all zeros)
3685 * we should report the status from the server
3691 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3692 state->smb2.hdr+SMB2_HDR_SIGNATURE,
3695 state->smb2.signing_skipped = true;
3701 static const uint8_t zeros[16];
3703 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3707 state->smb2.signing_skipped = true;
3714 status = smb2_signing_check_pdu(*signing_key,
3715 state->conn->protocol,
3717 if (!NT_STATUS_IS_OK(status)) {
3719 * If the signing check fails, we disconnect
3726 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
3727 (session != NULL) && session->disconnect_expired)
3730 * this should be a short term hack
3731 * until the upper layers have implemented
3732 * re-authentication.
3737 smbXcli_req_unset_pending(req);
3740 * There might be more than one response
3741 * we need to defer the notifications
3743 if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
3748 tevent_req_defer_callback(req, state->ev);
3752 * Note: here we use talloc_reference() in a way
3753 * that does not expose it to the caller.
3755 inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
3756 if (tevent_req_nomem(inbuf_ref, req)) {
3760 /* copy the related buffers */
3761 state->smb2.recv_iov[0] = cur[1];
3762 state->smb2.recv_iov[1] = cur[2];
3763 state->smb2.recv_iov[2] = cur[3];
3765 tevent_req_done(req);
3769 return NT_STATUS_RETRY;
3772 return NT_STATUS_OK;
3775 NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3776 struct iovec **piov,
3777 const struct smb2cli_req_expected_response *expected,
3778 size_t num_expected)
3780 struct smbXcli_req_state *state =
3781 tevent_req_data(req,
3782 struct smbXcli_req_state);
3785 bool found_status = false;
3786 bool found_size = false;
3793 if (tevent_req_is_in_progress(req) && state->smb2.got_async) {
3794 return STATUS_PENDING;
3797 if (tevent_req_is_nterror(req, &status)) {
3798 for (i=0; i < num_expected; i++) {
3799 if (NT_STATUS_EQUAL(status, expected[i].status)) {
3800 found_status = true;
3806 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
3812 if (num_expected == 0) {
3813 found_status = true;
3817 status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
3818 body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
3820 for (i=0; i < num_expected; i++) {
3821 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
3825 found_status = true;
3826 if (expected[i].body_size == 0) {
3831 if (expected[i].body_size == body_size) {
3837 if (!found_status) {
3841 if (state->smb2.signing_skipped) {
3842 if (num_expected > 0) {
3843 return NT_STATUS_ACCESS_DENIED;
3845 if (!NT_STATUS_IS_ERR(status)) {
3846 return NT_STATUS_ACCESS_DENIED;
3851 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3855 *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
3861 NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
3862 struct iovec *sent_iov)
3864 struct smbXcli_req_state *state =
3865 tevent_req_data(req,
3866 struct smbXcli_req_state);
3868 if (tevent_req_is_in_progress(req)) {
3869 return STATUS_PENDING;
3872 sent_iov[0].iov_base = state->smb2.hdr;
3873 sent_iov[0].iov_len = sizeof(state->smb2.hdr);
3875 sent_iov[1].iov_base = discard_const(state->smb2.fixed);
3876 sent_iov[1].iov_len = state->smb2.fixed_len;
3878 if (state->smb2.dyn != NULL) {
3879 sent_iov[2].iov_base = discard_const(state->smb2.dyn);
3880 sent_iov[2].iov_len = state->smb2.dyn_len;
3882 sent_iov[2].iov_base = NULL;
3883 sent_iov[2].iov_len = 0;
3886 return NT_STATUS_OK;
3889 static const struct {
3890 enum protocol_types proto;
3891 const char *smb1_name;
3892 } smb1cli_prots[] = {
3893 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
3894 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
3895 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
3896 {PROTOCOL_LANMAN1, "LANMAN1.0"},
3897 {PROTOCOL_LANMAN2, "LM1.2X002"},
3898 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
3899 {PROTOCOL_LANMAN2, "LANMAN2.1"},
3900 {PROTOCOL_LANMAN2, "Samba"},
3901 {PROTOCOL_NT1, "NT LANMAN 1.0"},
3902 {PROTOCOL_NT1, "NT LM 0.12"},
3903 {PROTOCOL_SMB2_02, "SMB 2.002"},
3904 {PROTOCOL_SMB2_10, "SMB 2.???"},
3907 static const struct {
3908 enum protocol_types proto;
3909 uint16_t smb2_dialect;
3910 } smb2cli_prots[] = {
3911 {PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202},
3912 {PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210},
3913 {PROTOCOL_SMB2_22, SMB2_DIALECT_REVISION_222},
3914 {PROTOCOL_SMB2_24, SMB2_DIALECT_REVISION_224},
3915 {PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300},
3916 {PROTOCOL_SMB3_02, SMB3_DIALECT_REVISION_302},
3917 {PROTOCOL_SMB3_10, SMB3_DIALECT_REVISION_310},
3918 {PROTOCOL_SMB3_11, SMB3_DIALECT_REVISION_311},
3921 struct smbXcli_negprot_state {
3922 struct smbXcli_conn *conn;
3923 struct tevent_context *ev;
3924 uint32_t timeout_msec;
3931 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
3932 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
3933 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
3934 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
3935 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
3936 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
3940 struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
3941 struct tevent_context *ev,
3942 struct smbXcli_conn *conn,
3943 uint32_t timeout_msec,
3944 enum protocol_types min_protocol,
3945 enum protocol_types max_protocol)
3947 struct tevent_req *req, *subreq;
3948 struct smbXcli_negprot_state *state;
3950 req = tevent_req_create(mem_ctx, &state,
3951 struct smbXcli_negprot_state);
3957 state->timeout_msec = timeout_msec;
3959 if (min_protocol == PROTOCOL_NONE) {
3960 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3961 return tevent_req_post(req, ev);
3964 if (max_protocol == PROTOCOL_NONE) {
3965 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3966 return tevent_req_post(req, ev);
3969 if (min_protocol > max_protocol) {
3970 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3971 return tevent_req_post(req, ev);
3974 conn->min_protocol = min_protocol;
3975 conn->max_protocol = max_protocol;
3976 conn->protocol = PROTOCOL_NONE;
3978 if ((min_protocol < PROTOCOL_SMB2_02) &&
3979 (max_protocol < PROTOCOL_SMB2_02)) {
3983 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
3985 subreq = smbXcli_negprot_smb1_subreq(state);
3986 if (tevent_req_nomem(subreq, req)) {
3987 return tevent_req_post(req, ev);
3989 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
3993 if ((min_protocol >= PROTOCOL_SMB2_02) &&
3994 (max_protocol >= PROTOCOL_SMB2_02)) {
3998 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4001 * As we're starting with an SMB2 negprot, emulate Windows
4002 * and ask for 31 credits in the initial SMB2 negprot.
4003 * If we don't and leave requested credits at
4004 * zero, MacOSX servers return zero credits on
4005 * the negprot reply and we fail to connect.
4007 smb2cli_conn_set_max_credits(conn,
4008 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
4010 subreq = smbXcli_negprot_smb2_subreq(state);
4011 if (tevent_req_nomem(subreq, req)) {
4012 return tevent_req_post(req, ev);
4014 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4019 * We send an SMB1 negprot with the SMB2 dialects
4020 * and expect a SMB1 or a SMB2 response.
4022 * smbXcli_negprot_dispatch_incoming() will fix the
4023 * callback to match protocol of the response.
4025 conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
4027 subreq = smbXcli_negprot_smb1_subreq(state);
4028 if (tevent_req_nomem(subreq, req)) {
4029 return tevent_req_post(req, ev);
4031 tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
4035 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
4037 struct tevent_req *req =
4038 tevent_req_callback_data(subreq,
4043 * we just want the low level error
4045 status = tevent_req_simple_recv_ntstatus(subreq);
4046 TALLOC_FREE(subreq);
4047 if (tevent_req_nterror(req, status)) {
4051 /* this should never happen */
4052 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
4055 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
4058 DATA_BLOB bytes = data_blob_null;
4062 /* setup the protocol strings */
4063 for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4067 if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4071 if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4075 ok = data_blob_append(state, &bytes, &c, sizeof(c));
4081 * We now it is already ascii and
4082 * we want NULL termination.
4084 ok = data_blob_append(state, &bytes,
4085 smb1cli_prots[i].smb1_name,
4086 strlen(smb1cli_prots[i].smb1_name)+1);
4092 smb1cli_req_flags(state->conn->max_protocol,
4093 state->conn->smb1.client.capabilities,
4098 return smb1cli_req_send(state, state->ev, state->conn,
4102 state->timeout_msec,
4103 0xFFFE, 0, NULL, /* pid, tid, session */
4104 0, NULL, /* wct, vwv */
4105 bytes.length, bytes.data);
4108 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
4110 struct tevent_req *req =
4111 tevent_req_callback_data(subreq,
4113 struct smbXcli_negprot_state *state =
4114 tevent_req_data(req,
4115 struct smbXcli_negprot_state);
4116 struct smbXcli_conn *conn = state->conn;
4117 struct iovec *recv_iov = NULL;
4126 size_t num_prots = 0;
4128 uint32_t client_capabilities = conn->smb1.client.capabilities;
4129 uint32_t both_capabilities;
4130 uint32_t server_capabilities = 0;
4131 uint32_t capabilities;
4132 uint32_t client_max_xmit = conn->smb1.client.max_xmit;
4133 uint32_t server_max_xmit = 0;
4135 uint32_t server_max_mux = 0;
4136 uint16_t server_security_mode = 0;
4137 uint32_t server_session_key = 0;
4138 bool server_readbraw = false;
4139 bool server_writebraw = false;
4140 bool server_lockread = false;
4141 bool server_writeunlock = false;
4142 struct GUID server_guid = GUID_zero();
4143 DATA_BLOB server_gss_blob = data_blob_null;
4144 uint8_t server_challenge[8];
4145 char *server_workgroup = NULL;
4146 char *server_name = NULL;
4147 int server_time_zone = 0;
4148 NTTIME server_system_time = 0;
4149 static const struct smb1cli_req_expected_response expected[] = {
4151 .status = NT_STATUS_OK,
4152 .wct = 0x11, /* NT1 */
4155 .status = NT_STATUS_OK,
4156 .wct = 0x0D, /* LM */
4159 .status = NT_STATUS_OK,
4160 .wct = 0x01, /* CORE */
4164 ZERO_STRUCT(server_challenge);
4166 status = smb1cli_req_recv(subreq, state,
4171 NULL, /* pvwv_offset */
4174 NULL, /* pbytes_offset */
4176 expected, ARRAY_SIZE(expected));
4177 TALLOC_FREE(subreq);
4178 if (tevent_req_nterror(req, status)) {
4182 flags = CVAL(inhdr, HDR_FLG);
4184 protnum = SVAL(vwv, 0);
4186 for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4187 if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4191 if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4195 if (protnum != num_prots) {
4200 conn->protocol = smb1cli_prots[i].proto;
4204 if (conn->protocol == PROTOCOL_NONE) {
4205 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4209 if ((conn->protocol < PROTOCOL_NT1) && conn->mandatory_signing) {
4210 DEBUG(0,("smbXcli_negprot: SMB signing is mandatory "
4211 "and the selected protocol level doesn't support it.\n"));
4212 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4216 if (flags & FLAG_SUPPORT_LOCKREAD) {
4217 server_lockread = true;
4218 server_writeunlock = true;
4221 if (conn->protocol >= PROTOCOL_NT1) {
4222 const char *client_signing = NULL;
4223 bool server_mandatory = false;
4224 bool server_allowed = false;
4225 const char *server_signing = NULL;
4230 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4235 server_security_mode = CVAL(vwv + 1, 0);
4236 server_max_mux = SVAL(vwv + 1, 1);
4237 server_max_xmit = IVAL(vwv + 3, 1);
4238 server_session_key = IVAL(vwv + 7, 1);
4239 server_time_zone = SVALS(vwv + 15, 1);
4240 server_time_zone *= 60;
4241 /* this time arrives in real GMT */
4242 server_system_time = BVAL(vwv + 11, 1);
4243 server_capabilities = IVAL(vwv + 9, 1);
4245 key_len = CVAL(vwv + 16, 1);
4247 if (server_capabilities & CAP_RAW_MODE) {
4248 server_readbraw = true;
4249 server_writebraw = true;
4251 if (server_capabilities & CAP_LOCK_AND_READ) {
4252 server_lockread = true;
4255 if (server_capabilities & CAP_EXTENDED_SECURITY) {
4256 DATA_BLOB blob1, blob2;
4258 if (num_bytes < 16) {
4259 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4263 blob1 = data_blob_const(bytes, 16);
4264 status = GUID_from_data_blob(&blob1, &server_guid);
4265 if (tevent_req_nterror(req, status)) {
4269 blob1 = data_blob_const(bytes+16, num_bytes-16);
4270 blob2 = data_blob_dup_talloc(state, blob1);
4271 if (blob1.length > 0 &&
4272 tevent_req_nomem(blob2.data, req)) {
4275 server_gss_blob = blob2;
4277 DATA_BLOB blob1, blob2;
4279 if (num_bytes < key_len) {
4280 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4284 if (key_len != 0 && key_len != 8) {
4285 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4290 memcpy(server_challenge, bytes, 8);
4293 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4294 blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
4295 if (blob1.length > 0) {
4298 len = utf16_len_n(blob1.data,
4302 ok = convert_string_talloc(state,
4310 status = map_nt_error_from_unix_common(errno);
4311 tevent_req_nterror(req, status);
4316 blob2.data += blob1.length;
4317 blob2.length -= blob1.length;
4318 if (blob2.length > 0) {
4321 len = utf16_len_n(blob1.data,
4325 ok = convert_string_talloc(state,
4333 status = map_nt_error_from_unix_common(errno);
4334 tevent_req_nterror(req, status);
4340 client_signing = "disabled";
4341 if (conn->allow_signing) {
4342 client_signing = "allowed";
4344 if (conn->mandatory_signing) {
4345 client_signing = "required";
4348 server_signing = "not supported";
4349 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
4350 server_signing = "supported";
4351 server_allowed = true;
4352 } else if (conn->mandatory_signing) {
4354 * We have mandatory signing as client
4355 * lets assume the server will look at our
4356 * FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
4357 * flag in the session setup
4359 server_signing = "not announced";
4360 server_allowed = true;
4362 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
4363 server_signing = "required";
4364 server_mandatory = true;
4367 ok = smb_signing_set_negotiated(conn->smb1.signing,
4371 DEBUG(1,("cli_negprot: SMB signing is required, "
4372 "but client[%s] and server[%s] mismatch\n",
4373 client_signing, server_signing));
4374 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4378 } else if (conn->protocol >= PROTOCOL_LANMAN1) {
4384 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4388 server_security_mode = SVAL(vwv + 1, 0);
4389 server_max_xmit = SVAL(vwv + 2, 0);
4390 server_max_mux = SVAL(vwv + 3, 0);
4391 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
4392 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
4393 server_session_key = IVAL(vwv + 6, 0);
4394 server_time_zone = SVALS(vwv + 10, 0);
4395 server_time_zone *= 60;
4396 /* this time is converted to GMT by make_unix_date */
4397 t = pull_dos_date((const uint8_t *)(vwv + 8), server_time_zone);
4398 unix_to_nt_time(&server_system_time, t);
4399 key_len = SVAL(vwv + 11, 0);
4401 if (num_bytes < key_len) {
4402 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4406 if (key_len != 0 && key_len != 8) {
4407 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4412 memcpy(server_challenge, bytes, 8);
4415 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4416 if (blob1.length > 0) {
4420 len = utf16_len_n(blob1.data,
4424 ok = convert_string_talloc(state,
4432 status = map_nt_error_from_unix_common(errno);
4433 tevent_req_nterror(req, status);
4439 /* the old core protocol */
4440 server_time_zone = get_time_zone(time(NULL));
4441 server_max_xmit = 1024;
4445 if (server_max_xmit < 1024) {
4446 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4450 if (server_max_mux < 1) {
4451 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4456 * Now calculate the negotiated capabilities
4457 * based on the mask for:
4458 * - client only flags
4459 * - flags used in both directions
4460 * - server only flags
4462 both_capabilities = client_capabilities & server_capabilities;
4463 capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
4464 capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
4465 capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
4467 max_xmit = MIN(client_max_xmit, server_max_xmit);
4469 conn->smb1.server.capabilities = server_capabilities;
4470 conn->smb1.capabilities = capabilities;
4472 conn->smb1.server.max_xmit = server_max_xmit;
4473 conn->smb1.max_xmit = max_xmit;
4475 conn->smb1.server.max_mux = server_max_mux;
4477 conn->smb1.server.security_mode = server_security_mode;
4479 conn->smb1.server.readbraw = server_readbraw;
4480 conn->smb1.server.writebraw = server_writebraw;
4481 conn->smb1.server.lockread = server_lockread;
4482 conn->smb1.server.writeunlock = server_writeunlock;
4484 conn->smb1.server.session_key = server_session_key;
4486 talloc_steal(conn, server_gss_blob.data);
4487 conn->smb1.server.gss_blob = server_gss_blob;
4488 conn->smb1.server.guid = server_guid;
4489 memcpy(conn->smb1.server.challenge, server_challenge, 8);
4490 conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
4491 conn->smb1.server.name = talloc_move(conn, &server_name);
4493 conn->smb1.server.time_zone = server_time_zone;
4494 conn->smb1.server.system_time = server_system_time;
4496 tevent_req_done(req);
4499 static size_t smbXcli_padding_helper(uint32_t offset, size_t n)
4501 if ((offset & (n-1)) == 0) return 0;
4502 return n - (offset & (n-1));
4505 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state)
4509 uint16_t dialect_count = 0;
4510 DATA_BLOB dyn = data_blob_null;
4512 for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4516 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4520 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4524 SSVAL(val, 0, smb2cli_prots[i].smb2_dialect);
4526 ok = data_blob_append(state, &dyn, val, sizeof(val));
4534 buf = state->smb2.fixed;
4536 SSVAL(buf, 2, dialect_count);
4537 SSVAL(buf, 4, state->conn->smb2.client.security_mode);
4538 SSVAL(buf, 6, 0); /* Reserved */
4539 if (state->conn->max_protocol >= PROTOCOL_SMB2_22) {
4540 SIVAL(buf, 8, state->conn->smb2.client.capabilities);
4542 SIVAL(buf, 8, 0); /* Capabilities */
4544 if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
4548 status = GUID_to_ndr_blob(&state->conn->smb2.client.guid,
4550 if (!NT_STATUS_IS_OK(status)) {
4553 memcpy(buf+12, blob.data, 16); /* ClientGuid */
4555 memset(buf+12, 0, 16); /* ClientGuid */
4558 if (state->conn->max_protocol >= PROTOCOL_SMB3_10) {
4560 struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4564 const uint8_t zeros[8] = {0, };
4568 SSVAL(p, 0, 1); /* HashAlgorithmCount */
4569 SSVAL(p, 2, 32); /* SaltLength */
4570 SSVAL(p, 4, SMB2_PREAUTH_INTEGRITY_SHA512);
4571 generate_random_buffer(p + 6, 32);
4573 b = data_blob_const(p, 38);
4574 status = smb2_negotiate_context_add(state, &c,
4575 SMB2_PREAUTH_INTEGRITY_CAPABILITIES, b);
4576 if (!NT_STATUS_IS_OK(status)) {
4580 SSVAL(p, 0, 2); /* ChiperCount */
4581 SSVAL(p, 2, SMB2_ENCRYPTION_AES128_GCM);
4582 SSVAL(p, 4, SMB2_ENCRYPTION_AES128_CCM);
4584 b = data_blob_const(p, 6);
4585 status = smb2_negotiate_context_add(state, &c,
4586 SMB2_ENCRYPTION_CAPABILITIES, b);
4587 if (!NT_STATUS_IS_OK(status)) {
4591 status = smb2_negotiate_context_push(state, &b, c);
4592 if (!NT_STATUS_IS_OK(status)) {
4596 offset = SMB2_HDR_BODY + sizeof(state->smb2.fixed) + dyn.length;
4597 pad = smbXcli_padding_helper(offset, 8);
4599 ok = data_blob_append(state, &dyn, zeros, pad);
4605 ok = data_blob_append(state, &dyn, b.data, b.length);
4610 SIVAL(buf, 28, offset); /* NegotiateContextOffset */
4611 SSVAL(buf, 32, c.num_contexts); /* NegotiateContextCount */
4612 SSVAL(buf, 34, 0); /* Reserved */
4614 SBVAL(buf, 28, 0); /* Reserved/ClientStartTime */
4617 return smb2cli_req_send(state, state->ev,
4618 state->conn, SMB2_OP_NEGPROT,
4620 state->timeout_msec,
4621 NULL, NULL, /* tcon, session */
4622 state->smb2.fixed, sizeof(state->smb2.fixed),
4623 dyn.data, dyn.length,
4624 UINT16_MAX); /* max_dyn_len */
4627 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
4629 struct tevent_req *req =
4630 tevent_req_callback_data(subreq,
4632 struct smbXcli_negprot_state *state =
4633 tevent_req_data(req,
4634 struct smbXcli_negprot_state);
4635 struct smbXcli_conn *conn = state->conn;
4636 size_t security_offset, security_length;
4642 uint16_t dialect_revision;
4643 struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4644 uint32_t negotiate_context_offset = 0;
4645 uint16_t negotiate_context_count = 0;
4646 DATA_BLOB negotiate_context_blob = data_blob_null;
4650 struct smb2_negotiate_context *preauth = NULL;
4651 uint16_t hash_count;
4652 uint16_t salt_length;
4653 uint16_t hash_selected;
4654 struct hc_sha512state sctx;
4655 struct smb2_negotiate_context *cipher = NULL;
4656 struct iovec sent_iov[3];
4657 static const struct smb2cli_req_expected_response expected[] = {
4659 .status = NT_STATUS_OK,
4664 status = smb2cli_req_recv(subreq, state, &iov,
4665 expected, ARRAY_SIZE(expected));
4666 if (tevent_req_nterror(req, status)) {
4670 body = (uint8_t *)iov[1].iov_base;
4672 dialect_revision = SVAL(body, 4);
4674 for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4675 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4679 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4683 if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
4687 conn->protocol = smb2cli_prots[i].proto;
4691 if (conn->protocol == PROTOCOL_NONE) {
4692 TALLOC_FREE(subreq);
4694 if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
4695 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4699 if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
4700 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4704 /* make sure we do not loop forever */
4705 state->conn->min_protocol = PROTOCOL_SMB2_02;
4708 * send a SMB2 negprot, in order to negotiate
4711 subreq = smbXcli_negprot_smb2_subreq(state);
4712 if (tevent_req_nomem(subreq, req)) {
4715 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4719 conn->smb2.server.security_mode = SVAL(body, 2);
4720 if (conn->protocol >= PROTOCOL_SMB3_10) {
4721 negotiate_context_count = SVAL(body, 6);
4724 blob = data_blob_const(body + 8, 16);
4725 status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
4726 if (tevent_req_nterror(req, status)) {
4730 conn->smb2.server.capabilities = IVAL(body, 24);
4731 conn->smb2.server.max_trans_size= IVAL(body, 28);
4732 conn->smb2.server.max_read_size = IVAL(body, 32);
4733 conn->smb2.server.max_write_size= IVAL(body, 36);
4734 conn->smb2.server.system_time = BVAL(body, 40);
4735 conn->smb2.server.start_time = BVAL(body, 48);
4737 security_offset = SVAL(body, 56);
4738 security_length = SVAL(body, 58);
4740 if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
4741 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4745 if (security_length > iov[2].iov_len) {
4746 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4750 conn->smb2.server.gss_blob = data_blob_talloc(conn,
4753 if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
4757 if (conn->protocol < PROTOCOL_SMB3_10) {
4758 TALLOC_FREE(subreq);
4760 if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
4761 conn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
4763 tevent_req_done(req);
4767 if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
4768 tevent_req_nterror(req,
4769 NT_STATUS_INVALID_NETWORK_RESPONSE);
4773 negotiate_context_offset = IVAL(body, 60);
4774 if (negotiate_context_offset < security_offset) {
4775 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4779 ctx_ofs = negotiate_context_offset - security_offset;
4780 if (ctx_ofs > iov[2].iov_len) {
4781 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4784 avail = iov[2].iov_len - security_length;
4785 needed = iov[2].iov_len - ctx_ofs;
4786 if (needed > avail) {
4787 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4791 negotiate_context_blob.data = (uint8_t *)iov[2].iov_base;
4792 negotiate_context_blob.length = iov[2].iov_len;
4794 negotiate_context_blob.data += ctx_ofs;
4795 negotiate_context_blob.length -= ctx_ofs;
4797 status = smb2_negotiate_context_parse(state, negotiate_context_blob, &c);
4798 if (tevent_req_nterror(req, status)) {
4802 if (negotiate_context_count != c.num_contexts) {
4803 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4807 preauth = smb2_negotiate_context_find(&c,
4808 SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
4809 if (preauth == NULL) {
4810 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4814 if (preauth->data.length < 6) {
4815 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4819 hash_count = SVAL(preauth->data.data, 0);
4820 salt_length = SVAL(preauth->data.data, 2);
4821 hash_selected = SVAL(preauth->data.data, 4);
4823 if (hash_count != 1) {
4824 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4828 if (preauth->data.length != (6 + salt_length)) {
4829 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4833 if (hash_selected != SMB2_PREAUTH_INTEGRITY_SHA512) {
4834 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4838 cipher = smb2_negotiate_context_find(&c, SMB2_ENCRYPTION_CAPABILITIES);
4839 if (cipher != NULL) {
4840 uint16_t cipher_count;
4842 if (cipher->data.length < 2) {
4843 tevent_req_nterror(req,
4844 NT_STATUS_INVALID_NETWORK_RESPONSE);
4848 cipher_count = SVAL(cipher->data.data, 0);
4850 if (cipher_count > 1) {
4851 tevent_req_nterror(req,
4852 NT_STATUS_INVALID_NETWORK_RESPONSE);
4856 if (cipher->data.length != (2 + 2 * cipher_count)) {
4857 tevent_req_nterror(req,
4858 NT_STATUS_INVALID_NETWORK_RESPONSE);
4862 if (cipher_count == 1) {
4863 uint16_t cipher_selected;
4865 cipher_selected = SVAL(cipher->data.data, 2);
4867 switch (cipher_selected) {
4868 case SMB2_ENCRYPTION_AES128_GCM:
4869 case SMB2_ENCRYPTION_AES128_CCM:
4870 conn->smb2.server.cipher = cipher_selected;
4876 /* First we hash the request */
4877 smb2cli_req_get_sent_iov(subreq, sent_iov);
4878 samba_SHA512_Init(&sctx);
4879 samba_SHA512_Update(&sctx, conn->smb2.preauth_sha512,
4880 sizeof(conn->smb2.preauth_sha512));
4881 for (i = 0; i < 3; i++) {
4882 samba_SHA512_Update(&sctx, sent_iov[i].iov_base, sent_iov[i].iov_len);
4884 samba_SHA512_Final(conn->smb2.preauth_sha512, &sctx);
4885 TALLOC_FREE(subreq);
4887 /* And now we hash the response */
4888 samba_SHA512_Init(&sctx);
4889 samba_SHA512_Update(&sctx, conn->smb2.preauth_sha512,
4890 sizeof(conn->smb2.preauth_sha512));
4891 for (i = 0; i < 3; i++) {
4892 samba_SHA512_Update(&sctx, iov[i].iov_base, iov[i].iov_len);
4894 samba_SHA512_Final(conn->smb2.preauth_sha512, &sctx);
4896 tevent_req_done(req);
4899 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
4900 TALLOC_CTX *tmp_mem,
4903 size_t num_pending = talloc_array_length(conn->pending);
4904 struct tevent_req *subreq;
4905 struct smbXcli_req_state *substate;
4906 struct tevent_req *req;
4907 uint32_t protocol_magic;
4908 size_t inbuf_len = smb_len_nbt(inbuf);
4910 if (num_pending != 1) {
4911 return NT_STATUS_INTERNAL_ERROR;
4914 if (inbuf_len < 4) {
4915 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4918 subreq = conn->pending[0];
4919 substate = tevent_req_data(subreq, struct smbXcli_req_state);
4920 req = tevent_req_callback_data(subreq, struct tevent_req);
4922 protocol_magic = IVAL(inbuf, 4);
4924 switch (protocol_magic) {
4926 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4927 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4928 return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
4931 if (substate->smb2.recv_iov == NULL) {
4933 * For the SMB1 negprot we have move it.
4935 substate->smb2.recv_iov = substate->smb1.recv_iov;
4936 substate->smb1.recv_iov = NULL;
4940 * we got an SMB2 answer, which consumed sequence number 0
4941 * so we need to use 1 as the next one.
4943 * we also need to set the current credits to 0
4944 * as we consumed the initial one. The SMB2 answer
4945 * hopefully grant us a new credit.
4948 conn->smb2.cur_credits = 0;
4949 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4950 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4951 return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
4954 DEBUG(10, ("Got non-SMB PDU\n"));
4955 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4958 NTSTATUS smbXcli_negprot_recv(struct tevent_req *req)
4960 return tevent_req_simple_recv_ntstatus(req);
4963 NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
4964 uint32_t timeout_msec,
4965 enum protocol_types min_protocol,
4966 enum protocol_types max_protocol)
4968 TALLOC_CTX *frame = talloc_stackframe();
4969 struct tevent_context *ev;
4970 struct tevent_req *req;
4971 NTSTATUS status = NT_STATUS_NO_MEMORY;
4974 if (smbXcli_conn_has_async_calls(conn)) {
4976 * Can't use sync call while an async call is in flight
4978 status = NT_STATUS_INVALID_PARAMETER_MIX;
4981 ev = samba_tevent_context_init(frame);
4985 req = smbXcli_negprot_send(frame, ev, conn, timeout_msec,
4986 min_protocol, max_protocol);
4990 ok = tevent_req_poll_ntstatus(req, ev, &status);
4994 status = smbXcli_negprot_recv(req);
5000 struct smb2cli_validate_negotiate_info_state {
5001 struct smbXcli_conn *conn;
5002 DATA_BLOB in_input_buffer;
5003 DATA_BLOB in_output_buffer;
5004 DATA_BLOB out_input_buffer;
5005 DATA_BLOB out_output_buffer;
5009 static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq);
5011 struct tevent_req *smb2cli_validate_negotiate_info_send(TALLOC_CTX *mem_ctx,
5012 struct tevent_context *ev,
5013 struct smbXcli_conn *conn,
5014 uint32_t timeout_msec,
5015 struct smbXcli_session *session,
5016 struct smbXcli_tcon *tcon)
5018 struct tevent_req *req;
5019 struct smb2cli_validate_negotiate_info_state *state;
5021 uint16_t dialect_count = 0;
5022 struct tevent_req *subreq;
5023 bool _save_should_sign;
5026 req = tevent_req_create(mem_ctx, &state,
5027 struct smb2cli_validate_negotiate_info_state);
5033 state->in_input_buffer = data_blob_talloc_zero(state,
5034 4 + 16 + 1 + 1 + 2);
5035 if (tevent_req_nomem(state->in_input_buffer.data, req)) {
5036 return tevent_req_post(req, ev);
5038 buf = state->in_input_buffer.data;
5040 if (state->conn->max_protocol >= PROTOCOL_SMB2_22) {
5041 SIVAL(buf, 0, conn->smb2.client.capabilities);
5043 SIVAL(buf, 0, 0); /* Capabilities */
5045 if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
5049 status = GUID_to_ndr_blob(&conn->smb2.client.guid,
5051 if (!NT_STATUS_IS_OK(status)) {
5054 memcpy(buf+4, blob.data, 16); /* ClientGuid */
5056 memset(buf+4, 0, 16); /* ClientGuid */
5058 if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5059 SCVAL(buf, 20, conn->smb2.client.security_mode);
5063 SCVAL(buf, 21, 0); /* reserved */
5065 for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5069 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5073 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5077 if (smb2cli_prots[i].proto == state->conn->protocol) {
5078 state->dialect = smb2cli_prots[i].smb2_dialect;
5081 ofs = state->in_input_buffer.length;
5082 ok = data_blob_realloc(state, &state->in_input_buffer,
5085 tevent_req_oom(req);
5086 return tevent_req_post(req, ev);
5089 buf = state->in_input_buffer.data;
5090 SSVAL(buf, ofs, smb2cli_prots[i].smb2_dialect);
5094 buf = state->in_input_buffer.data;
5095 SSVAL(buf, 22, dialect_count);
5097 _save_should_sign = smb2cli_tcon_is_signing_on(tcon);
5098 smb2cli_tcon_should_sign(tcon, true);
5099 subreq = smb2cli_ioctl_send(state, ev, conn,
5100 timeout_msec, session, tcon,
5101 UINT64_MAX, /* in_fid_persistent */
5102 UINT64_MAX, /* in_fid_volatile */
5103 FSCTL_VALIDATE_NEGOTIATE_INFO,
5104 0, /* in_max_input_length */
5105 &state->in_input_buffer,
5106 24, /* in_max_output_length */
5107 &state->in_output_buffer,
5108 SMB2_IOCTL_FLAG_IS_FSCTL);
5109 smb2cli_tcon_should_sign(tcon, _save_should_sign);
5110 if (tevent_req_nomem(subreq, req)) {
5111 return tevent_req_post(req, ev);
5113 tevent_req_set_callback(subreq,
5114 smb2cli_validate_negotiate_info_done,
5120 static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
5122 struct tevent_req *req =
5123 tevent_req_callback_data(subreq,
5125 struct smb2cli_validate_negotiate_info_state *state =
5126 tevent_req_data(req,
5127 struct smb2cli_validate_negotiate_info_state);
5130 uint32_t capabilities;
5131 DATA_BLOB guid_blob;
5132 struct GUID server_guid;
5133 uint16_t security_mode;
5136 status = smb2cli_ioctl_recv(subreq, state,
5137 &state->out_input_buffer,
5138 &state->out_output_buffer);
5139 TALLOC_FREE(subreq);
5140 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
5142 * The response was signed, but not supported
5144 * Older Windows and Samba releases return
5145 * NT_STATUS_FILE_CLOSED.
5147 tevent_req_done(req);
5150 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
5152 * The response was signed, but not supported
5154 * This is returned by the NTVFS based Samba 4.x file server
5157 tevent_req_done(req);
5160 if (NT_STATUS_EQUAL(status, NT_STATUS_FS_DRIVER_REQUIRED)) {
5162 * The response was signed, but not supported
5164 * This is returned by the NTVFS based Samba 4.x file server
5167 tevent_req_done(req);
5170 if (tevent_req_nterror(req, status)) {
5174 if (state->out_output_buffer.length != 24) {
5175 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5179 buf = state->out_output_buffer.data;
5181 capabilities = IVAL(buf, 0);
5182 guid_blob = data_blob_const(buf + 4, 16);
5183 status = GUID_from_data_blob(&guid_blob, &server_guid);
5184 if (tevent_req_nterror(req, status)) {
5187 security_mode = CVAL(buf, 20);
5188 dialect = SVAL(buf, 22);
5190 if (capabilities != state->conn->smb2.server.capabilities) {
5191 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5195 if (!GUID_equal(&server_guid, &state->conn->smb2.server.guid)) {
5196 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5200 if (security_mode != state->conn->smb2.server.security_mode) {
5201 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5205 if (dialect != state->dialect) {
5206 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5210 tevent_req_done(req);
5213 NTSTATUS smb2cli_validate_negotiate_info_recv(struct tevent_req *req)
5215 return tevent_req_simple_recv_ntstatus(req);
5218 static int smbXcli_session_destructor(struct smbXcli_session *session)
5220 if (session->conn == NULL) {
5224 DLIST_REMOVE(session->conn->sessions, session);
5228 struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
5229 struct smbXcli_conn *conn)
5231 struct smbXcli_session *session;
5233 session = talloc_zero(mem_ctx, struct smbXcli_session);
5234 if (session == NULL) {
5237 session->smb2 = talloc_zero(session, struct smb2cli_session);
5238 if (session->smb2 == NULL) {
5239 talloc_free(session);
5242 talloc_set_destructor(session, smbXcli_session_destructor);
5244 DLIST_ADD_END(conn->sessions, session, struct smbXcli_session *);
5245 session->conn = conn;
5247 memcpy(session->smb2_channel.preauth_sha512,
5248 conn->smb2.preauth_sha512,
5249 sizeof(session->smb2_channel.preauth_sha512));
5254 struct smbXcli_session *smbXcli_session_copy(TALLOC_CTX *mem_ctx,
5255 struct smbXcli_session *src)
5257 struct smbXcli_session *session;
5259 session = talloc_zero(mem_ctx, struct smbXcli_session);
5260 if (session == NULL) {
5263 session->smb2 = talloc_zero(session, struct smb2cli_session);
5264 if (session->smb2 == NULL) {
5265 talloc_free(session);
5269 session->conn = src->conn;
5270 *session->smb2 = *src->smb2;
5271 session->smb2_channel = src->smb2_channel;
5272 session->disconnect_expired = src->disconnect_expired;
5274 DLIST_ADD_END(src->conn->sessions, session, struct smbXcli_session *);
5275 talloc_set_destructor(session, smbXcli_session_destructor);
5280 bool smbXcli_session_is_authenticated(struct smbXcli_session *session)
5282 const DATA_BLOB *application_key;
5284 if (session->conn == NULL) {
5289 * If we have an application key we had a session key negotiated
5292 if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5293 application_key = &session->smb2->application_key;
5295 application_key = &session->smb1.application_key;
5298 if (application_key->length == 0) {
5305 NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
5306 TALLOC_CTX *mem_ctx,
5309 const DATA_BLOB *application_key;
5311 *key = data_blob_null;
5313 if (session->conn == NULL) {
5314 return NT_STATUS_NO_USER_SESSION_KEY;
5317 if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5318 application_key = &session->smb2->application_key;
5320 application_key = &session->smb1.application_key;
5323 if (application_key->length == 0) {
5324 return NT_STATUS_NO_USER_SESSION_KEY;
5327 *key = data_blob_dup_talloc(mem_ctx, *application_key);
5328 if (key->data == NULL) {
5329 return NT_STATUS_NO_MEMORY;
5332 return NT_STATUS_OK;
5335 void smbXcli_session_set_disconnect_expired(struct smbXcli_session *session)
5337 session->disconnect_expired = true;
5340 uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
5342 return session->smb1.session_id;
5345 void smb1cli_session_set_id(struct smbXcli_session *session,
5346 uint16_t session_id)
5348 session->smb1.session_id = session_id;
5351 NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
5352 const DATA_BLOB _session_key)
5354 struct smbXcli_conn *conn = session->conn;
5355 uint8_t session_key[16];
5358 return NT_STATUS_INVALID_PARAMETER_MIX;
5361 if (session->smb1.application_key.length != 0) {
5363 * TODO: do not allow this...
5365 * return NT_STATUS_INVALID_PARAMETER_MIX;
5367 data_blob_clear_free(&session->smb1.application_key);
5368 session->smb1.protected_key = false;
5371 if (_session_key.length == 0) {
5372 return NT_STATUS_OK;
5375 ZERO_STRUCT(session_key);
5376 memcpy(session_key, _session_key.data,
5377 MIN(_session_key.length, sizeof(session_key)));
5379 session->smb1.application_key = data_blob_talloc(session,
5381 sizeof(session_key));
5382 ZERO_STRUCT(session_key);
5383 if (session->smb1.application_key.data == NULL) {
5384 return NT_STATUS_NO_MEMORY;
5387 session->smb1.protected_key = false;
5389 return NT_STATUS_OK;
5392 NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
5394 if (session->smb1.protected_key) {
5395 /* already protected */
5396 return NT_STATUS_OK;
5399 if (session->smb1.application_key.length != 16) {
5400 return NT_STATUS_INVALID_PARAMETER_MIX;
5403 smb_key_derivation(session->smb1.application_key.data,
5404 session->smb1.application_key.length,
5405 session->smb1.application_key.data);
5407 session->smb1.protected_key = true;
5409 return NT_STATUS_OK;
5412 uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
5414 struct smbXcli_conn *conn = session->conn;
5415 uint8_t security_mode = 0;
5418 return security_mode;
5421 security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
5422 if (conn->mandatory_signing) {
5423 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
5426 return security_mode;
5429 uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
5431 return session->smb2->session_id;
5434 uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
5436 return session->smb2->session_flags;
5439 void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
5440 uint64_t session_id,
5441 uint16_t session_flags)
5443 session->smb2->session_id = session_id;
5444 session->smb2->session_flags = session_flags;
5447 void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
5449 session->smb2->channel_sequence += 1;
5452 uint16_t smb2cli_session_reset_channel_sequence(struct smbXcli_session *session,
5453 uint16_t channel_sequence)
5457 prev_cs = session->smb2->channel_sequence;
5458 session->smb2->channel_sequence = channel_sequence;
5463 void smb2cli_session_start_replay(struct smbXcli_session *session)
5465 session->smb2->replay_active = true;
5468 void smb2cli_session_stop_replay(struct smbXcli_session *session)
5470 session->smb2->replay_active = false;
5473 NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
5474 const struct iovec *iov)
5476 struct hc_sha512state sctx;
5479 if (session->conn == NULL) {
5480 return NT_STATUS_INTERNAL_ERROR;
5483 if (session->conn->protocol < PROTOCOL_SMB3_10) {
5484 return NT_STATUS_OK;
5487 if (session->smb2_channel.signing_key.length != 0) {
5488 return NT_STATUS_OK;
5491 samba_SHA512_Init(&sctx);
5492 samba_SHA512_Update(&sctx, session->smb2_channel.preauth_sha512,
5493 sizeof(session->smb2_channel.preauth_sha512));
5494 for (i = 0; i < 3; i++) {
5495 samba_SHA512_Update(&sctx, iov[i].iov_base, iov[i].iov_len);
5497 samba_SHA512_Final(session->smb2_channel.preauth_sha512, &sctx);
5499 return NT_STATUS_OK;
5502 NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
5503 const DATA_BLOB _session_key,
5504 const struct iovec *recv_iov)
5506 struct smbXcli_conn *conn = session->conn;
5507 uint16_t no_sign_flags;
5508 uint8_t session_key[16];
5509 bool check_signature = true;
5512 struct _derivation {
5517 struct _derivation signing;
5518 struct _derivation encryption;
5519 struct _derivation decryption;
5520 struct _derivation application;
5522 size_t nonce_size = 0;
5525 return NT_STATUS_INVALID_PARAMETER_MIX;
5528 if (recv_iov[0].iov_len != SMB2_HDR_BODY) {
5529 return NT_STATUS_INVALID_PARAMETER_MIX;
5532 no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST | SMB2_SESSION_FLAG_IS_NULL;
5534 if (session->smb2->session_flags & no_sign_flags) {
5535 session->smb2->should_sign = false;
5536 return NT_STATUS_OK;
5539 if (session->smb2->signing_key.length != 0) {
5540 return NT_STATUS_INVALID_PARAMETER_MIX;
5543 if (conn->protocol >= PROTOCOL_SMB3_10) {
5544 struct _derivation *d;
5547 p = data_blob_const(session->smb2_channel.preauth_sha512,
5548 sizeof(session->smb2_channel.preauth_sha512));
5550 d = &derivation.signing;
5551 d->label = data_blob_string_const_null("SMBSigningKey");
5554 d = &derivation.encryption;
5555 d->label = data_blob_string_const_null("SMBC2SCipherKey");
5558 d = &derivation.decryption;
5559 d->label = data_blob_string_const_null("SMBS2CCipherKey");
5562 d = &derivation.application;
5563 d->label = data_blob_string_const_null("SMBAppKey");
5566 } else if (conn->protocol >= PROTOCOL_SMB2_24) {
5567 struct _derivation *d;
5569 d = &derivation.signing;
5570 d->label = data_blob_string_const_null("SMB2AESCMAC");
5571 d->context = data_blob_string_const_null("SmbSign");
5573 d = &derivation.encryption;
5574 d->label = data_blob_string_const_null("SMB2AESCCM");
5575 d->context = data_blob_string_const_null("ServerIn ");
5577 d = &derivation.decryption;
5578 d->label = data_blob_string_const_null("SMB2AESCCM");
5579 d->context = data_blob_string_const_null("ServerOut");
5581 d = &derivation.application;
5582 d->label = data_blob_string_const_null("SMB2APP");
5583 d->context = data_blob_string_const_null("SmbRpc");
5586 ZERO_STRUCT(session_key);
5587 memcpy(session_key, _session_key.data,
5588 MIN(_session_key.length, sizeof(session_key)));
5590 session->smb2->signing_key = data_blob_talloc(session,
5592 sizeof(session_key));
5593 if (session->smb2->signing_key.data == NULL) {
5594 ZERO_STRUCT(session_key);
5595 return NT_STATUS_NO_MEMORY;
5598 if (conn->protocol >= PROTOCOL_SMB2_24) {
5599 struct _derivation *d = &derivation.signing;
5601 smb2_key_derivation(session_key, sizeof(session_key),
5602 d->label.data, d->label.length,
5603 d->context.data, d->context.length,
5604 session->smb2->signing_key.data);
5607 session->smb2->encryption_key = data_blob_dup_talloc(session,
5608 session->smb2->signing_key);
5609 if (session->smb2->encryption_key.data == NULL) {
5610 ZERO_STRUCT(session_key);
5611 return NT_STATUS_NO_MEMORY;
5614 if (conn->protocol >= PROTOCOL_SMB2_24) {
5615 struct _derivation *d = &derivation.encryption;
5617 smb2_key_derivation(session_key, sizeof(session_key),
5618 d->label.data, d->label.length,
5619 d->context.data, d->context.length,
5620 session->smb2->encryption_key.data);
5623 session->smb2->decryption_key = data_blob_dup_talloc(session,
5624 session->smb2->signing_key);
5625 if (session->smb2->decryption_key.data == NULL) {
5626 ZERO_STRUCT(session_key);
5627 return NT_STATUS_NO_MEMORY;
5630 if (conn->protocol >= PROTOCOL_SMB2_24) {
5631 struct _derivation *d = &derivation.decryption;
5633 smb2_key_derivation(session_key, sizeof(session_key),
5634 d->label.data, d->label.length,
5635 d->context.data, d->context.length,
5636 session->smb2->decryption_key.data);
5639 session->smb2->application_key = data_blob_dup_talloc(session,
5640 session->smb2->signing_key);
5641 if (session->smb2->application_key.data == NULL) {
5642 ZERO_STRUCT(session_key);
5643 return NT_STATUS_NO_MEMORY;
5646 if (conn->protocol >= PROTOCOL_SMB2_24) {
5647 struct _derivation *d = &derivation.application;
5649 smb2_key_derivation(session_key, sizeof(session_key),
5650 d->label.data, d->label.length,
5651 d->context.data, d->context.length,
5652 session->smb2->application_key.data);
5654 ZERO_STRUCT(session_key);
5656 session->smb2_channel.signing_key = data_blob_dup_talloc(session,
5657 session->smb2->signing_key);
5658 if (session->smb2_channel.signing_key.data == NULL) {
5659 return NT_STATUS_NO_MEMORY;
5662 check_signature = conn->mandatory_signing;
5664 hdr_flags = IVAL(recv_iov[0].iov_base, SMB2_HDR_FLAGS);
5665 if (hdr_flags & SMB2_HDR_FLAG_SIGNED) {
5667 * Sadly some vendors don't sign the
5668 * final SMB2 session setup response
5670 * At least Windows and Samba are always doing this
5671 * if there's a session key available.
5673 * We only check the signature if it's mandatory
5674 * or SMB2_HDR_FLAG_SIGNED is provided.
5676 check_signature = true;
5679 if (conn->protocol >= PROTOCOL_SMB3_10) {
5680 check_signature = true;
5683 if (check_signature) {
5684 status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
5685 session->conn->protocol,
5687 if (!NT_STATUS_IS_OK(status)) {
5692 session->smb2->should_sign = false;
5693 session->smb2->should_encrypt = false;
5695 if (conn->desire_signing) {
5696 session->smb2->should_sign = true;
5699 if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
5700 session->smb2->should_sign = true;
5703 if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
5704 session->smb2->should_encrypt = true;
5707 if (conn->protocol < PROTOCOL_SMB2_24) {
5708 session->smb2->should_encrypt = false;
5711 if (conn->smb2.server.cipher == 0) {
5712 session->smb2->should_encrypt = false;
5716 * CCM and GCM algorithms must never have their
5717 * nonce wrap, or the security of the whole
5718 * communication and the keys is destroyed.
5719 * We must drop the connection once we have
5720 * transfered too much data.
5722 * NOTE: We assume nonces greater than 8 bytes.
5724 generate_random_buffer((uint8_t *)&session->smb2->nonce_high_random,
5725 sizeof(session->smb2->nonce_high_random));
5726 switch (conn->smb2.server.cipher) {
5727 case SMB2_ENCRYPTION_AES128_CCM:
5728 nonce_size = AES_CCM_128_NONCE_SIZE;
5730 case SMB2_ENCRYPTION_AES128_GCM:
5731 nonce_size = AES_GCM_128_IV_SIZE;
5737 session->smb2->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
5738 session->smb2->nonce_high = 0;
5739 session->smb2->nonce_low = 0;
5741 return NT_STATUS_OK;
5744 NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
5745 struct smbXcli_session *session1,
5746 struct smbXcli_conn *conn,
5747 struct smbXcli_session **_session2)
5749 struct smbXcli_session *session2;
5751 if (session1->smb2->signing_key.length == 0) {
5752 return NT_STATUS_INVALID_PARAMETER_MIX;
5756 return NT_STATUS_INVALID_PARAMETER_MIX;
5759 session2 = talloc_zero(mem_ctx, struct smbXcli_session);
5760 if (session2 == NULL) {
5761 return NT_STATUS_NO_MEMORY;
5763 session2->smb2 = talloc_reference(session2, session1->smb2);
5764 if (session2->smb2 == NULL) {
5765 talloc_free(session2);
5766 return NT_STATUS_NO_MEMORY;
5769 talloc_set_destructor(session2, smbXcli_session_destructor);
5770 DLIST_ADD_END(conn->sessions, session2, struct smbXcli_session *);
5771 session2->conn = conn;
5773 memcpy(session2->smb2_channel.preauth_sha512,
5774 conn->smb2.preauth_sha512,
5775 sizeof(session2->smb2_channel.preauth_sha512));
5777 *_session2 = session2;
5778 return NT_STATUS_OK;
5781 NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
5782 const DATA_BLOB _channel_key,
5783 const struct iovec *recv_iov)
5785 struct smbXcli_conn *conn = session->conn;
5786 uint8_t channel_key[16];
5788 struct _derivation {
5793 struct _derivation signing;
5797 return NT_STATUS_INVALID_PARAMETER_MIX;
5800 if (session->smb2_channel.signing_key.length != 0) {
5801 return NT_STATUS_INVALID_PARAMETER_MIX;
5804 if (conn->protocol >= PROTOCOL_SMB3_10) {
5805 struct _derivation *d;
5808 p = data_blob_const(session->smb2_channel.preauth_sha512,
5809 sizeof(session->smb2_channel.preauth_sha512));
5811 d = &derivation.signing;
5812 d->label = data_blob_string_const_null("SMBSigningKey");
5814 } else if (conn->protocol >= PROTOCOL_SMB2_24) {
5815 struct _derivation *d;
5817 d = &derivation.signing;
5818 d->label = data_blob_string_const_null("SMB2AESCMAC");
5819 d->context = data_blob_string_const_null("SmbSign");
5822 ZERO_STRUCT(channel_key);
5823 memcpy(channel_key, _channel_key.data,
5824 MIN(_channel_key.length, sizeof(channel_key)));
5826 session->smb2_channel.signing_key = data_blob_talloc(session,
5828 sizeof(channel_key));
5829 if (session->smb2_channel.signing_key.data == NULL) {
5830 ZERO_STRUCT(channel_key);
5831 return NT_STATUS_NO_MEMORY;
5834 if (conn->protocol >= PROTOCOL_SMB2_24) {
5835 struct _derivation *d = &derivation.signing;
5837 smb2_key_derivation(channel_key, sizeof(channel_key),
5838 d->label.data, d->label.length,
5839 d->context.data, d->context.length,
5840 session->smb2_channel.signing_key.data);
5842 ZERO_STRUCT(channel_key);
5844 status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
5845 session->conn->protocol,
5847 if (!NT_STATUS_IS_OK(status)) {
5851 return NT_STATUS_OK;
5854 NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
5856 if (session->smb2->should_encrypt) {
5857 return NT_STATUS_OK;
5860 if (session->conn->protocol < PROTOCOL_SMB2_24) {
5861 return NT_STATUS_NOT_SUPPORTED;
5864 if (session->conn->smb2.server.cipher == 0) {
5865 return NT_STATUS_NOT_SUPPORTED;
5868 if (session->smb2->signing_key.data == NULL) {
5869 return NT_STATUS_NOT_SUPPORTED;
5871 session->smb2->should_encrypt = true;
5872 return NT_STATUS_OK;
5875 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
5877 struct smbXcli_tcon *tcon;
5879 tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
5887 void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
5888 uint32_t fs_attributes)
5890 tcon->fs_attributes = fs_attributes;
5893 uint32_t smbXcli_tcon_get_fs_attributes(struct smbXcli_tcon *tcon)
5895 return tcon->fs_attributes;
5898 bool smbXcli_tcon_is_dfs_share(struct smbXcli_tcon *tcon)
5904 if (tcon->is_smb1) {
5905 if (tcon->smb1.optional_support & SMB_SHARE_IN_DFS) {
5912 if (tcon->smb2.capabilities & SMB2_SHARE_CAP_DFS) {
5919 uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
5921 return tcon->smb1.tcon_id;
5924 void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
5926 tcon->is_smb1 = true;
5927 tcon->smb1.tcon_id = tcon_id;
5930 bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
5932 uint16_t optional_support,
5933 uint32_t maximal_access,
5934 uint32_t guest_maximal_access,
5935 const char *service,
5936 const char *fs_type)
5938 tcon->is_smb1 = true;
5939 tcon->fs_attributes = 0;
5940 tcon->smb1.tcon_id = tcon_id;
5941 tcon->smb1.optional_support = optional_support;
5942 tcon->smb1.maximal_access = maximal_access;
5943 tcon->smb1.guest_maximal_access = guest_maximal_access;
5945 TALLOC_FREE(tcon->smb1.service);
5946 tcon->smb1.service = talloc_strdup(tcon, service);
5947 if (service != NULL && tcon->smb1.service == NULL) {
5951 TALLOC_FREE(tcon->smb1.fs_type);
5952 tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
5953 if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
5960 uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
5962 return tcon->smb2.tcon_id;
5965 uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
5967 return tcon->smb2.capabilities;
5970 void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
5971 struct smbXcli_session *session,
5975 uint32_t capabilities,
5976 uint32_t maximal_access)
5978 tcon->is_smb1 = false;
5979 tcon->fs_attributes = 0;
5980 tcon->smb2.tcon_id = tcon_id;
5981 tcon->smb2.type = type;
5982 tcon->smb2.flags = flags;
5983 tcon->smb2.capabilities = capabilities;
5984 tcon->smb2.maximal_access = maximal_access;
5986 tcon->smb2.should_sign = false;
5987 tcon->smb2.should_encrypt = false;
5989 if (session == NULL) {
5993 tcon->smb2.should_sign = session->smb2->should_sign;
5994 tcon->smb2.should_encrypt = session->smb2->should_encrypt;
5996 if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
5997 tcon->smb2.should_encrypt = true;
6001 void smb2cli_tcon_should_sign(struct smbXcli_tcon *tcon,
6004 tcon->smb2.should_sign = should_sign;
6007 bool smb2cli_tcon_is_signing_on(struct smbXcli_tcon *tcon)
6009 if (tcon->smb2.should_encrypt) {
6013 return tcon->smb2.should_sign;
6016 void smb2cli_tcon_should_encrypt(struct smbXcli_tcon *tcon,
6017 bool should_encrypt)
6019 tcon->smb2.should_encrypt = should_encrypt;
6022 bool smb2cli_tcon_is_encryption_on(struct smbXcli_tcon *tcon)
6024 return tcon->smb2.should_encrypt;