samba-tool: Add a gpo command for listing Sudoers Group Policies
[Samba.git] / libcli / smb / smbXcli_base.c
blobdf80be6bf16fcfbb4ddee44dcda5485083b89c92
1 /*
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/>.
21 #include "includes.h"
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 "libcli/smb/smb2_signing.h"
38 #include "lib/crypto/gnutls_helpers.h"
39 #include <gnutls/gnutls.h>
40 #include <gnutls/crypto.h>
42 struct smbXcli_conn;
43 struct smbXcli_req;
44 struct smbXcli_session;
45 struct smbXcli_tcon;
47 struct smbXcli_conn {
48 int sock_fd;
49 struct sockaddr_storage local_ss;
50 struct sockaddr_storage remote_ss;
51 const char *remote_name;
53 struct tevent_queue *outgoing;
54 struct tevent_req **pending;
55 struct tevent_req *read_smb_req;
56 struct tevent_req *suicide_req;
58 enum protocol_types min_protocol;
59 enum protocol_types max_protocol;
60 enum protocol_types protocol;
61 bool allow_signing;
62 bool desire_signing;
63 bool mandatory_signing;
66 * The incoming dispatch function should return:
67 * - NT_STATUS_RETRY, if more incoming PDUs are expected.
68 * - NT_STATUS_OK, if no more processing is desired, e.g.
69 * the dispatch function called
70 * tevent_req_done().
71 * - All other return values disconnect the connection.
73 NTSTATUS (*dispatch_incoming)(struct smbXcli_conn *conn,
74 TALLOC_CTX *tmp_mem,
75 uint8_t *inbuf);
77 struct {
78 struct {
79 uint32_t capabilities;
80 uint32_t max_xmit;
81 } client;
83 struct {
84 uint32_t capabilities;
85 uint32_t max_xmit;
86 uint16_t max_mux;
87 uint16_t security_mode;
88 bool readbraw;
89 bool writebraw;
90 bool lockread;
91 bool writeunlock;
92 uint32_t session_key;
93 struct GUID guid;
94 DATA_BLOB gss_blob;
95 uint8_t challenge[8];
96 const char *workgroup;
97 const char *name;
98 int time_zone;
99 NTTIME system_time;
100 } server;
102 uint32_t capabilities;
103 uint32_t max_xmit;
105 uint16_t mid;
107 struct smb_signing_state *signing;
108 struct smb_trans_enc_state *trans_enc;
110 struct tevent_req *read_braw_req;
111 } smb1;
113 struct {
114 struct {
115 uint32_t capabilities;
116 uint16_t security_mode;
117 struct GUID guid;
118 } client;
120 struct {
121 uint32_t capabilities;
122 uint16_t security_mode;
123 struct GUID guid;
124 uint32_t max_trans_size;
125 uint32_t max_read_size;
126 uint32_t max_write_size;
127 NTTIME system_time;
128 NTTIME start_time;
129 DATA_BLOB gss_blob;
130 uint16_t cipher;
131 } server;
133 uint64_t mid;
134 uint16_t cur_credits;
135 uint16_t max_credits;
137 uint32_t cc_chunk_len;
138 uint32_t cc_max_chunks;
140 uint8_t io_priority;
142 bool force_channel_sequence;
144 uint8_t preauth_sha512[64];
145 } smb2;
147 struct smbXcli_session *sessions;
150 struct smb2cli_session {
151 uint64_t session_id;
152 uint16_t session_flags;
153 DATA_BLOB application_key;
154 struct smb2_signing_key *signing_key;
155 bool should_sign;
156 bool should_encrypt;
157 struct smb2_signing_key *encryption_key;
158 struct smb2_signing_key *decryption_key;
159 uint64_t nonce_high_random;
160 uint64_t nonce_high_max;
161 uint64_t nonce_high;
162 uint64_t nonce_low;
163 uint16_t channel_sequence;
164 bool replay_active;
165 bool require_signed_response;
168 struct smbXcli_session {
169 struct smbXcli_session *prev, *next;
170 struct smbXcli_conn *conn;
172 struct {
173 uint16_t session_id;
174 uint16_t action;
175 DATA_BLOB application_key;
176 bool protected_key;
177 } smb1;
179 struct smb2cli_session *smb2;
181 struct {
182 struct smb2_signing_key *signing_key;
183 uint8_t preauth_sha512[64];
184 } smb2_channel;
187 * this should be a short term hack
188 * until the upper layers have implemented
189 * re-authentication.
191 bool disconnect_expired;
194 struct smbXcli_tcon {
195 bool is_smb1;
196 uint32_t fs_attributes;
198 struct {
199 uint16_t tcon_id;
200 uint16_t optional_support;
201 uint32_t maximal_access;
202 uint32_t guest_maximal_access;
203 char *service;
204 char *fs_type;
205 } smb1;
207 struct {
208 uint32_t tcon_id;
209 uint8_t type;
210 uint32_t flags;
211 uint32_t capabilities;
212 uint32_t maximal_access;
213 bool should_sign;
214 bool should_encrypt;
215 } smb2;
218 struct smbXcli_req_state {
219 struct tevent_context *ev;
220 struct smbXcli_conn *conn;
221 struct smbXcli_session *session; /* maybe NULL */
222 struct smbXcli_tcon *tcon; /* maybe NULL */
224 uint8_t length_hdr[4];
226 bool one_way;
228 uint8_t *inbuf;
230 struct tevent_req *write_req;
232 struct timeval endtime;
234 struct {
235 /* Space for the header including the wct */
236 uint8_t hdr[HDR_VWV];
239 * For normal requests, smb1cli_req_send chooses a mid.
240 * SecondaryV trans requests need to use the mid of the primary
241 * request, so we need a place to store it.
242 * Assume it is set if != 0.
244 uint16_t mid;
246 uint16_t *vwv;
247 uint8_t bytecount_buf[2];
249 #define MAX_SMB_IOV 10
250 /* length_hdr, hdr, words, byte_count, buffers */
251 struct iovec iov[1 + 3 + MAX_SMB_IOV];
252 int iov_count;
254 bool one_way_seqnum;
255 uint32_t seqnum;
256 struct tevent_req **chained_requests;
258 uint8_t recv_cmd;
259 NTSTATUS recv_status;
260 /* always an array of 3 talloc elements */
261 struct iovec *recv_iov;
262 } smb1;
264 struct {
265 const uint8_t *fixed;
266 uint16_t fixed_len;
267 const uint8_t *dyn;
268 uint32_t dyn_len;
270 uint8_t transform[SMB2_TF_HDR_SIZE];
271 uint8_t hdr[SMB2_HDR_BODY];
272 uint8_t pad[7]; /* padding space for compounding */
275 * always an array of 3 talloc elements
276 * (without a SMB2_TRANSFORM header!)
278 * HDR, BODY, DYN
280 struct iovec *recv_iov;
283 * the expected max for the response dyn_len
285 uint32_t max_dyn_len;
287 uint16_t credit_charge;
289 bool should_sign;
290 bool should_encrypt;
291 uint64_t encryption_session_id;
293 bool signing_skipped;
294 bool require_signed_response;
295 bool notify_async;
296 bool got_async;
297 uint16_t cancel_flags;
298 uint64_t cancel_mid;
299 uint64_t cancel_aid;
300 } smb2;
303 static int smbXcli_conn_destructor(struct smbXcli_conn *conn)
306 * NT_STATUS_OK, means we do not notify the callers
308 smbXcli_conn_disconnect(conn, NT_STATUS_OK);
310 while (conn->sessions) {
311 conn->sessions->conn = NULL;
312 DLIST_REMOVE(conn->sessions, conn->sessions);
315 if (conn->smb1.trans_enc) {
316 TALLOC_FREE(conn->smb1.trans_enc);
319 return 0;
322 struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
323 int fd,
324 const char *remote_name,
325 enum smb_signing_setting signing_state,
326 uint32_t smb1_capabilities,
327 struct GUID *client_guid,
328 uint32_t smb2_capabilities)
330 struct smbXcli_conn *conn = NULL;
331 void *ss = NULL;
332 struct sockaddr *sa = NULL;
333 socklen_t sa_length;
334 int ret;
336 conn = talloc_zero(mem_ctx, struct smbXcli_conn);
337 if (!conn) {
338 return NULL;
341 ret = set_blocking(fd, false);
342 if (ret < 0) {
343 goto error;
345 conn->sock_fd = fd;
347 conn->remote_name = talloc_strdup(conn, remote_name);
348 if (conn->remote_name == NULL) {
349 goto error;
352 ss = (void *)&conn->local_ss;
353 sa = (struct sockaddr *)ss;
354 sa_length = sizeof(conn->local_ss);
355 ret = getsockname(fd, sa, &sa_length);
356 if (ret == -1) {
357 goto error;
359 ss = (void *)&conn->remote_ss;
360 sa = (struct sockaddr *)ss;
361 sa_length = sizeof(conn->remote_ss);
362 ret = getpeername(fd, sa, &sa_length);
363 if (ret == -1) {
364 goto error;
367 conn->outgoing = tevent_queue_create(conn, "smbXcli_outgoing");
368 if (conn->outgoing == NULL) {
369 goto error;
371 conn->pending = NULL;
373 conn->min_protocol = PROTOCOL_NONE;
374 conn->max_protocol = PROTOCOL_NONE;
375 conn->protocol = PROTOCOL_NONE;
377 switch (signing_state) {
378 case SMB_SIGNING_OFF:
379 /* never */
380 conn->allow_signing = false;
381 conn->desire_signing = false;
382 conn->mandatory_signing = false;
383 break;
384 case SMB_SIGNING_DEFAULT:
385 case SMB_SIGNING_IF_REQUIRED:
386 /* if the server requires it */
387 conn->allow_signing = true;
388 conn->desire_signing = false;
389 conn->mandatory_signing = false;
390 break;
391 case SMB_SIGNING_DESIRED:
392 /* if the server desires it */
393 conn->allow_signing = true;
394 conn->desire_signing = true;
395 conn->mandatory_signing = false;
396 break;
397 case SMB_SIGNING_IPC_DEFAULT:
398 case SMB_SIGNING_REQUIRED:
399 /* always */
400 conn->allow_signing = true;
401 conn->desire_signing = true;
402 conn->mandatory_signing = true;
403 break;
406 conn->smb1.client.capabilities = smb1_capabilities;
407 conn->smb1.client.max_xmit = UINT16_MAX;
409 conn->smb1.capabilities = conn->smb1.client.capabilities;
410 conn->smb1.max_xmit = 1024;
412 conn->smb1.mid = 1;
414 /* initialise signing */
415 conn->smb1.signing = smb_signing_init(conn,
416 conn->allow_signing,
417 conn->desire_signing,
418 conn->mandatory_signing);
419 if (!conn->smb1.signing) {
420 goto error;
423 conn->smb2.client.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
424 if (conn->mandatory_signing) {
425 conn->smb2.client.security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
427 if (client_guid) {
428 conn->smb2.client.guid = *client_guid;
430 conn->smb2.client.capabilities = smb2_capabilities;
432 conn->smb2.cur_credits = 1;
433 conn->smb2.max_credits = 0;
434 conn->smb2.io_priority = 1;
437 * Samba and Windows servers accept a maximum of 16 MiB with a maximum
438 * chunk length of 1 MiB.
440 conn->smb2.cc_chunk_len = 1024 * 1024;
441 conn->smb2.cc_max_chunks = 16;
443 talloc_set_destructor(conn, smbXcli_conn_destructor);
444 return conn;
446 error:
447 TALLOC_FREE(conn);
448 return NULL;
451 bool smbXcli_conn_is_connected(struct smbXcli_conn *conn)
453 if (conn == NULL) {
454 return false;
457 if (conn->sock_fd == -1) {
458 return false;
461 return true;
464 enum protocol_types smbXcli_conn_protocol(struct smbXcli_conn *conn)
466 return conn->protocol;
469 bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn)
471 if (conn->protocol >= PROTOCOL_SMB2_02) {
472 return true;
475 if (conn->smb1.capabilities & CAP_UNICODE) {
476 return true;
479 return false;
482 bool smbXcli_conn_signing_mandatory(struct smbXcli_conn *conn)
484 return conn->mandatory_signing;
488 * [MS-SMB] 2.2.2.3.5 - SMB1 support for passing through
489 * query/set commands to the file system
491 bool smbXcli_conn_support_passthrough(struct smbXcli_conn *conn)
493 if (conn->protocol >= PROTOCOL_SMB2_02) {
494 return true;
497 if (conn->smb1.capabilities & CAP_W2K_SMBS) {
498 return true;
501 return false;
504 void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options)
506 set_socket_options(conn->sock_fd, options);
509 const struct sockaddr_storage *smbXcli_conn_local_sockaddr(struct smbXcli_conn *conn)
511 return &conn->local_ss;
514 const struct sockaddr_storage *smbXcli_conn_remote_sockaddr(struct smbXcli_conn *conn)
516 return &conn->remote_ss;
519 const char *smbXcli_conn_remote_name(struct smbXcli_conn *conn)
521 return conn->remote_name;
524 uint16_t smbXcli_conn_max_requests(struct smbXcli_conn *conn)
526 if (conn->protocol >= PROTOCOL_SMB2_02) {
528 * TODO...
530 return 1;
533 return conn->smb1.server.max_mux;
536 NTTIME smbXcli_conn_server_system_time(struct smbXcli_conn *conn)
538 if (conn->protocol >= PROTOCOL_SMB2_02) {
539 return conn->smb2.server.system_time;
542 return conn->smb1.server.system_time;
545 const DATA_BLOB *smbXcli_conn_server_gss_blob(struct smbXcli_conn *conn)
547 if (conn->protocol >= PROTOCOL_SMB2_02) {
548 return &conn->smb2.server.gss_blob;
551 return &conn->smb1.server.gss_blob;
554 const struct GUID *smbXcli_conn_server_guid(struct smbXcli_conn *conn)
556 if (conn->protocol >= PROTOCOL_SMB2_02) {
557 return &conn->smb2.server.guid;
560 return &conn->smb1.server.guid;
563 bool smbXcli_conn_get_force_channel_sequence(struct smbXcli_conn *conn)
565 return conn->smb2.force_channel_sequence;
568 void smbXcli_conn_set_force_channel_sequence(struct smbXcli_conn *conn,
569 bool v)
571 conn->smb2.force_channel_sequence = v;
574 struct smbXcli_conn_samba_suicide_state {
575 struct smbXcli_conn *conn;
576 struct iovec iov;
577 uint8_t buf[9];
578 struct tevent_req *write_req;
581 static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
582 enum tevent_req_state req_state);
583 static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq);
585 struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx,
586 struct tevent_context *ev,
587 struct smbXcli_conn *conn,
588 uint8_t exitcode)
590 struct tevent_req *req, *subreq;
591 struct smbXcli_conn_samba_suicide_state *state;
593 req = tevent_req_create(mem_ctx, &state,
594 struct smbXcli_conn_samba_suicide_state);
595 if (req == NULL) {
596 return NULL;
598 state->conn = conn;
599 SIVAL(state->buf, 4, SMB_SUICIDE_PACKET);
600 SCVAL(state->buf, 8, exitcode);
601 _smb_setlen_nbt(state->buf, sizeof(state->buf)-4);
603 if (conn->suicide_req != NULL) {
604 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
605 return tevent_req_post(req, ev);
608 state->iov.iov_base = state->buf;
609 state->iov.iov_len = sizeof(state->buf);
611 subreq = writev_send(state, ev, conn->outgoing, conn->sock_fd,
612 false, &state->iov, 1);
613 if (tevent_req_nomem(subreq, req)) {
614 return tevent_req_post(req, ev);
616 tevent_req_set_callback(subreq, smbXcli_conn_samba_suicide_done, req);
617 state->write_req = subreq;
619 tevent_req_set_cleanup_fn(req, smbXcli_conn_samba_suicide_cleanup);
622 * We need to use tevent_req_defer_callback()
623 * in order to allow smbXcli_conn_disconnect()
624 * to do a safe cleanup.
626 tevent_req_defer_callback(req, ev);
627 conn->suicide_req = req;
629 return req;
632 static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
633 enum tevent_req_state req_state)
635 struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
636 req, struct smbXcli_conn_samba_suicide_state);
638 TALLOC_FREE(state->write_req);
640 if (state->conn == NULL) {
641 return;
644 if (state->conn->suicide_req == req) {
645 state->conn->suicide_req = NULL;
647 state->conn = NULL;
650 static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq)
652 struct tevent_req *req = tevent_req_callback_data(
653 subreq, struct tevent_req);
654 struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
655 req, struct smbXcli_conn_samba_suicide_state);
656 ssize_t nwritten;
657 int err;
659 state->write_req = NULL;
661 nwritten = writev_recv(subreq, &err);
662 TALLOC_FREE(subreq);
663 if (nwritten == -1) {
664 /* here, we need to notify all pending requests */
665 NTSTATUS status = map_nt_error_from_unix_common(err);
666 smbXcli_conn_disconnect(state->conn, status);
667 return;
669 tevent_req_done(req);
672 NTSTATUS smbXcli_conn_samba_suicide_recv(struct tevent_req *req)
674 return tevent_req_simple_recv_ntstatus(req);
677 NTSTATUS smbXcli_conn_samba_suicide(struct smbXcli_conn *conn,
678 uint8_t exitcode)
680 TALLOC_CTX *frame = talloc_stackframe();
681 struct tevent_context *ev;
682 struct tevent_req *req;
683 NTSTATUS status = NT_STATUS_NO_MEMORY;
684 bool ok;
686 if (smbXcli_conn_has_async_calls(conn)) {
688 * Can't use sync call while an async call is in flight
690 status = NT_STATUS_INVALID_PARAMETER_MIX;
691 goto fail;
693 ev = samba_tevent_context_init(frame);
694 if (ev == NULL) {
695 goto fail;
697 req = smbXcli_conn_samba_suicide_send(frame, ev, conn, exitcode);
698 if (req == NULL) {
699 goto fail;
701 ok = tevent_req_poll_ntstatus(req, ev, &status);
702 if (!ok) {
703 goto fail;
705 status = smbXcli_conn_samba_suicide_recv(req);
706 fail:
707 TALLOC_FREE(frame);
708 return status;
711 uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn)
713 return conn->smb1.capabilities;
716 uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn)
718 return conn->smb1.max_xmit;
721 bool smb1cli_conn_req_possible(struct smbXcli_conn *conn)
723 size_t pending = talloc_array_length(conn->pending);
724 uint16_t possible = conn->smb1.server.max_mux;
726 if (pending >= possible) {
727 return false;
730 return true;
733 uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn)
735 return conn->smb1.server.session_key;
738 const uint8_t *smb1cli_conn_server_challenge(struct smbXcli_conn *conn)
740 return conn->smb1.server.challenge;
743 uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn)
745 return conn->smb1.server.security_mode;
748 bool smb1cli_conn_server_readbraw(struct smbXcli_conn *conn)
750 return conn->smb1.server.readbraw;
753 bool smb1cli_conn_server_writebraw(struct smbXcli_conn *conn)
755 return conn->smb1.server.writebraw;
758 bool smb1cli_conn_server_lockread(struct smbXcli_conn *conn)
760 return conn->smb1.server.lockread;
763 bool smb1cli_conn_server_writeunlock(struct smbXcli_conn *conn)
765 return conn->smb1.server.writeunlock;
768 int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn)
770 return conn->smb1.server.time_zone;
773 bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
774 const DATA_BLOB user_session_key,
775 const DATA_BLOB response)
777 return smb_signing_activate(conn->smb1.signing,
778 user_session_key,
779 response);
782 bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
783 const uint8_t *buf, uint32_t seqnum)
785 const uint8_t *hdr = buf + NBT_HDR_SIZE;
786 size_t len = smb_len_nbt(buf);
788 return smb_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
791 bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
793 return smb_signing_is_active(conn->smb1.signing);
796 void smb1cli_conn_set_encryption(struct smbXcli_conn *conn,
797 struct smb_trans_enc_state *es)
799 /* Replace the old state, if any. */
800 if (conn->smb1.trans_enc) {
801 TALLOC_FREE(conn->smb1.trans_enc);
803 conn->smb1.trans_enc = es;
806 bool smb1cli_conn_encryption_on(struct smbXcli_conn *conn)
808 return common_encryption_on(conn->smb1.trans_enc);
812 static NTSTATUS smb1cli_pull_raw_error(const uint8_t *hdr)
814 uint32_t flags2 = SVAL(hdr, HDR_FLG2);
815 NTSTATUS status = NT_STATUS(IVAL(hdr, HDR_RCLS));
817 if (NT_STATUS_IS_OK(status)) {
818 return NT_STATUS_OK;
821 if (flags2 & FLAGS2_32_BIT_ERROR_CODES) {
822 return status;
825 return NT_STATUS_DOS(CVAL(hdr, HDR_RCLS), SVAL(hdr, HDR_ERR));
829 * Is the SMB command able to hold an AND_X successor
830 * @param[in] cmd The SMB command in question
831 * @retval Can we add a chained request after "cmd"?
833 bool smb1cli_is_andx_req(uint8_t cmd)
835 switch (cmd) {
836 case SMBtconX:
837 case SMBlockingX:
838 case SMBopenX:
839 case SMBreadX:
840 case SMBwriteX:
841 case SMBsesssetupX:
842 case SMBulogoffX:
843 case SMBntcreateX:
844 return true;
845 break;
846 default:
847 break;
850 return false;
853 static uint16_t smb1cli_alloc_mid(struct smbXcli_conn *conn)
855 size_t num_pending = talloc_array_length(conn->pending);
856 uint16_t result;
858 if (conn->protocol == PROTOCOL_NONE) {
860 * This is what windows sends on the SMB1 Negprot request
861 * and some vendors reuse the SMB1 MID as SMB2 sequence number.
863 return 0;
866 while (true) {
867 size_t i;
869 result = conn->smb1.mid++;
870 if ((result == 0) || (result == 0xffff)) {
871 continue;
874 for (i=0; i<num_pending; i++) {
875 if (result == smb1cli_req_mid(conn->pending[i])) {
876 break;
880 if (i == num_pending) {
881 return result;
886 static NTSTATUS smbXcli_req_cancel_write_req(struct tevent_req *req)
888 struct smbXcli_req_state *state =
889 tevent_req_data(req,
890 struct smbXcli_req_state);
891 struct smbXcli_conn *conn = state->conn;
892 size_t num_pending = talloc_array_length(conn->pending);
893 ssize_t ret;
894 int err;
895 bool ok;
897 if (state->write_req == NULL) {
898 return NT_STATUS_OK;
902 * Check if it's possible to cancel the request.
903 * If the result is true it's not too late.
904 * See writev_cancel().
906 ok = tevent_req_cancel(state->write_req);
907 if (ok) {
908 TALLOC_FREE(state->write_req);
910 if (conn->protocol >= PROTOCOL_SMB2_02) {
912 * SMB2 has a sane signing state.
914 return NT_STATUS_OK;
917 if (num_pending > 1) {
919 * We have more pending requests following us. This
920 * means the signing state will be broken for them.
922 * As a solution we could add the requests directly to
923 * our outgoing queue and do the signing in the trigger
924 * function and then use writev_send() without passing a
925 * queue. That way we'll only sign packets we're most
926 * likely send to the wire.
928 return NT_STATUS_REQUEST_OUT_OF_SEQUENCE;
932 * If we're the only request that's
933 * pending, we're able to recover the signing
934 * state.
936 smb_signing_cancel_reply(conn->smb1.signing,
937 state->smb1.one_way_seqnum);
938 return NT_STATUS_OK;
941 ret = writev_recv(state->write_req, &err);
942 TALLOC_FREE(state->write_req);
943 if (ret == -1) {
944 return map_nt_error_from_unix_common(err);
947 return NT_STATUS_OK;
950 void smbXcli_req_unset_pending(struct tevent_req *req)
952 struct smbXcli_req_state *state =
953 tevent_req_data(req,
954 struct smbXcli_req_state);
955 struct smbXcli_conn *conn = state->conn;
956 size_t num_pending = talloc_array_length(conn->pending);
957 size_t i;
958 NTSTATUS cancel_status;
960 cancel_status = smbXcli_req_cancel_write_req(req);
962 if (state->smb1.mid != 0) {
964 * This is a [nt]trans[2] request which waits
965 * for more than one reply.
967 if (!NT_STATUS_IS_OK(cancel_status)) {
969 * If the write_req cancel didn't work
970 * we can't use the connection anymore.
972 smbXcli_conn_disconnect(conn, cancel_status);
973 return;
975 return;
978 tevent_req_set_cleanup_fn(req, NULL);
980 if (num_pending == 1) {
982 * The pending read_smb tevent_req is a child of
983 * conn->pending. So if nothing is pending anymore, we need to
984 * delete the socket read fde.
986 /* TODO: smbXcli_conn_cancel_read_req */
987 TALLOC_FREE(conn->pending);
988 conn->read_smb_req = NULL;
990 if (!NT_STATUS_IS_OK(cancel_status)) {
992 * If the write_req cancel didn't work
993 * we can't use the connection anymore.
995 smbXcli_conn_disconnect(conn, cancel_status);
996 return;
998 return;
1001 for (i=0; i<num_pending; i++) {
1002 if (req == conn->pending[i]) {
1003 break;
1006 if (i == num_pending) {
1008 * Something's seriously broken. Just returning here is the
1009 * right thing nevertheless, the point of this routine is to
1010 * remove ourselves from conn->pending.
1013 if (!NT_STATUS_IS_OK(cancel_status)) {
1015 * If the write_req cancel didn't work
1016 * we can't use the connection anymore.
1018 smbXcli_conn_disconnect(conn, cancel_status);
1019 return;
1021 return;
1025 * Remove ourselves from the conn->pending array
1027 for (; i < (num_pending - 1); i++) {
1028 conn->pending[i] = conn->pending[i+1];
1032 * No NULL check here, we're shrinking by sizeof(void *), and
1033 * talloc_realloc just adjusts the size for this.
1035 conn->pending = talloc_realloc(NULL, conn->pending, struct tevent_req *,
1036 num_pending - 1);
1038 if (!NT_STATUS_IS_OK(cancel_status)) {
1040 * If the write_req cancel didn't work
1041 * we can't use the connection anymore.
1043 smbXcli_conn_disconnect(conn, cancel_status);
1044 return;
1046 return;
1049 static void smbXcli_req_cleanup(struct tevent_req *req,
1050 enum tevent_req_state req_state)
1052 struct smbXcli_req_state *state =
1053 tevent_req_data(req,
1054 struct smbXcli_req_state);
1055 struct smbXcli_conn *conn = state->conn;
1056 NTSTATUS cancel_status;
1058 switch (req_state) {
1059 case TEVENT_REQ_RECEIVED:
1061 * Make sure we really remove it from
1062 * the pending array on destruction.
1064 * smbXcli_req_unset_pending() calls
1065 * smbXcli_req_cancel_write_req() internal
1067 state->smb1.mid = 0;
1068 smbXcli_req_unset_pending(req);
1069 return;
1070 default:
1071 cancel_status = smbXcli_req_cancel_write_req(req);
1072 if (!NT_STATUS_IS_OK(cancel_status)) {
1074 * If the write_req cancel didn't work
1075 * we can't use the connection anymore.
1077 smbXcli_conn_disconnect(conn, cancel_status);
1078 return;
1080 return;
1084 static bool smb1cli_req_cancel(struct tevent_req *req);
1085 static bool smb2cli_req_cancel(struct tevent_req *req);
1087 static bool smbXcli_req_cancel(struct tevent_req *req)
1089 struct smbXcli_req_state *state =
1090 tevent_req_data(req,
1091 struct smbXcli_req_state);
1093 if (!smbXcli_conn_is_connected(state->conn)) {
1094 return false;
1097 if (state->conn->protocol == PROTOCOL_NONE) {
1098 return false;
1101 if (state->conn->protocol >= PROTOCOL_SMB2_02) {
1102 return smb2cli_req_cancel(req);
1105 return smb1cli_req_cancel(req);
1108 static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
1110 bool smbXcli_req_set_pending(struct tevent_req *req)
1112 struct smbXcli_req_state *state =
1113 tevent_req_data(req,
1114 struct smbXcli_req_state);
1115 struct smbXcli_conn *conn;
1116 struct tevent_req **pending;
1117 size_t num_pending;
1119 conn = state->conn;
1121 if (!smbXcli_conn_is_connected(conn)) {
1122 return false;
1125 num_pending = talloc_array_length(conn->pending);
1127 pending = talloc_realloc(conn, conn->pending, struct tevent_req *,
1128 num_pending+1);
1129 if (pending == NULL) {
1130 return false;
1132 pending[num_pending] = req;
1133 conn->pending = pending;
1134 tevent_req_set_cleanup_fn(req, smbXcli_req_cleanup);
1135 tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1137 if (!smbXcli_conn_receive_next(conn)) {
1139 * the caller should notify the current request
1141 * And all other pending requests get notified
1142 * by smbXcli_conn_disconnect().
1144 smbXcli_req_unset_pending(req);
1145 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1146 return false;
1149 return true;
1152 static void smbXcli_conn_received(struct tevent_req *subreq);
1154 static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
1156 size_t num_pending = talloc_array_length(conn->pending);
1157 struct tevent_req *req;
1158 struct smbXcli_req_state *state;
1160 if (conn->read_smb_req != NULL) {
1161 return true;
1164 if (num_pending == 0) {
1165 if (conn->smb2.mid < UINT64_MAX) {
1166 /* no more pending requests, so we are done for now */
1167 return true;
1171 * If there are no more SMB2 requests possible,
1172 * because we are out of message ids,
1173 * we need to disconnect.
1175 smbXcli_conn_disconnect(conn, NT_STATUS_CONNECTION_ABORTED);
1176 return true;
1179 req = conn->pending[0];
1180 state = tevent_req_data(req, struct smbXcli_req_state);
1183 * We're the first ones, add the read_smb request that waits for the
1184 * answer from the server
1186 conn->read_smb_req = read_smb_send(conn->pending,
1187 state->ev,
1188 conn->sock_fd);
1189 if (conn->read_smb_req == NULL) {
1190 return false;
1192 tevent_req_set_callback(conn->read_smb_req, smbXcli_conn_received, conn);
1193 return true;
1196 void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
1198 struct smbXcli_session *session;
1199 int sock_fd = conn->sock_fd;
1201 tevent_queue_stop(conn->outgoing);
1203 conn->sock_fd = -1;
1205 session = conn->sessions;
1206 if (talloc_array_length(conn->pending) == 0) {
1208 * if we do not have pending requests
1209 * there is no need to update the channel_sequence
1211 session = NULL;
1213 for (; session; session = session->next) {
1214 smb2cli_session_increment_channel_sequence(session);
1217 if (conn->suicide_req != NULL) {
1219 * smbXcli_conn_samba_suicide_send()
1220 * used tevent_req_defer_callback() already.
1222 if (!NT_STATUS_IS_OK(status)) {
1223 tevent_req_nterror(conn->suicide_req, status);
1225 conn->suicide_req = NULL;
1229 * Cancel all pending requests. We do not do a for-loop walking
1230 * conn->pending because that array changes in
1231 * smbXcli_req_unset_pending.
1233 while (conn->pending != NULL &&
1234 talloc_array_length(conn->pending) > 0) {
1235 struct tevent_req *req;
1236 struct smbXcli_req_state *state;
1237 struct tevent_req **chain;
1238 size_t num_chained;
1239 size_t i;
1241 req = conn->pending[0];
1242 state = tevent_req_data(req, struct smbXcli_req_state);
1244 if (state->smb1.chained_requests == NULL) {
1245 bool in_progress;
1248 * We're dead. No point waiting for trans2
1249 * replies.
1251 state->smb1.mid = 0;
1253 smbXcli_req_unset_pending(req);
1255 if (NT_STATUS_IS_OK(status)) {
1256 /* do not notify the callers */
1257 continue;
1260 in_progress = tevent_req_is_in_progress(req);
1261 if (!in_progress) {
1263 * already finished
1265 continue;
1269 * we need to defer the callback, because we may notify
1270 * more then one caller.
1272 tevent_req_defer_callback(req, state->ev);
1273 tevent_req_nterror(req, status);
1274 continue;
1277 chain = talloc_move(conn, &state->smb1.chained_requests);
1278 num_chained = talloc_array_length(chain);
1280 for (i=0; i<num_chained; i++) {
1281 bool in_progress;
1283 req = chain[i];
1284 state = tevent_req_data(req, struct smbXcli_req_state);
1287 * We're dead. No point waiting for trans2
1288 * replies.
1290 state->smb1.mid = 0;
1292 smbXcli_req_unset_pending(req);
1294 if (NT_STATUS_IS_OK(status)) {
1295 /* do not notify the callers */
1296 continue;
1299 in_progress = tevent_req_is_in_progress(req);
1300 if (!in_progress) {
1302 * already finished
1304 continue;
1308 * we need to defer the callback, because we may notify
1309 * more than one caller.
1311 tevent_req_defer_callback(req, state->ev);
1312 tevent_req_nterror(req, status);
1314 TALLOC_FREE(chain);
1317 if (sock_fd != -1) {
1318 close(sock_fd);
1323 * Fetch a smb request's mid. Only valid after the request has been sent by
1324 * smb1cli_req_send().
1326 uint16_t smb1cli_req_mid(struct tevent_req *req)
1328 struct smbXcli_req_state *state =
1329 tevent_req_data(req,
1330 struct smbXcli_req_state);
1332 if (state->smb1.mid != 0) {
1333 return state->smb1.mid;
1336 return SVAL(state->smb1.hdr, HDR_MID);
1339 void smb1cli_req_set_mid(struct tevent_req *req, uint16_t mid)
1341 struct smbXcli_req_state *state =
1342 tevent_req_data(req,
1343 struct smbXcli_req_state);
1345 state->smb1.mid = mid;
1348 uint32_t smb1cli_req_seqnum(struct tevent_req *req)
1350 struct smbXcli_req_state *state =
1351 tevent_req_data(req,
1352 struct smbXcli_req_state);
1354 return state->smb1.seqnum;
1357 void smb1cli_req_set_seqnum(struct tevent_req *req, uint32_t seqnum)
1359 struct smbXcli_req_state *state =
1360 tevent_req_data(req,
1361 struct smbXcli_req_state);
1363 state->smb1.seqnum = seqnum;
1366 static size_t smbXcli_iov_len(const struct iovec *iov, int count)
1368 ssize_t ret = iov_buflen(iov, count);
1370 /* Ignore the overflow case for now ... */
1371 return ret;
1374 static void smb1cli_req_flags(enum protocol_types protocol,
1375 uint32_t smb1_capabilities,
1376 uint8_t smb_command,
1377 uint8_t additional_flags,
1378 uint8_t clear_flags,
1379 uint8_t *_flags,
1380 uint16_t additional_flags2,
1381 uint16_t clear_flags2,
1382 uint16_t *_flags2)
1384 uint8_t flags = 0;
1385 uint16_t flags2 = 0;
1387 if (protocol >= PROTOCOL_LANMAN1) {
1388 flags |= FLAG_CASELESS_PATHNAMES;
1389 flags |= FLAG_CANONICAL_PATHNAMES;
1392 if (protocol >= PROTOCOL_LANMAN2) {
1393 flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
1394 flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
1397 if (protocol >= PROTOCOL_NT1) {
1398 flags2 |= FLAGS2_IS_LONG_NAME;
1400 if (smb1_capabilities & CAP_UNICODE) {
1401 flags2 |= FLAGS2_UNICODE_STRINGS;
1403 if (smb1_capabilities & CAP_STATUS32) {
1404 flags2 |= FLAGS2_32_BIT_ERROR_CODES;
1406 if (smb1_capabilities & CAP_EXTENDED_SECURITY) {
1407 flags2 |= FLAGS2_EXTENDED_SECURITY;
1411 flags |= additional_flags;
1412 flags &= ~clear_flags;
1413 flags2 |= additional_flags2;
1414 flags2 &= ~clear_flags2;
1416 *_flags = flags;
1417 *_flags2 = flags2;
1420 static void smb1cli_req_cancel_done(struct tevent_req *subreq);
1422 static bool smb1cli_req_cancel(struct tevent_req *req)
1424 struct smbXcli_req_state *state =
1425 tevent_req_data(req,
1426 struct smbXcli_req_state);
1427 uint8_t flags;
1428 uint16_t flags2;
1429 uint32_t pid;
1430 uint16_t mid;
1431 struct tevent_req *subreq;
1432 NTSTATUS status;
1434 flags = CVAL(state->smb1.hdr, HDR_FLG);
1435 flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
1436 pid = SVAL(state->smb1.hdr, HDR_PID);
1437 pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
1438 mid = SVAL(state->smb1.hdr, HDR_MID);
1440 subreq = smb1cli_req_create(state, state->ev,
1441 state->conn,
1442 SMBntcancel,
1443 flags, 0,
1444 flags2, 0,
1445 0, /* timeout */
1446 pid,
1447 state->tcon,
1448 state->session,
1449 0, NULL, /* vwv */
1450 0, NULL); /* bytes */
1451 if (subreq == NULL) {
1452 return false;
1454 smb1cli_req_set_mid(subreq, mid);
1456 status = smb1cli_req_chain_submit(&subreq, 1);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 TALLOC_FREE(subreq);
1459 return false;
1461 smb1cli_req_set_mid(subreq, 0);
1463 tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
1465 return true;
1468 static void smb1cli_req_cancel_done(struct tevent_req *subreq)
1470 /* we do not care about the result */
1471 TALLOC_FREE(subreq);
1474 struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
1475 struct tevent_context *ev,
1476 struct smbXcli_conn *conn,
1477 uint8_t smb_command,
1478 uint8_t additional_flags,
1479 uint8_t clear_flags,
1480 uint16_t additional_flags2,
1481 uint16_t clear_flags2,
1482 uint32_t timeout_msec,
1483 uint32_t pid,
1484 struct smbXcli_tcon *tcon,
1485 struct smbXcli_session *session,
1486 uint8_t wct, uint16_t *vwv,
1487 int iov_count,
1488 struct iovec *bytes_iov)
1490 struct tevent_req *req;
1491 struct smbXcli_req_state *state;
1492 uint8_t flags = 0;
1493 uint16_t flags2 = 0;
1494 uint16_t uid = 0;
1495 uint16_t tid = 0;
1496 ssize_t num_bytes;
1498 if (iov_count > MAX_SMB_IOV) {
1500 * Should not happen :-)
1502 return NULL;
1505 req = tevent_req_create(mem_ctx, &state,
1506 struct smbXcli_req_state);
1507 if (req == NULL) {
1508 return NULL;
1510 state->ev = ev;
1511 state->conn = conn;
1512 state->session = session;
1513 state->tcon = tcon;
1515 if (session) {
1516 uid = session->smb1.session_id;
1519 if (tcon) {
1520 tid = tcon->smb1.tcon_id;
1522 if (tcon->fs_attributes & FILE_CASE_SENSITIVE_SEARCH) {
1523 clear_flags |= FLAG_CASELESS_PATHNAMES;
1524 } else {
1525 /* Default setting, case insensitive. */
1526 additional_flags |= FLAG_CASELESS_PATHNAMES;
1529 if (smbXcli_conn_dfs_supported(conn) &&
1530 smbXcli_tcon_is_dfs_share(tcon))
1532 additional_flags2 |= FLAGS2_DFS_PATHNAMES;
1536 state->smb1.recv_cmd = 0xFF;
1537 state->smb1.recv_status = NT_STATUS_INTERNAL_ERROR;
1538 state->smb1.recv_iov = talloc_zero_array(state, struct iovec, 3);
1539 if (state->smb1.recv_iov == NULL) {
1540 TALLOC_FREE(req);
1541 return NULL;
1544 smb1cli_req_flags(conn->protocol,
1545 conn->smb1.capabilities,
1546 smb_command,
1547 additional_flags,
1548 clear_flags,
1549 &flags,
1550 additional_flags2,
1551 clear_flags2,
1552 &flags2);
1554 SIVAL(state->smb1.hdr, 0, SMB_MAGIC);
1555 SCVAL(state->smb1.hdr, HDR_COM, smb_command);
1556 SIVAL(state->smb1.hdr, HDR_RCLS, NT_STATUS_V(NT_STATUS_OK));
1557 SCVAL(state->smb1.hdr, HDR_FLG, flags);
1558 SSVAL(state->smb1.hdr, HDR_FLG2, flags2);
1559 SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);
1560 SSVAL(state->smb1.hdr, HDR_TID, tid);
1561 SSVAL(state->smb1.hdr, HDR_PID, pid);
1562 SSVAL(state->smb1.hdr, HDR_UID, uid);
1563 SSVAL(state->smb1.hdr, HDR_MID, 0); /* this comes later */
1564 SCVAL(state->smb1.hdr, HDR_WCT, wct);
1566 state->smb1.vwv = vwv;
1568 num_bytes = iov_buflen(bytes_iov, iov_count);
1569 if (num_bytes == -1) {
1571 * I'd love to add a check for num_bytes<=UINT16_MAX here, but
1572 * the smbclient->samba connections can lie and transfer more.
1574 TALLOC_FREE(req);
1575 return NULL;
1578 SSVAL(state->smb1.bytecount_buf, 0, num_bytes);
1580 state->smb1.iov[0].iov_base = (void *)state->length_hdr;
1581 state->smb1.iov[0].iov_len = sizeof(state->length_hdr);
1582 state->smb1.iov[1].iov_base = (void *)state->smb1.hdr;
1583 state->smb1.iov[1].iov_len = sizeof(state->smb1.hdr);
1584 state->smb1.iov[2].iov_base = (void *)state->smb1.vwv;
1585 state->smb1.iov[2].iov_len = wct * sizeof(uint16_t);
1586 state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;
1587 state->smb1.iov[3].iov_len = sizeof(uint16_t);
1589 if (iov_count != 0) {
1590 memcpy(&state->smb1.iov[4], bytes_iov,
1591 iov_count * sizeof(*bytes_iov));
1593 state->smb1.iov_count = iov_count + 4;
1595 if (timeout_msec > 0) {
1596 state->endtime = timeval_current_ofs_msec(timeout_msec);
1597 if (!tevent_req_set_endtime(req, ev, state->endtime)) {
1598 return req;
1602 switch (smb_command) {
1603 case SMBtranss:
1604 case SMBtranss2:
1605 case SMBnttranss:
1606 state->one_way = true;
1607 break;
1608 case SMBntcancel:
1609 state->one_way = true;
1610 state->smb1.one_way_seqnum = true;
1611 break;
1612 case SMBlockingX:
1613 if ((wct == 8) &&
1614 (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
1615 state->one_way = true;
1617 break;
1620 return req;
1623 static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
1624 struct iovec *iov, int iov_count,
1625 uint32_t *seqnum,
1626 bool one_way_seqnum)
1628 TALLOC_CTX *frame = NULL;
1629 NTSTATUS status;
1630 uint8_t *buf;
1633 * Obvious optimization: Make cli_calculate_sign_mac work with struct
1634 * iovec directly. MD5Update would do that just fine.
1637 if (iov_count < 4) {
1638 return NT_STATUS_INVALID_PARAMETER_MIX;
1640 if (iov[0].iov_len != NBT_HDR_SIZE) {
1641 return NT_STATUS_INVALID_PARAMETER_MIX;
1643 if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1644 return NT_STATUS_INVALID_PARAMETER_MIX;
1646 if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1647 return NT_STATUS_INVALID_PARAMETER_MIX;
1649 if (iov[3].iov_len != sizeof(uint16_t)) {
1650 return NT_STATUS_INVALID_PARAMETER_MIX;
1653 frame = talloc_stackframe();
1655 buf = iov_concat(frame, &iov[1], iov_count - 1);
1656 if (buf == NULL) {
1657 return NT_STATUS_NO_MEMORY;
1660 *seqnum = smb_signing_next_seqnum(conn->smb1.signing,
1661 one_way_seqnum);
1662 status = smb_signing_sign_pdu(conn->smb1.signing,
1663 buf,
1664 talloc_get_size(buf),
1665 *seqnum);
1666 if (!NT_STATUS_IS_OK(status)) {
1667 return status;
1669 memcpy(iov[1].iov_base, buf, iov[1].iov_len);
1671 TALLOC_FREE(frame);
1672 return NT_STATUS_OK;
1675 static void smb1cli_req_writev_done(struct tevent_req *subreq);
1676 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1677 TALLOC_CTX *tmp_mem,
1678 uint8_t *inbuf);
1680 static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
1681 struct smbXcli_req_state *state,
1682 struct iovec *iov, int iov_count)
1684 struct tevent_req *subreq;
1685 NTSTATUS status;
1686 uint8_t cmd;
1687 uint16_t mid;
1688 ssize_t nbtlen;
1690 if (!smbXcli_conn_is_connected(state->conn)) {
1691 return NT_STATUS_CONNECTION_DISCONNECTED;
1694 if (state->conn->protocol > PROTOCOL_NT1) {
1695 DBG_ERR("called for dialect[%s] server[%s]\n",
1696 smb_protocol_types_string(state->conn->protocol),
1697 smbXcli_conn_remote_name(state->conn));
1698 return NT_STATUS_REVISION_MISMATCH;
1701 if (iov_count < 4) {
1702 return NT_STATUS_INVALID_PARAMETER_MIX;
1704 if (iov[0].iov_len != NBT_HDR_SIZE) {
1705 return NT_STATUS_INVALID_PARAMETER_MIX;
1707 if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1708 return NT_STATUS_INVALID_PARAMETER_MIX;
1710 if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1711 return NT_STATUS_INVALID_PARAMETER_MIX;
1713 if (iov[3].iov_len != sizeof(uint16_t)) {
1714 return NT_STATUS_INVALID_PARAMETER_MIX;
1717 cmd = CVAL(iov[1].iov_base, HDR_COM);
1718 if (cmd == SMBreadBraw) {
1719 if (smbXcli_conn_has_async_calls(state->conn)) {
1720 return NT_STATUS_INVALID_PARAMETER_MIX;
1722 state->conn->smb1.read_braw_req = req;
1725 if (state->smb1.mid != 0) {
1726 mid = state->smb1.mid;
1727 } else {
1728 mid = smb1cli_alloc_mid(state->conn);
1730 SSVAL(iov[1].iov_base, HDR_MID, mid);
1732 nbtlen = iov_buflen(&iov[1], iov_count-1);
1733 if ((nbtlen == -1) || (nbtlen > 0x1FFFF)) {
1734 return NT_STATUS_INVALID_PARAMETER_MIX;
1737 _smb_setlen_nbt(iov[0].iov_base, nbtlen);
1739 status = smb1cli_conn_signv(state->conn, iov, iov_count,
1740 &state->smb1.seqnum,
1741 state->smb1.one_way_seqnum);
1743 if (!NT_STATUS_IS_OK(status)) {
1744 return status;
1748 * If we supported multiple encrytion contexts
1749 * here we'd look up based on tid.
1751 if (common_encryption_on(state->conn->smb1.trans_enc)) {
1752 char *buf, *enc_buf;
1754 buf = (char *)iov_concat(talloc_tos(), iov, iov_count);
1755 if (buf == NULL) {
1756 return NT_STATUS_NO_MEMORY;
1758 status = common_encrypt_buffer(state->conn->smb1.trans_enc,
1759 (char *)buf, &enc_buf);
1760 TALLOC_FREE(buf);
1761 if (!NT_STATUS_IS_OK(status)) {
1762 DEBUG(0, ("Error in encrypting client message: %s\n",
1763 nt_errstr(status)));
1764 return status;
1766 buf = (char *)talloc_memdup(state, enc_buf,
1767 smb_len_nbt(enc_buf)+4);
1768 SAFE_FREE(enc_buf);
1769 if (buf == NULL) {
1770 return NT_STATUS_NO_MEMORY;
1772 iov[0].iov_base = (void *)buf;
1773 iov[0].iov_len = talloc_get_size(buf);
1774 iov_count = 1;
1777 if (state->conn->dispatch_incoming == NULL) {
1778 state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
1781 if (!smbXcli_req_set_pending(req)) {
1782 return NT_STATUS_NO_MEMORY;
1785 tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1787 subreq = writev_send(state, state->ev, state->conn->outgoing,
1788 state->conn->sock_fd, false, iov, iov_count);
1789 if (subreq == NULL) {
1790 return NT_STATUS_NO_MEMORY;
1792 tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
1793 state->write_req = subreq;
1795 return NT_STATUS_OK;
1798 struct tevent_req *smb1cli_req_send(TALLOC_CTX *mem_ctx,
1799 struct tevent_context *ev,
1800 struct smbXcli_conn *conn,
1801 uint8_t smb_command,
1802 uint8_t additional_flags,
1803 uint8_t clear_flags,
1804 uint16_t additional_flags2,
1805 uint16_t clear_flags2,
1806 uint32_t timeout_msec,
1807 uint32_t pid,
1808 struct smbXcli_tcon *tcon,
1809 struct smbXcli_session *session,
1810 uint8_t wct, uint16_t *vwv,
1811 uint32_t num_bytes,
1812 const uint8_t *bytes)
1814 struct tevent_req *req;
1815 struct iovec iov;
1816 NTSTATUS status;
1818 iov.iov_base = discard_const_p(void, bytes);
1819 iov.iov_len = num_bytes;
1821 req = smb1cli_req_create(mem_ctx, ev, conn, smb_command,
1822 additional_flags, clear_flags,
1823 additional_flags2, clear_flags2,
1824 timeout_msec,
1825 pid, tcon, session,
1826 wct, vwv, 1, &iov);
1827 if (req == NULL) {
1828 return NULL;
1830 if (!tevent_req_is_in_progress(req)) {
1831 return tevent_req_post(req, ev);
1833 status = smb1cli_req_chain_submit(&req, 1);
1834 if (tevent_req_nterror(req, status)) {
1835 return tevent_req_post(req, ev);
1837 return req;
1840 static void smb1cli_req_writev_done(struct tevent_req *subreq)
1842 struct tevent_req *req =
1843 tevent_req_callback_data(subreq,
1844 struct tevent_req);
1845 struct smbXcli_req_state *state =
1846 tevent_req_data(req,
1847 struct smbXcli_req_state);
1848 ssize_t nwritten;
1849 int err;
1851 state->write_req = NULL;
1853 nwritten = writev_recv(subreq, &err);
1854 TALLOC_FREE(subreq);
1855 if (nwritten == -1) {
1856 /* here, we need to notify all pending requests */
1857 NTSTATUS status = map_nt_error_from_unix_common(err);
1858 smbXcli_conn_disconnect(state->conn, status);
1859 return;
1862 if (state->one_way) {
1863 state->inbuf = NULL;
1864 tevent_req_done(req);
1865 return;
1869 static void smbXcli_conn_received(struct tevent_req *subreq)
1871 struct smbXcli_conn *conn =
1872 tevent_req_callback_data(subreq,
1873 struct smbXcli_conn);
1874 TALLOC_CTX *frame = talloc_stackframe();
1875 NTSTATUS status;
1876 uint8_t *inbuf;
1877 ssize_t received;
1878 int err;
1880 if (subreq != conn->read_smb_req) {
1881 DEBUG(1, ("Internal error: cli_smb_received called with "
1882 "unexpected subreq\n"));
1883 smbXcli_conn_disconnect(conn, NT_STATUS_INTERNAL_ERROR);
1884 TALLOC_FREE(frame);
1885 return;
1887 conn->read_smb_req = NULL;
1889 received = read_smb_recv(subreq, frame, &inbuf, &err);
1890 TALLOC_FREE(subreq);
1891 if (received == -1) {
1892 status = map_nt_error_from_unix_common(err);
1893 smbXcli_conn_disconnect(conn, status);
1894 TALLOC_FREE(frame);
1895 return;
1898 status = conn->dispatch_incoming(conn, frame, inbuf);
1899 TALLOC_FREE(frame);
1900 if (NT_STATUS_IS_OK(status)) {
1902 * We should not do any more processing
1903 * as the dispatch function called
1904 * tevent_req_done().
1906 return;
1909 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1911 * We got an error, so notify all pending requests
1913 smbXcli_conn_disconnect(conn, status);
1914 return;
1918 * We got NT_STATUS_RETRY, so we may ask for a
1919 * next incoming pdu.
1921 if (!smbXcli_conn_receive_next(conn)) {
1922 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1926 static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
1927 struct iovec **piov, int *pnum_iov)
1929 struct iovec *iov;
1930 size_t num_iov;
1931 size_t buflen;
1932 size_t taken;
1933 size_t remaining;
1934 uint8_t *hdr;
1935 uint8_t cmd;
1936 uint32_t wct_ofs;
1937 NTSTATUS status;
1938 size_t min_size = MIN_SMB_SIZE;
1940 buflen = smb_len_tcp(buf);
1941 taken = 0;
1943 hdr = buf + NBT_HDR_SIZE;
1945 status = smb1cli_pull_raw_error(hdr);
1946 if (NT_STATUS_IS_ERR(status)) {
1948 * This is an ugly hack to support OS/2
1949 * which skips the byte_count in the DATA block
1950 * on some error responses.
1952 * See bug #9096
1954 min_size -= sizeof(uint16_t);
1957 if (buflen < min_size) {
1958 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1962 * This returns iovec elements in the following order:
1964 * - SMB header
1966 * - Parameter Block
1967 * - Data Block
1969 * - Parameter Block
1970 * - Data Block
1972 * - Parameter Block
1973 * - Data Block
1975 num_iov = 1;
1977 iov = talloc_array(mem_ctx, struct iovec, num_iov);
1978 if (iov == NULL) {
1979 return NT_STATUS_NO_MEMORY;
1981 iov[0].iov_base = hdr;
1982 iov[0].iov_len = HDR_WCT;
1983 taken += HDR_WCT;
1985 cmd = CVAL(hdr, HDR_COM);
1986 wct_ofs = HDR_WCT;
1988 while (true) {
1989 size_t len = buflen - taken;
1990 struct iovec *cur;
1991 struct iovec *iov_tmp;
1992 uint8_t wct;
1993 uint32_t bcc_ofs;
1994 uint16_t bcc;
1995 size_t needed;
1998 * we need at least WCT
2000 needed = sizeof(uint8_t);
2001 if (len < needed) {
2002 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2003 __location__, (int)len, (int)needed));
2004 goto inval;
2008 * Now we check if the specified words are there
2010 wct = CVAL(hdr, wct_ofs);
2011 needed += wct * sizeof(uint16_t);
2012 if (len < needed) {
2013 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2014 __location__, (int)len, (int)needed));
2015 goto inval;
2018 if ((num_iov == 1) &&
2019 (len == needed) &&
2020 NT_STATUS_IS_ERR(status))
2023 * This is an ugly hack to support OS/2
2024 * which skips the byte_count in the DATA block
2025 * on some error responses.
2027 * See bug #9096
2029 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2030 num_iov + 2);
2031 if (iov_tmp == NULL) {
2032 TALLOC_FREE(iov);
2033 return NT_STATUS_NO_MEMORY;
2035 iov = iov_tmp;
2036 cur = &iov[num_iov];
2037 num_iov += 2;
2039 cur[0].iov_len = 0;
2040 cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2041 cur[1].iov_len = 0;
2042 cur[1].iov_base = cur[0].iov_base;
2044 taken += needed;
2045 break;
2049 * we need at least BCC
2051 needed += sizeof(uint16_t);
2052 if (len < needed) {
2053 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2054 __location__, (int)len, (int)needed));
2055 goto inval;
2059 * Now we check if the specified bytes are there
2061 bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
2062 bcc = SVAL(hdr, bcc_ofs);
2063 needed += bcc * sizeof(uint8_t);
2064 if (len < needed) {
2065 DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2066 __location__, (int)len, (int)needed));
2067 goto inval;
2071 * we allocate 2 iovec structures for words and bytes
2073 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2074 num_iov + 2);
2075 if (iov_tmp == NULL) {
2076 TALLOC_FREE(iov);
2077 return NT_STATUS_NO_MEMORY;
2079 iov = iov_tmp;
2080 cur = &iov[num_iov];
2081 num_iov += 2;
2083 cur[0].iov_len = wct * sizeof(uint16_t);
2084 cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2085 cur[1].iov_len = bcc * sizeof(uint8_t);
2086 cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
2088 taken += needed;
2090 if (!smb1cli_is_andx_req(cmd)) {
2092 * If the current command does not have AndX chanining
2093 * we are done.
2095 break;
2098 if (wct == 0 && bcc == 0) {
2100 * An empty response also ends the chain,
2101 * most likely with an error.
2103 break;
2106 if (wct < 2) {
2107 DEBUG(10, ("%s: wct[%d] < 2 for cmd[0x%02X]\n",
2108 __location__, (int)wct, (int)cmd));
2109 goto inval;
2111 cmd = CVAL(cur[0].iov_base, 0);
2112 if (cmd == 0xFF) {
2114 * If it is the end of the chain we are also done.
2116 break;
2118 wct_ofs = SVAL(cur[0].iov_base, 2);
2120 if (wct_ofs < taken) {
2121 goto inval;
2123 if (wct_ofs > buflen) {
2124 goto inval;
2128 * we consumed everything up to the start of the next
2129 * parameter block.
2131 taken = wct_ofs;
2134 remaining = buflen - taken;
2136 if (remaining > 0 && num_iov >= 3) {
2138 * The last DATA block gets the remaining
2139 * bytes, this is needed to support
2140 * CAP_LARGE_WRITEX and CAP_LARGE_READX.
2142 iov[num_iov-1].iov_len += remaining;
2145 *piov = iov;
2146 *pnum_iov = num_iov;
2147 return NT_STATUS_OK;
2149 inval:
2150 TALLOC_FREE(iov);
2151 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2154 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2155 TALLOC_CTX *tmp_mem,
2156 uint8_t *inbuf)
2158 struct tevent_req *req;
2159 struct smbXcli_req_state *state;
2160 NTSTATUS status;
2161 size_t num_pending;
2162 size_t i;
2163 uint8_t cmd;
2164 uint16_t mid;
2165 bool oplock_break;
2166 uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
2167 size_t len = smb_len_tcp(inbuf);
2168 struct iovec *iov = NULL;
2169 int num_iov = 0;
2170 struct tevent_req **chain = NULL;
2171 size_t num_chained = 0;
2172 size_t num_responses = 0;
2174 if (conn->smb1.read_braw_req != NULL) {
2175 req = conn->smb1.read_braw_req;
2176 conn->smb1.read_braw_req = NULL;
2177 state = tevent_req_data(req, struct smbXcli_req_state);
2179 smbXcli_req_unset_pending(req);
2181 if (state->smb1.recv_iov == NULL) {
2183 * For requests with more than
2184 * one response, we have to readd the
2185 * recv_iov array.
2187 state->smb1.recv_iov = talloc_zero_array(state,
2188 struct iovec,
2190 if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2191 return NT_STATUS_OK;
2195 state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
2196 state->smb1.recv_iov[0].iov_len = len;
2197 ZERO_STRUCT(state->smb1.recv_iov[1]);
2198 ZERO_STRUCT(state->smb1.recv_iov[2]);
2200 state->smb1.recv_cmd = SMBreadBraw;
2201 state->smb1.recv_status = NT_STATUS_OK;
2202 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2204 tevent_req_done(req);
2205 return NT_STATUS_OK;
2208 if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
2209 && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
2210 DEBUG(10, ("Got non-SMB PDU\n"));
2211 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2215 * If we supported multiple encrytion contexts
2216 * here we'd look up based on tid.
2218 if (common_encryption_on(conn->smb1.trans_enc)
2219 && (CVAL(inbuf, 0) == 0)) {
2220 uint16_t enc_ctx_num;
2222 status = get_enc_ctx_num(inbuf, &enc_ctx_num);
2223 if (!NT_STATUS_IS_OK(status)) {
2224 DEBUG(10, ("get_enc_ctx_num returned %s\n",
2225 nt_errstr(status)));
2226 return status;
2229 if (enc_ctx_num != conn->smb1.trans_enc->enc_ctx_num) {
2230 DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
2231 enc_ctx_num,
2232 conn->smb1.trans_enc->enc_ctx_num));
2233 return NT_STATUS_INVALID_HANDLE;
2236 status = common_decrypt_buffer(conn->smb1.trans_enc,
2237 (char *)inbuf);
2238 if (!NT_STATUS_IS_OK(status)) {
2239 DEBUG(10, ("common_decrypt_buffer returned %s\n",
2240 nt_errstr(status)));
2241 return status;
2243 inhdr = inbuf + NBT_HDR_SIZE;
2244 len = smb_len_nbt(inbuf);
2247 mid = SVAL(inhdr, HDR_MID);
2248 num_pending = talloc_array_length(conn->pending);
2250 for (i=0; i<num_pending; i++) {
2251 if (mid == smb1cli_req_mid(conn->pending[i])) {
2252 break;
2255 if (i == num_pending) {
2256 /* Dump unexpected reply */
2257 return NT_STATUS_RETRY;
2260 oplock_break = false;
2262 if (mid == 0xffff) {
2264 * Paranoia checks that this is really an oplock break request.
2266 oplock_break = (len == 51); /* hdr + 8 words */
2267 oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
2268 oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
2269 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
2270 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
2272 if (!oplock_break) {
2273 /* Dump unexpected reply */
2274 return NT_STATUS_RETRY;
2278 req = conn->pending[i];
2279 state = tevent_req_data(req, struct smbXcli_req_state);
2281 if (!oplock_break /* oplock breaks are not signed */
2282 && !smb_signing_check_pdu(conn->smb1.signing,
2283 inhdr, len, state->smb1.seqnum+1)) {
2284 DEBUG(10, ("cli_check_sign_mac failed\n"));
2285 return NT_STATUS_ACCESS_DENIED;
2288 status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
2289 &iov, &num_iov);
2290 if (!NT_STATUS_IS_OK(status)) {
2291 DEBUG(10,("smb1cli_inbuf_parse_chain - %s\n",
2292 nt_errstr(status)));
2293 return status;
2296 cmd = CVAL(inhdr, HDR_COM);
2297 status = smb1cli_pull_raw_error(inhdr);
2299 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
2300 (state->session != NULL) && state->session->disconnect_expired)
2303 * this should be a short term hack
2304 * until the upper layers have implemented
2305 * re-authentication.
2307 return status;
2310 if (state->smb1.chained_requests == NULL) {
2311 if (num_iov != 3) {
2312 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2315 smbXcli_req_unset_pending(req);
2317 if (state->smb1.recv_iov == NULL) {
2319 * For requests with more than
2320 * one response, we have to readd the
2321 * recv_iov array.
2323 state->smb1.recv_iov = talloc_zero_array(state,
2324 struct iovec,
2326 if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2327 return NT_STATUS_OK;
2331 state->smb1.recv_cmd = cmd;
2332 state->smb1.recv_status = status;
2333 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2335 state->smb1.recv_iov[0] = iov[0];
2336 state->smb1.recv_iov[1] = iov[1];
2337 state->smb1.recv_iov[2] = iov[2];
2339 if (talloc_array_length(conn->pending) == 0) {
2340 tevent_req_done(req);
2341 return NT_STATUS_OK;
2344 tevent_req_defer_callback(req, state->ev);
2345 tevent_req_done(req);
2346 return NT_STATUS_RETRY;
2349 chain = talloc_move(tmp_mem, &state->smb1.chained_requests);
2350 num_chained = talloc_array_length(chain);
2351 num_responses = (num_iov - 1)/2;
2353 if (num_responses > num_chained) {
2354 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2357 for (i=0; i<num_chained; i++) {
2358 size_t iov_idx = 1 + (i*2);
2359 struct iovec *cur = &iov[iov_idx];
2360 uint8_t *inbuf_ref;
2362 req = chain[i];
2363 state = tevent_req_data(req, struct smbXcli_req_state);
2365 smbXcli_req_unset_pending(req);
2368 * as we finish multiple requests here
2369 * we need to defer the callbacks as
2370 * they could destroy our current stack state.
2372 tevent_req_defer_callback(req, state->ev);
2374 if (i >= num_responses) {
2375 tevent_req_nterror(req, NT_STATUS_REQUEST_ABORTED);
2376 continue;
2379 if (state->smb1.recv_iov == NULL) {
2381 * For requests with more than
2382 * one response, we have to readd the
2383 * recv_iov array.
2385 state->smb1.recv_iov = talloc_zero_array(state,
2386 struct iovec,
2388 if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2389 continue;
2393 state->smb1.recv_cmd = cmd;
2395 if (i == (num_responses - 1)) {
2397 * The last request in the chain gets the status
2399 state->smb1.recv_status = status;
2400 } else {
2401 cmd = CVAL(cur[0].iov_base, 0);
2402 state->smb1.recv_status = NT_STATUS_OK;
2405 state->inbuf = inbuf;
2408 * Note: here we use talloc_reference() in a way
2409 * that does not expose it to the caller.
2411 inbuf_ref = talloc_reference(state->smb1.recv_iov, inbuf);
2412 if (tevent_req_nomem(inbuf_ref, req)) {
2413 continue;
2416 /* copy the related buffers */
2417 state->smb1.recv_iov[0] = iov[0];
2418 state->smb1.recv_iov[1] = cur[0];
2419 state->smb1.recv_iov[2] = cur[1];
2421 tevent_req_done(req);
2424 return NT_STATUS_RETRY;
2427 NTSTATUS smb1cli_req_recv(struct tevent_req *req,
2428 TALLOC_CTX *mem_ctx,
2429 struct iovec **piov,
2430 uint8_t **phdr,
2431 uint8_t *pwct,
2432 uint16_t **pvwv,
2433 uint32_t *pvwv_offset,
2434 uint32_t *pnum_bytes,
2435 uint8_t **pbytes,
2436 uint32_t *pbytes_offset,
2437 uint8_t **pinbuf,
2438 const struct smb1cli_req_expected_response *expected,
2439 size_t num_expected)
2441 struct smbXcli_req_state *state =
2442 tevent_req_data(req,
2443 struct smbXcli_req_state);
2444 NTSTATUS status = NT_STATUS_OK;
2445 struct iovec *recv_iov = NULL;
2446 uint8_t *hdr = NULL;
2447 uint8_t wct = 0;
2448 uint32_t vwv_offset = 0;
2449 uint16_t *vwv = NULL;
2450 uint32_t num_bytes = 0;
2451 uint32_t bytes_offset = 0;
2452 uint8_t *bytes = NULL;
2453 size_t i;
2454 bool found_status = false;
2455 bool found_size = false;
2457 if (piov != NULL) {
2458 *piov = NULL;
2460 if (phdr != NULL) {
2461 *phdr = 0;
2463 if (pwct != NULL) {
2464 *pwct = 0;
2466 if (pvwv != NULL) {
2467 *pvwv = NULL;
2469 if (pvwv_offset != NULL) {
2470 *pvwv_offset = 0;
2472 if (pnum_bytes != NULL) {
2473 *pnum_bytes = 0;
2475 if (pbytes != NULL) {
2476 *pbytes = NULL;
2478 if (pbytes_offset != NULL) {
2479 *pbytes_offset = 0;
2481 if (pinbuf != NULL) {
2482 *pinbuf = NULL;
2485 if (state->inbuf != NULL) {
2486 recv_iov = state->smb1.recv_iov;
2487 state->smb1.recv_iov = NULL;
2488 if (state->smb1.recv_cmd != SMBreadBraw) {
2489 hdr = (uint8_t *)recv_iov[0].iov_base;
2490 wct = recv_iov[1].iov_len/2;
2491 vwv = (uint16_t *)recv_iov[1].iov_base;
2492 vwv_offset = PTR_DIFF(vwv, hdr);
2493 num_bytes = recv_iov[2].iov_len;
2494 bytes = (uint8_t *)recv_iov[2].iov_base;
2495 bytes_offset = PTR_DIFF(bytes, hdr);
2499 if (tevent_req_is_nterror(req, &status)) {
2500 for (i=0; i < num_expected; i++) {
2501 if (NT_STATUS_EQUAL(status, expected[i].status)) {
2502 found_status = true;
2503 break;
2507 if (found_status) {
2508 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2511 return status;
2514 if (num_expected == 0) {
2515 found_status = true;
2516 found_size = true;
2519 status = state->smb1.recv_status;
2521 for (i=0; i < num_expected; i++) {
2522 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
2523 continue;
2526 found_status = true;
2527 if (expected[i].wct == 0) {
2528 found_size = true;
2529 break;
2532 if (expected[i].wct == wct) {
2533 found_size = true;
2534 break;
2538 if (!found_status) {
2539 return status;
2542 if (!found_size) {
2543 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2546 if (piov != NULL) {
2547 *piov = talloc_move(mem_ctx, &recv_iov);
2550 if (phdr != NULL) {
2551 *phdr = hdr;
2553 if (pwct != NULL) {
2554 *pwct = wct;
2556 if (pvwv != NULL) {
2557 *pvwv = vwv;
2559 if (pvwv_offset != NULL) {
2560 *pvwv_offset = vwv_offset;
2562 if (pnum_bytes != NULL) {
2563 *pnum_bytes = num_bytes;
2565 if (pbytes != NULL) {
2566 *pbytes = bytes;
2568 if (pbytes_offset != NULL) {
2569 *pbytes_offset = bytes_offset;
2571 if (pinbuf != NULL) {
2572 *pinbuf = state->inbuf;
2575 return status;
2578 size_t smb1cli_req_wct_ofs(struct tevent_req **reqs, int num_reqs)
2580 size_t wct_ofs;
2581 int i;
2583 wct_ofs = HDR_WCT;
2585 for (i=0; i<num_reqs; i++) {
2586 struct smbXcli_req_state *state;
2587 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2588 wct_ofs += smbXcli_iov_len(state->smb1.iov+2,
2589 state->smb1.iov_count-2);
2590 wct_ofs = (wct_ofs + 3) & ~3;
2592 return wct_ofs;
2595 NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
2597 struct smbXcli_req_state *first_state =
2598 tevent_req_data(reqs[0],
2599 struct smbXcli_req_state);
2600 struct smbXcli_req_state *state;
2601 size_t wct_offset;
2602 size_t chain_padding = 0;
2603 int i, iovlen;
2604 struct iovec *iov = NULL;
2605 struct iovec *this_iov;
2606 NTSTATUS status;
2607 ssize_t nbt_len;
2609 if (num_reqs == 1) {
2610 return smb1cli_req_writev_submit(reqs[0], first_state,
2611 first_state->smb1.iov,
2612 first_state->smb1.iov_count);
2615 iovlen = 0;
2616 for (i=0; i<num_reqs; i++) {
2617 if (!tevent_req_is_in_progress(reqs[i])) {
2618 return NT_STATUS_INTERNAL_ERROR;
2621 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2623 if (state->smb1.iov_count < 4) {
2624 return NT_STATUS_INVALID_PARAMETER_MIX;
2627 if (i == 0) {
2629 * The NBT and SMB header
2631 iovlen += 2;
2632 } else {
2634 * Chain padding
2636 iovlen += 1;
2640 * words and bytes
2642 iovlen += state->smb1.iov_count - 2;
2645 iov = talloc_zero_array(first_state, struct iovec, iovlen);
2646 if (iov == NULL) {
2647 return NT_STATUS_NO_MEMORY;
2650 first_state->smb1.chained_requests = (struct tevent_req **)talloc_memdup(
2651 first_state, reqs, sizeof(*reqs) * num_reqs);
2652 if (first_state->smb1.chained_requests == NULL) {
2653 TALLOC_FREE(iov);
2654 return NT_STATUS_NO_MEMORY;
2657 wct_offset = HDR_WCT;
2658 this_iov = iov;
2660 for (i=0; i<num_reqs; i++) {
2661 size_t next_padding = 0;
2662 uint16_t *vwv;
2664 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2666 if (i < num_reqs-1) {
2667 if (!smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))
2668 || CVAL(state->smb1.hdr, HDR_WCT) < 2) {
2669 TALLOC_FREE(iov);
2670 TALLOC_FREE(first_state->smb1.chained_requests);
2671 return NT_STATUS_INVALID_PARAMETER_MIX;
2675 wct_offset += smbXcli_iov_len(state->smb1.iov+2,
2676 state->smb1.iov_count-2) + 1;
2677 if ((wct_offset % 4) != 0) {
2678 next_padding = 4 - (wct_offset % 4);
2680 wct_offset += next_padding;
2681 vwv = state->smb1.vwv;
2683 if (i < num_reqs-1) {
2684 struct smbXcli_req_state *next_state =
2685 tevent_req_data(reqs[i+1],
2686 struct smbXcli_req_state);
2687 SCVAL(vwv+0, 0, CVAL(next_state->smb1.hdr, HDR_COM));
2688 SCVAL(vwv+0, 1, 0);
2689 SSVAL(vwv+1, 0, wct_offset);
2690 } else if (smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))) {
2691 /* properly end the chain */
2692 SCVAL(vwv+0, 0, 0xff);
2693 SCVAL(vwv+0, 1, 0xff);
2694 SSVAL(vwv+1, 0, 0);
2697 if (i == 0) {
2699 * The NBT and SMB header
2701 this_iov[0] = state->smb1.iov[0];
2702 this_iov[1] = state->smb1.iov[1];
2703 this_iov += 2;
2704 } else {
2706 * This one is a bit subtle. We have to add
2707 * chain_padding bytes between the requests, and we
2708 * have to also include the wct field of the
2709 * subsequent requests. We use the subsequent header
2710 * for the padding, it contains the wct field in its
2711 * last byte.
2713 this_iov[0].iov_len = chain_padding+1;
2714 this_iov[0].iov_base = (void *)&state->smb1.hdr[
2715 sizeof(state->smb1.hdr) - this_iov[0].iov_len];
2716 memset(this_iov[0].iov_base, 0, this_iov[0].iov_len-1);
2717 this_iov += 1;
2721 * copy the words and bytes
2723 memcpy(this_iov, state->smb1.iov+2,
2724 sizeof(struct iovec) * (state->smb1.iov_count-2));
2725 this_iov += state->smb1.iov_count - 2;
2726 chain_padding = next_padding;
2729 nbt_len = iov_buflen(&iov[1], iovlen-1);
2730 if ((nbt_len == -1) || (nbt_len > first_state->conn->smb1.max_xmit)) {
2731 TALLOC_FREE(iov);
2732 TALLOC_FREE(first_state->smb1.chained_requests);
2733 return NT_STATUS_INVALID_PARAMETER_MIX;
2736 status = smb1cli_req_writev_submit(reqs[0], first_state, iov, iovlen);
2737 if (!NT_STATUS_IS_OK(status)) {
2738 TALLOC_FREE(iov);
2739 TALLOC_FREE(first_state->smb1.chained_requests);
2740 return status;
2743 return NT_STATUS_OK;
2746 bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
2748 return ((tevent_queue_length(conn->outgoing) != 0)
2749 || (talloc_array_length(conn->pending) != 0));
2752 bool smbXcli_conn_dfs_supported(struct smbXcli_conn *conn)
2754 if (conn->protocol >= PROTOCOL_SMB2_02) {
2755 return (smb2cli_conn_server_capabilities(conn) & SMB2_CAP_DFS);
2758 return (smb1cli_conn_capabilities(conn) & CAP_DFS);
2761 bool smb2cli_conn_req_possible(struct smbXcli_conn *conn, uint32_t *max_dyn_len)
2763 uint16_t credits = 1;
2765 if (conn->smb2.cur_credits == 0) {
2766 if (max_dyn_len != NULL) {
2767 *max_dyn_len = 0;
2769 return false;
2772 if (conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2773 credits = conn->smb2.cur_credits;
2776 if (max_dyn_len != NULL) {
2777 *max_dyn_len = credits * 65536;
2780 return true;
2783 uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
2785 return conn->smb2.server.capabilities;
2788 uint16_t smb2cli_conn_server_security_mode(struct smbXcli_conn *conn)
2790 return conn->smb2.server.security_mode;
2793 uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
2795 return conn->smb2.server.max_trans_size;
2798 uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
2800 return conn->smb2.server.max_read_size;
2803 uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
2805 return conn->smb2.server.max_write_size;
2808 void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
2809 uint16_t max_credits)
2811 conn->smb2.max_credits = max_credits;
2814 uint16_t smb2cli_conn_get_cur_credits(struct smbXcli_conn *conn)
2816 return conn->smb2.cur_credits;
2819 uint8_t smb2cli_conn_get_io_priority(struct smbXcli_conn *conn)
2821 if (conn->protocol < PROTOCOL_SMB3_11) {
2822 return 0;
2825 return conn->smb2.io_priority;
2828 void smb2cli_conn_set_io_priority(struct smbXcli_conn *conn,
2829 uint8_t io_priority)
2831 conn->smb2.io_priority = io_priority;
2834 uint32_t smb2cli_conn_cc_chunk_len(struct smbXcli_conn *conn)
2836 return conn->smb2.cc_chunk_len;
2839 void smb2cli_conn_set_cc_chunk_len(struct smbXcli_conn *conn,
2840 uint32_t chunk_len)
2842 conn->smb2.cc_chunk_len = chunk_len;
2845 uint32_t smb2cli_conn_cc_max_chunks(struct smbXcli_conn *conn)
2847 return conn->smb2.cc_max_chunks;
2850 void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
2851 uint32_t max_chunks)
2853 conn->smb2.cc_max_chunks = max_chunks;
2856 static void smb2cli_req_cancel_done(struct tevent_req *subreq);
2858 static bool smb2cli_req_cancel(struct tevent_req *req)
2860 struct smbXcli_req_state *state =
2861 tevent_req_data(req,
2862 struct smbXcli_req_state);
2863 struct smbXcli_tcon *tcon = state->tcon;
2864 struct smbXcli_session *session = state->session;
2865 uint8_t *fixed = state->smb2.pad;
2866 uint16_t fixed_len = 4;
2867 struct tevent_req *subreq;
2868 struct smbXcli_req_state *substate;
2869 NTSTATUS status;
2871 SSVAL(fixed, 0, 0x04);
2872 SSVAL(fixed, 2, 0);
2874 subreq = smb2cli_req_create(state, state->ev,
2875 state->conn,
2876 SMB2_OP_CANCEL,
2877 0, 0, /* flags */
2878 0, /* timeout */
2879 tcon, session,
2880 fixed, fixed_len,
2881 NULL, 0, 0);
2882 if (subreq == NULL) {
2883 return false;
2885 substate = tevent_req_data(subreq, struct smbXcli_req_state);
2887 SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, state->smb2.cancel_flags);
2888 SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, state->smb2.cancel_mid);
2889 SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, state->smb2.cancel_aid);
2891 status = smb2cli_req_compound_submit(&subreq, 1);
2892 if (!NT_STATUS_IS_OK(status)) {
2893 TALLOC_FREE(subreq);
2894 return false;
2897 tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2899 return true;
2902 static void smb2cli_req_cancel_done(struct tevent_req *subreq)
2904 /* we do not care about the result */
2905 TALLOC_FREE(subreq);
2908 struct timeval smbXcli_req_endtime(struct tevent_req *req)
2910 struct smbXcli_req_state *state = tevent_req_data(
2911 req, struct smbXcli_req_state);
2913 return state->endtime;
2916 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
2917 struct tevent_context *ev,
2918 struct smbXcli_conn *conn,
2919 uint16_t cmd,
2920 uint32_t additional_flags,
2921 uint32_t clear_flags,
2922 uint32_t timeout_msec,
2923 struct smbXcli_tcon *tcon,
2924 struct smbXcli_session *session,
2925 const uint8_t *fixed,
2926 uint16_t fixed_len,
2927 const uint8_t *dyn,
2928 uint32_t dyn_len,
2929 uint32_t max_dyn_len)
2931 struct tevent_req *req;
2932 struct smbXcli_req_state *state;
2933 uint32_t flags = 0;
2934 uint32_t tid = 0;
2935 uint64_t uid = 0;
2936 bool use_channel_sequence = conn->smb2.force_channel_sequence;
2937 uint16_t channel_sequence = 0;
2938 bool use_replay_flag = false;
2940 req = tevent_req_create(mem_ctx, &state,
2941 struct smbXcli_req_state);
2942 if (req == NULL) {
2943 return NULL;
2946 state->ev = ev;
2947 state->conn = conn;
2948 state->session = session;
2949 state->tcon = tcon;
2951 if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
2952 use_channel_sequence = true;
2953 } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
2954 use_channel_sequence = true;
2957 if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_00) {
2958 use_replay_flag = true;
2961 if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
2962 flags |= SMB2_PRIORITY_VALUE_TO_MASK(conn->smb2.io_priority);
2965 if (session) {
2966 uid = session->smb2->session_id;
2968 if (use_channel_sequence) {
2969 channel_sequence = session->smb2->channel_sequence;
2972 if (use_replay_flag && session->smb2->replay_active) {
2973 additional_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
2976 state->smb2.should_sign = session->smb2->should_sign;
2977 state->smb2.should_encrypt = session->smb2->should_encrypt;
2978 state->smb2.require_signed_response =
2979 session->smb2->require_signed_response;
2981 if (cmd == SMB2_OP_SESSSETUP &&
2982 !smb2_signing_key_valid(session->smb2_channel.signing_key) &&
2983 smb2_signing_key_valid(session->smb2->signing_key))
2986 * a session bind needs to be signed
2988 state->smb2.should_sign = true;
2991 if (cmd == SMB2_OP_SESSSETUP &&
2992 !smb2_signing_key_valid(session->smb2_channel.signing_key)) {
2993 state->smb2.should_encrypt = false;
2996 if (additional_flags & SMB2_HDR_FLAG_SIGNED) {
2997 if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
2998 tevent_req_nterror(req, NT_STATUS_NO_USER_SESSION_KEY);
2999 return req;
3002 additional_flags &= ~SMB2_HDR_FLAG_SIGNED;
3003 state->smb2.should_sign = true;
3007 if (tcon) {
3008 tid = tcon->smb2.tcon_id;
3010 if (tcon->smb2.should_sign) {
3011 state->smb2.should_sign = true;
3013 if (tcon->smb2.should_encrypt) {
3014 state->smb2.should_encrypt = true;
3018 if (state->smb2.should_encrypt) {
3019 state->smb2.should_sign = false;
3022 state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
3023 if (state->smb2.recv_iov == NULL) {
3024 TALLOC_FREE(req);
3025 return NULL;
3028 flags |= additional_flags;
3029 flags &= ~clear_flags;
3031 state->smb2.fixed = fixed;
3032 state->smb2.fixed_len = fixed_len;
3033 state->smb2.dyn = dyn;
3034 state->smb2.dyn_len = dyn_len;
3035 state->smb2.max_dyn_len = max_dyn_len;
3037 if (state->smb2.should_encrypt) {
3038 SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3039 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
3042 SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
3043 SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
3044 SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE, cmd);
3045 SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
3046 SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS, flags);
3047 SIVAL(state->smb2.hdr, SMB2_HDR_PID, 0); /* reserved */
3048 SIVAL(state->smb2.hdr, SMB2_HDR_TID, tid);
3049 SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID, uid);
3051 switch (cmd) {
3052 case SMB2_OP_CANCEL:
3053 state->one_way = true;
3054 break;
3055 case SMB2_OP_BREAK:
3057 * If this is a dummy request, it will have
3058 * UINT64_MAX as message id.
3059 * If we send on break acknowledgement,
3060 * this gets overwritten later.
3062 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
3063 break;
3066 if (timeout_msec > 0) {
3067 state->endtime = timeval_current_ofs_msec(timeout_msec);
3068 if (!tevent_req_set_endtime(req, ev, state->endtime)) {
3069 return req;
3073 return req;
3076 void smb2cli_req_set_notify_async(struct tevent_req *req)
3078 struct smbXcli_req_state *state =
3079 tevent_req_data(req,
3080 struct smbXcli_req_state);
3082 state->smb2.notify_async = true;
3085 static void smb2cli_req_writev_done(struct tevent_req *subreq);
3086 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3087 TALLOC_CTX *tmp_mem,
3088 uint8_t *inbuf);
3090 NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
3091 int num_reqs)
3093 struct smbXcli_req_state *state;
3094 struct tevent_req *subreq;
3095 struct iovec *iov;
3096 int i, num_iov, nbt_len;
3097 int tf_iov = -1;
3098 struct smb2_signing_key *encryption_key = NULL;
3099 uint64_t encryption_session_id = 0;
3100 uint64_t nonce_high = UINT64_MAX;
3101 uint64_t nonce_low = UINT64_MAX;
3104 * 1 for the nbt length, optional TRANSFORM
3105 * per request: HDR, fixed, dyn, padding
3106 * -1 because the last one does not need padding
3109 iov = talloc_array(reqs[0], struct iovec, 1 + 1 + 4*num_reqs - 1);
3110 if (iov == NULL) {
3111 return NT_STATUS_NO_MEMORY;
3114 num_iov = 1;
3115 nbt_len = 0;
3118 * the session of the first request that requires encryption
3119 * specifies the encryption key.
3121 for (i=0; i<num_reqs; i++) {
3122 if (!tevent_req_is_in_progress(reqs[i])) {
3123 return NT_STATUS_INTERNAL_ERROR;
3126 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3128 if (!smbXcli_conn_is_connected(state->conn)) {
3129 return NT_STATUS_CONNECTION_DISCONNECTED;
3132 if ((state->conn->protocol != PROTOCOL_NONE) &&
3133 (state->conn->protocol < PROTOCOL_SMB2_02)) {
3134 return NT_STATUS_REVISION_MISMATCH;
3137 if (state->session == NULL) {
3138 continue;
3141 if (!state->smb2.should_encrypt) {
3142 continue;
3145 encryption_key = state->session->smb2->encryption_key;
3146 if (!smb2_signing_key_valid(encryption_key)) {
3147 return NT_STATUS_INVALID_PARAMETER_MIX;
3150 encryption_session_id = state->session->smb2->session_id;
3152 state->session->smb2->nonce_low += 1;
3153 if (state->session->smb2->nonce_low == 0) {
3154 state->session->smb2->nonce_high += 1;
3155 state->session->smb2->nonce_low += 1;
3159 * CCM and GCM algorithms must never have their
3160 * nonce wrap, or the security of the whole
3161 * communication and the keys is destroyed.
3162 * We must drop the connection once we have
3163 * transfered too much data.
3165 * NOTE: We assume nonces greater than 8 bytes.
3167 if (state->session->smb2->nonce_high >=
3168 state->session->smb2->nonce_high_max)
3170 return NT_STATUS_ENCRYPTION_FAILED;
3173 nonce_high = state->session->smb2->nonce_high_random;
3174 nonce_high += state->session->smb2->nonce_high;
3175 nonce_low = state->session->smb2->nonce_low;
3177 tf_iov = num_iov;
3178 iov[num_iov].iov_base = state->smb2.transform;
3179 iov[num_iov].iov_len = sizeof(state->smb2.transform);
3180 num_iov += 1;
3182 SBVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3183 SBVAL(state->smb2.transform, SMB2_TF_NONCE,
3184 nonce_low);
3185 SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
3186 nonce_high);
3187 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID,
3188 encryption_session_id);
3190 nbt_len += SMB2_TF_HDR_SIZE;
3191 break;
3194 for (i=0; i<num_reqs; i++) {
3195 int hdr_iov;
3196 size_t reqlen;
3197 bool ret;
3198 uint16_t opcode;
3199 uint64_t avail;
3200 uint16_t charge;
3201 uint16_t credits;
3202 uint64_t mid;
3203 struct smb2_signing_key *signing_key = NULL;
3205 if (!tevent_req_is_in_progress(reqs[i])) {
3206 return NT_STATUS_INTERNAL_ERROR;
3209 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3211 if (!smbXcli_conn_is_connected(state->conn)) {
3212 return NT_STATUS_CONNECTION_DISCONNECTED;
3215 if ((state->conn->protocol != PROTOCOL_NONE) &&
3216 (state->conn->protocol < PROTOCOL_SMB2_02)) {
3217 return NT_STATUS_REVISION_MISMATCH;
3220 opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3221 if (opcode == SMB2_OP_CANCEL) {
3222 goto skip_credits;
3225 avail = UINT64_MAX - state->conn->smb2.mid;
3226 if (avail < 1) {
3227 return NT_STATUS_CONNECTION_ABORTED;
3230 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3231 uint32_t max_dyn_len = 1;
3233 max_dyn_len = MAX(max_dyn_len, state->smb2.dyn_len);
3234 max_dyn_len = MAX(max_dyn_len, state->smb2.max_dyn_len);
3236 charge = (max_dyn_len - 1)/ 65536 + 1;
3237 } else {
3238 charge = 1;
3241 charge = MAX(state->smb2.credit_charge, charge);
3243 avail = MIN(avail, state->conn->smb2.cur_credits);
3244 if (avail < charge) {
3245 DBG_ERR("Insufficient credits. "
3246 "%"PRIu64" available, %"PRIu16" needed\n",
3247 avail, charge);
3248 return NT_STATUS_INTERNAL_ERROR;
3251 credits = 0;
3252 if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
3253 credits = state->conn->smb2.max_credits -
3254 state->conn->smb2.cur_credits;
3256 if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
3257 credits += 1;
3260 mid = state->conn->smb2.mid;
3261 state->conn->smb2.mid += charge;
3262 state->conn->smb2.cur_credits -= charge;
3264 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3265 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
3267 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
3268 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
3270 state->smb2.cancel_flags = 0;
3271 state->smb2.cancel_mid = mid;
3272 state->smb2.cancel_aid = 0;
3274 skip_credits:
3275 if (state->session && encryption_key == NULL) {
3277 * We prefer the channel signing key if it is
3278 * already there.
3280 if (state->smb2.should_sign) {
3281 signing_key = state->session->smb2_channel.signing_key;
3285 * If it is a channel binding, we already have the main
3286 * signing key and try that one.
3288 if (signing_key != NULL &&
3289 !smb2_signing_key_valid(signing_key)) {
3290 signing_key = state->session->smb2->signing_key;
3294 * If we do not have any session key yet, we skip the
3295 * signing of SMB2_OP_SESSSETUP requests.
3297 if (signing_key != NULL &&
3298 !smb2_signing_key_valid(signing_key)) {
3299 signing_key = NULL;
3303 hdr_iov = num_iov;
3304 iov[num_iov].iov_base = state->smb2.hdr;
3305 iov[num_iov].iov_len = sizeof(state->smb2.hdr);
3306 num_iov += 1;
3308 iov[num_iov].iov_base = discard_const(state->smb2.fixed);
3309 iov[num_iov].iov_len = state->smb2.fixed_len;
3310 num_iov += 1;
3312 if (state->smb2.dyn != NULL) {
3313 iov[num_iov].iov_base = discard_const(state->smb2.dyn);
3314 iov[num_iov].iov_len = state->smb2.dyn_len;
3315 num_iov += 1;
3318 reqlen = sizeof(state->smb2.hdr);
3319 reqlen += state->smb2.fixed_len;
3320 reqlen += state->smb2.dyn_len;
3322 if (i < num_reqs-1) {
3323 if ((reqlen % 8) > 0) {
3324 uint8_t pad = 8 - (reqlen % 8);
3325 iov[num_iov].iov_base = state->smb2.pad;
3326 iov[num_iov].iov_len = pad;
3327 num_iov += 1;
3328 reqlen += pad;
3330 SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
3333 state->smb2.encryption_session_id = encryption_session_id;
3335 if (signing_key != NULL) {
3336 NTSTATUS status;
3338 status = smb2_signing_sign_pdu(signing_key,
3339 state->session->conn->protocol,
3340 &iov[hdr_iov], num_iov - hdr_iov);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 return status;
3346 nbt_len += reqlen;
3348 ret = smbXcli_req_set_pending(reqs[i]);
3349 if (!ret) {
3350 return NT_STATUS_NO_MEMORY;
3354 state = tevent_req_data(reqs[0], struct smbXcli_req_state);
3355 _smb_setlen_tcp(state->length_hdr, nbt_len);
3356 iov[0].iov_base = state->length_hdr;
3357 iov[0].iov_len = sizeof(state->length_hdr);
3359 if (encryption_key != NULL) {
3360 NTSTATUS status;
3361 size_t buflen = nbt_len - SMB2_TF_HDR_SIZE;
3362 uint8_t *buf;
3363 int vi;
3365 buf = talloc_array(iov, uint8_t, buflen);
3366 if (buf == NULL) {
3367 return NT_STATUS_NO_MEMORY;
3371 * We copy the buffers before encrypting them,
3372 * this is at least currently needed for the
3373 * to keep state->smb2.hdr.
3375 * Also the callers may expect there buffers
3376 * to be const.
3378 for (vi = tf_iov + 1; vi < num_iov; vi++) {
3379 struct iovec *v = &iov[vi];
3380 const uint8_t *o = (const uint8_t *)v->iov_base;
3382 memcpy(buf, o, v->iov_len);
3383 v->iov_base = (void *)buf;
3384 buf += v->iov_len;
3387 status = smb2_signing_encrypt_pdu(encryption_key,
3388 state->conn->smb2.server.cipher,
3389 &iov[tf_iov], num_iov - tf_iov);
3390 if (!NT_STATUS_IS_OK(status)) {
3391 return status;
3395 if (state->conn->dispatch_incoming == NULL) {
3396 state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3399 subreq = writev_send(state, state->ev, state->conn->outgoing,
3400 state->conn->sock_fd, false, iov, num_iov);
3401 if (subreq == NULL) {
3402 return NT_STATUS_NO_MEMORY;
3404 tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
3405 state->write_req = subreq;
3407 return NT_STATUS_OK;
3410 void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
3412 struct smbXcli_req_state *state =
3413 tevent_req_data(req,
3414 struct smbXcli_req_state);
3416 state->smb2.credit_charge = charge;
3419 struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
3420 struct tevent_context *ev,
3421 struct smbXcli_conn *conn,
3422 uint16_t cmd,
3423 uint32_t additional_flags,
3424 uint32_t clear_flags,
3425 uint32_t timeout_msec,
3426 struct smbXcli_tcon *tcon,
3427 struct smbXcli_session *session,
3428 const uint8_t *fixed,
3429 uint16_t fixed_len,
3430 const uint8_t *dyn,
3431 uint32_t dyn_len,
3432 uint32_t max_dyn_len)
3434 struct tevent_req *req;
3435 NTSTATUS status;
3437 req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
3438 additional_flags, clear_flags,
3439 timeout_msec,
3440 tcon, session,
3441 fixed, fixed_len,
3442 dyn, dyn_len,
3443 max_dyn_len);
3444 if (req == NULL) {
3445 return NULL;
3447 if (!tevent_req_is_in_progress(req)) {
3448 return tevent_req_post(req, ev);
3450 status = smb2cli_req_compound_submit(&req, 1);
3451 if (tevent_req_nterror(req, status)) {
3452 return tevent_req_post(req, ev);
3454 return req;
3457 static void smb2cli_req_writev_done(struct tevent_req *subreq)
3459 struct tevent_req *req =
3460 tevent_req_callback_data(subreq,
3461 struct tevent_req);
3462 struct smbXcli_req_state *state =
3463 tevent_req_data(req,
3464 struct smbXcli_req_state);
3465 ssize_t nwritten;
3466 int err;
3468 state->write_req = NULL;
3470 nwritten = writev_recv(subreq, &err);
3471 TALLOC_FREE(subreq);
3472 if (nwritten == -1) {
3473 /* here, we need to notify all pending requests */
3474 NTSTATUS status = map_nt_error_from_unix_common(err);
3475 smbXcli_conn_disconnect(state->conn, status);
3476 return;
3480 static struct smbXcli_session* smbXcli_session_by_uid(struct smbXcli_conn *conn,
3481 uint64_t uid)
3483 struct smbXcli_session *s = conn->sessions;
3485 for (; s; s = s->next) {
3486 if (s->smb2->session_id != uid) {
3487 continue;
3489 break;
3492 return s;
3495 static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
3496 uint8_t *buf,
3497 size_t buflen,
3498 TALLOC_CTX *mem_ctx,
3499 struct iovec **piov,
3500 size_t *pnum_iov)
3502 struct iovec *iov;
3503 int num_iov = 0;
3504 size_t taken = 0;
3505 uint8_t *first_hdr = buf;
3506 size_t verified_buflen = 0;
3507 uint8_t *tf = NULL;
3508 size_t tf_len = 0;
3510 iov = talloc_array(mem_ctx, struct iovec, num_iov);
3511 if (iov == NULL) {
3512 return NT_STATUS_NO_MEMORY;
3515 while (taken < buflen) {
3516 size_t len = buflen - taken;
3517 uint8_t *hdr = first_hdr + taken;
3518 struct iovec *cur;
3519 size_t full_size;
3520 size_t next_command_ofs;
3521 uint16_t body_size;
3522 struct iovec *iov_tmp;
3524 if (verified_buflen > taken) {
3525 len = verified_buflen - taken;
3526 } else {
3527 tf = NULL;
3528 tf_len = 0;
3531 if (len < 4) {
3532 DEBUG(10, ("%d bytes left, expected at least %d\n",
3533 (int)len, 4));
3534 goto inval;
3536 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
3537 struct smbXcli_session *s;
3538 uint64_t uid;
3539 struct iovec tf_iov[2];
3540 size_t enc_len;
3541 NTSTATUS status;
3543 if (len < SMB2_TF_HDR_SIZE) {
3544 DEBUG(10, ("%d bytes left, expected at least %d\n",
3545 (int)len, SMB2_TF_HDR_SIZE));
3546 goto inval;
3548 tf = hdr;
3549 tf_len = SMB2_TF_HDR_SIZE;
3550 taken += tf_len;
3552 hdr = first_hdr + taken;
3553 enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
3554 uid = BVAL(tf, SMB2_TF_SESSION_ID);
3556 if (len < SMB2_TF_HDR_SIZE + enc_len) {
3557 DEBUG(10, ("%d bytes left, expected at least %d\n",
3558 (int)len,
3559 (int)(SMB2_TF_HDR_SIZE + enc_len)));
3560 goto inval;
3563 s = smbXcli_session_by_uid(conn, uid);
3564 if (s == NULL) {
3565 DEBUG(10, ("unknown session_id %llu\n",
3566 (unsigned long long)uid));
3567 goto inval;
3570 tf_iov[0].iov_base = (void *)tf;
3571 tf_iov[0].iov_len = tf_len;
3572 tf_iov[1].iov_base = (void *)hdr;
3573 tf_iov[1].iov_len = enc_len;
3575 status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
3576 conn->smb2.server.cipher,
3577 tf_iov, 2);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 TALLOC_FREE(iov);
3580 return status;
3583 verified_buflen = taken + enc_len;
3584 len = enc_len;
3588 * We need the header plus the body length field
3591 if (len < SMB2_HDR_BODY + 2) {
3592 DEBUG(10, ("%d bytes left, expected at least %d\n",
3593 (int)len, SMB2_HDR_BODY));
3594 goto inval;
3596 if (IVAL(hdr, 0) != SMB2_MAGIC) {
3597 DEBUG(10, ("Got non-SMB2 PDU: %x\n",
3598 IVAL(hdr, 0)));
3599 goto inval;
3601 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
3602 DEBUG(10, ("Got HDR len %d, expected %d\n",
3603 SVAL(hdr, 4), SMB2_HDR_BODY));
3604 goto inval;
3607 full_size = len;
3608 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
3609 body_size = SVAL(hdr, SMB2_HDR_BODY);
3611 if (next_command_ofs != 0) {
3612 if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
3613 goto inval;
3615 if (next_command_ofs > full_size) {
3616 goto inval;
3618 full_size = next_command_ofs;
3620 if (body_size < 2) {
3621 goto inval;
3623 body_size &= 0xfffe;
3625 if (body_size > (full_size - SMB2_HDR_BODY)) {
3626 goto inval;
3629 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
3630 num_iov + 4);
3631 if (iov_tmp == NULL) {
3632 TALLOC_FREE(iov);
3633 return NT_STATUS_NO_MEMORY;
3635 iov = iov_tmp;
3636 cur = &iov[num_iov];
3637 num_iov += 4;
3639 cur[0].iov_base = tf;
3640 cur[0].iov_len = tf_len;
3641 cur[1].iov_base = hdr;
3642 cur[1].iov_len = SMB2_HDR_BODY;
3643 cur[2].iov_base = hdr + SMB2_HDR_BODY;
3644 cur[2].iov_len = body_size;
3645 cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
3646 cur[3].iov_len = full_size - (SMB2_HDR_BODY + body_size);
3648 taken += full_size;
3651 *piov = iov;
3652 *pnum_iov = num_iov;
3653 return NT_STATUS_OK;
3655 inval:
3656 TALLOC_FREE(iov);
3657 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3660 static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
3661 uint64_t mid)
3663 size_t num_pending = talloc_array_length(conn->pending);
3664 size_t i;
3666 for (i=0; i<num_pending; i++) {
3667 struct tevent_req *req = conn->pending[i];
3668 struct smbXcli_req_state *state =
3669 tevent_req_data(req,
3670 struct smbXcli_req_state);
3672 if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
3673 return req;
3676 return NULL;
3679 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3680 TALLOC_CTX *tmp_mem,
3681 uint8_t *inbuf)
3683 struct tevent_req *req;
3684 struct smbXcli_req_state *state = NULL;
3685 struct iovec *iov = NULL;
3686 size_t i, num_iov = 0;
3687 NTSTATUS status;
3688 bool defer = true;
3689 struct smbXcli_session *last_session = NULL;
3690 size_t inbuf_len = smb_len_tcp(inbuf);
3692 status = smb2cli_inbuf_parse_compound(conn,
3693 inbuf + NBT_HDR_SIZE,
3694 inbuf_len,
3695 tmp_mem,
3696 &iov, &num_iov);
3697 if (!NT_STATUS_IS_OK(status)) {
3698 return status;
3701 for (i=0; i<num_iov; i+=4) {
3702 uint8_t *inbuf_ref = NULL;
3703 struct iovec *cur = &iov[i];
3704 uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
3705 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3706 uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3707 uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3708 uint16_t req_opcode;
3709 uint32_t req_flags;
3710 uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
3711 uint32_t new_credits;
3712 struct smbXcli_session *session = NULL;
3713 struct smb2_signing_key *signing_key = NULL;
3714 bool was_encrypted = false;
3716 new_credits = conn->smb2.cur_credits;
3717 new_credits += credits;
3718 if (new_credits > UINT16_MAX) {
3719 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3721 conn->smb2.cur_credits += credits;
3723 req = smb2cli_conn_find_pending(conn, mid);
3724 if (req == NULL) {
3725 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3727 state = tevent_req_data(req, struct smbXcli_req_state);
3729 req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3730 if (opcode != req_opcode) {
3731 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3733 req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3735 if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
3736 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3739 status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
3740 if ((flags & SMB2_HDR_FLAG_ASYNC) &&
3741 NT_STATUS_EQUAL(status, NT_STATUS_PENDING)) {
3742 uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
3744 if (state->smb2.got_async) {
3745 /* We only expect one STATUS_PENDING response */
3746 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3748 state->smb2.got_async = true;
3751 * async interim responses are not signed,
3752 * even if the SMB2_HDR_FLAG_SIGNED flag
3753 * is set.
3755 state->smb2.cancel_flags = SMB2_HDR_FLAG_ASYNC;
3756 state->smb2.cancel_mid = 0;
3757 state->smb2.cancel_aid = async_id;
3759 if (state->smb2.notify_async) {
3760 tevent_req_defer_callback(req, state->ev);
3761 tevent_req_notify_callback(req);
3763 continue;
3766 session = state->session;
3767 if (req_flags & SMB2_HDR_FLAG_CHAINED) {
3768 session = last_session;
3770 last_session = session;
3772 if (flags & SMB2_HDR_FLAG_SIGNED) {
3773 uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
3775 if (session == NULL) {
3776 session = smbXcli_session_by_uid(state->conn,
3777 uid);
3780 if (session == NULL) {
3781 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3784 last_session = session;
3785 signing_key = session->smb2_channel.signing_key;
3788 if (opcode == SMB2_OP_SESSSETUP) {
3790 * We prefer the channel signing key, if it is
3791 * already there.
3793 * If we do not have a channel signing key yet,
3794 * we try the main signing key, if it is not
3795 * the final response.
3797 if (signing_key != NULL &&
3798 !smb2_signing_key_valid(signing_key) &&
3799 !NT_STATUS_IS_OK(status)) {
3800 signing_key = session->smb2->signing_key;
3803 if (signing_key != NULL &&
3804 !smb2_signing_key_valid(signing_key)) {
3806 * If we do not have a session key to
3807 * verify the signature, we defer the
3808 * signing check to the caller.
3810 * The caller gets NT_STATUS_OK, it
3811 * has to call
3812 * smb2cli_session_set_session_key()
3813 * or
3814 * smb2cli_session_set_channel_key()
3815 * which will check the signature
3816 * with the channel signing key.
3818 signing_key = NULL;
3821 if (!NT_STATUS_IS_OK(status)) {
3823 * Only check the signature of the last response
3824 * of a successfull session auth. This matches
3825 * Windows behaviour for NTLM auth and reauth.
3827 state->smb2.require_signed_response = false;
3831 if (state->smb2.should_sign ||
3832 state->smb2.require_signed_response)
3834 if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
3835 return NT_STATUS_ACCESS_DENIED;
3839 if (!smb2_signing_key_valid(signing_key) &&
3840 state->smb2.require_signed_response) {
3841 signing_key = session->smb2_channel.signing_key;
3844 if (cur[0].iov_len == SMB2_TF_HDR_SIZE) {
3845 const uint8_t *tf = (const uint8_t *)cur[0].iov_base;
3846 uint64_t uid = BVAL(tf, SMB2_TF_SESSION_ID);
3849 * If the response was encrypted in a SMB2_TRANSFORM
3850 * pdu, which belongs to the correct session,
3851 * we do not need to do signing checks
3853 * It could be the session the response belongs to
3854 * or the session that was used to encrypt the
3855 * SMB2_TRANSFORM request.
3857 if ((session && session->smb2->session_id == uid) ||
3858 (state->smb2.encryption_session_id == uid)) {
3859 signing_key = NULL;
3860 was_encrypted = true;
3864 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
3866 * if the server returns NT_STATUS_USER_SESSION_DELETED
3867 * the response is not signed and we should
3868 * propagate the NT_STATUS_USER_SESSION_DELETED
3869 * status to the caller.
3871 state->smb2.signing_skipped = true;
3872 signing_key = NULL;
3875 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3877 * if the server returns
3878 * NT_STATUS_INVALID_PARAMETER
3879 * the response might not be encrypted.
3881 if (state->smb2.should_encrypt && !was_encrypted) {
3882 state->smb2.signing_skipped = true;
3883 signing_key = NULL;
3887 if (state->smb2.should_encrypt && !was_encrypted) {
3888 if (!state->smb2.signing_skipped) {
3889 return NT_STATUS_ACCESS_DENIED;
3893 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
3894 NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
3895 NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3897 * if the server returns
3898 * NT_STATUS_NETWORK_NAME_DELETED
3899 * NT_STATUS_FILE_CLOSED
3900 * NT_STATUS_INVALID_PARAMETER
3901 * the response might not be signed
3902 * as this happens before the signing checks.
3904 * If server echos the signature (or all zeros)
3905 * we should report the status from the server
3906 * to the caller.
3908 if (signing_key) {
3909 int cmp;
3911 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3912 state->smb2.hdr+SMB2_HDR_SIGNATURE,
3913 16);
3914 if (cmp == 0) {
3915 state->smb2.signing_skipped = true;
3916 signing_key = NULL;
3919 if (signing_key) {
3920 bool zero;
3921 zero = all_zero(inhdr+SMB2_HDR_SIGNATURE, 16);
3922 if (zero) {
3923 state->smb2.signing_skipped = true;
3924 signing_key = NULL;
3929 if (signing_key) {
3930 NTSTATUS signing_status;
3932 signing_status = smb2_signing_check_pdu(signing_key,
3933 state->conn->protocol,
3934 &cur[1], 3);
3935 if (!NT_STATUS_IS_OK(signing_status)) {
3937 * If the signing check fails, we disconnect
3938 * the connection.
3940 return signing_status;
3944 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
3945 (session != NULL) && session->disconnect_expired)
3948 * this should be a short term hack
3949 * until the upper layers have implemented
3950 * re-authentication.
3952 return status;
3955 smbXcli_req_unset_pending(req);
3958 * There might be more than one response
3959 * we need to defer the notifications
3961 if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
3962 defer = false;
3965 if (defer) {
3966 tevent_req_defer_callback(req, state->ev);
3970 * Note: here we use talloc_reference() in a way
3971 * that does not expose it to the caller.
3973 inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
3974 if (tevent_req_nomem(inbuf_ref, req)) {
3975 continue;
3978 /* copy the related buffers */
3979 state->smb2.recv_iov[0] = cur[1];
3980 state->smb2.recv_iov[1] = cur[2];
3981 state->smb2.recv_iov[2] = cur[3];
3983 tevent_req_done(req);
3986 if (defer) {
3987 return NT_STATUS_RETRY;
3990 return NT_STATUS_OK;
3993 NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3994 struct iovec **piov,
3995 const struct smb2cli_req_expected_response *expected,
3996 size_t num_expected)
3998 struct smbXcli_req_state *state =
3999 tevent_req_data(req,
4000 struct smbXcli_req_state);
4001 NTSTATUS status;
4002 size_t body_size;
4003 bool found_status = false;
4004 bool found_size = false;
4005 size_t i;
4007 if (piov != NULL) {
4008 *piov = NULL;
4011 if (tevent_req_is_in_progress(req) && state->smb2.got_async) {
4012 return NT_STATUS_PENDING;
4015 if (tevent_req_is_nterror(req, &status)) {
4016 for (i=0; i < num_expected; i++) {
4017 if (NT_STATUS_EQUAL(status, expected[i].status)) {
4018 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
4022 return status;
4025 if (num_expected == 0) {
4026 found_status = true;
4027 found_size = true;
4030 status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
4031 body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
4033 for (i=0; i < num_expected; i++) {
4034 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
4035 continue;
4038 found_status = true;
4039 if (expected[i].body_size == 0) {
4040 found_size = true;
4041 break;
4044 if (expected[i].body_size == body_size) {
4045 found_size = true;
4046 break;
4050 if (!found_status) {
4051 return status;
4054 if (state->smb2.signing_skipped) {
4055 if (num_expected > 0) {
4056 return NT_STATUS_ACCESS_DENIED;
4058 if (!NT_STATUS_IS_ERR(status)) {
4059 return NT_STATUS_ACCESS_DENIED;
4063 if (!found_size) {
4064 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4067 if (piov != NULL) {
4068 *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
4071 return status;
4074 NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
4075 struct iovec *sent_iov)
4077 struct smbXcli_req_state *state =
4078 tevent_req_data(req,
4079 struct smbXcli_req_state);
4081 if (tevent_req_is_in_progress(req)) {
4082 return NT_STATUS_PENDING;
4085 sent_iov[0].iov_base = state->smb2.hdr;
4086 sent_iov[0].iov_len = sizeof(state->smb2.hdr);
4088 sent_iov[1].iov_base = discard_const(state->smb2.fixed);
4089 sent_iov[1].iov_len = state->smb2.fixed_len;
4091 if (state->smb2.dyn != NULL) {
4092 sent_iov[2].iov_base = discard_const(state->smb2.dyn);
4093 sent_iov[2].iov_len = state->smb2.dyn_len;
4094 } else {
4095 sent_iov[2].iov_base = NULL;
4096 sent_iov[2].iov_len = 0;
4099 return NT_STATUS_OK;
4102 static const struct {
4103 enum protocol_types proto;
4104 const char *smb1_name;
4105 } smb1cli_prots[] = {
4106 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
4107 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
4108 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
4109 {PROTOCOL_LANMAN1, "LANMAN1.0"},
4110 {PROTOCOL_LANMAN2, "LM1.2X002"},
4111 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
4112 {PROTOCOL_LANMAN2, "LANMAN2.1"},
4113 {PROTOCOL_LANMAN2, "Samba"},
4114 {PROTOCOL_NT1, "NT LANMAN 1.0"},
4115 {PROTOCOL_NT1, "NT LM 0.12"},
4116 {PROTOCOL_SMB2_02, "SMB 2.002"},
4117 {PROTOCOL_SMB2_10, "SMB 2.???"},
4120 static const struct {
4121 enum protocol_types proto;
4122 uint16_t smb2_dialect;
4123 } smb2cli_prots[] = {
4124 {PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202},
4125 {PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210},
4126 {PROTOCOL_SMB2_22, SMB2_DIALECT_REVISION_222},
4127 {PROTOCOL_SMB2_24, SMB2_DIALECT_REVISION_224},
4128 {PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300},
4129 {PROTOCOL_SMB3_02, SMB3_DIALECT_REVISION_302},
4130 {PROTOCOL_SMB3_10, SMB3_DIALECT_REVISION_310},
4131 {PROTOCOL_SMB3_11, SMB3_DIALECT_REVISION_311},
4134 struct smbXcli_negprot_state {
4135 struct smbXcli_conn *conn;
4136 struct tevent_context *ev;
4137 uint32_t timeout_msec;
4139 struct {
4140 uint8_t fixed[36];
4141 } smb2;
4144 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
4145 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
4146 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
4147 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
4148 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
4149 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
4150 TALLOC_CTX *frame,
4151 uint8_t *inbuf);
4153 struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
4154 struct tevent_context *ev,
4155 struct smbXcli_conn *conn,
4156 uint32_t timeout_msec,
4157 enum protocol_types min_protocol,
4158 enum protocol_types max_protocol,
4159 uint16_t max_credits)
4161 struct tevent_req *req, *subreq;
4162 struct smbXcli_negprot_state *state;
4164 req = tevent_req_create(mem_ctx, &state,
4165 struct smbXcli_negprot_state);
4166 if (req == NULL) {
4167 return NULL;
4169 state->conn = conn;
4170 state->ev = ev;
4171 state->timeout_msec = timeout_msec;
4173 if (min_protocol == PROTOCOL_NONE) {
4174 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4175 return tevent_req_post(req, ev);
4178 if (max_protocol == PROTOCOL_NONE) {
4179 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4180 return tevent_req_post(req, ev);
4183 if (min_protocol > max_protocol) {
4184 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4185 return tevent_req_post(req, ev);
4188 conn->min_protocol = min_protocol;
4189 conn->max_protocol = max_protocol;
4190 conn->protocol = PROTOCOL_NONE;
4192 if (max_protocol >= PROTOCOL_SMB2_02) {
4193 conn->smb2.max_credits = max_credits;
4196 if ((min_protocol < PROTOCOL_SMB2_02) &&
4197 (max_protocol < PROTOCOL_SMB2_02)) {
4199 * SMB1 only...
4201 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4203 subreq = smbXcli_negprot_smb1_subreq(state);
4204 if (tevent_req_nomem(subreq, req)) {
4205 return tevent_req_post(req, ev);
4207 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4208 return req;
4211 if ((min_protocol >= PROTOCOL_SMB2_02) &&
4212 (max_protocol >= PROTOCOL_SMB2_02)) {
4214 * SMB2 only...
4216 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4218 subreq = smbXcli_negprot_smb2_subreq(state);
4219 if (tevent_req_nomem(subreq, req)) {
4220 return tevent_req_post(req, ev);
4222 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4223 return req;
4227 * We send an SMB1 negprot with the SMB2 dialects
4228 * and expect a SMB1 or a SMB2 response.
4230 * smbXcli_negprot_dispatch_incoming() will fix the
4231 * callback to match protocol of the response.
4233 conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
4235 subreq = smbXcli_negprot_smb1_subreq(state);
4236 if (tevent_req_nomem(subreq, req)) {
4237 return tevent_req_post(req, ev);
4239 tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
4240 return req;
4243 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
4245 struct tevent_req *req =
4246 tevent_req_callback_data(subreq,
4247 struct tevent_req);
4248 NTSTATUS status;
4251 * we just want the low level error
4253 status = tevent_req_simple_recv_ntstatus(subreq);
4254 TALLOC_FREE(subreq);
4255 if (tevent_req_nterror(req, status)) {
4256 return;
4259 /* this should never happen */
4260 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
4263 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
4265 size_t i;
4266 DATA_BLOB bytes = data_blob_null;
4267 uint8_t flags;
4268 uint16_t flags2;
4270 /* setup the protocol strings */
4271 for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4272 uint8_t c = 2;
4273 bool ok;
4275 if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4276 continue;
4279 if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4280 continue;
4283 ok = data_blob_append(state, &bytes, &c, sizeof(c));
4284 if (!ok) {
4285 return NULL;
4289 * We now it is already ascii and
4290 * we want NULL termination.
4292 ok = data_blob_append(state, &bytes,
4293 smb1cli_prots[i].smb1_name,
4294 strlen(smb1cli_prots[i].smb1_name)+1);
4295 if (!ok) {
4296 return NULL;
4300 smb1cli_req_flags(state->conn->max_protocol,
4301 state->conn->smb1.client.capabilities,
4302 SMBnegprot,
4303 0, 0, &flags,
4304 0, 0, &flags2);
4306 return smb1cli_req_send(state, state->ev, state->conn,
4307 SMBnegprot,
4308 flags, ~flags,
4309 flags2, ~flags2,
4310 state->timeout_msec,
4311 0xFFFE, 0, NULL, /* pid, tid, session */
4312 0, NULL, /* wct, vwv */
4313 bytes.length, bytes.data);
4316 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
4318 struct tevent_req *req =
4319 tevent_req_callback_data(subreq,
4320 struct tevent_req);
4321 struct smbXcli_negprot_state *state =
4322 tevent_req_data(req,
4323 struct smbXcli_negprot_state);
4324 struct smbXcli_conn *conn = state->conn;
4325 struct iovec *recv_iov = NULL;
4326 uint8_t *inhdr = NULL;
4327 uint8_t wct;
4328 uint16_t *vwv;
4329 uint32_t num_bytes;
4330 uint8_t *bytes;
4331 NTSTATUS status;
4332 uint16_t protnum;
4333 size_t i;
4334 size_t num_prots = 0;
4335 uint8_t flags;
4336 uint32_t client_capabilities = conn->smb1.client.capabilities;
4337 uint32_t both_capabilities;
4338 uint32_t server_capabilities = 0;
4339 uint32_t capabilities;
4340 uint32_t client_max_xmit = conn->smb1.client.max_xmit;
4341 uint32_t server_max_xmit = 0;
4342 uint32_t max_xmit;
4343 uint32_t server_max_mux = 0;
4344 uint16_t server_security_mode = 0;
4345 uint32_t server_session_key = 0;
4346 bool server_readbraw = false;
4347 bool server_writebraw = false;
4348 bool server_lockread = false;
4349 bool server_writeunlock = false;
4350 struct GUID server_guid = GUID_zero();
4351 DATA_BLOB server_gss_blob = data_blob_null;
4352 uint8_t server_challenge[8];
4353 char *server_workgroup = NULL;
4354 char *server_name = NULL;
4355 int server_time_zone = 0;
4356 NTTIME server_system_time = 0;
4357 static const struct smb1cli_req_expected_response expected[] = {
4359 .status = NT_STATUS_OK,
4360 .wct = 0x11, /* NT1 */
4363 .status = NT_STATUS_OK,
4364 .wct = 0x0D, /* LM */
4367 .status = NT_STATUS_OK,
4368 .wct = 0x01, /* CORE */
4372 ZERO_STRUCT(server_challenge);
4374 status = smb1cli_req_recv(subreq, state,
4375 &recv_iov,
4376 &inhdr,
4377 &wct,
4378 &vwv,
4379 NULL, /* pvwv_offset */
4380 &num_bytes,
4381 &bytes,
4382 NULL, /* pbytes_offset */
4383 NULL, /* pinbuf */
4384 expected, ARRAY_SIZE(expected));
4385 TALLOC_FREE(subreq);
4386 if (inhdr == NULL || tevent_req_nterror(req, status)) {
4387 return;
4390 flags = CVAL(inhdr, HDR_FLG);
4392 protnum = SVAL(vwv, 0);
4394 for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4395 if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4396 continue;
4399 if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4400 continue;
4403 if (protnum != num_prots) {
4404 num_prots++;
4405 continue;
4408 conn->protocol = smb1cli_prots[i].proto;
4409 break;
4412 if (conn->protocol == PROTOCOL_NONE) {
4413 DBG_ERR("No compatible protocol selected by server.\n");
4414 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4415 return;
4418 if ((conn->protocol < PROTOCOL_NT1) && conn->mandatory_signing) {
4419 DEBUG(0,("smbXcli_negprot: SMB signing is mandatory "
4420 "and the selected protocol level doesn't support it.\n"));
4421 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4422 return;
4425 if (flags & FLAG_SUPPORT_LOCKREAD) {
4426 server_lockread = true;
4427 server_writeunlock = true;
4430 if (conn->protocol >= PROTOCOL_NT1) {
4431 const char *client_signing = NULL;
4432 bool server_mandatory = false;
4433 bool server_allowed = false;
4434 const char *server_signing = NULL;
4435 bool ok;
4436 uint8_t key_len;
4438 if (wct != 0x11) {
4439 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4440 return;
4443 /* NT protocol */
4444 server_security_mode = CVAL(vwv + 1, 0);
4445 server_max_mux = SVAL(vwv + 1, 1);
4446 server_max_xmit = IVAL(vwv + 3, 1);
4447 server_session_key = IVAL(vwv + 7, 1);
4448 server_time_zone = SVALS(vwv + 15, 1);
4449 server_time_zone *= 60;
4450 /* this time arrives in real GMT */
4451 server_system_time = BVAL(vwv + 11, 1);
4452 server_capabilities = IVAL(vwv + 9, 1);
4454 key_len = CVAL(vwv + 16, 1);
4456 if (server_capabilities & CAP_RAW_MODE) {
4457 server_readbraw = true;
4458 server_writebraw = true;
4460 if (server_capabilities & CAP_LOCK_AND_READ) {
4461 server_lockread = true;
4464 if (server_capabilities & CAP_EXTENDED_SECURITY) {
4465 DATA_BLOB blob1, blob2;
4467 if (num_bytes < 16) {
4468 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4469 return;
4472 blob1 = data_blob_const(bytes, 16);
4473 status = GUID_from_data_blob(&blob1, &server_guid);
4474 if (tevent_req_nterror(req, status)) {
4475 return;
4478 blob1 = data_blob_const(bytes+16, num_bytes-16);
4479 blob2 = data_blob_dup_talloc(state, blob1);
4480 if (blob1.length > 0 &&
4481 tevent_req_nomem(blob2.data, req)) {
4482 return;
4484 server_gss_blob = blob2;
4485 } else {
4486 DATA_BLOB blob1, blob2;
4488 if (num_bytes < key_len) {
4489 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4490 return;
4493 if (key_len != 0 && key_len != 8) {
4494 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4495 return;
4498 if (key_len == 8) {
4499 memcpy(server_challenge, bytes, 8);
4502 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4503 blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
4504 if (blob1.length > 0) {
4505 size_t len;
4507 len = utf16_len_n(blob1.data,
4508 blob1.length);
4509 blob1.length = len;
4511 ok = convert_string_talloc(state,
4512 CH_UTF16LE,
4513 CH_UNIX,
4514 blob1.data,
4515 blob1.length,
4516 &server_workgroup,
4517 &len);
4518 if (!ok) {
4519 status = map_nt_error_from_unix_common(errno);
4520 tevent_req_nterror(req, status);
4521 return;
4525 blob2.data += blob1.length;
4526 blob2.length -= blob1.length;
4527 if (blob2.length > 0) {
4528 size_t len;
4530 len = utf16_len_n(blob1.data,
4531 blob1.length);
4532 blob1.length = len;
4534 ok = convert_string_talloc(state,
4535 CH_UTF16LE,
4536 CH_UNIX,
4537 blob2.data,
4538 blob2.length,
4539 &server_name,
4540 &len);
4541 if (!ok) {
4542 status = map_nt_error_from_unix_common(errno);
4543 tevent_req_nterror(req, status);
4544 return;
4549 client_signing = "disabled";
4550 if (conn->allow_signing) {
4551 client_signing = "allowed";
4553 if (conn->mandatory_signing) {
4554 client_signing = "required";
4557 server_signing = "not supported";
4558 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
4559 server_signing = "supported";
4560 server_allowed = true;
4561 } else if (conn->mandatory_signing) {
4563 * We have mandatory signing as client
4564 * lets assume the server will look at our
4565 * FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
4566 * flag in the session setup
4568 server_signing = "not announced";
4569 server_allowed = true;
4571 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
4572 server_signing = "required";
4573 server_mandatory = true;
4576 ok = smb_signing_set_negotiated(conn->smb1.signing,
4577 server_allowed,
4578 server_mandatory);
4579 if (!ok) {
4580 DEBUG(1,("cli_negprot: SMB signing is required, "
4581 "but client[%s] and server[%s] mismatch\n",
4582 client_signing, server_signing));
4583 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4584 return;
4587 } else if (conn->protocol >= PROTOCOL_LANMAN1) {
4588 DATA_BLOB blob1;
4589 uint8_t key_len;
4590 time_t t;
4592 if (wct != 0x0D) {
4593 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4594 return;
4597 server_security_mode = SVAL(vwv + 1, 0);
4598 server_max_xmit = SVAL(vwv + 2, 0);
4599 server_max_mux = SVAL(vwv + 3, 0);
4600 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
4601 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
4602 server_session_key = IVAL(vwv + 6, 0);
4603 server_time_zone = SVALS(vwv + 10, 0);
4604 server_time_zone *= 60;
4605 /* this time is converted to GMT by make_unix_date */
4606 t = pull_dos_date((const uint8_t *)(vwv + 8), server_time_zone);
4607 unix_to_nt_time(&server_system_time, t);
4608 key_len = SVAL(vwv + 11, 0);
4610 if (num_bytes < key_len) {
4611 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4612 return;
4615 if (key_len != 0 && key_len != 8) {
4616 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4617 return;
4620 if (key_len == 8) {
4621 memcpy(server_challenge, bytes, 8);
4624 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4625 if (blob1.length > 0) {
4626 size_t len;
4627 bool ok;
4629 len = utf16_len_n(blob1.data,
4630 blob1.length);
4631 blob1.length = len;
4633 ok = convert_string_talloc(state,
4634 CH_DOS,
4635 CH_UNIX,
4636 blob1.data,
4637 blob1.length,
4638 &server_workgroup,
4639 &len);
4640 if (!ok) {
4641 status = map_nt_error_from_unix_common(errno);
4642 tevent_req_nterror(req, status);
4643 return;
4647 } else {
4648 /* the old core protocol */
4649 server_time_zone = get_time_zone(time(NULL));
4650 server_max_xmit = 1024;
4651 server_max_mux = 1;
4654 if (server_max_xmit < 1024) {
4655 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4656 return;
4659 if (server_max_mux < 1) {
4660 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4661 return;
4665 * Now calculate the negotiated capabilities
4666 * based on the mask for:
4667 * - client only flags
4668 * - flags used in both directions
4669 * - server only flags
4671 both_capabilities = client_capabilities & server_capabilities;
4672 capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
4673 capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
4674 capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
4676 max_xmit = MIN(client_max_xmit, server_max_xmit);
4678 conn->smb1.server.capabilities = server_capabilities;
4679 conn->smb1.capabilities = capabilities;
4681 conn->smb1.server.max_xmit = server_max_xmit;
4682 conn->smb1.max_xmit = max_xmit;
4684 conn->smb1.server.max_mux = server_max_mux;
4686 conn->smb1.server.security_mode = server_security_mode;
4688 conn->smb1.server.readbraw = server_readbraw;
4689 conn->smb1.server.writebraw = server_writebraw;
4690 conn->smb1.server.lockread = server_lockread;
4691 conn->smb1.server.writeunlock = server_writeunlock;
4693 conn->smb1.server.session_key = server_session_key;
4695 talloc_steal(conn, server_gss_blob.data);
4696 conn->smb1.server.gss_blob = server_gss_blob;
4697 conn->smb1.server.guid = server_guid;
4698 memcpy(conn->smb1.server.challenge, server_challenge, 8);
4699 conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
4700 conn->smb1.server.name = talloc_move(conn, &server_name);
4702 conn->smb1.server.time_zone = server_time_zone;
4703 conn->smb1.server.system_time = server_system_time;
4705 tevent_req_done(req);
4708 static size_t smbXcli_padding_helper(uint32_t offset, size_t n)
4710 if ((offset & (n-1)) == 0) return 0;
4711 return n - (offset & (n-1));
4714 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state)
4716 size_t i;
4717 uint8_t *buf;
4718 uint16_t dialect_count = 0;
4719 DATA_BLOB dyn = data_blob_null;
4721 for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4722 bool ok;
4723 uint8_t val[2];
4725 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4726 continue;
4729 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4730 continue;
4733 SSVAL(val, 0, smb2cli_prots[i].smb2_dialect);
4735 ok = data_blob_append(state, &dyn, val, sizeof(val));
4736 if (!ok) {
4737 return NULL;
4740 dialect_count++;
4743 buf = state->smb2.fixed;
4744 SSVAL(buf, 0, 36);
4745 SSVAL(buf, 2, dialect_count);
4746 SSVAL(buf, 4, state->conn->smb2.client.security_mode);
4747 SSVAL(buf, 6, 0); /* Reserved */
4748 if (state->conn->max_protocol >= PROTOCOL_SMB2_22) {
4749 SIVAL(buf, 8, state->conn->smb2.client.capabilities);
4750 } else {
4751 SIVAL(buf, 8, 0); /* Capabilities */
4753 if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
4754 NTSTATUS status;
4755 struct GUID_ndr_buf guid_buf = { .buf = {0}, };
4757 status = GUID_to_ndr_buf(&state->conn->smb2.client.guid,
4758 &guid_buf);
4759 if (!NT_STATUS_IS_OK(status)) {
4760 return NULL;
4762 memcpy(buf+12, guid_buf.buf, 16); /* ClientGuid */
4763 } else {
4764 memset(buf+12, 0, 16); /* ClientGuid */
4767 if (state->conn->max_protocol >= PROTOCOL_SMB3_10) {
4768 NTSTATUS status;
4769 struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4770 uint8_t *netname_utf16 = NULL;
4771 size_t netname_utf16_len = 0;
4772 uint32_t offset;
4773 DATA_BLOB b;
4774 uint8_t p[38];
4775 const uint8_t zeros[8] = {0, };
4776 size_t pad;
4777 bool ok;
4779 SSVAL(p, 0, 1); /* HashAlgorithmCount */
4780 SSVAL(p, 2, 32); /* SaltLength */
4781 SSVAL(p, 4, SMB2_PREAUTH_INTEGRITY_SHA512);
4782 generate_random_buffer(p + 6, 32);
4784 status = smb2_negotiate_context_add(
4785 state, &c, SMB2_PREAUTH_INTEGRITY_CAPABILITIES, p, 38);
4786 if (!NT_STATUS_IS_OK(status)) {
4787 return NULL;
4790 SSVAL(p, 0, 2); /* ChiperCount */
4792 SSVAL(p, 2, SMB2_ENCRYPTION_AES128_GCM);
4793 SSVAL(p, 4, SMB2_ENCRYPTION_AES128_CCM);
4795 status = smb2_negotiate_context_add(
4796 state, &c, SMB2_ENCRYPTION_CAPABILITIES, p, 6);
4797 if (!NT_STATUS_IS_OK(status)) {
4798 return NULL;
4801 ok = convert_string_talloc(state, CH_UNIX, CH_UTF16,
4802 state->conn->remote_name,
4803 strlen(state->conn->remote_name),
4804 &netname_utf16, &netname_utf16_len);
4805 if (!ok) {
4806 return NULL;
4809 status = smb2_negotiate_context_add(state, &c,
4810 SMB2_NETNAME_NEGOTIATE_CONTEXT_ID,
4811 netname_utf16, netname_utf16_len);
4812 if (!NT_STATUS_IS_OK(status)) {
4813 return NULL;
4816 status = smb2_negotiate_context_push(state, &b, c);
4817 if (!NT_STATUS_IS_OK(status)) {
4818 return NULL;
4821 offset = SMB2_HDR_BODY + sizeof(state->smb2.fixed) + dyn.length;
4822 pad = smbXcli_padding_helper(offset, 8);
4824 ok = data_blob_append(state, &dyn, zeros, pad);
4825 if (!ok) {
4826 return NULL;
4828 offset += pad;
4830 ok = data_blob_append(state, &dyn, b.data, b.length);
4831 if (!ok) {
4832 return NULL;
4835 SIVAL(buf, 28, offset); /* NegotiateContextOffset */
4836 SSVAL(buf, 32, c.num_contexts); /* NegotiateContextCount */
4837 SSVAL(buf, 34, 0); /* Reserved */
4838 } else {
4839 SBVAL(buf, 28, 0); /* Reserved/ClientStartTime */
4842 return smb2cli_req_send(state, state->ev,
4843 state->conn, SMB2_OP_NEGPROT,
4844 0, 0, /* flags */
4845 state->timeout_msec,
4846 NULL, NULL, /* tcon, session */
4847 state->smb2.fixed, sizeof(state->smb2.fixed),
4848 dyn.data, dyn.length,
4849 UINT16_MAX); /* max_dyn_len */
4852 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
4854 struct tevent_req *req =
4855 tevent_req_callback_data(subreq,
4856 struct tevent_req);
4857 struct smbXcli_negprot_state *state =
4858 tevent_req_data(req,
4859 struct smbXcli_negprot_state);
4860 struct smbXcli_conn *conn = state->conn;
4861 size_t security_offset, security_length;
4862 DATA_BLOB blob;
4863 NTSTATUS status;
4864 struct iovec *iov = NULL;
4865 uint8_t *body;
4866 size_t i;
4867 uint16_t dialect_revision;
4868 struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4869 uint32_t negotiate_context_offset = 0;
4870 uint16_t negotiate_context_count = 0;
4871 DATA_BLOB negotiate_context_blob = data_blob_null;
4872 size_t avail;
4873 size_t ctx_ofs;
4874 size_t needed;
4875 struct smb2_negotiate_context *preauth = NULL;
4876 uint16_t hash_count;
4877 uint16_t salt_length;
4878 uint16_t hash_selected;
4879 gnutls_hash_hd_t hash_hnd = NULL;
4880 struct smb2_negotiate_context *cipher = NULL;
4881 struct iovec sent_iov[3] = {{0}, {0}, {0}};
4882 static const struct smb2cli_req_expected_response expected[] = {
4884 .status = NT_STATUS_OK,
4885 .body_size = 0x41
4888 int rc;
4890 status = smb2cli_req_recv(subreq, state, &iov,
4891 expected, ARRAY_SIZE(expected));
4892 if (tevent_req_nterror(req, status) || iov == NULL) {
4893 return;
4896 body = (uint8_t *)iov[1].iov_base;
4898 dialect_revision = SVAL(body, 4);
4900 for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4901 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4902 continue;
4905 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4906 continue;
4909 if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
4910 continue;
4913 conn->protocol = smb2cli_prots[i].proto;
4914 break;
4917 if (conn->protocol == PROTOCOL_NONE) {
4918 TALLOC_FREE(subreq);
4920 if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
4921 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4922 return;
4925 if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
4926 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4927 return;
4930 /* make sure we do not loop forever */
4931 state->conn->min_protocol = PROTOCOL_SMB2_02;
4934 * send a SMB2 negprot, in order to negotiate
4935 * the SMB2 dialect.
4937 subreq = smbXcli_negprot_smb2_subreq(state);
4938 if (tevent_req_nomem(subreq, req)) {
4939 return;
4941 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4942 return;
4945 conn->smb2.server.security_mode = SVAL(body, 2);
4946 if (conn->protocol >= PROTOCOL_SMB3_10) {
4947 negotiate_context_count = SVAL(body, 6);
4950 blob = data_blob_const(body + 8, 16);
4951 status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
4952 if (tevent_req_nterror(req, status)) {
4953 return;
4956 conn->smb2.server.capabilities = IVAL(body, 24);
4957 conn->smb2.server.max_trans_size= IVAL(body, 28);
4958 conn->smb2.server.max_read_size = IVAL(body, 32);
4959 conn->smb2.server.max_write_size= IVAL(body, 36);
4960 conn->smb2.server.system_time = BVAL(body, 40);
4961 conn->smb2.server.start_time = BVAL(body, 48);
4963 security_offset = SVAL(body, 56);
4964 security_length = SVAL(body, 58);
4966 if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
4967 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4968 return;
4971 if (security_length > iov[2].iov_len) {
4972 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4973 return;
4976 conn->smb2.server.gss_blob = data_blob_talloc(conn,
4977 iov[2].iov_base,
4978 security_length);
4979 if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
4980 return;
4983 if (conn->protocol < PROTOCOL_SMB3_10) {
4984 TALLOC_FREE(subreq);
4986 if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
4987 conn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
4989 tevent_req_done(req);
4990 return;
4994 * Here we are now at SMB3_11, so encryption should be
4995 * negotiated via context, not capabilities.
4998 if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
5000 * Server set SMB2_CAP_ENCRYPTION capability,
5001 * but *SHOULD* not, not *MUST* not. Just mask it off.
5002 * NetApp seems to do this:
5003 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13009
5005 conn->smb2.server.capabilities &= ~SMB2_CAP_ENCRYPTION;
5008 negotiate_context_offset = IVAL(body, 60);
5009 if (negotiate_context_offset < security_offset) {
5010 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5011 return;
5014 ctx_ofs = negotiate_context_offset - security_offset;
5015 if (ctx_ofs > iov[2].iov_len) {
5016 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5017 return;
5019 avail = iov[2].iov_len - security_length;
5020 needed = iov[2].iov_len - ctx_ofs;
5021 if (needed > avail) {
5022 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5023 return;
5026 negotiate_context_blob.data = (uint8_t *)iov[2].iov_base;
5027 negotiate_context_blob.length = iov[2].iov_len;
5029 negotiate_context_blob.data += ctx_ofs;
5030 negotiate_context_blob.length -= ctx_ofs;
5032 status = smb2_negotiate_context_parse(state, negotiate_context_blob, &c);
5033 if (tevent_req_nterror(req, status)) {
5034 return;
5037 if (negotiate_context_count != c.num_contexts) {
5038 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5039 return;
5042 preauth = smb2_negotiate_context_find(&c,
5043 SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
5044 if (preauth == NULL) {
5045 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5046 return;
5049 if (preauth->data.length < 6) {
5050 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5051 return;
5054 hash_count = SVAL(preauth->data.data, 0);
5055 salt_length = SVAL(preauth->data.data, 2);
5056 hash_selected = SVAL(preauth->data.data, 4);
5058 if (hash_count != 1) {
5059 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5060 return;
5063 if (preauth->data.length != (6 + salt_length)) {
5064 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5065 return;
5068 if (hash_selected != SMB2_PREAUTH_INTEGRITY_SHA512) {
5069 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5070 return;
5073 cipher = smb2_negotiate_context_find(&c, SMB2_ENCRYPTION_CAPABILITIES);
5074 if (cipher != NULL) {
5075 uint16_t cipher_count;
5077 if (cipher->data.length < 2) {
5078 tevent_req_nterror(req,
5079 NT_STATUS_INVALID_NETWORK_RESPONSE);
5080 return;
5083 cipher_count = SVAL(cipher->data.data, 0);
5085 if (cipher_count > 1) {
5086 tevent_req_nterror(req,
5087 NT_STATUS_INVALID_NETWORK_RESPONSE);
5088 return;
5091 if (cipher->data.length < (2 + 2 * cipher_count)) {
5092 tevent_req_nterror(req,
5093 NT_STATUS_INVALID_NETWORK_RESPONSE);
5094 return;
5097 if (cipher_count == 1) {
5098 uint16_t cipher_selected;
5100 cipher_selected = SVAL(cipher->data.data, 2);
5102 switch (cipher_selected) {
5103 case SMB2_ENCRYPTION_AES128_GCM:
5104 case SMB2_ENCRYPTION_AES128_CCM:
5105 conn->smb2.server.cipher = cipher_selected;
5106 break;
5111 /* First we hash the request */
5112 smb2cli_req_get_sent_iov(subreq, sent_iov);
5114 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
5115 if (rc < 0) {
5116 tevent_req_nterror(req,
5117 gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5118 return;
5121 rc = gnutls_hash(hash_hnd,
5122 conn->smb2.preauth_sha512,
5123 sizeof(conn->smb2.preauth_sha512));
5124 if (rc < 0) {
5125 gnutls_hash_deinit(hash_hnd, NULL);
5126 tevent_req_nterror(req,
5127 gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5128 return;
5130 for (i = 0; i < 3; i++) {
5131 rc = gnutls_hash(hash_hnd,
5132 sent_iov[i].iov_base,
5133 sent_iov[i].iov_len);
5134 if (rc < 0) {
5135 gnutls_hash_deinit(hash_hnd, NULL);
5136 tevent_req_nterror(req,
5137 gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5138 return;
5142 if (rc < 0) {
5143 gnutls_hash_deinit(hash_hnd, NULL);
5144 tevent_req_nterror(req,
5145 gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5146 return;
5149 /* This resets the hash state */
5150 gnutls_hash_output(hash_hnd, conn->smb2.preauth_sha512);
5151 TALLOC_FREE(subreq);
5153 /* And now we hash the response */
5154 rc = gnutls_hash(hash_hnd,
5155 conn->smb2.preauth_sha512,
5156 sizeof(conn->smb2.preauth_sha512));
5157 if (rc < 0) {
5158 gnutls_hash_deinit(hash_hnd, NULL);
5159 tevent_req_nterror(req,
5160 gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5161 return;
5163 for (i = 0; i < 3; i++) {
5164 rc = gnutls_hash(hash_hnd,
5165 iov[i].iov_base,
5166 iov[i].iov_len);
5167 if (rc < 0) {
5168 gnutls_hash_deinit(hash_hnd, NULL);
5169 tevent_req_nterror(req,
5170 gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5171 return;
5174 gnutls_hash_deinit(hash_hnd, conn->smb2.preauth_sha512);
5175 if (rc < 0) {
5176 tevent_req_nterror(req,
5177 NT_STATUS_UNSUCCESSFUL);
5178 return;
5181 tevent_req_done(req);
5184 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
5185 TALLOC_CTX *tmp_mem,
5186 uint8_t *inbuf)
5188 size_t num_pending = talloc_array_length(conn->pending);
5189 struct tevent_req *subreq;
5190 struct smbXcli_req_state *substate;
5191 struct tevent_req *req;
5192 uint32_t protocol_magic;
5193 size_t inbuf_len = smb_len_nbt(inbuf);
5195 if (num_pending != 1) {
5196 return NT_STATUS_INTERNAL_ERROR;
5199 if (inbuf_len < 4) {
5200 return NT_STATUS_INVALID_NETWORK_RESPONSE;
5203 subreq = conn->pending[0];
5204 substate = tevent_req_data(subreq, struct smbXcli_req_state);
5205 req = tevent_req_callback_data(subreq, struct tevent_req);
5207 protocol_magic = IVAL(inbuf, 4);
5209 switch (protocol_magic) {
5210 case SMB_MAGIC:
5211 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
5212 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
5213 return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5215 case SMB2_MAGIC:
5216 if (substate->smb2.recv_iov == NULL) {
5218 * For the SMB1 negprot we have move it.
5220 substate->smb2.recv_iov = substate->smb1.recv_iov;
5221 substate->smb1.recv_iov = NULL;
5225 * we got an SMB2 answer, which consumed sequence number 0
5226 * so we need to use 1 as the next one.
5228 * we also need to set the current credits to 0
5229 * as we consumed the initial one. The SMB2 answer
5230 * hopefully grant us a new credit.
5232 conn->smb2.mid = 1;
5233 conn->smb2.cur_credits = 0;
5234 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
5235 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
5236 return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5239 DEBUG(10, ("Got non-SMB PDU\n"));
5240 return NT_STATUS_INVALID_NETWORK_RESPONSE;
5243 NTSTATUS smbXcli_negprot_recv(struct tevent_req *req)
5245 return tevent_req_simple_recv_ntstatus(req);
5248 NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
5249 uint32_t timeout_msec,
5250 enum protocol_types min_protocol,
5251 enum protocol_types max_protocol)
5253 TALLOC_CTX *frame = talloc_stackframe();
5254 struct tevent_context *ev;
5255 struct tevent_req *req;
5256 NTSTATUS status = NT_STATUS_NO_MEMORY;
5257 bool ok;
5259 if (smbXcli_conn_has_async_calls(conn)) {
5261 * Can't use sync call while an async call is in flight
5263 status = NT_STATUS_INVALID_PARAMETER_MIX;
5264 goto fail;
5266 ev = samba_tevent_context_init(frame);
5267 if (ev == NULL) {
5268 goto fail;
5270 req = smbXcli_negprot_send(frame, ev, conn, timeout_msec,
5271 min_protocol, max_protocol,
5272 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
5273 if (req == NULL) {
5274 goto fail;
5276 ok = tevent_req_poll_ntstatus(req, ev, &status);
5277 if (!ok) {
5278 goto fail;
5280 status = smbXcli_negprot_recv(req);
5281 fail:
5282 TALLOC_FREE(frame);
5283 return status;
5286 struct smb2cli_validate_negotiate_info_state {
5287 struct smbXcli_conn *conn;
5288 DATA_BLOB in_input_buffer;
5289 DATA_BLOB in_output_buffer;
5290 DATA_BLOB out_input_buffer;
5291 DATA_BLOB out_output_buffer;
5292 uint16_t dialect;
5295 static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq);
5297 struct tevent_req *smb2cli_validate_negotiate_info_send(TALLOC_CTX *mem_ctx,
5298 struct tevent_context *ev,
5299 struct smbXcli_conn *conn,
5300 uint32_t timeout_msec,
5301 struct smbXcli_session *session,
5302 struct smbXcli_tcon *tcon)
5304 struct tevent_req *req;
5305 struct smb2cli_validate_negotiate_info_state *state;
5306 uint8_t *buf;
5307 uint16_t dialect_count = 0;
5308 struct tevent_req *subreq;
5309 bool _save_should_sign;
5310 size_t i;
5312 req = tevent_req_create(mem_ctx, &state,
5313 struct smb2cli_validate_negotiate_info_state);
5314 if (req == NULL) {
5315 return NULL;
5317 state->conn = conn;
5319 state->in_input_buffer = data_blob_talloc_zero(state,
5320 4 + 16 + 1 + 1 + 2);
5321 if (tevent_req_nomem(state->in_input_buffer.data, req)) {
5322 return tevent_req_post(req, ev);
5324 buf = state->in_input_buffer.data;
5326 if (state->conn->max_protocol >= PROTOCOL_SMB2_22) {
5327 SIVAL(buf, 0, conn->smb2.client.capabilities);
5328 } else {
5329 SIVAL(buf, 0, 0); /* Capabilities */
5331 if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
5332 NTSTATUS status;
5333 struct GUID_ndr_buf guid_buf = { .buf = {0}, };
5335 status = GUID_to_ndr_buf(&conn->smb2.client.guid,
5336 &guid_buf);
5337 if (!NT_STATUS_IS_OK(status)) {
5338 return NULL;
5340 memcpy(buf+4, guid_buf.buf, 16); /* ClientGuid */
5341 } else {
5342 memset(buf+4, 0, 16); /* ClientGuid */
5344 if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5345 SCVAL(buf, 20, conn->smb2.client.security_mode);
5346 } else {
5347 SCVAL(buf, 20, 0);
5349 SCVAL(buf, 21, 0); /* reserved */
5351 for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5352 bool ok;
5353 size_t ofs;
5355 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5356 continue;
5359 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5360 continue;
5363 if (smb2cli_prots[i].proto == state->conn->protocol) {
5364 state->dialect = smb2cli_prots[i].smb2_dialect;
5367 ofs = state->in_input_buffer.length;
5368 ok = data_blob_realloc(state, &state->in_input_buffer,
5369 ofs + 2);
5370 if (!ok) {
5371 tevent_req_oom(req);
5372 return tevent_req_post(req, ev);
5375 buf = state->in_input_buffer.data;
5376 SSVAL(buf, ofs, smb2cli_prots[i].smb2_dialect);
5378 dialect_count++;
5380 buf = state->in_input_buffer.data;
5381 SSVAL(buf, 22, dialect_count);
5383 _save_should_sign = smb2cli_tcon_is_signing_on(tcon);
5384 smb2cli_tcon_should_sign(tcon, true);
5385 subreq = smb2cli_ioctl_send(state, ev, conn,
5386 timeout_msec, session, tcon,
5387 UINT64_MAX, /* in_fid_persistent */
5388 UINT64_MAX, /* in_fid_volatile */
5389 FSCTL_VALIDATE_NEGOTIATE_INFO,
5390 0, /* in_max_input_length */
5391 &state->in_input_buffer,
5392 24, /* in_max_output_length */
5393 &state->in_output_buffer,
5394 SMB2_IOCTL_FLAG_IS_FSCTL);
5395 smb2cli_tcon_should_sign(tcon, _save_should_sign);
5396 if (tevent_req_nomem(subreq, req)) {
5397 return tevent_req_post(req, ev);
5399 tevent_req_set_callback(subreq,
5400 smb2cli_validate_negotiate_info_done,
5401 req);
5403 return req;
5406 static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
5408 struct tevent_req *req =
5409 tevent_req_callback_data(subreq,
5410 struct tevent_req);
5411 struct smb2cli_validate_negotiate_info_state *state =
5412 tevent_req_data(req,
5413 struct smb2cli_validate_negotiate_info_state);
5414 NTSTATUS status;
5415 const uint8_t *buf;
5416 uint32_t capabilities;
5417 DATA_BLOB guid_blob;
5418 struct GUID server_guid;
5419 uint16_t security_mode;
5420 uint16_t dialect;
5422 status = smb2cli_ioctl_recv(subreq, state,
5423 &state->out_input_buffer,
5424 &state->out_output_buffer);
5425 TALLOC_FREE(subreq);
5426 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
5428 * The response was signed, but not supported
5430 * Older Windows and Samba releases return
5431 * NT_STATUS_FILE_CLOSED.
5433 tevent_req_done(req);
5434 return;
5436 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
5438 * The response was signed, but not supported
5440 * This is returned by the NTVFS based Samba 4.x file server
5441 * for file shares.
5443 tevent_req_done(req);
5444 return;
5446 if (NT_STATUS_EQUAL(status, NT_STATUS_FS_DRIVER_REQUIRED)) {
5448 * The response was signed, but not supported
5450 * This is returned by the NTVFS based Samba 4.x file server
5451 * for ipc shares.
5453 tevent_req_done(req);
5454 return;
5456 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
5458 * The response was signed, but not supported
5460 * This might be returned by older Windows versions or by
5461 * NetApp SMB server implementations.
5463 * See
5465 * https://blogs.msdn.microsoft.com/openspecification/2012/06/28/smb3-secure-dialect-negotiation/
5468 tevent_req_done(req);
5469 return;
5471 if (tevent_req_nterror(req, status)) {
5472 return;
5475 if (state->out_output_buffer.length != 24) {
5476 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5477 return;
5480 buf = state->out_output_buffer.data;
5482 capabilities = IVAL(buf, 0);
5483 guid_blob = data_blob_const(buf + 4, 16);
5484 status = GUID_from_data_blob(&guid_blob, &server_guid);
5485 if (tevent_req_nterror(req, status)) {
5486 return;
5488 security_mode = CVAL(buf, 20);
5489 dialect = SVAL(buf, 22);
5491 if (capabilities != state->conn->smb2.server.capabilities) {
5492 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5493 return;
5496 if (!GUID_equal(&server_guid, &state->conn->smb2.server.guid)) {
5497 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5498 return;
5501 if (security_mode != state->conn->smb2.server.security_mode) {
5502 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5503 return;
5506 if (dialect != state->dialect) {
5507 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5508 return;
5511 tevent_req_done(req);
5514 NTSTATUS smb2cli_validate_negotiate_info_recv(struct tevent_req *req)
5516 return tevent_req_simple_recv_ntstatus(req);
5519 static int smbXcli_session_destructor(struct smbXcli_session *session)
5521 if (session->conn == NULL) {
5522 return 0;
5525 DLIST_REMOVE(session->conn->sessions, session);
5526 return 0;
5529 struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
5530 struct smbXcli_conn *conn)
5532 struct smbXcli_session *session;
5534 session = talloc_zero(mem_ctx, struct smbXcli_session);
5535 if (session == NULL) {
5536 return NULL;
5538 session->smb2 = talloc_zero(session, struct smb2cli_session);
5539 if (session->smb2 == NULL) {
5540 talloc_free(session);
5541 return NULL;
5543 talloc_set_destructor(session, smbXcli_session_destructor);
5545 session->smb2->signing_key = talloc_zero(session,
5546 struct smb2_signing_key);
5547 if (session->smb2->signing_key == NULL) {
5548 talloc_free(session);
5549 return NULL;
5551 talloc_set_destructor(session->smb2->signing_key,
5552 smb2_signing_key_destructor);
5554 DLIST_ADD_END(conn->sessions, session);
5555 session->conn = conn;
5557 session->smb2_channel.signing_key =
5558 talloc_zero(session, struct smb2_signing_key);
5559 if (session->smb2_channel.signing_key == NULL) {
5560 talloc_free(session);
5561 return NULL;
5563 talloc_set_destructor(session->smb2_channel.signing_key,
5564 smb2_signing_key_destructor);
5566 memcpy(session->smb2_channel.preauth_sha512,
5567 conn->smb2.preauth_sha512,
5568 sizeof(session->smb2_channel.preauth_sha512));
5570 return session;
5573 struct smbXcli_session *smbXcli_session_shallow_copy(TALLOC_CTX *mem_ctx,
5574 struct smbXcli_session *src)
5576 struct smbXcli_session *session;
5577 struct timespec ts;
5578 NTTIME nt;
5580 session = talloc_zero(mem_ctx, struct smbXcli_session);
5581 if (session == NULL) {
5582 return NULL;
5584 session->smb2 = talloc_zero(session, struct smb2cli_session);
5585 if (session->smb2 == NULL) {
5586 talloc_free(session);
5587 return NULL;
5591 * Note we keep a pointer to the session keys of the
5592 * main session and rely on the caller to free the
5593 * shallow copy first!
5595 session->conn = src->conn;
5596 *session->smb2 = *src->smb2;
5597 session->smb2_channel = src->smb2_channel;
5598 session->disconnect_expired = src->disconnect_expired;
5601 * This is only supposed to be called in test code
5602 * but we should not reuse nonces!
5604 * Add the current timestamp as NTTIME to nonce_high
5605 * and set nonce_low to a value we can recognize in captures.
5607 clock_gettime_mono(&ts);
5608 nt = unix_timespec_to_nt_time(ts);
5609 nt &= session->smb2->nonce_high_max;
5610 if (nt == session->smb2->nonce_high_max || nt < UINT8_MAX) {
5611 talloc_free(session);
5612 return NULL;
5614 session->smb2->nonce_high += nt;
5615 session->smb2->nonce_low = UINT32_MAX;
5617 DLIST_ADD_END(src->conn->sessions, session);
5618 talloc_set_destructor(session, smbXcli_session_destructor);
5620 return session;
5623 bool smbXcli_session_is_guest(struct smbXcli_session *session)
5625 if (session == NULL) {
5626 return false;
5629 if (session->conn == NULL) {
5630 return false;
5633 if (session->conn->mandatory_signing) {
5634 return false;
5637 if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5638 if (session->smb2->session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
5639 return true;
5641 return false;
5644 if (session->smb1.action & SMB_SETUP_GUEST) {
5645 return true;
5648 return false;
5651 bool smbXcli_session_is_authenticated(struct smbXcli_session *session)
5653 const DATA_BLOB *application_key;
5655 if (session == NULL) {
5656 return false;
5659 if (session->conn == NULL) {
5660 return false;
5664 * If we have an application key we had a session key negotiated
5665 * at auth time.
5667 if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5668 application_key = &session->smb2->application_key;
5669 } else {
5670 application_key = &session->smb1.application_key;
5673 if (application_key->length == 0) {
5674 return false;
5677 return true;
5680 NTSTATUS smb2cli_session_signing_key(struct smbXcli_session *session,
5681 TALLOC_CTX *mem_ctx,
5682 DATA_BLOB *key)
5684 const struct smb2_signing_key *sig = NULL;
5686 if (session->conn == NULL) {
5687 return NT_STATUS_NO_USER_SESSION_KEY;
5691 * Use channel signing key if there is one, otherwise fallback
5692 * to session.
5695 if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
5696 sig = session->smb2_channel.signing_key;
5697 } else if (smb2_signing_key_valid(session->smb2->signing_key)) {
5698 sig = session->smb2->signing_key;
5699 } else {
5700 return NT_STATUS_NO_USER_SESSION_KEY;
5703 *key = data_blob_dup_talloc(mem_ctx, sig->blob);
5704 if (key->data == NULL) {
5705 return NT_STATUS_NO_MEMORY;
5708 return NT_STATUS_OK;
5711 NTSTATUS smb2cli_session_encryption_key(struct smbXcli_session *session,
5712 TALLOC_CTX *mem_ctx,
5713 DATA_BLOB *key)
5715 if (session->conn == NULL) {
5716 return NT_STATUS_NO_USER_SESSION_KEY;
5719 if (session->conn->protocol < PROTOCOL_SMB3_00) {
5720 return NT_STATUS_NO_USER_SESSION_KEY;
5723 if (!smb2_signing_key_valid(session->smb2->encryption_key)) {
5724 return NT_STATUS_NO_USER_SESSION_KEY;
5727 *key = data_blob_dup_talloc(mem_ctx, session->smb2->encryption_key->blob);
5728 if (key->data == NULL) {
5729 return NT_STATUS_NO_MEMORY;
5732 return NT_STATUS_OK;
5735 NTSTATUS smb2cli_session_decryption_key(struct smbXcli_session *session,
5736 TALLOC_CTX *mem_ctx,
5737 DATA_BLOB *key)
5739 if (session->conn == NULL) {
5740 return NT_STATUS_NO_USER_SESSION_KEY;
5743 if (session->conn->protocol < PROTOCOL_SMB3_00) {
5744 return NT_STATUS_NO_USER_SESSION_KEY;
5747 if (!smb2_signing_key_valid(session->smb2->decryption_key)) {
5748 return NT_STATUS_NO_USER_SESSION_KEY;
5751 *key = data_blob_dup_talloc(mem_ctx, session->smb2->decryption_key->blob);
5752 if (key->data == NULL) {
5753 return NT_STATUS_NO_MEMORY;
5756 return NT_STATUS_OK;
5759 NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
5760 TALLOC_CTX *mem_ctx,
5761 DATA_BLOB *key)
5763 const DATA_BLOB *application_key;
5765 *key = data_blob_null;
5767 if (session->conn == NULL) {
5768 return NT_STATUS_NO_USER_SESSION_KEY;
5771 if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5772 application_key = &session->smb2->application_key;
5773 } else {
5774 application_key = &session->smb1.application_key;
5777 if (application_key->length == 0) {
5778 return NT_STATUS_NO_USER_SESSION_KEY;
5781 *key = data_blob_dup_talloc(mem_ctx, *application_key);
5782 if (key->data == NULL) {
5783 return NT_STATUS_NO_MEMORY;
5786 return NT_STATUS_OK;
5789 void smbXcli_session_set_disconnect_expired(struct smbXcli_session *session)
5791 session->disconnect_expired = true;
5794 uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
5796 return session->smb1.session_id;
5799 void smb1cli_session_set_id(struct smbXcli_session *session,
5800 uint16_t session_id)
5802 session->smb1.session_id = session_id;
5805 void smb1cli_session_set_action(struct smbXcli_session *session,
5806 uint16_t action)
5808 session->smb1.action = action;
5811 NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
5812 const DATA_BLOB _session_key)
5814 struct smbXcli_conn *conn = session->conn;
5815 uint8_t session_key[16];
5817 if (conn == NULL) {
5818 return NT_STATUS_INVALID_PARAMETER_MIX;
5821 if (session->smb1.application_key.length != 0) {
5823 * TODO: do not allow this...
5825 * return NT_STATUS_INVALID_PARAMETER_MIX;
5827 data_blob_clear_free(&session->smb1.application_key);
5828 session->smb1.protected_key = false;
5831 if (_session_key.length == 0) {
5832 return NT_STATUS_OK;
5835 ZERO_STRUCT(session_key);
5836 memcpy(session_key, _session_key.data,
5837 MIN(_session_key.length, sizeof(session_key)));
5839 session->smb1.application_key = data_blob_talloc(session,
5840 session_key,
5841 sizeof(session_key));
5842 ZERO_STRUCT(session_key);
5843 if (session->smb1.application_key.data == NULL) {
5844 return NT_STATUS_NO_MEMORY;
5847 session->smb1.protected_key = false;
5849 return NT_STATUS_OK;
5852 NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
5854 NTSTATUS status;
5856 if (session->smb1.protected_key) {
5857 /* already protected */
5858 return NT_STATUS_OK;
5861 if (session->smb1.application_key.length != 16) {
5862 return NT_STATUS_INVALID_PARAMETER_MIX;
5865 status = smb_key_derivation(session->smb1.application_key.data,
5866 session->smb1.application_key.length,
5867 session->smb1.application_key.data);
5868 if (!NT_STATUS_IS_OK(status)) {
5869 return status;
5872 session->smb1.protected_key = true;
5874 return NT_STATUS_OK;
5877 uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
5879 struct smbXcli_conn *conn = session->conn;
5880 uint8_t security_mode = 0;
5882 if (conn == NULL) {
5883 return security_mode;
5886 security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
5887 if (conn->mandatory_signing) {
5888 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
5890 if (session->smb2->should_sign) {
5891 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
5894 return security_mode;
5897 uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
5899 return session->smb2->session_id;
5902 uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
5904 return session->smb2->session_flags;
5907 void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
5908 uint64_t session_id,
5909 uint16_t session_flags)
5911 session->smb2->session_id = session_id;
5912 session->smb2->session_flags = session_flags;
5915 void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
5917 session->smb2->channel_sequence += 1;
5920 uint16_t smb2cli_session_reset_channel_sequence(struct smbXcli_session *session,
5921 uint16_t channel_sequence)
5923 uint16_t prev_cs;
5925 prev_cs = session->smb2->channel_sequence;
5926 session->smb2->channel_sequence = channel_sequence;
5928 return prev_cs;
5931 uint16_t smb2cli_session_current_channel_sequence(struct smbXcli_session *session)
5933 return session->smb2->channel_sequence;
5936 void smb2cli_session_start_replay(struct smbXcli_session *session)
5938 session->smb2->replay_active = true;
5941 void smb2cli_session_stop_replay(struct smbXcli_session *session)
5943 session->smb2->replay_active = false;
5946 void smb2cli_session_require_signed_response(struct smbXcli_session *session,
5947 bool require_signed_response)
5949 session->smb2->require_signed_response = require_signed_response;
5952 NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
5953 const struct iovec *iov)
5955 gnutls_hash_hd_t hash_hnd = NULL;
5956 size_t i;
5957 int rc;
5959 if (session->conn == NULL) {
5960 return NT_STATUS_INTERNAL_ERROR;
5963 if (session->conn->protocol < PROTOCOL_SMB3_10) {
5964 return NT_STATUS_OK;
5967 if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
5968 return NT_STATUS_OK;
5971 rc = gnutls_hash_init(&hash_hnd,
5972 GNUTLS_DIG_SHA512);
5973 if (rc < 0) {
5974 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
5977 rc = gnutls_hash(hash_hnd,
5978 session->smb2_channel.preauth_sha512,
5979 sizeof(session->smb2_channel.preauth_sha512));
5980 if (rc < 0) {
5981 gnutls_hash_deinit(hash_hnd, NULL);
5982 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
5984 for (i = 0; i < 3; i++) {
5985 rc = gnutls_hash(hash_hnd,
5986 iov[i].iov_base,
5987 iov[i].iov_len);
5988 if (rc < 0) {
5989 gnutls_hash_deinit(hash_hnd, NULL);
5990 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
5993 gnutls_hash_deinit(hash_hnd, session->smb2_channel.preauth_sha512);
5995 return NT_STATUS_OK;
5998 NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
5999 const DATA_BLOB _session_key,
6000 const struct iovec *recv_iov)
6002 struct smbXcli_conn *conn = session->conn;
6003 uint16_t no_sign_flags = 0;
6004 uint8_t session_key[16];
6005 bool check_signature = true;
6006 uint32_t hdr_flags;
6007 NTSTATUS status;
6008 struct _derivation {
6009 DATA_BLOB label;
6010 DATA_BLOB context;
6012 struct {
6013 struct _derivation signing;
6014 struct _derivation encryption;
6015 struct _derivation decryption;
6016 struct _derivation application;
6017 } derivation = {
6018 .signing.label.length = 0,
6020 size_t nonce_size = 0;
6022 if (conn == NULL) {
6023 return NT_STATUS_INVALID_PARAMETER_MIX;
6026 if (recv_iov[0].iov_len != SMB2_HDR_BODY) {
6027 return NT_STATUS_INVALID_PARAMETER_MIX;
6030 if (!conn->mandatory_signing) {
6032 * only allow guest sessions without
6033 * mandatory signing.
6035 * If we try an authentication with username != ""
6036 * and the server let us in without verifying the
6037 * password we don't have a negotiated session key
6038 * for signing.
6040 no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST;
6043 if (session->smb2->session_flags & no_sign_flags) {
6044 session->smb2->should_sign = false;
6045 return NT_STATUS_OK;
6048 if (smb2_signing_key_valid(session->smb2->signing_key)) {
6049 return NT_STATUS_INVALID_PARAMETER_MIX;
6052 if (conn->protocol >= PROTOCOL_SMB3_10) {
6053 struct _derivation *d;
6054 DATA_BLOB p;
6056 p = data_blob_const(session->smb2_channel.preauth_sha512,
6057 sizeof(session->smb2_channel.preauth_sha512));
6059 d = &derivation.signing;
6060 d->label = data_blob_string_const_null("SMBSigningKey");
6061 d->context = p;
6063 d = &derivation.encryption;
6064 d->label = data_blob_string_const_null("SMBC2SCipherKey");
6065 d->context = p;
6067 d = &derivation.decryption;
6068 d->label = data_blob_string_const_null("SMBS2CCipherKey");
6069 d->context = p;
6071 d = &derivation.application;
6072 d->label = data_blob_string_const_null("SMBAppKey");
6073 d->context = p;
6075 } else if (conn->protocol >= PROTOCOL_SMB2_24) {
6076 struct _derivation *d;
6078 d = &derivation.signing;
6079 d->label = data_blob_string_const_null("SMB2AESCMAC");
6080 d->context = data_blob_string_const_null("SmbSign");
6082 d = &derivation.encryption;
6083 d->label = data_blob_string_const_null("SMB2AESCCM");
6084 d->context = data_blob_string_const_null("ServerIn ");
6086 d = &derivation.decryption;
6087 d->label = data_blob_string_const_null("SMB2AESCCM");
6088 d->context = data_blob_string_const_null("ServerOut");
6090 d = &derivation.application;
6091 d->label = data_blob_string_const_null("SMB2APP");
6092 d->context = data_blob_string_const_null("SmbRpc");
6095 ZERO_STRUCT(session_key);
6096 memcpy(session_key, _session_key.data,
6097 MIN(_session_key.length, sizeof(session_key)));
6099 session->smb2->signing_key->blob =
6100 data_blob_talloc(session->smb2->signing_key,
6101 session_key,
6102 sizeof(session_key));
6103 if (!smb2_signing_key_valid(session->smb2->signing_key)) {
6104 ZERO_STRUCT(session_key);
6105 return NT_STATUS_NO_MEMORY;
6108 if (conn->protocol >= PROTOCOL_SMB2_24) {
6109 struct _derivation *d = &derivation.signing;
6111 status = smb2_key_derivation(session_key, sizeof(session_key),
6112 d->label.data, d->label.length,
6113 d->context.data, d->context.length,
6114 session->smb2->signing_key->blob.data);
6115 if (!NT_STATUS_IS_OK(status)) {
6116 return status;
6120 session->smb2->encryption_key =
6121 talloc_zero(session, struct smb2_signing_key);
6122 if (session->smb2->encryption_key == NULL) {
6123 ZERO_STRUCT(session_key);
6124 return NT_STATUS_NO_MEMORY;
6126 talloc_set_destructor(session->smb2->encryption_key,
6127 smb2_signing_key_destructor);
6129 session->smb2->encryption_key->blob =
6130 data_blob_dup_talloc(session->smb2->encryption_key,
6131 session->smb2->signing_key->blob);
6132 if (!smb2_signing_key_valid(session->smb2->encryption_key)) {
6133 ZERO_STRUCT(session_key);
6134 return NT_STATUS_NO_MEMORY;
6137 if (conn->protocol >= PROTOCOL_SMB2_24) {
6138 struct _derivation *d = &derivation.encryption;
6140 status = smb2_key_derivation(session_key, sizeof(session_key),
6141 d->label.data, d->label.length,
6142 d->context.data, d->context.length,
6143 session->smb2->encryption_key->blob.data);
6144 if (!NT_STATUS_IS_OK(status)) {
6145 return status;
6149 session->smb2->decryption_key =
6150 talloc_zero(session, struct smb2_signing_key);
6151 if (session->smb2->decryption_key == NULL) {
6152 ZERO_STRUCT(session_key);
6153 return NT_STATUS_NO_MEMORY;
6155 talloc_set_destructor(session->smb2->decryption_key,
6156 smb2_signing_key_destructor);
6158 session->smb2->decryption_key->blob =
6159 data_blob_dup_talloc(session->smb2->decryption_key,
6160 session->smb2->signing_key->blob);
6161 if (!smb2_signing_key_valid(session->smb2->decryption_key)) {
6162 ZERO_STRUCT(session_key);
6163 return NT_STATUS_NO_MEMORY;
6166 if (conn->protocol >= PROTOCOL_SMB2_24) {
6167 struct _derivation *d = &derivation.decryption;
6169 status = smb2_key_derivation(session_key, sizeof(session_key),
6170 d->label.data, d->label.length,
6171 d->context.data, d->context.length,
6172 session->smb2->decryption_key->blob.data);
6173 if (!NT_STATUS_IS_OK(status)) {
6174 return status;
6178 session->smb2->application_key =
6179 data_blob_dup_talloc(session,
6180 session->smb2->signing_key->blob);
6181 if (session->smb2->application_key.data == NULL) {
6182 ZERO_STRUCT(session_key);
6183 return NT_STATUS_NO_MEMORY;
6186 if (conn->protocol >= PROTOCOL_SMB2_24) {
6187 struct _derivation *d = &derivation.application;
6189 status = smb2_key_derivation(session_key, sizeof(session_key),
6190 d->label.data, d->label.length,
6191 d->context.data, d->context.length,
6192 session->smb2->application_key.data);
6193 if (!NT_STATUS_IS_OK(status)) {
6194 return status;
6197 ZERO_STRUCT(session_key);
6199 session->smb2_channel.signing_key->blob =
6200 data_blob_dup_talloc(session->smb2_channel.signing_key,
6201 session->smb2->signing_key->blob);
6202 if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6203 return NT_STATUS_NO_MEMORY;
6206 check_signature = conn->mandatory_signing;
6208 hdr_flags = IVAL(recv_iov[0].iov_base, SMB2_HDR_FLAGS);
6209 if (hdr_flags & SMB2_HDR_FLAG_SIGNED) {
6211 * Sadly some vendors don't sign the
6212 * final SMB2 session setup response
6214 * At least Windows and Samba are always doing this
6215 * if there's a session key available.
6217 * We only check the signature if it's mandatory
6218 * or SMB2_HDR_FLAG_SIGNED is provided.
6220 check_signature = true;
6223 if (conn->protocol >= PROTOCOL_SMB3_10) {
6224 check_signature = true;
6227 if (check_signature) {
6228 status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
6229 session->conn->protocol,
6230 recv_iov, 3);
6231 if (!NT_STATUS_IS_OK(status)) {
6232 return status;
6236 session->smb2->should_sign = false;
6237 session->smb2->should_encrypt = false;
6239 if (conn->desire_signing) {
6240 session->smb2->should_sign = true;
6243 if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
6244 session->smb2->should_sign = true;
6247 if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
6248 session->smb2->should_encrypt = true;
6251 if (conn->protocol < PROTOCOL_SMB2_24) {
6252 session->smb2->should_encrypt = false;
6255 if (conn->smb2.server.cipher == 0) {
6256 session->smb2->should_encrypt = false;
6260 * CCM and GCM algorithms must never have their
6261 * nonce wrap, or the security of the whole
6262 * communication and the keys is destroyed.
6263 * We must drop the connection once we have
6264 * transfered too much data.
6266 * NOTE: We assume nonces greater than 8 bytes.
6268 generate_nonce_buffer((uint8_t *)&session->smb2->nonce_high_random,
6269 sizeof(session->smb2->nonce_high_random));
6270 switch (conn->smb2.server.cipher) {
6271 case SMB2_ENCRYPTION_AES128_CCM:
6272 nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
6273 break;
6274 case SMB2_ENCRYPTION_AES128_GCM:
6275 nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
6276 break;
6277 default:
6278 nonce_size = 0;
6279 break;
6281 session->smb2->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
6282 session->smb2->nonce_high = 0;
6283 session->smb2->nonce_low = 0;
6285 return NT_STATUS_OK;
6288 NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
6289 struct smbXcli_session *session1,
6290 struct smbXcli_conn *conn,
6291 struct smbXcli_session **_session2)
6293 struct smbXcli_session *session2;
6295 if (!smb2_signing_key_valid(session1->smb2->signing_key)) {
6296 return NT_STATUS_INVALID_PARAMETER_MIX;
6299 if (conn == NULL) {
6300 return NT_STATUS_INVALID_PARAMETER_MIX;
6303 session2 = talloc_zero(mem_ctx, struct smbXcli_session);
6304 if (session2 == NULL) {
6305 return NT_STATUS_NO_MEMORY;
6307 session2->smb2 = talloc_reference(session2, session1->smb2);
6308 if (session2->smb2 == NULL) {
6309 talloc_free(session2);
6310 return NT_STATUS_NO_MEMORY;
6313 talloc_set_destructor(session2, smbXcli_session_destructor);
6314 DLIST_ADD_END(conn->sessions, session2);
6315 session2->conn = conn;
6317 session2->smb2_channel.signing_key =
6318 talloc_zero(session2, struct smb2_signing_key);
6319 if (session2->smb2_channel.signing_key == NULL) {
6320 talloc_free(session2);
6321 return NT_STATUS_NO_MEMORY;
6323 talloc_set_destructor(session2->smb2_channel.signing_key,
6324 smb2_signing_key_destructor);
6326 memcpy(session2->smb2_channel.preauth_sha512,
6327 conn->smb2.preauth_sha512,
6328 sizeof(session2->smb2_channel.preauth_sha512));
6330 *_session2 = session2;
6331 return NT_STATUS_OK;
6334 NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
6335 const DATA_BLOB _channel_key,
6336 const struct iovec *recv_iov)
6338 struct smbXcli_conn *conn = session->conn;
6339 uint8_t channel_key[16];
6340 NTSTATUS status;
6341 struct _derivation {
6342 DATA_BLOB label;
6343 DATA_BLOB context;
6345 struct {
6346 struct _derivation signing;
6347 } derivation = {
6348 .signing.label.length = 0,
6351 if (conn == NULL) {
6352 return NT_STATUS_INVALID_PARAMETER_MIX;
6355 if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6356 return NT_STATUS_INVALID_PARAMETER_MIX;
6359 if (conn->protocol >= PROTOCOL_SMB3_10) {
6360 struct _derivation *d;
6361 DATA_BLOB p;
6363 p = data_blob_const(session->smb2_channel.preauth_sha512,
6364 sizeof(session->smb2_channel.preauth_sha512));
6366 d = &derivation.signing;
6367 d->label = data_blob_string_const_null("SMBSigningKey");
6368 d->context = p;
6369 } else if (conn->protocol >= PROTOCOL_SMB2_24) {
6370 struct _derivation *d;
6372 d = &derivation.signing;
6373 d->label = data_blob_string_const_null("SMB2AESCMAC");
6374 d->context = data_blob_string_const_null("SmbSign");
6377 ZERO_STRUCT(channel_key);
6378 memcpy(channel_key, _channel_key.data,
6379 MIN(_channel_key.length, sizeof(channel_key)));
6381 session->smb2_channel.signing_key->blob =
6382 data_blob_talloc(session->smb2_channel.signing_key,
6383 channel_key,
6384 sizeof(channel_key));
6385 if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6386 ZERO_STRUCT(channel_key);
6387 return NT_STATUS_NO_MEMORY;
6390 if (conn->protocol >= PROTOCOL_SMB2_24) {
6391 struct _derivation *d = &derivation.signing;
6393 status = smb2_key_derivation(channel_key, sizeof(channel_key),
6394 d->label.data, d->label.length,
6395 d->context.data, d->context.length,
6396 session->smb2_channel.signing_key->blob.data);
6397 if (!NT_STATUS_IS_OK(status)) {
6398 return status;
6401 ZERO_STRUCT(channel_key);
6403 status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
6404 session->conn->protocol,
6405 recv_iov, 3);
6406 if (!NT_STATUS_IS_OK(status)) {
6407 return status;
6410 return NT_STATUS_OK;
6413 NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
6415 if (!session->smb2->should_sign) {
6417 * We need required signing on the session
6418 * in order to prevent man in the middle attacks.
6420 return NT_STATUS_INVALID_PARAMETER_MIX;
6423 if (session->smb2->should_encrypt) {
6424 return NT_STATUS_OK;
6427 if (session->conn->protocol < PROTOCOL_SMB2_24) {
6428 return NT_STATUS_NOT_SUPPORTED;
6431 if (session->conn->smb2.server.cipher == 0) {
6432 return NT_STATUS_NOT_SUPPORTED;
6435 if (!smb2_signing_key_valid(session->smb2->signing_key)) {
6436 return NT_STATUS_NOT_SUPPORTED;
6438 session->smb2->should_encrypt = true;
6439 return NT_STATUS_OK;
6442 uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session)
6444 if (session->conn->protocol < PROTOCOL_SMB2_24) {
6445 return 0;
6448 if (!session->smb2->should_encrypt) {
6449 return 0;
6452 return session->conn->smb2.server.cipher;
6455 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
6457 struct smbXcli_tcon *tcon;
6459 tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
6460 if (tcon == NULL) {
6461 return NULL;
6464 return tcon;
6468 * Return a deep structure copy of a struct smbXcli_tcon *
6471 struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
6472 const struct smbXcli_tcon *tcon_in)
6474 struct smbXcli_tcon *tcon;
6476 tcon = talloc_memdup(mem_ctx, tcon_in, sizeof(struct smbXcli_tcon));
6477 if (tcon == NULL) {
6478 return NULL;
6481 /* Deal with the SMB1 strings. */
6482 if (tcon_in->smb1.service != NULL) {
6483 tcon->smb1.service = talloc_strdup(tcon, tcon_in->smb1.service);
6484 if (tcon->smb1.service == NULL) {
6485 TALLOC_FREE(tcon);
6486 return NULL;
6489 if (tcon->smb1.fs_type != NULL) {
6490 tcon->smb1.fs_type = talloc_strdup(tcon, tcon_in->smb1.fs_type);
6491 if (tcon->smb1.fs_type == NULL) {
6492 TALLOC_FREE(tcon);
6493 return NULL;
6496 return tcon;
6499 void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
6500 uint32_t fs_attributes)
6502 tcon->fs_attributes = fs_attributes;
6505 uint32_t smbXcli_tcon_get_fs_attributes(struct smbXcli_tcon *tcon)
6507 return tcon->fs_attributes;
6510 bool smbXcli_tcon_is_dfs_share(struct smbXcli_tcon *tcon)
6512 if (tcon == NULL) {
6513 return false;
6516 if (tcon->is_smb1) {
6517 if (tcon->smb1.optional_support & SMB_SHARE_IN_DFS) {
6518 return true;
6521 return false;
6524 if (tcon->smb2.capabilities & SMB2_SHARE_CAP_DFS) {
6525 return true;
6528 return false;
6531 uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
6533 return tcon->smb1.tcon_id;
6536 void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
6538 tcon->is_smb1 = true;
6539 tcon->smb1.tcon_id = tcon_id;
6542 bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
6543 uint16_t tcon_id,
6544 uint16_t optional_support,
6545 uint32_t maximal_access,
6546 uint32_t guest_maximal_access,
6547 const char *service,
6548 const char *fs_type)
6550 tcon->is_smb1 = true;
6551 tcon->fs_attributes = 0;
6552 tcon->smb1.tcon_id = tcon_id;
6553 tcon->smb1.optional_support = optional_support;
6554 tcon->smb1.maximal_access = maximal_access;
6555 tcon->smb1.guest_maximal_access = guest_maximal_access;
6557 TALLOC_FREE(tcon->smb1.service);
6558 tcon->smb1.service = talloc_strdup(tcon, service);
6559 if (service != NULL && tcon->smb1.service == NULL) {
6560 return false;
6563 TALLOC_FREE(tcon->smb1.fs_type);
6564 tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
6565 if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
6566 return false;
6569 return true;
6572 uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
6574 return tcon->smb2.tcon_id;
6577 void smb2cli_tcon_set_id(struct smbXcli_tcon *tcon, uint32_t tcon_id)
6579 tcon->smb2.tcon_id = tcon_id;
6582 uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
6584 return tcon->smb2.capabilities;
6587 uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon)
6589 return tcon->smb2.flags;
6592 void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
6593 struct smbXcli_session *session,
6594 uint32_t tcon_id,
6595 uint8_t type,
6596 uint32_t flags,
6597 uint32_t capabilities,
6598 uint32_t maximal_access)
6600 tcon->is_smb1 = false;
6601 tcon->fs_attributes = 0;
6602 tcon->smb2.tcon_id = tcon_id;
6603 tcon->smb2.type = type;
6604 tcon->smb2.flags = flags;
6605 tcon->smb2.capabilities = capabilities;
6606 tcon->smb2.maximal_access = maximal_access;
6608 tcon->smb2.should_sign = false;
6609 tcon->smb2.should_encrypt = false;
6611 if (session == NULL) {
6612 return;
6615 tcon->smb2.should_sign = session->smb2->should_sign;
6616 tcon->smb2.should_encrypt = session->smb2->should_encrypt;
6618 if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
6619 tcon->smb2.should_encrypt = true;
6623 void smb2cli_tcon_should_sign(struct smbXcli_tcon *tcon,
6624 bool should_sign)
6626 tcon->smb2.should_sign = should_sign;
6629 bool smb2cli_tcon_is_signing_on(struct smbXcli_tcon *tcon)
6631 if (tcon->smb2.should_encrypt) {
6632 return true;
6635 return tcon->smb2.should_sign;
6638 void smb2cli_tcon_should_encrypt(struct smbXcli_tcon *tcon,
6639 bool should_encrypt)
6641 tcon->smb2.should_encrypt = should_encrypt;
6644 bool smb2cli_tcon_is_encryption_on(struct smbXcli_tcon *tcon)
6646 return tcon->smb2.should_encrypt;
6649 void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid)
6651 conn->smb2.mid = mid;
6654 uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
6656 return conn->smb2.mid;