Line data Source code
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
6 :
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.
11 :
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.
16 :
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/>.
19 : */
20 :
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"
37 :
38 : #include "lib/crypto/gnutls_helpers.h"
39 : #include <gnutls/gnutls.h>
40 : #include <gnutls/crypto.h>
41 :
42 : struct smbXcli_conn;
43 : struct smbXcli_req;
44 : struct smbXcli_session;
45 : struct smbXcli_tcon;
46 :
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;
52 :
53 : struct tevent_queue *outgoing;
54 : struct tevent_req **pending;
55 : struct tevent_req *read_smb_req;
56 : struct tevent_req *suicide_req;
57 :
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;
64 :
65 : /*
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.
72 : */
73 : NTSTATUS (*dispatch_incoming)(struct smbXcli_conn *conn,
74 : TALLOC_CTX *tmp_mem,
75 : uint8_t *inbuf);
76 :
77 : struct {
78 : struct {
79 : uint32_t capabilities;
80 : uint32_t max_xmit;
81 : } client;
82 :
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;
101 :
102 : uint32_t capabilities;
103 : uint32_t max_xmit;
104 :
105 : uint16_t mid;
106 :
107 : struct smb1_signing_state *signing;
108 : struct smb_trans_enc_state *trans_enc;
109 :
110 : struct tevent_req *read_braw_req;
111 : } smb1;
112 :
113 : struct {
114 : struct {
115 : uint32_t capabilities;
116 : uint16_t security_mode;
117 : struct GUID guid;
118 : struct smb311_capabilities smb3_capabilities;
119 : } client;
120 :
121 : struct {
122 : uint32_t capabilities;
123 : uint16_t security_mode;
124 : struct GUID guid;
125 : uint32_t max_trans_size;
126 : uint32_t max_read_size;
127 : uint32_t max_write_size;
128 : NTTIME system_time;
129 : NTTIME start_time;
130 : DATA_BLOB gss_blob;
131 : uint16_t sign_algo;
132 : uint16_t cipher;
133 : bool smb311_posix;
134 : } server;
135 :
136 : uint64_t mid;
137 : uint16_t cur_credits;
138 : uint16_t max_credits;
139 :
140 : uint32_t cc_chunk_len;
141 : uint32_t cc_max_chunks;
142 :
143 : uint8_t io_priority;
144 :
145 : bool force_channel_sequence;
146 :
147 : uint8_t preauth_sha512[64];
148 : } smb2;
149 :
150 : struct smbXcli_session *sessions;
151 : };
152 :
153 : struct smb2cli_session {
154 : uint64_t session_id;
155 : uint16_t session_flags;
156 : struct smb2_signing_key *application_key;
157 : struct smb2_signing_key *signing_key;
158 : bool should_sign;
159 : bool should_encrypt;
160 : struct smb2_signing_key *encryption_key;
161 : struct smb2_signing_key *decryption_key;
162 : uint64_t nonce_high_random;
163 : uint64_t nonce_high_max;
164 : uint64_t nonce_high;
165 : uint64_t nonce_low;
166 : uint16_t channel_sequence;
167 : bool replay_active;
168 : bool require_signed_response;
169 :
170 : /*
171 : * The following are just for torture tests
172 : */
173 : bool anonymous_signing;
174 : bool anonymous_encryption;
175 : bool no_signing_disconnect;
176 : };
177 :
178 : struct smbXcli_session {
179 : struct smbXcli_session *prev, *next;
180 : struct smbXcli_conn *conn;
181 :
182 : struct {
183 : uint16_t session_id;
184 : uint16_t action;
185 : DATA_BLOB application_key;
186 : bool protected_key;
187 : } smb1;
188 :
189 : struct smb2cli_session *smb2;
190 :
191 : struct {
192 : struct smb2_signing_key *signing_key;
193 : uint8_t preauth_sha512[64];
194 : } smb2_channel;
195 :
196 : /*
197 : * this should be a short term hack
198 : * until the upper layers have implemented
199 : * re-authentication.
200 : */
201 : bool disconnect_expired;
202 : };
203 :
204 : struct smbXcli_tcon {
205 : bool is_smb1;
206 : uint32_t fs_attributes;
207 :
208 : struct {
209 : uint16_t tcon_id;
210 : uint16_t optional_support;
211 : uint32_t maximal_access;
212 : uint32_t guest_maximal_access;
213 : char *service;
214 : char *fs_type;
215 : } smb1;
216 :
217 : struct {
218 : uint32_t tcon_id;
219 : uint8_t type;
220 : uint32_t flags;
221 : uint32_t capabilities;
222 : uint32_t maximal_access;
223 : bool should_sign;
224 : bool should_encrypt;
225 : } smb2;
226 : };
227 :
228 : struct smbXcli_req_state {
229 : struct tevent_context *ev;
230 : struct smbXcli_conn *conn;
231 : struct smbXcli_session *session; /* maybe NULL */
232 : struct smbXcli_tcon *tcon; /* maybe NULL */
233 :
234 : uint8_t length_hdr[4];
235 :
236 : bool one_way;
237 :
238 : uint8_t *inbuf;
239 :
240 : struct tevent_req *write_req;
241 :
242 : struct timeval endtime;
243 :
244 : struct {
245 : /* Space for the header including the wct */
246 : uint8_t hdr[HDR_VWV];
247 :
248 : /*
249 : * For normal requests, smb1cli_req_send chooses a mid.
250 : * SecondaryV trans requests need to use the mid of the primary
251 : * request, so we need a place to store it.
252 : * Assume it is set if != 0.
253 : */
254 : uint16_t mid;
255 :
256 : uint16_t *vwv;
257 : uint8_t bytecount_buf[2];
258 :
259 : #define MAX_SMB_IOV 10
260 : /* length_hdr, hdr, words, byte_count, buffers */
261 : struct iovec iov[1 + 3 + MAX_SMB_IOV];
262 : int iov_count;
263 :
264 : bool one_way_seqnum;
265 : uint32_t seqnum;
266 : struct tevent_req **chained_requests;
267 :
268 : uint8_t recv_cmd;
269 : NTSTATUS recv_status;
270 : /* always an array of 3 talloc elements */
271 : struct iovec *recv_iov;
272 : } smb1;
273 :
274 : struct {
275 : const uint8_t *fixed;
276 : uint16_t fixed_len;
277 : const uint8_t *dyn;
278 : uint32_t dyn_len;
279 :
280 : uint8_t transform[SMB2_TF_HDR_SIZE];
281 : uint8_t hdr[SMB2_HDR_BODY];
282 : uint8_t pad[7]; /* padding space for compounding */
283 :
284 : /*
285 : * always an array of 3 talloc elements
286 : * (without a SMB2_TRANSFORM header!)
287 : *
288 : * HDR, BODY, DYN
289 : */
290 : struct iovec *recv_iov;
291 :
292 : /*
293 : * the expected max for the response dyn_len
294 : */
295 : uint32_t max_dyn_len;
296 :
297 : uint16_t credit_charge;
298 :
299 : bool should_sign;
300 : bool should_encrypt;
301 : uint64_t encryption_session_id;
302 :
303 : bool signing_skipped;
304 : bool require_signed_response;
305 : bool notify_async;
306 : bool got_async;
307 : uint16_t cancel_flags;
308 : uint64_t cancel_mid;
309 : uint64_t cancel_aid;
310 : } smb2;
311 : };
312 :
313 32604 : static int smbXcli_conn_destructor(struct smbXcli_conn *conn)
314 : {
315 : /*
316 : * NT_STATUS_OK, means we do not notify the callers
317 : */
318 32604 : smbXcli_conn_disconnect(conn, NT_STATUS_OK);
319 :
320 33140 : while (conn->sessions) {
321 620 : conn->sessions->conn = NULL;
322 1477 : DLIST_REMOVE(conn->sessions, conn->sessions);
323 : }
324 :
325 32604 : if (conn->smb1.trans_enc) {
326 260 : TALLOC_FREE(conn->smb1.trans_enc);
327 : }
328 :
329 32604 : return 0;
330 : }
331 :
332 34031 : struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
333 : int fd,
334 : const char *remote_name,
335 : enum smb_signing_setting signing_state,
336 : uint32_t smb1_capabilities,
337 : struct GUID *client_guid,
338 : uint32_t smb2_capabilities,
339 : const struct smb311_capabilities *smb3_capabilities)
340 : {
341 34031 : struct smbXcli_conn *conn = NULL;
342 34031 : void *ss = NULL;
343 34031 : struct sockaddr *sa = NULL;
344 862 : socklen_t sa_length;
345 862 : int ret;
346 :
347 34031 : if (smb3_capabilities != NULL) {
348 31190 : const struct smb3_signing_capabilities *sign_algos =
349 : &smb3_capabilities->signing;
350 31190 : const struct smb3_encryption_capabilities *ciphers =
351 : &smb3_capabilities->encryption;
352 :
353 31190 : SMB_ASSERT(sign_algos->num_algos <= SMB3_SIGNING_CAPABILITIES_MAX_ALGOS);
354 31190 : SMB_ASSERT(ciphers->num_algos <= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS);
355 : }
356 :
357 34031 : conn = talloc_zero(mem_ctx, struct smbXcli_conn);
358 34031 : if (!conn) {
359 0 : return NULL;
360 : }
361 :
362 34031 : ret = set_blocking(fd, false);
363 34031 : if (ret < 0) {
364 0 : goto error;
365 : }
366 34031 : conn->sock_fd = fd;
367 :
368 34031 : conn->remote_name = talloc_strdup(conn, remote_name);
369 34031 : if (conn->remote_name == NULL) {
370 0 : goto error;
371 : }
372 :
373 34031 : ss = (void *)&conn->local_ss;
374 34031 : sa = (struct sockaddr *)ss;
375 34031 : sa_length = sizeof(conn->local_ss);
376 34031 : ret = getsockname(fd, sa, &sa_length);
377 34031 : if (ret == -1) {
378 0 : goto error;
379 : }
380 34031 : ss = (void *)&conn->remote_ss;
381 34031 : sa = (struct sockaddr *)ss;
382 34031 : sa_length = sizeof(conn->remote_ss);
383 34031 : ret = getpeername(fd, sa, &sa_length);
384 34031 : if (ret == -1) {
385 0 : goto error;
386 : }
387 :
388 34031 : conn->outgoing = tevent_queue_create(conn, "smbXcli_outgoing");
389 34031 : if (conn->outgoing == NULL) {
390 0 : goto error;
391 : }
392 34031 : conn->pending = NULL;
393 :
394 34031 : conn->min_protocol = PROTOCOL_NONE;
395 34031 : conn->max_protocol = PROTOCOL_NONE;
396 34031 : conn->protocol = PROTOCOL_NONE;
397 :
398 34031 : switch (signing_state) {
399 158 : case SMB_SIGNING_OFF:
400 : /* never */
401 158 : conn->allow_signing = false;
402 158 : conn->desire_signing = false;
403 158 : conn->mandatory_signing = false;
404 158 : break;
405 22670 : case SMB_SIGNING_DEFAULT:
406 : case SMB_SIGNING_IF_REQUIRED:
407 : /* if the server requires it */
408 22670 : conn->allow_signing = true;
409 22670 : conn->desire_signing = false;
410 22670 : conn->mandatory_signing = false;
411 22670 : break;
412 6 : case SMB_SIGNING_DESIRED:
413 : /* if the server desires it */
414 6 : conn->allow_signing = true;
415 6 : conn->desire_signing = true;
416 6 : conn->mandatory_signing = false;
417 6 : break;
418 11197 : case SMB_SIGNING_IPC_DEFAULT:
419 : case SMB_SIGNING_REQUIRED:
420 : /* always */
421 11197 : conn->allow_signing = true;
422 11197 : conn->desire_signing = true;
423 11197 : conn->mandatory_signing = true;
424 11197 : break;
425 : }
426 :
427 34031 : conn->smb1.client.capabilities = smb1_capabilities;
428 34031 : conn->smb1.client.max_xmit = UINT16_MAX;
429 :
430 34031 : conn->smb1.capabilities = conn->smb1.client.capabilities;
431 34031 : conn->smb1.max_xmit = 1024;
432 :
433 34031 : conn->smb1.mid = 1;
434 :
435 : /* initialise signing */
436 68062 : conn->smb1.signing = smb1_signing_init(conn,
437 34031 : conn->allow_signing,
438 34031 : conn->desire_signing,
439 34031 : conn->mandatory_signing);
440 34031 : if (!conn->smb1.signing) {
441 0 : goto error;
442 : }
443 :
444 34031 : conn->smb2.client.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
445 34031 : if (conn->mandatory_signing) {
446 11197 : conn->smb2.client.security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
447 : }
448 34031 : if (client_guid) {
449 31190 : conn->smb2.client.guid = *client_guid;
450 : }
451 34031 : conn->smb2.client.capabilities = smb2_capabilities;
452 34031 : if (smb3_capabilities != NULL) {
453 31190 : conn->smb2.client.smb3_capabilities = *smb3_capabilities;
454 : }
455 :
456 34031 : conn->smb2.cur_credits = 1;
457 34031 : conn->smb2.max_credits = 0;
458 34031 : conn->smb2.io_priority = 1;
459 :
460 : /*
461 : * Samba and Windows servers accept a maximum of 16 MiB with a maximum
462 : * chunk length of 1 MiB.
463 : */
464 34031 : conn->smb2.cc_chunk_len = 1024 * 1024;
465 34031 : conn->smb2.cc_max_chunks = 16;
466 :
467 34031 : talloc_set_destructor(conn, smbXcli_conn_destructor);
468 34031 : return conn;
469 :
470 0 : error:
471 0 : TALLOC_FREE(conn);
472 0 : return NULL;
473 : }
474 :
475 9121140 : bool smbXcli_conn_is_connected(struct smbXcli_conn *conn)
476 : {
477 9121140 : if (conn == NULL) {
478 13418 : return false;
479 : }
480 :
481 9106616 : if (conn->sock_fd == -1) {
482 101 : return false;
483 : }
484 :
485 9032291 : return true;
486 : }
487 :
488 6531347 : enum protocol_types smbXcli_conn_protocol(struct smbXcli_conn *conn)
489 : {
490 6531347 : return conn->protocol;
491 : }
492 :
493 165973 : bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn)
494 : {
495 165973 : if (conn->protocol >= PROTOCOL_SMB2_02) {
496 12201 : return true;
497 : }
498 :
499 153772 : if (conn->smb1.capabilities & CAP_UNICODE) {
500 153644 : return true;
501 : }
502 :
503 128 : return false;
504 : }
505 :
506 316 : bool smbXcli_conn_signing_mandatory(struct smbXcli_conn *conn)
507 : {
508 316 : return conn->mandatory_signing;
509 : }
510 :
511 9275 : bool smbXcli_conn_have_posix(struct smbXcli_conn *conn)
512 : {
513 9275 : if (conn->protocol >= PROTOCOL_SMB3_11) {
514 7276 : return conn->smb2.server.smb311_posix;
515 : }
516 1999 : if (conn->protocol <= PROTOCOL_NT1) {
517 360 : return (conn->smb1.capabilities & CAP_UNIX);
518 : }
519 1639 : return false;
520 : }
521 :
522 : /*
523 : * [MS-SMB] 2.2.2.3.5 - SMB1 support for passing through
524 : * query/set commands to the file system
525 : */
526 6 : bool smbXcli_conn_support_passthrough(struct smbXcli_conn *conn)
527 : {
528 6 : if (conn->protocol >= PROTOCOL_SMB2_02) {
529 0 : return true;
530 : }
531 :
532 6 : if (conn->smb1.capabilities & CAP_W2K_SMBS) {
533 6 : return true;
534 : }
535 :
536 0 : return false;
537 : }
538 :
539 367 : void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options)
540 : {
541 367 : set_socket_options(conn->sock_fd, options);
542 367 : }
543 :
544 857 : const struct sockaddr_storage *smbXcli_conn_local_sockaddr(struct smbXcli_conn *conn)
545 : {
546 857 : return &conn->local_ss;
547 : }
548 :
549 10856 : const struct sockaddr_storage *smbXcli_conn_remote_sockaddr(struct smbXcli_conn *conn)
550 : {
551 10856 : return &conn->remote_ss;
552 : }
553 :
554 203058 : const char *smbXcli_conn_remote_name(struct smbXcli_conn *conn)
555 : {
556 203058 : return conn->remote_name;
557 : }
558 :
559 10471 : uint16_t smbXcli_conn_max_requests(struct smbXcli_conn *conn)
560 : {
561 10471 : if (conn->protocol >= PROTOCOL_SMB2_02) {
562 : /*
563 : * TODO...
564 : */
565 0 : return 1;
566 : }
567 :
568 10471 : return conn->smb1.server.max_mux;
569 : }
570 :
571 2767 : NTTIME smbXcli_conn_server_system_time(struct smbXcli_conn *conn)
572 : {
573 2767 : if (conn->protocol >= PROTOCOL_SMB2_02) {
574 6 : return conn->smb2.server.system_time;
575 : }
576 :
577 2761 : return conn->smb1.server.system_time;
578 : }
579 :
580 37426 : const DATA_BLOB *smbXcli_conn_server_gss_blob(struct smbXcli_conn *conn)
581 : {
582 37426 : if (conn->protocol >= PROTOCOL_SMB2_02) {
583 30423 : return &conn->smb2.server.gss_blob;
584 : }
585 :
586 7003 : return &conn->smb1.server.gss_blob;
587 : }
588 :
589 0 : const struct GUID *smbXcli_conn_server_guid(struct smbXcli_conn *conn)
590 : {
591 0 : if (conn->protocol >= PROTOCOL_SMB2_02) {
592 0 : return &conn->smb2.server.guid;
593 : }
594 :
595 0 : return &conn->smb1.server.guid;
596 : }
597 :
598 0 : bool smbXcli_conn_get_force_channel_sequence(struct smbXcli_conn *conn)
599 : {
600 0 : return conn->smb2.force_channel_sequence;
601 : }
602 :
603 8 : void smbXcli_conn_set_force_channel_sequence(struct smbXcli_conn *conn,
604 : bool v)
605 : {
606 8 : conn->smb2.force_channel_sequence = v;
607 8 : }
608 :
609 : struct smbXcli_conn_samba_suicide_state {
610 : struct smbXcli_conn *conn;
611 : struct iovec iov;
612 : uint8_t buf[9];
613 : struct tevent_req *write_req;
614 : };
615 :
616 : static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
617 : enum tevent_req_state req_state);
618 : static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq);
619 :
620 17 : struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx,
621 : struct tevent_context *ev,
622 : struct smbXcli_conn *conn,
623 : uint8_t exitcode)
624 : {
625 0 : struct tevent_req *req, *subreq;
626 0 : struct smbXcli_conn_samba_suicide_state *state;
627 :
628 17 : req = tevent_req_create(mem_ctx, &state,
629 : struct smbXcli_conn_samba_suicide_state);
630 17 : if (req == NULL) {
631 0 : return NULL;
632 : }
633 17 : state->conn = conn;
634 17 : SIVAL(state->buf, 4, SMB_SUICIDE_PACKET);
635 17 : SCVAL(state->buf, 8, exitcode);
636 17 : _smb_setlen_nbt(state->buf, sizeof(state->buf)-4);
637 :
638 17 : if (conn->suicide_req != NULL) {
639 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
640 0 : return tevent_req_post(req, ev);
641 : }
642 :
643 17 : state->iov.iov_base = state->buf;
644 17 : state->iov.iov_len = sizeof(state->buf);
645 :
646 17 : subreq = writev_send(state, ev, conn->outgoing, conn->sock_fd,
647 17 : false, &state->iov, 1);
648 17 : if (tevent_req_nomem(subreq, req)) {
649 0 : return tevent_req_post(req, ev);
650 : }
651 17 : tevent_req_set_callback(subreq, smbXcli_conn_samba_suicide_done, req);
652 17 : state->write_req = subreq;
653 :
654 17 : tevent_req_set_cleanup_fn(req, smbXcli_conn_samba_suicide_cleanup);
655 :
656 : /*
657 : * We need to use tevent_req_defer_callback()
658 : * in order to allow smbXcli_conn_disconnect()
659 : * to do a safe cleanup.
660 : */
661 17 : tevent_req_defer_callback(req, ev);
662 17 : conn->suicide_req = req;
663 :
664 17 : return req;
665 : }
666 :
667 34 : static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
668 : enum tevent_req_state req_state)
669 : {
670 34 : struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
671 : req, struct smbXcli_conn_samba_suicide_state);
672 :
673 34 : TALLOC_FREE(state->write_req);
674 :
675 34 : if (state->conn == NULL) {
676 17 : return;
677 : }
678 :
679 17 : if (state->conn->suicide_req == req) {
680 17 : state->conn->suicide_req = NULL;
681 : }
682 17 : state->conn = NULL;
683 : }
684 :
685 17 : static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq)
686 : {
687 17 : struct tevent_req *req = tevent_req_callback_data(
688 : subreq, struct tevent_req);
689 17 : struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
690 : req, struct smbXcli_conn_samba_suicide_state);
691 0 : ssize_t nwritten;
692 0 : int err;
693 :
694 17 : state->write_req = NULL;
695 :
696 17 : nwritten = writev_recv(subreq, &err);
697 17 : TALLOC_FREE(subreq);
698 17 : if (nwritten == -1) {
699 : /* here, we need to notify all pending requests */
700 0 : NTSTATUS status = map_nt_error_from_unix_common(err);
701 0 : smbXcli_conn_disconnect(state->conn, status);
702 0 : return;
703 : }
704 17 : tevent_req_done(req);
705 : }
706 :
707 17 : NTSTATUS smbXcli_conn_samba_suicide_recv(struct tevent_req *req)
708 : {
709 17 : return tevent_req_simple_recv_ntstatus(req);
710 : }
711 :
712 17 : NTSTATUS smbXcli_conn_samba_suicide(struct smbXcli_conn *conn,
713 : uint8_t exitcode)
714 : {
715 17 : TALLOC_CTX *frame = talloc_stackframe();
716 0 : struct tevent_context *ev;
717 0 : struct tevent_req *req;
718 17 : NTSTATUS status = NT_STATUS_NO_MEMORY;
719 0 : bool ok;
720 :
721 17 : if (smbXcli_conn_has_async_calls(conn)) {
722 : /*
723 : * Can't use sync call while an async call is in flight
724 : */
725 0 : status = NT_STATUS_INVALID_PARAMETER_MIX;
726 0 : goto fail;
727 : }
728 17 : ev = samba_tevent_context_init(frame);
729 17 : if (ev == NULL) {
730 0 : goto fail;
731 : }
732 17 : req = smbXcli_conn_samba_suicide_send(frame, ev, conn, exitcode);
733 17 : if (req == NULL) {
734 0 : goto fail;
735 : }
736 17 : ok = tevent_req_poll_ntstatus(req, ev, &status);
737 17 : if (!ok) {
738 0 : goto fail;
739 : }
740 17 : status = smbXcli_conn_samba_suicide_recv(req);
741 17 : fail:
742 17 : TALLOC_FREE(frame);
743 17 : return status;
744 : }
745 :
746 992354 : uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn)
747 : {
748 992354 : return conn->smb1.capabilities;
749 : }
750 :
751 120399 : uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn)
752 : {
753 120399 : return conn->smb1.max_xmit;
754 : }
755 :
756 13958 : bool smb1cli_conn_req_possible(struct smbXcli_conn *conn)
757 : {
758 13958 : size_t pending = talloc_array_length(conn->pending);
759 13958 : uint16_t possible = conn->smb1.server.max_mux;
760 :
761 13958 : if (pending >= possible) {
762 3296 : return false;
763 : }
764 :
765 10662 : return true;
766 : }
767 :
768 10491 : uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn)
769 : {
770 10491 : return conn->smb1.server.session_key;
771 : }
772 :
773 76 : const uint8_t *smb1cli_conn_server_challenge(struct smbXcli_conn *conn)
774 : {
775 76 : return conn->smb1.server.challenge;
776 : }
777 :
778 31553 : uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn)
779 : {
780 31553 : return conn->smb1.server.security_mode;
781 : }
782 :
783 2755 : bool smb1cli_conn_server_readbraw(struct smbXcli_conn *conn)
784 : {
785 2755 : return conn->smb1.server.readbraw;
786 : }
787 :
788 2755 : bool smb1cli_conn_server_writebraw(struct smbXcli_conn *conn)
789 : {
790 2755 : return conn->smb1.server.writebraw;
791 : }
792 :
793 2755 : bool smb1cli_conn_server_lockread(struct smbXcli_conn *conn)
794 : {
795 2755 : return conn->smb1.server.lockread;
796 : }
797 :
798 0 : bool smb1cli_conn_server_writeunlock(struct smbXcli_conn *conn)
799 : {
800 0 : return conn->smb1.server.writeunlock;
801 : }
802 :
803 5325 : int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn)
804 : {
805 5325 : return conn->smb1.server.time_zone;
806 : }
807 :
808 6580 : bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
809 : const DATA_BLOB user_session_key,
810 : const DATA_BLOB response)
811 : {
812 6580 : return smb1_signing_activate(conn->smb1.signing,
813 : user_session_key,
814 : response);
815 : }
816 :
817 3076 : bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
818 : const uint8_t *buf, uint32_t seqnum)
819 : {
820 3076 : const uint8_t *hdr = buf + NBT_HDR_SIZE;
821 3076 : size_t len = smb_len_nbt(buf);
822 :
823 3076 : return smb1_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
824 : }
825 :
826 22668 : bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
827 : {
828 22668 : return smb1_signing_is_active(conn->smb1.signing);
829 : }
830 :
831 442 : void smb1cli_conn_set_encryption(struct smbXcli_conn *conn,
832 : struct smb_trans_enc_state *es)
833 : {
834 : /* Replace the old state, if any. */
835 442 : if (conn->smb1.trans_enc) {
836 112 : TALLOC_FREE(conn->smb1.trans_enc);
837 : }
838 442 : conn->smb1.trans_enc = es;
839 442 : }
840 :
841 7492 : bool smb1cli_conn_encryption_on(struct smbXcli_conn *conn)
842 : {
843 7492 : return common_encryption_on(conn->smb1.trans_enc);
844 : }
845 :
846 :
847 1865216 : static NTSTATUS smb1cli_pull_raw_error(const uint8_t *hdr)
848 : {
849 1865216 : uint32_t flags2 = SVAL(hdr, HDR_FLG2);
850 1865216 : NTSTATUS status = NT_STATUS(IVAL(hdr, HDR_RCLS));
851 :
852 1865216 : if (NT_STATUS_IS_OK(status)) {
853 933488 : return NT_STATUS_OK;
854 : }
855 :
856 931728 : if (flags2 & FLAGS2_32_BIT_ERROR_CODES) {
857 275856 : return status;
858 : }
859 :
860 655872 : return NT_STATUS_DOS(CVAL(hdr, HDR_RCLS), SVAL(hdr, HDR_ERR));
861 : }
862 :
863 : /**
864 : * Is the SMB command able to hold an AND_X successor
865 : * @param[in] cmd The SMB command in question
866 : * @retval Can we add a chained request after "cmd"?
867 : */
868 1742429 : bool smb1cli_is_andx_req(uint8_t cmd)
869 : {
870 1742429 : switch (cmd) {
871 616452 : case SMBtconX:
872 : case SMBlockingX:
873 : case SMBopenX:
874 : case SMBreadX:
875 : case SMBwriteX:
876 : case SMBsesssetupX:
877 : case SMBulogoffX:
878 : case SMBntcreateX:
879 616452 : return true;
880 13721 : break;
881 1110082 : default:
882 1123803 : break;
883 : }
884 :
885 1123803 : return false;
886 : }
887 :
888 951509 : static uint16_t smb1cli_alloc_mid(struct smbXcli_conn *conn)
889 : {
890 951509 : size_t num_pending = talloc_array_length(conn->pending);
891 8249 : uint16_t result;
892 :
893 951509 : if (conn->protocol == PROTOCOL_NONE) {
894 : /*
895 : * This is what windows sends on the SMB1 Negprot request
896 : * and some vendors reuse the SMB1 MID as SMB2 sequence number.
897 : */
898 25239 : return 0;
899 : }
900 :
901 7728 : while (true) {
902 7718 : size_t i;
903 :
904 925749 : result = conn->smb1.mid++;
905 925749 : if ((result == 0) || (result == 0xffff)) {
906 10 : continue;
907 : }
908 :
909 1298355 : for (i=0; i<num_pending; i++) {
910 372616 : if (result == smb1cli_req_mid(conn->pending[i])) {
911 0 : break;
912 : }
913 : }
914 :
915 925739 : if (i == num_pending) {
916 925739 : return result;
917 : }
918 : }
919 : }
920 :
921 3030864 : static NTSTATUS smbXcli_req_cancel_write_req(struct tevent_req *req)
922 : {
923 22682 : struct smbXcli_req_state *state =
924 3030864 : tevent_req_data(req,
925 : struct smbXcli_req_state);
926 3030864 : struct smbXcli_conn *conn = state->conn;
927 3030864 : size_t num_pending = talloc_array_length(conn->pending);
928 22682 : ssize_t ret;
929 22682 : int err;
930 22682 : bool ok;
931 :
932 3030864 : if (state->write_req == NULL) {
933 3024091 : return NT_STATUS_OK;
934 : }
935 :
936 : /*
937 : * Check if it's possible to cancel the request.
938 : * If the result is true it's not too late.
939 : * See writev_cancel().
940 : */
941 6773 : ok = tevent_req_cancel(state->write_req);
942 6773 : if (ok) {
943 506 : TALLOC_FREE(state->write_req);
944 :
945 506 : if (conn->protocol >= PROTOCOL_SMB2_02) {
946 : /*
947 : * SMB2 has a sane signing state.
948 : */
949 504 : return NT_STATUS_OK;
950 : }
951 :
952 2 : if (num_pending > 1) {
953 : /*
954 : * We have more pending requests following us. This
955 : * means the signing state will be broken for them.
956 : *
957 : * As a solution we could add the requests directly to
958 : * our outgoing queue and do the signing in the trigger
959 : * function and then use writev_send() without passing a
960 : * queue. That way we'll only sign packets we're most
961 : * likely send to the wire.
962 : */
963 2 : return NT_STATUS_REQUEST_OUT_OF_SEQUENCE;
964 : }
965 :
966 : /*
967 : * If we're the only request that's
968 : * pending, we're able to recover the signing
969 : * state.
970 : */
971 0 : smb1_signing_cancel_reply(conn->smb1.signing,
972 0 : state->smb1.one_way_seqnum);
973 0 : return NT_STATUS_OK;
974 : }
975 :
976 6267 : ret = writev_recv(state->write_req, &err);
977 6267 : TALLOC_FREE(state->write_req);
978 6267 : if (ret == -1) {
979 0 : return map_nt_error_from_unix_common(err);
980 : }
981 :
982 6267 : return NT_STATUS_OK;
983 : }
984 :
985 2933517 : void smbXcli_req_unset_pending(struct tevent_req *req)
986 : {
987 21399 : struct smbXcli_req_state *state =
988 2933517 : tevent_req_data(req,
989 : struct smbXcli_req_state);
990 2933517 : struct smbXcli_conn *conn = state->conn;
991 2933517 : size_t num_pending = talloc_array_length(conn->pending);
992 21399 : size_t i;
993 21399 : NTSTATUS cancel_status;
994 :
995 2933517 : cancel_status = smbXcli_req_cancel_write_req(req);
996 :
997 2933517 : if (state->smb1.mid != 0) {
998 : /*
999 : * This is a [nt]trans[2] request which waits
1000 : * for more than one reply.
1001 : */
1002 95710 : if (!NT_STATUS_IS_OK(cancel_status)) {
1003 : /*
1004 : * If the write_req cancel didn't work
1005 : * we can't use the connection anymore.
1006 : */
1007 0 : smbXcli_conn_disconnect(conn, cancel_status);
1008 0 : return;
1009 : }
1010 94427 : return;
1011 : }
1012 :
1013 2837807 : tevent_req_set_cleanup_fn(req, NULL);
1014 :
1015 2837807 : if (num_pending == 1) {
1016 : /*
1017 : * The pending read_smb tevent_req is a child of
1018 : * conn->pending. So if nothing is pending anymore, we need to
1019 : * delete the socket read fde.
1020 : */
1021 : /* TODO: smbXcli_conn_cancel_read_req */
1022 2739438 : TALLOC_FREE(conn->pending);
1023 2739438 : conn->read_smb_req = NULL;
1024 :
1025 2739438 : if (!NT_STATUS_IS_OK(cancel_status)) {
1026 : /*
1027 : * If the write_req cancel didn't work
1028 : * we can't use the connection anymore.
1029 : */
1030 0 : smbXcli_conn_disconnect(conn, cancel_status);
1031 0 : return;
1032 : }
1033 2719519 : return;
1034 : }
1035 :
1036 182518 : for (i=0; i<num_pending; i++) {
1037 182462 : if (req == conn->pending[i]) {
1038 98119 : break;
1039 : }
1040 : }
1041 98369 : if (i == num_pending) {
1042 : /*
1043 : * Something's seriously broken. Just returning here is the
1044 : * right thing nevertheless, the point of this routine is to
1045 : * remove ourselves from conn->pending.
1046 : */
1047 :
1048 56 : if (!NT_STATUS_IS_OK(cancel_status)) {
1049 : /*
1050 : * If the write_req cancel didn't work
1051 : * we can't use the connection anymore.
1052 : */
1053 0 : smbXcli_conn_disconnect(conn, cancel_status);
1054 0 : return;
1055 : }
1056 53 : return;
1057 : }
1058 :
1059 : /*
1060 : * Remove ourselves from the conn->pending array
1061 : */
1062 431902 : for (; i < (num_pending - 1); i++) {
1063 333589 : conn->pending[i] = conn->pending[i+1];
1064 : }
1065 :
1066 : /*
1067 : * No NULL check here, we're shrinking by sizeof(void *), and
1068 : * talloc_realloc just adjusts the size for this.
1069 : */
1070 98313 : conn->pending = talloc_realloc(NULL, conn->pending, struct tevent_req *,
1071 : num_pending - 1);
1072 :
1073 98313 : if (!NT_STATUS_IS_OK(cancel_status)) {
1074 : /*
1075 : * If the write_req cancel didn't work
1076 : * we can't use the connection anymore.
1077 : */
1078 2 : smbXcli_conn_disconnect(conn, cancel_status);
1079 2 : return;
1080 : }
1081 98117 : return;
1082 : }
1083 :
1084 107621 : static void smbXcli_req_cleanup(struct tevent_req *req,
1085 : enum tevent_req_state req_state)
1086 : {
1087 1761 : struct smbXcli_req_state *state =
1088 107621 : tevent_req_data(req,
1089 : struct smbXcli_req_state);
1090 107621 : struct smbXcli_conn *conn = state->conn;
1091 1761 : NTSTATUS cancel_status;
1092 :
1093 107621 : switch (req_state) {
1094 10274 : case TEVENT_REQ_RECEIVED:
1095 : /*
1096 : * Make sure we really remove it from
1097 : * the pending array on destruction.
1098 : *
1099 : * smbXcli_req_unset_pending() calls
1100 : * smbXcli_req_cancel_write_req() internal
1101 : */
1102 10274 : state->smb1.mid = 0;
1103 10274 : smbXcli_req_unset_pending(req);
1104 10274 : return;
1105 97347 : default:
1106 97347 : cancel_status = smbXcli_req_cancel_write_req(req);
1107 97347 : if (!NT_STATUS_IS_OK(cancel_status)) {
1108 : /*
1109 : * If the write_req cancel didn't work
1110 : * we can't use the connection anymore.
1111 : */
1112 0 : smbXcli_conn_disconnect(conn, cancel_status);
1113 0 : return;
1114 : }
1115 96064 : return;
1116 : }
1117 : }
1118 :
1119 : static bool smb1cli_req_cancel(struct tevent_req *req);
1120 : static bool smb2cli_req_cancel(struct tevent_req *req);
1121 :
1122 3155 : static bool smbXcli_req_cancel(struct tevent_req *req)
1123 : {
1124 16 : struct smbXcli_req_state *state =
1125 3155 : tevent_req_data(req,
1126 : struct smbXcli_req_state);
1127 :
1128 3155 : if (!smbXcli_conn_is_connected(state->conn)) {
1129 0 : return false;
1130 : }
1131 :
1132 3155 : if (state->conn->protocol == PROTOCOL_NONE) {
1133 0 : return false;
1134 : }
1135 :
1136 3155 : if (state->conn->protocol >= PROTOCOL_SMB2_02) {
1137 1620 : return smb2cli_req_cancel(req);
1138 : }
1139 :
1140 1535 : return smb1cli_req_cancel(req);
1141 : }
1142 :
1143 : static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
1144 :
1145 2837763 : bool smbXcli_req_set_pending(struct tevent_req *req)
1146 : {
1147 20113 : struct smbXcli_req_state *state =
1148 2837763 : tevent_req_data(req,
1149 : struct smbXcli_req_state);
1150 20113 : struct smbXcli_conn *conn;
1151 20113 : struct tevent_req **pending;
1152 20113 : size_t num_pending;
1153 :
1154 2837763 : conn = state->conn;
1155 :
1156 2837763 : if (!smbXcli_conn_is_connected(conn)) {
1157 8 : return false;
1158 : }
1159 :
1160 2837755 : num_pending = talloc_array_length(conn->pending);
1161 :
1162 2837755 : pending = talloc_realloc(conn, conn->pending, struct tevent_req *,
1163 : num_pending+1);
1164 2837755 : if (pending == NULL) {
1165 0 : return false;
1166 : }
1167 2837755 : pending[num_pending] = req;
1168 2837755 : conn->pending = pending;
1169 2837755 : tevent_req_set_cleanup_fn(req, smbXcli_req_cleanup);
1170 2837755 : tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1171 :
1172 2837755 : if (!smbXcli_conn_receive_next(conn)) {
1173 : /*
1174 : * the caller should notify the current request
1175 : *
1176 : * And all other pending requests get notified
1177 : * by smbXcli_conn_disconnect().
1178 : */
1179 0 : smbXcli_req_unset_pending(req);
1180 0 : smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1181 0 : return false;
1182 : }
1183 :
1184 2817642 : return true;
1185 : }
1186 :
1187 : static void smbXcli_conn_received(struct tevent_req *subreq);
1188 :
1189 5014511 : static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
1190 : {
1191 5014511 : size_t num_pending = talloc_array_length(conn->pending);
1192 36082 : struct tevent_req *req;
1193 36082 : struct smbXcli_req_state *state;
1194 :
1195 5014511 : if (conn->read_smb_req != NULL) {
1196 98119 : return true;
1197 : }
1198 :
1199 4916198 : if (num_pending == 0) {
1200 1880109 : if (conn->smb2.mid < UINT64_MAX) {
1201 : /* no more pending requests, so we are done for now */
1202 1868428 : return true;
1203 : }
1204 :
1205 : /*
1206 : * If there are no more SMB2 requests possible,
1207 : * because we are out of message ids,
1208 : * we need to disconnect.
1209 : */
1210 0 : smbXcli_conn_disconnect(conn, NT_STATUS_CONNECTION_ABORTED);
1211 0 : return true;
1212 : }
1213 :
1214 3036089 : req = conn->pending[0];
1215 3036089 : state = tevent_req_data(req, struct smbXcli_req_state);
1216 :
1217 : /*
1218 : * We're the first ones, add the read_smb request that waits for the
1219 : * answer from the server
1220 : */
1221 3036089 : conn->read_smb_req = read_smb_send(conn->pending,
1222 : state->ev,
1223 : conn->sock_fd);
1224 3036089 : if (conn->read_smb_req == NULL) {
1225 0 : return false;
1226 : }
1227 3036089 : tevent_req_set_callback(conn->read_smb_req, smbXcli_conn_received, conn);
1228 3036089 : return true;
1229 : }
1230 :
1231 64047 : void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
1232 : {
1233 1729 : struct smbXcli_session *session;
1234 64047 : int sock_fd = conn->sock_fd;
1235 :
1236 64047 : tevent_queue_stop(conn->outgoing);
1237 :
1238 64047 : conn->sock_fd = -1;
1239 :
1240 64047 : session = conn->sessions;
1241 64047 : if (talloc_array_length(conn->pending) == 0) {
1242 : /*
1243 : * if we do not have pending requests
1244 : * there is no need to update the channel_sequence
1245 : */
1246 62291 : session = NULL;
1247 : }
1248 65023 : for (; session; session = session->next) {
1249 976 : smb2cli_session_increment_channel_sequence(session);
1250 : }
1251 :
1252 64047 : if (conn->suicide_req != NULL) {
1253 : /*
1254 : * smbXcli_conn_samba_suicide_send()
1255 : * used tevent_req_defer_callback() already.
1256 : */
1257 0 : if (!NT_STATUS_IS_OK(status)) {
1258 0 : tevent_req_nterror(conn->suicide_req, status);
1259 : }
1260 0 : conn->suicide_req = NULL;
1261 : }
1262 :
1263 : /*
1264 : * Cancel all pending requests. We do not do a for-loop walking
1265 : * conn->pending because that array changes in
1266 : * smbXcli_req_unset_pending.
1267 : */
1268 67253 : while (conn->pending != NULL &&
1269 2471 : talloc_array_length(conn->pending) > 0) {
1270 7 : struct tevent_req *req;
1271 7 : struct smbXcli_req_state *state;
1272 7 : struct tevent_req **chain;
1273 7 : size_t num_chained;
1274 7 : size_t i;
1275 :
1276 2471 : req = conn->pending[0];
1277 2471 : state = tevent_req_data(req, struct smbXcli_req_state);
1278 :
1279 2471 : if (state->smb1.chained_requests == NULL) {
1280 7 : bool in_progress;
1281 :
1282 : /*
1283 : * We're dead. No point waiting for trans2
1284 : * replies.
1285 : */
1286 2471 : state->smb1.mid = 0;
1287 :
1288 2471 : smbXcli_req_unset_pending(req);
1289 :
1290 2471 : if (NT_STATUS_IS_OK(status)) {
1291 : /* do not notify the callers */
1292 0 : continue;
1293 : }
1294 :
1295 2471 : in_progress = tevent_req_is_in_progress(req);
1296 2471 : if (!in_progress) {
1297 : /*
1298 : * already finished
1299 : */
1300 0 : continue;
1301 : }
1302 :
1303 : /*
1304 : * we need to defer the callback, because we may notify
1305 : * more then one caller.
1306 : */
1307 2471 : tevent_req_defer_callback(req, state->ev);
1308 2471 : tevent_req_nterror(req, status);
1309 2471 : continue;
1310 : }
1311 :
1312 0 : chain = talloc_move(conn, &state->smb1.chained_requests);
1313 0 : num_chained = talloc_array_length(chain);
1314 :
1315 0 : for (i=0; i<num_chained; i++) {
1316 0 : bool in_progress;
1317 :
1318 0 : req = chain[i];
1319 0 : state = tevent_req_data(req, struct smbXcli_req_state);
1320 :
1321 : /*
1322 : * We're dead. No point waiting for trans2
1323 : * replies.
1324 : */
1325 0 : state->smb1.mid = 0;
1326 :
1327 0 : smbXcli_req_unset_pending(req);
1328 :
1329 0 : if (NT_STATUS_IS_OK(status)) {
1330 : /* do not notify the callers */
1331 0 : continue;
1332 : }
1333 :
1334 0 : in_progress = tevent_req_is_in_progress(req);
1335 0 : if (!in_progress) {
1336 : /*
1337 : * already finished
1338 : */
1339 0 : continue;
1340 : }
1341 :
1342 : /*
1343 : * we need to defer the callback, because we may notify
1344 : * more than one caller.
1345 : */
1346 0 : tevent_req_defer_callback(req, state->ev);
1347 0 : tevent_req_nterror(req, status);
1348 : }
1349 1736 : TALLOC_FREE(chain);
1350 : }
1351 :
1352 64047 : if (sock_fd != -1) {
1353 32617 : close(sock_fd);
1354 : }
1355 64047 : }
1356 :
1357 : /*
1358 : * Fetch a smb request's mid. Only valid after the request has been sent by
1359 : * smb1cli_req_send().
1360 : */
1361 1473575 : uint16_t smb1cli_req_mid(struct tevent_req *req)
1362 : {
1363 9194 : struct smbXcli_req_state *state =
1364 1473575 : tevent_req_data(req,
1365 : struct smbXcli_req_state);
1366 :
1367 1473575 : if (state->smb1.mid != 0) {
1368 281990 : return state->smb1.mid;
1369 : }
1370 :
1371 1190250 : return SVAL(state->smb1.hdr, HDR_MID);
1372 : }
1373 :
1374 194589 : void smb1cli_req_set_mid(struct tevent_req *req, uint16_t mid)
1375 : {
1376 2568 : struct smbXcli_req_state *state =
1377 194589 : tevent_req_data(req,
1378 : struct smbXcli_req_state);
1379 :
1380 194589 : state->smb1.mid = mid;
1381 194589 : }
1382 :
1383 0 : uint32_t smb1cli_req_seqnum(struct tevent_req *req)
1384 : {
1385 0 : struct smbXcli_req_state *state =
1386 0 : tevent_req_data(req,
1387 : struct smbXcli_req_state);
1388 :
1389 0 : return state->smb1.seqnum;
1390 : }
1391 :
1392 0 : void smb1cli_req_set_seqnum(struct tevent_req *req, uint32_t seqnum)
1393 : {
1394 0 : struct smbXcli_req_state *state =
1395 0 : tevent_req_data(req,
1396 : struct smbXcli_req_state);
1397 :
1398 0 : state->smb1.seqnum = seqnum;
1399 0 : }
1400 :
1401 134 : static size_t smbXcli_iov_len(const struct iovec *iov, int count)
1402 : {
1403 143 : ssize_t ret = iov_buflen(iov, count);
1404 :
1405 : /* Ignore the overflow case for now ... */
1406 134 : return ret;
1407 : }
1408 :
1409 979352 : static void smb1cli_req_flags(enum protocol_types protocol,
1410 : uint32_t smb1_capabilities,
1411 : uint8_t smb_command,
1412 : uint8_t additional_flags,
1413 : uint8_t clear_flags,
1414 : uint8_t *_flags,
1415 : uint16_t additional_flags2,
1416 : uint16_t clear_flags2,
1417 : uint16_t *_flags2)
1418 : {
1419 979352 : uint8_t flags = 0;
1420 979352 : uint16_t flags2 = 0;
1421 :
1422 978821 : if (protocol >= PROTOCOL_LANMAN1) {
1423 953580 : flags |= FLAG_CASELESS_PATHNAMES;
1424 953580 : flags |= FLAG_CANONICAL_PATHNAMES;
1425 : }
1426 :
1427 979352 : if (protocol >= PROTOCOL_LANMAN2) {
1428 953560 : flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
1429 953560 : flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
1430 : }
1431 :
1432 979352 : if (protocol >= PROTOCOL_NT1) {
1433 953468 : flags2 |= FLAGS2_IS_LONG_NAME;
1434 :
1435 953468 : if (smb1_capabilities & CAP_UNICODE) {
1436 953458 : flags2 |= FLAGS2_UNICODE_STRINGS;
1437 : }
1438 953468 : if (smb1_capabilities & CAP_STATUS32) {
1439 953290 : flags2 |= FLAGS2_32_BIT_ERROR_CODES;
1440 : }
1441 953468 : if (smb1_capabilities & CAP_EXTENDED_SECURITY) {
1442 952552 : flags2 |= FLAGS2_EXTENDED_SECURITY;
1443 : }
1444 : }
1445 :
1446 979352 : flags |= additional_flags;
1447 979352 : flags &= ~clear_flags;
1448 979352 : flags2 |= additional_flags2;
1449 979352 : flags2 &= ~clear_flags2;
1450 :
1451 979352 : *_flags = flags;
1452 979352 : *_flags2 = flags2;
1453 978821 : }
1454 :
1455 : static void smb1cli_req_cancel_done(struct tevent_req *subreq);
1456 :
1457 1535 : static bool smb1cli_req_cancel(struct tevent_req *req)
1458 : {
1459 0 : struct smbXcli_req_state *state =
1460 1535 : tevent_req_data(req,
1461 : struct smbXcli_req_state);
1462 0 : uint8_t flags;
1463 0 : uint16_t flags2;
1464 0 : uint32_t pid;
1465 0 : uint16_t mid;
1466 0 : struct tevent_req *subreq;
1467 0 : NTSTATUS status;
1468 :
1469 1535 : flags = CVAL(state->smb1.hdr, HDR_FLG);
1470 1535 : flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
1471 1535 : pid = SVAL(state->smb1.hdr, HDR_PID);
1472 1535 : pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
1473 1535 : mid = SVAL(state->smb1.hdr, HDR_MID);
1474 :
1475 1535 : subreq = smb1cli_req_create(state, state->ev,
1476 : state->conn,
1477 : SMBntcancel,
1478 : flags, 0,
1479 : flags2, 0,
1480 : 0, /* timeout */
1481 : pid,
1482 : state->tcon,
1483 : state->session,
1484 : 0, NULL, /* vwv */
1485 : 0, NULL); /* bytes */
1486 1535 : if (subreq == NULL) {
1487 0 : return false;
1488 : }
1489 1535 : smb1cli_req_set_mid(subreq, mid);
1490 :
1491 1535 : status = smb1cli_req_chain_submit(&subreq, 1);
1492 1535 : if (!NT_STATUS_IS_OK(status)) {
1493 0 : TALLOC_FREE(subreq);
1494 0 : return false;
1495 : }
1496 1535 : smb1cli_req_set_mid(subreq, 0);
1497 :
1498 1535 : tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
1499 :
1500 1535 : return true;
1501 : }
1502 :
1503 1535 : static void smb1cli_req_cancel_done(struct tevent_req *subreq)
1504 : {
1505 : /* we do not care about the result */
1506 1535 : TALLOC_FREE(subreq);
1507 1535 : }
1508 :
1509 953622 : struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
1510 : struct tevent_context *ev,
1511 : struct smbXcli_conn *conn,
1512 : uint8_t smb_command,
1513 : uint8_t additional_flags,
1514 : uint8_t clear_flags,
1515 : uint16_t additional_flags2,
1516 : uint16_t clear_flags2,
1517 : uint32_t timeout_msec,
1518 : uint32_t pid,
1519 : struct smbXcli_tcon *tcon,
1520 : struct smbXcli_session *session,
1521 : uint8_t wct, uint16_t *vwv,
1522 : int iov_count,
1523 : struct iovec *bytes_iov)
1524 : {
1525 8254 : struct tevent_req *req;
1526 8254 : struct smbXcli_req_state *state;
1527 953622 : uint8_t flags = 0;
1528 953622 : uint16_t flags2 = 0;
1529 953622 : uint16_t uid = 0;
1530 953622 : uint16_t tid = 0;
1531 8254 : ssize_t num_bytes;
1532 :
1533 953622 : if (iov_count > MAX_SMB_IOV) {
1534 : /*
1535 : * Should not happen :-)
1536 : */
1537 0 : return NULL;
1538 : }
1539 :
1540 953622 : req = tevent_req_create(mem_ctx, &state,
1541 : struct smbXcli_req_state);
1542 953622 : if (req == NULL) {
1543 0 : return NULL;
1544 : }
1545 953622 : state->ev = ev;
1546 953622 : state->conn = conn;
1547 953622 : state->session = session;
1548 953622 : state->tcon = tcon;
1549 :
1550 953622 : if (session) {
1551 927341 : uid = session->smb1.session_id;
1552 : }
1553 :
1554 953622 : if (tcon) {
1555 910411 : tid = tcon->smb1.tcon_id;
1556 :
1557 910411 : if (tcon->fs_attributes & FILE_CASE_SENSITIVE_SEARCH) {
1558 907 : clear_flags |= FLAG_CASELESS_PATHNAMES;
1559 : } else {
1560 : /* Default setting, case insensitive. */
1561 909504 : additional_flags |= FLAG_CASELESS_PATHNAMES;
1562 : }
1563 :
1564 1820364 : if (smbXcli_conn_dfs_supported(conn) &&
1565 909953 : smbXcli_tcon_is_dfs_share(tcon))
1566 : {
1567 1812 : additional_flags2 |= FLAGS2_DFS_PATHNAMES;
1568 : }
1569 : }
1570 :
1571 953622 : state->smb1.recv_cmd = 0xFF;
1572 953622 : state->smb1.recv_status = NT_STATUS_INTERNAL_ERROR;
1573 953622 : state->smb1.recv_iov = talloc_zero_array(state, struct iovec, 3);
1574 953622 : if (state->smb1.recv_iov == NULL) {
1575 0 : TALLOC_FREE(req);
1576 0 : return NULL;
1577 : }
1578 :
1579 953622 : smb1cli_req_flags(conn->protocol,
1580 : conn->smb1.capabilities,
1581 : smb_command,
1582 : additional_flags,
1583 : clear_flags,
1584 : &flags,
1585 : additional_flags2,
1586 : clear_flags2,
1587 : &flags2);
1588 :
1589 953622 : SIVAL(state->smb1.hdr, 0, SMB_MAGIC);
1590 953622 : SCVAL(state->smb1.hdr, HDR_COM, smb_command);
1591 953622 : SIVAL(state->smb1.hdr, HDR_RCLS, NT_STATUS_V(NT_STATUS_OK));
1592 953622 : SCVAL(state->smb1.hdr, HDR_FLG, flags);
1593 953622 : SSVAL(state->smb1.hdr, HDR_FLG2, flags2);
1594 953622 : SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);
1595 953622 : SSVAL(state->smb1.hdr, HDR_TID, tid);
1596 953622 : SSVAL(state->smb1.hdr, HDR_PID, pid);
1597 953622 : SSVAL(state->smb1.hdr, HDR_UID, uid);
1598 953622 : SSVAL(state->smb1.hdr, HDR_MID, 0); /* this comes later */
1599 953622 : SCVAL(state->smb1.hdr, HDR_WCT, wct);
1600 :
1601 953622 : state->smb1.vwv = vwv;
1602 :
1603 953622 : num_bytes = iov_buflen(bytes_iov, iov_count);
1604 953622 : if (num_bytes == -1) {
1605 : /*
1606 : * I'd love to add a check for num_bytes<=UINT16_MAX here, but
1607 : * the smbclient->samba connections can lie and transfer more.
1608 : */
1609 0 : TALLOC_FREE(req);
1610 0 : return NULL;
1611 : }
1612 :
1613 953622 : SSVAL(state->smb1.bytecount_buf, 0, num_bytes);
1614 :
1615 953622 : state->smb1.iov[0].iov_base = (void *)state->length_hdr;
1616 953622 : state->smb1.iov[0].iov_len = sizeof(state->length_hdr);
1617 953622 : state->smb1.iov[1].iov_base = (void *)state->smb1.hdr;
1618 953622 : state->smb1.iov[1].iov_len = sizeof(state->smb1.hdr);
1619 953622 : state->smb1.iov[2].iov_base = (void *)state->smb1.vwv;
1620 953622 : state->smb1.iov[2].iov_len = wct * sizeof(uint16_t);
1621 953622 : state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;
1622 953622 : state->smb1.iov[3].iov_len = sizeof(uint16_t);
1623 :
1624 953622 : if (iov_count != 0) {
1625 939870 : memcpy(&state->smb1.iov[4], bytes_iov,
1626 : iov_count * sizeof(*bytes_iov));
1627 : }
1628 953622 : state->smb1.iov_count = iov_count + 4;
1629 :
1630 953622 : if (timeout_msec > 0) {
1631 951568 : state->endtime = timeval_current_ofs_msec(timeout_msec);
1632 951568 : if (!tevent_req_set_endtime(req, ev, state->endtime)) {
1633 0 : return req;
1634 : }
1635 : }
1636 :
1637 953622 : switch (smb_command) {
1638 0 : case SMBtranss:
1639 : case SMBtranss2:
1640 : case SMBnttranss:
1641 0 : state->one_way = true;
1642 0 : break;
1643 1535 : case SMBntcancel:
1644 1535 : state->one_way = true;
1645 1535 : state->smb1.one_way_seqnum = true;
1646 1535 : break;
1647 6932 : case SMBlockingX:
1648 6932 : if ((wct == 8) &&
1649 6932 : (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
1650 144 : state->one_way = true;
1651 : }
1652 6917 : break;
1653 : }
1654 :
1655 945368 : return req;
1656 : }
1657 :
1658 953044 : static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
1659 : struct iovec *iov, int iov_count,
1660 : uint32_t *seqnum,
1661 : bool one_way_seqnum)
1662 : {
1663 953044 : TALLOC_CTX *frame = NULL;
1664 8249 : NTSTATUS status;
1665 8249 : uint8_t *buf;
1666 :
1667 : /*
1668 : * Obvious optimization: Make cli_calculate_sign_mac work with struct
1669 : * iovec directly. MD5Update would do that just fine.
1670 : */
1671 :
1672 953044 : if (iov_count < 4) {
1673 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1674 : }
1675 953044 : if (iov[0].iov_len != NBT_HDR_SIZE) {
1676 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1677 : }
1678 953044 : if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1679 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1680 : }
1681 953044 : if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1682 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1683 : }
1684 953044 : if (iov[3].iov_len != sizeof(uint16_t)) {
1685 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1686 : }
1687 :
1688 953044 : frame = talloc_stackframe();
1689 :
1690 953044 : buf = iov_concat(frame, &iov[1], iov_count - 1);
1691 953044 : if (buf == NULL) {
1692 0 : return NT_STATUS_NO_MEMORY;
1693 : }
1694 :
1695 953044 : *seqnum = smb1_signing_next_seqnum(conn->smb1.signing,
1696 : one_way_seqnum);
1697 953044 : status = smb1_signing_sign_pdu(conn->smb1.signing,
1698 : buf,
1699 : talloc_get_size(buf),
1700 : *seqnum);
1701 953044 : if (!NT_STATUS_IS_OK(status)) {
1702 0 : return status;
1703 : }
1704 953044 : memcpy(iov[1].iov_base, buf, iov[1].iov_len);
1705 :
1706 953044 : TALLOC_FREE(frame);
1707 953044 : return NT_STATUS_OK;
1708 : }
1709 :
1710 : static void smb1cli_req_writev_done(struct tevent_req *subreq);
1711 : static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1712 : TALLOC_CTX *tmp_mem,
1713 : uint8_t *inbuf);
1714 :
1715 953056 : static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
1716 : struct smbXcli_req_state *state,
1717 : struct iovec *iov, int iov_count)
1718 : {
1719 8249 : struct tevent_req *subreq;
1720 8249 : NTSTATUS status;
1721 8249 : uint8_t cmd;
1722 8249 : uint16_t mid;
1723 8249 : ssize_t nbtlen;
1724 :
1725 953056 : if (!smbXcli_conn_is_connected(state->conn)) {
1726 8 : return NT_STATUS_CONNECTION_DISCONNECTED;
1727 : }
1728 :
1729 953048 : if (state->conn->protocol > PROTOCOL_NT1) {
1730 4 : DBG_ERR("called for dialect[%s] server[%s]\n",
1731 : smb_protocol_types_string(state->conn->protocol),
1732 : smbXcli_conn_remote_name(state->conn));
1733 4 : return NT_STATUS_REVISION_MISMATCH;
1734 : }
1735 :
1736 953044 : if (iov_count < 4) {
1737 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1738 : }
1739 953044 : if (iov[0].iov_len != NBT_HDR_SIZE) {
1740 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1741 : }
1742 953044 : if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1743 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1744 : }
1745 953044 : if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1746 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1747 : }
1748 953044 : if (iov[3].iov_len != sizeof(uint16_t)) {
1749 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1750 : }
1751 :
1752 953044 : cmd = CVAL(iov[1].iov_base, HDR_COM);
1753 953044 : if (cmd == SMBreadBraw) {
1754 60 : if (smbXcli_conn_has_async_calls(state->conn)) {
1755 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1756 : }
1757 60 : state->conn->smb1.read_braw_req = req;
1758 : }
1759 :
1760 953044 : if (state->smb1.mid != 0) {
1761 1535 : mid = state->smb1.mid;
1762 : } else {
1763 951509 : mid = smb1cli_alloc_mid(state->conn);
1764 : }
1765 953044 : SSVAL(iov[1].iov_base, HDR_MID, mid);
1766 :
1767 953044 : nbtlen = iov_buflen(&iov[1], iov_count-1);
1768 953044 : if ((nbtlen == -1) || (nbtlen > 0x1FFFF)) {
1769 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1770 : }
1771 :
1772 953044 : _smb_setlen_nbt(iov[0].iov_base, nbtlen);
1773 :
1774 961293 : status = smb1cli_conn_signv(state->conn, iov, iov_count,
1775 : &state->smb1.seqnum,
1776 953044 : state->smb1.one_way_seqnum);
1777 :
1778 953044 : if (!NT_STATUS_IS_OK(status)) {
1779 0 : return status;
1780 : }
1781 :
1782 : /*
1783 : * If we supported multiple encryption contexts
1784 : * here we'd look up based on tid.
1785 : */
1786 953044 : if (common_encryption_on(state->conn->smb1.trans_enc)) {
1787 0 : char *buf, *enc_buf;
1788 :
1789 149456 : buf = (char *)iov_concat(talloc_tos(), iov, iov_count);
1790 149456 : if (buf == NULL) {
1791 0 : return NT_STATUS_NO_MEMORY;
1792 : }
1793 149456 : status = common_encrypt_buffer(state->conn->smb1.trans_enc,
1794 : (char *)buf, &enc_buf);
1795 149456 : TALLOC_FREE(buf);
1796 149456 : if (!NT_STATUS_IS_OK(status)) {
1797 0 : DEBUG(0, ("Error in encrypting client message: %s\n",
1798 : nt_errstr(status)));
1799 0 : return status;
1800 : }
1801 149456 : buf = (char *)talloc_memdup(state, enc_buf,
1802 : smb_len_nbt(enc_buf)+4);
1803 149456 : SAFE_FREE(enc_buf);
1804 149456 : if (buf == NULL) {
1805 0 : return NT_STATUS_NO_MEMORY;
1806 : }
1807 149456 : iov[0].iov_base = (void *)buf;
1808 149456 : iov[0].iov_len = talloc_get_size(buf);
1809 149456 : iov_count = 1;
1810 : }
1811 :
1812 953044 : if (state->conn->dispatch_incoming == NULL) {
1813 28 : state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
1814 : }
1815 :
1816 953044 : if (!smbXcli_req_set_pending(req)) {
1817 0 : return NT_STATUS_NO_MEMORY;
1818 : }
1819 :
1820 953044 : tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1821 :
1822 961293 : subreq = writev_send(state, state->ev, state->conn->outgoing,
1823 953044 : state->conn->sock_fd, false, iov, iov_count);
1824 953044 : if (subreq == NULL) {
1825 0 : return NT_STATUS_NO_MEMORY;
1826 : }
1827 953044 : tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
1828 953044 : state->write_req = subreq;
1829 :
1830 953044 : return NT_STATUS_OK;
1831 : }
1832 :
1833 378503 : struct tevent_req *smb1cli_req_send(TALLOC_CTX *mem_ctx,
1834 : struct tevent_context *ev,
1835 : struct smbXcli_conn *conn,
1836 : uint8_t smb_command,
1837 : uint8_t additional_flags,
1838 : uint8_t clear_flags,
1839 : uint16_t additional_flags2,
1840 : uint16_t clear_flags2,
1841 : uint32_t timeout_msec,
1842 : uint32_t pid,
1843 : struct smbXcli_tcon *tcon,
1844 : struct smbXcli_session *session,
1845 : uint8_t wct, uint16_t *vwv,
1846 : uint32_t num_bytes,
1847 : const uint8_t *bytes)
1848 : {
1849 531 : struct tevent_req *req;
1850 531 : struct iovec iov;
1851 531 : NTSTATUS status;
1852 :
1853 378503 : iov.iov_base = discard_const_p(void, bytes);
1854 378503 : iov.iov_len = num_bytes;
1855 :
1856 378503 : req = smb1cli_req_create(mem_ctx, ev, conn, smb_command,
1857 : additional_flags, clear_flags,
1858 : additional_flags2, clear_flags2,
1859 : timeout_msec,
1860 : pid, tcon, session,
1861 : wct, vwv, 1, &iov);
1862 378503 : if (req == NULL) {
1863 0 : return NULL;
1864 : }
1865 378503 : if (!tevent_req_is_in_progress(req)) {
1866 0 : return tevent_req_post(req, ev);
1867 : }
1868 378503 : status = smb1cli_req_chain_submit(&req, 1);
1869 378503 : if (tevent_req_nterror(req, status)) {
1870 0 : return tevent_req_post(req, ev);
1871 : }
1872 378503 : return req;
1873 : }
1874 :
1875 952950 : static void smb1cli_req_writev_done(struct tevent_req *subreq)
1876 : {
1877 8249 : struct tevent_req *req =
1878 952950 : tevent_req_callback_data(subreq,
1879 : struct tevent_req);
1880 8249 : struct smbXcli_req_state *state =
1881 952950 : tevent_req_data(req,
1882 : struct smbXcli_req_state);
1883 8249 : ssize_t nwritten;
1884 8249 : int err;
1885 :
1886 952950 : state->write_req = NULL;
1887 :
1888 952950 : nwritten = writev_recv(subreq, &err);
1889 952950 : TALLOC_FREE(subreq);
1890 952950 : if (nwritten == -1) {
1891 : /* here, we need to notify all pending requests */
1892 0 : NTSTATUS status = map_nt_error_from_unix_common(err);
1893 0 : smbXcli_conn_disconnect(state->conn, status);
1894 0 : return;
1895 : }
1896 :
1897 952950 : if (state->one_way) {
1898 1679 : state->inbuf = NULL;
1899 1679 : tevent_req_done(req);
1900 1679 : return;
1901 : }
1902 : }
1903 :
1904 2940355 : static void smbXcli_conn_received(struct tevent_req *subreq)
1905 : {
1906 22535 : struct smbXcli_conn *conn =
1907 2940355 : tevent_req_callback_data(subreq,
1908 : struct smbXcli_conn);
1909 2940355 : TALLOC_CTX *frame = talloc_stackframe();
1910 22535 : NTSTATUS status;
1911 22535 : uint8_t *inbuf;
1912 22535 : ssize_t received;
1913 22535 : int err;
1914 :
1915 2940355 : if (subreq != conn->read_smb_req) {
1916 0 : DEBUG(1, ("Internal error: cli_smb_received called with "
1917 : "unexpected subreq\n"));
1918 0 : smbXcli_conn_disconnect(conn, NT_STATUS_INTERNAL_ERROR);
1919 0 : TALLOC_FREE(frame);
1920 0 : return;
1921 : }
1922 2940355 : conn->read_smb_req = NULL;
1923 :
1924 2940355 : received = read_smb_recv(subreq, frame, &inbuf, &err);
1925 2940355 : TALLOC_FREE(subreq);
1926 2940355 : if (received == -1) {
1927 266 : status = map_nt_error_from_unix_common(err);
1928 266 : smbXcli_conn_disconnect(conn, status);
1929 266 : TALLOC_FREE(frame);
1930 266 : return;
1931 : }
1932 :
1933 2940089 : status = conn->dispatch_incoming(conn, frame, inbuf);
1934 2940089 : TALLOC_FREE(frame);
1935 2940089 : if (NT_STATUS_IS_OK(status)) {
1936 : /*
1937 : * We should not do any more processing
1938 : * as the dispatch function called
1939 : * tevent_req_done().
1940 : */
1941 756763 : return;
1942 : }
1943 :
1944 2176765 : if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1945 : /*
1946 : * We got an error, so notify all pending requests
1947 : */
1948 9 : smbXcli_conn_disconnect(conn, status);
1949 9 : return;
1950 : }
1951 :
1952 : /*
1953 : * We got NT_STATUS_RETRY, so we may ask for a
1954 : * next incoming pdu.
1955 : */
1956 2176756 : if (!smbXcli_conn_receive_next(conn)) {
1957 0 : smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1958 : }
1959 : }
1960 :
1961 932608 : static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
1962 : struct iovec **piov, int *pnum_iov)
1963 : {
1964 7859 : struct iovec *iov;
1965 7859 : size_t num_iov;
1966 7859 : size_t buflen;
1967 7859 : size_t taken;
1968 7859 : size_t remaining;
1969 7859 : uint8_t *hdr;
1970 7859 : uint8_t cmd;
1971 7859 : uint32_t wct_ofs;
1972 7859 : NTSTATUS status;
1973 932608 : size_t min_size = MIN_SMB_SIZE;
1974 :
1975 932608 : buflen = smb_len_tcp(buf);
1976 932608 : taken = 0;
1977 :
1978 932608 : hdr = buf + NBT_HDR_SIZE;
1979 :
1980 932608 : status = smb1cli_pull_raw_error(hdr);
1981 932608 : if (NT_STATUS_IS_ERR(status)) {
1982 : /*
1983 : * This is an ugly hack to support OS/2
1984 : * which skips the byte_count in the DATA block
1985 : * on some error responses.
1986 : *
1987 : * See bug #9096
1988 : */
1989 465603 : min_size -= sizeof(uint16_t);
1990 : }
1991 :
1992 932608 : if (buflen < min_size) {
1993 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
1994 : }
1995 :
1996 : /*
1997 : * This returns iovec elements in the following order:
1998 : *
1999 : * - SMB header
2000 : *
2001 : * - Parameter Block
2002 : * - Data Block
2003 : *
2004 : * - Parameter Block
2005 : * - Data Block
2006 : *
2007 : * - Parameter Block
2008 : * - Data Block
2009 : */
2010 932608 : num_iov = 1;
2011 :
2012 932608 : iov = talloc_array(mem_ctx, struct iovec, num_iov);
2013 932608 : if (iov == NULL) {
2014 0 : return NT_STATUS_NO_MEMORY;
2015 : }
2016 932608 : iov[0].iov_base = hdr;
2017 932608 : iov[0].iov_len = HDR_WCT;
2018 932608 : taken += HDR_WCT;
2019 :
2020 932608 : cmd = CVAL(hdr, HDR_COM);
2021 932608 : wct_ofs = HDR_WCT;
2022 :
2023 7897 : while (true) {
2024 932646 : size_t len = buflen - taken;
2025 7861 : struct iovec *cur;
2026 7861 : struct iovec *iov_tmp;
2027 7861 : uint8_t wct;
2028 7861 : uint32_t bcc_ofs;
2029 7861 : uint16_t bcc;
2030 7861 : size_t needed;
2031 :
2032 : /*
2033 : * we need at least WCT
2034 : */
2035 932646 : needed = sizeof(uint8_t);
2036 932646 : if (len < needed) {
2037 0 : DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2038 : __location__, (int)len, (int)needed));
2039 0 : goto inval;
2040 : }
2041 :
2042 : /*
2043 : * Now we check if the specified words are there
2044 : */
2045 932646 : wct = CVAL(hdr, wct_ofs);
2046 932646 : needed += wct * sizeof(uint16_t);
2047 932646 : if (len < needed) {
2048 0 : DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2049 : __location__, (int)len, (int)needed));
2050 0 : goto inval;
2051 : }
2052 :
2053 932646 : if ((num_iov == 1) &&
2054 7861 : (len == needed) &&
2055 0 : NT_STATUS_IS_ERR(status))
2056 : {
2057 : /*
2058 : * This is an ugly hack to support OS/2
2059 : * which skips the byte_count in the DATA block
2060 : * on some error responses.
2061 : *
2062 : * See bug #9096
2063 : */
2064 0 : iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2065 : num_iov + 2);
2066 0 : if (iov_tmp == NULL) {
2067 0 : TALLOC_FREE(iov);
2068 0 : return NT_STATUS_NO_MEMORY;
2069 : }
2070 0 : iov = iov_tmp;
2071 0 : cur = &iov[num_iov];
2072 0 : num_iov += 2;
2073 :
2074 0 : cur[0].iov_len = 0;
2075 0 : cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2076 0 : cur[1].iov_len = 0;
2077 0 : cur[1].iov_base = cur[0].iov_base;
2078 :
2079 0 : taken += needed;
2080 0 : break;
2081 : }
2082 :
2083 : /*
2084 : * we need at least BCC
2085 : */
2086 932646 : needed += sizeof(uint16_t);
2087 932646 : if (len < needed) {
2088 0 : DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2089 : __location__, (int)len, (int)needed));
2090 0 : goto inval;
2091 : }
2092 :
2093 : /*
2094 : * Now we check if the specified bytes are there
2095 : */
2096 932646 : bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
2097 932646 : bcc = SVAL(hdr, bcc_ofs);
2098 932646 : needed += bcc * sizeof(uint8_t);
2099 932646 : if (len < needed) {
2100 0 : DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2101 : __location__, (int)len, (int)needed));
2102 0 : goto inval;
2103 : }
2104 :
2105 : /*
2106 : * we allocate 2 iovec structures for words and bytes
2107 : */
2108 932646 : iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2109 : num_iov + 2);
2110 932646 : if (iov_tmp == NULL) {
2111 0 : TALLOC_FREE(iov);
2112 0 : return NT_STATUS_NO_MEMORY;
2113 : }
2114 932646 : iov = iov_tmp;
2115 932646 : cur = &iov[num_iov];
2116 932646 : num_iov += 2;
2117 :
2118 932646 : cur[0].iov_len = wct * sizeof(uint16_t);
2119 932646 : cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2120 932646 : cur[1].iov_len = bcc * sizeof(uint8_t);
2121 932646 : cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
2122 :
2123 932646 : taken += needed;
2124 :
2125 932646 : if (!smb1cli_is_andx_req(cmd)) {
2126 : /*
2127 : * If the current command does not have AndX chanining
2128 : * we are done.
2129 : */
2130 675014 : break;
2131 : }
2132 :
2133 250777 : if (wct == 0 && bcc == 0) {
2134 : /*
2135 : * An empty response also ends the chain,
2136 : * most likely with an error.
2137 : */
2138 47208 : break;
2139 : }
2140 :
2141 203202 : if (wct < 2) {
2142 0 : DEBUG(10, ("%s: wct[%d] < 2 for cmd[0x%02X]\n",
2143 : __location__, (int)wct, (int)cmd));
2144 0 : goto inval;
2145 : }
2146 203202 : cmd = CVAL(cur[0].iov_base, 0);
2147 203202 : if (cmd == 0xFF) {
2148 : /*
2149 : * If it is the end of the chain we are also done.
2150 : */
2151 202527 : break;
2152 : }
2153 38 : wct_ofs = SVAL(cur[0].iov_base, 2);
2154 :
2155 38 : if (wct_ofs < taken) {
2156 0 : goto inval;
2157 : }
2158 38 : if (wct_ofs > buflen) {
2159 0 : goto inval;
2160 : }
2161 :
2162 : /*
2163 : * we consumed everything up to the start of the next
2164 : * parameter block.
2165 : */
2166 36 : taken = wct_ofs;
2167 : }
2168 :
2169 932608 : remaining = buflen - taken;
2170 :
2171 932608 : if (remaining > 0 && num_iov >= 3) {
2172 : /*
2173 : * The last DATA block gets the remaining
2174 : * bytes, this is needed to support
2175 : * CAP_LARGE_WRITEX and CAP_LARGE_READX.
2176 : */
2177 965 : iov[num_iov-1].iov_len += remaining;
2178 : }
2179 :
2180 932608 : *piov = iov;
2181 932608 : *pnum_iov = num_iov;
2182 932608 : return NT_STATUS_OK;
2183 :
2184 0 : inval:
2185 0 : TALLOC_FREE(iov);
2186 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2187 : }
2188 :
2189 932684 : static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2190 : TALLOC_CTX *tmp_mem,
2191 : uint8_t *inbuf)
2192 : {
2193 7859 : struct tevent_req *req;
2194 7859 : struct smbXcli_req_state *state;
2195 7859 : NTSTATUS status;
2196 7859 : size_t num_pending;
2197 7859 : size_t i;
2198 7859 : uint8_t cmd;
2199 7859 : uint16_t mid;
2200 7859 : bool oplock_break;
2201 932684 : uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
2202 932684 : size_t len = smb_len_tcp(inbuf);
2203 932684 : struct iovec *iov = NULL;
2204 932684 : int num_iov = 0;
2205 932684 : struct tevent_req **chain = NULL;
2206 932684 : size_t num_chained = 0;
2207 932684 : size_t num_responses = 0;
2208 :
2209 932684 : if (conn->smb1.read_braw_req != NULL) {
2210 60 : req = conn->smb1.read_braw_req;
2211 60 : conn->smb1.read_braw_req = NULL;
2212 60 : state = tevent_req_data(req, struct smbXcli_req_state);
2213 :
2214 60 : smbXcli_req_unset_pending(req);
2215 :
2216 60 : if (state->smb1.recv_iov == NULL) {
2217 : /*
2218 : * For requests with more than
2219 : * one response, we have to readd the
2220 : * recv_iov array.
2221 : */
2222 0 : state->smb1.recv_iov = talloc_zero_array(state,
2223 : struct iovec,
2224 : 3);
2225 0 : if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2226 0 : return NT_STATUS_OK;
2227 : }
2228 : }
2229 :
2230 60 : state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
2231 60 : state->smb1.recv_iov[0].iov_len = len;
2232 60 : ZERO_STRUCT(state->smb1.recv_iov[1]);
2233 60 : ZERO_STRUCT(state->smb1.recv_iov[2]);
2234 :
2235 60 : state->smb1.recv_cmd = SMBreadBraw;
2236 60 : state->smb1.recv_status = NT_STATUS_OK;
2237 60 : state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2238 :
2239 60 : tevent_req_done(req);
2240 60 : return NT_STATUS_OK;
2241 : }
2242 :
2243 932624 : if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
2244 149460 : && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
2245 0 : DEBUG(10, ("Got non-SMB PDU\n"));
2246 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2247 : }
2248 :
2249 : /*
2250 : * If we supported multiple encryption contexts
2251 : * here we'd look up based on tid.
2252 : */
2253 932624 : if (common_encryption_on(conn->smb1.trans_enc)
2254 149460 : && (CVAL(inbuf, 0) == 0)) {
2255 0 : uint16_t enc_ctx_num;
2256 :
2257 149460 : status = get_enc_ctx_num(inbuf, &enc_ctx_num);
2258 149460 : if (!NT_STATUS_IS_OK(status)) {
2259 0 : DEBUG(10, ("get_enc_ctx_num returned %s\n",
2260 : nt_errstr(status)));
2261 0 : return status;
2262 : }
2263 :
2264 149460 : if (enc_ctx_num != conn->smb1.trans_enc->enc_ctx_num) {
2265 0 : DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
2266 : enc_ctx_num,
2267 : conn->smb1.trans_enc->enc_ctx_num));
2268 0 : return NT_STATUS_INVALID_HANDLE;
2269 : }
2270 :
2271 149460 : status = common_decrypt_buffer(conn->smb1.trans_enc,
2272 : (char *)inbuf);
2273 149460 : if (!NT_STATUS_IS_OK(status)) {
2274 0 : DEBUG(10, ("common_decrypt_buffer returned %s\n",
2275 : nt_errstr(status)));
2276 0 : return status;
2277 : }
2278 149460 : inhdr = inbuf + NBT_HDR_SIZE;
2279 149460 : len = smb_len_nbt(inbuf);
2280 : }
2281 :
2282 932624 : mid = SVAL(inhdr, HDR_MID);
2283 932624 : num_pending = talloc_array_length(conn->pending);
2284 :
2285 1005470 : for (i=0; i<num_pending; i++) {
2286 1005456 : if (mid == smb1cli_req_mid(conn->pending[i])) {
2287 924751 : break;
2288 : }
2289 : }
2290 932624 : if (i == num_pending) {
2291 : /* Dump unexpected reply */
2292 14 : return NT_STATUS_RETRY;
2293 : }
2294 :
2295 932610 : oplock_break = false;
2296 :
2297 932610 : if (mid == 0xffff) {
2298 : /*
2299 : * Paranoia checks that this is really an oplock break request.
2300 : */
2301 168 : oplock_break = (len == 51); /* hdr + 8 words */
2302 168 : oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
2303 168 : oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
2304 168 : oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
2305 168 : oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
2306 :
2307 168 : if (!oplock_break) {
2308 : /* Dump unexpected reply */
2309 0 : return NT_STATUS_RETRY;
2310 : }
2311 : }
2312 :
2313 932610 : req = conn->pending[i];
2314 932610 : state = tevent_req_data(req, struct smbXcli_req_state);
2315 :
2316 932610 : if (!oplock_break /* oplock breaks are not signed */
2317 932442 : && !smb1_signing_check_pdu(conn->smb1.signing,
2318 932442 : inhdr, len, state->smb1.seqnum+1)) {
2319 2 : DEBUG(10, ("cli_check_sign_mac failed\n"));
2320 2 : return NT_STATUS_ACCESS_DENIED;
2321 : }
2322 :
2323 932608 : status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
2324 : &iov, &num_iov);
2325 932608 : if (!NT_STATUS_IS_OK(status)) {
2326 0 : DEBUG(10,("smb1cli_inbuf_parse_chain - %s\n",
2327 : nt_errstr(status)));
2328 0 : return status;
2329 : }
2330 :
2331 932608 : cmd = CVAL(inhdr, HDR_COM);
2332 932608 : status = smb1cli_pull_raw_error(inhdr);
2333 :
2334 932608 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
2335 4 : (state->session != NULL) && state->session->disconnect_expired)
2336 : {
2337 : /*
2338 : * this should be a short term hack
2339 : * until the upper layers have implemented
2340 : * re-authentication.
2341 : */
2342 0 : return status;
2343 : }
2344 :
2345 932608 : if (state->smb1.chained_requests == NULL) {
2346 932565 : if (num_iov != 3) {
2347 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2348 : }
2349 :
2350 932565 : smbXcli_req_unset_pending(req);
2351 :
2352 932565 : if (state->smb1.recv_iov == NULL) {
2353 : /*
2354 : * For requests with more than
2355 : * one response, we have to readd the
2356 : * recv_iov array.
2357 : */
2358 42 : state->smb1.recv_iov = talloc_zero_array(state,
2359 : struct iovec,
2360 : 3);
2361 42 : if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2362 0 : return NT_STATUS_OK;
2363 : }
2364 : }
2365 :
2366 932565 : state->smb1.recv_cmd = cmd;
2367 932565 : state->smb1.recv_status = status;
2368 932565 : state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2369 :
2370 932565 : state->smb1.recv_iov[0] = iov[0];
2371 932565 : state->smb1.recv_iov[1] = iov[1];
2372 932565 : state->smb1.recv_iov[2] = iov[2];
2373 :
2374 932565 : if (talloc_array_length(conn->pending) == 0) {
2375 763264 : tevent_req_done(req);
2376 763264 : return NT_STATUS_OK;
2377 : }
2378 :
2379 169301 : tevent_req_defer_callback(req, state->ev);
2380 169301 : tevent_req_done(req);
2381 169301 : return NT_STATUS_RETRY;
2382 : }
2383 :
2384 43 : chain = talloc_move(tmp_mem, &state->smb1.chained_requests);
2385 43 : num_chained = talloc_array_length(chain);
2386 43 : num_responses = (num_iov - 1)/2;
2387 :
2388 43 : if (num_responses > num_chained) {
2389 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2390 : }
2391 :
2392 139 : for (i=0; i<num_chained; i++) {
2393 96 : size_t iov_idx = 1 + (i*2);
2394 96 : struct iovec *cur = &iov[iov_idx];
2395 6 : uint8_t *inbuf_ref;
2396 :
2397 96 : req = chain[i];
2398 96 : state = tevent_req_data(req, struct smbXcli_req_state);
2399 :
2400 96 : smbXcli_req_unset_pending(req);
2401 :
2402 : /*
2403 : * as we finish multiple requests here
2404 : * we need to defer the callbacks as
2405 : * they could destroy our current stack state.
2406 : */
2407 96 : tevent_req_defer_callback(req, state->ev);
2408 :
2409 96 : if (i >= num_responses) {
2410 15 : tevent_req_nterror(req, NT_STATUS_REQUEST_ABORTED);
2411 15 : continue;
2412 : }
2413 :
2414 81 : if (state->smb1.recv_iov == NULL) {
2415 : /*
2416 : * For requests with more than
2417 : * one response, we have to readd the
2418 : * recv_iov array.
2419 : */
2420 0 : state->smb1.recv_iov = talloc_zero_array(state,
2421 : struct iovec,
2422 : 3);
2423 0 : if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2424 0 : continue;
2425 : }
2426 : }
2427 :
2428 81 : state->smb1.recv_cmd = cmd;
2429 :
2430 81 : if (i == (num_responses - 1)) {
2431 : /*
2432 : * The last request in the chain gets the status
2433 : */
2434 43 : state->smb1.recv_status = status;
2435 : } else {
2436 38 : cmd = CVAL(cur[0].iov_base, 0);
2437 38 : state->smb1.recv_status = NT_STATUS_OK;
2438 : }
2439 :
2440 81 : state->inbuf = inbuf;
2441 :
2442 : /*
2443 : * Note: here we use talloc_reference() in a way
2444 : * that does not expose it to the caller.
2445 : */
2446 81 : inbuf_ref = talloc_reference(state->smb1.recv_iov, inbuf);
2447 81 : if (tevent_req_nomem(inbuf_ref, req)) {
2448 0 : continue;
2449 : }
2450 :
2451 : /* copy the related buffers */
2452 81 : state->smb1.recv_iov[0] = iov[0];
2453 81 : state->smb1.recv_iov[1] = cur[0];
2454 81 : state->smb1.recv_iov[2] = cur[1];
2455 :
2456 81 : tevent_req_done(req);
2457 : }
2458 :
2459 43 : return NT_STATUS_RETRY;
2460 : }
2461 :
2462 933484 : NTSTATUS smb1cli_req_recv(struct tevent_req *req,
2463 : TALLOC_CTX *mem_ctx,
2464 : struct iovec **piov,
2465 : uint8_t **phdr,
2466 : uint8_t *pwct,
2467 : uint16_t **pvwv,
2468 : uint32_t *pvwv_offset,
2469 : uint32_t *pnum_bytes,
2470 : uint8_t **pbytes,
2471 : uint32_t *pbytes_offset,
2472 : uint8_t **pinbuf,
2473 : const struct smb1cli_req_expected_response *expected,
2474 : size_t num_expected)
2475 : {
2476 7861 : struct smbXcli_req_state *state =
2477 933484 : tevent_req_data(req,
2478 : struct smbXcli_req_state);
2479 933484 : NTSTATUS status = NT_STATUS_OK;
2480 933484 : struct iovec *recv_iov = NULL;
2481 933484 : uint8_t *hdr = NULL;
2482 933484 : uint8_t wct = 0;
2483 933484 : uint32_t vwv_offset = 0;
2484 933484 : uint16_t *vwv = NULL;
2485 933484 : uint32_t num_bytes = 0;
2486 933484 : uint32_t bytes_offset = 0;
2487 933484 : uint8_t *bytes = NULL;
2488 7861 : size_t i;
2489 933484 : bool found_status = false;
2490 933484 : bool found_size = false;
2491 :
2492 933484 : if (piov != NULL) {
2493 933183 : *piov = NULL;
2494 : }
2495 933484 : if (phdr != NULL) {
2496 552765 : *phdr = 0;
2497 : }
2498 933484 : if (pwct != NULL) {
2499 933004 : *pwct = 0;
2500 : }
2501 933484 : if (pvwv != NULL) {
2502 933158 : *pvwv = NULL;
2503 : }
2504 933484 : if (pvwv_offset != NULL) {
2505 95545 : *pvwv_offset = 0;
2506 : }
2507 933484 : if (pnum_bytes != NULL) {
2508 932546 : *pnum_bytes = 0;
2509 : }
2510 933484 : if (pbytes != NULL) {
2511 932546 : *pbytes = NULL;
2512 : }
2513 933484 : if (pbytes_offset != NULL) {
2514 95579 : *pbytes_offset = 0;
2515 : }
2516 933484 : if (pinbuf != NULL) {
2517 829161 : *pinbuf = NULL;
2518 : }
2519 :
2520 933484 : if (state->inbuf != NULL) {
2521 932706 : recv_iov = state->smb1.recv_iov;
2522 932706 : state->smb1.recv_iov = NULL;
2523 932706 : if (state->smb1.recv_cmd != SMBreadBraw) {
2524 932646 : hdr = (uint8_t *)recv_iov[0].iov_base;
2525 932646 : wct = recv_iov[1].iov_len/2;
2526 932646 : vwv = (uint16_t *)recv_iov[1].iov_base;
2527 932646 : vwv_offset = PTR_DIFF(vwv, hdr);
2528 932646 : num_bytes = recv_iov[2].iov_len;
2529 932646 : bytes = (uint8_t *)recv_iov[2].iov_base;
2530 932646 : bytes_offset = PTR_DIFF(bytes, hdr);
2531 : }
2532 : }
2533 :
2534 933484 : if (tevent_req_is_nterror(req, &status)) {
2535 2416 : for (i=0; i < num_expected; i++) {
2536 1782 : if (NT_STATUS_EQUAL(status, expected[i].status)) {
2537 0 : found_status = true;
2538 0 : break;
2539 : }
2540 : }
2541 :
2542 634 : if (found_status) {
2543 0 : return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2544 : }
2545 :
2546 634 : return status;
2547 : }
2548 :
2549 932850 : if (num_expected == 0) {
2550 916988 : found_status = true;
2551 916988 : found_size = true;
2552 : }
2553 :
2554 932850 : status = state->smb1.recv_status;
2555 :
2556 937929 : for (i=0; i < num_expected; i++) {
2557 20820 : if (!NT_STATUS_EQUAL(status, expected[i].status)) {
2558 4063 : continue;
2559 : }
2560 :
2561 16757 : found_status = true;
2562 16757 : if (expected[i].wct == 0) {
2563 274 : found_size = true;
2564 274 : break;
2565 : }
2566 :
2567 16483 : if (expected[i].wct == wct) {
2568 15326 : found_size = true;
2569 15326 : break;
2570 : }
2571 : }
2572 :
2573 932850 : if (!found_status) {
2574 121 : return status;
2575 : }
2576 :
2577 932729 : if (!found_size) {
2578 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2579 : }
2580 :
2581 932729 : if (piov != NULL) {
2582 932453 : *piov = talloc_move(mem_ctx, &recv_iov);
2583 : }
2584 :
2585 932729 : if (phdr != NULL) {
2586 552114 : *phdr = hdr;
2587 : }
2588 932729 : if (pwct != NULL) {
2589 932274 : *pwct = wct;
2590 : }
2591 932729 : if (pvwv != NULL) {
2592 932428 : *pvwv = vwv;
2593 : }
2594 932729 : if (pvwv_offset != NULL) {
2595 95542 : *pvwv_offset = vwv_offset;
2596 : }
2597 932729 : if (pnum_bytes != NULL) {
2598 931864 : *pnum_bytes = num_bytes;
2599 : }
2600 932729 : if (pbytes != NULL) {
2601 931864 : *pbytes = bytes;
2602 : }
2603 932729 : if (pbytes_offset != NULL) {
2604 95576 : *pbytes_offset = bytes_offset;
2605 : }
2606 932729 : if (pinbuf != NULL) {
2607 829076 : *pinbuf = state->inbuf;
2608 : }
2609 :
2610 932729 : return status;
2611 : }
2612 :
2613 22580 : size_t smb1cli_req_wct_ofs(struct tevent_req **reqs, int num_reqs)
2614 : {
2615 3 : size_t wct_ofs;
2616 3 : int i;
2617 :
2618 22580 : wct_ofs = HDR_WCT;
2619 :
2620 22618 : for (i=0; i<num_reqs; i++) {
2621 3 : struct smbXcli_req_state *state;
2622 38 : state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2623 76 : wct_ofs += smbXcli_iov_len(state->smb1.iov+2,
2624 38 : state->smb1.iov_count-2);
2625 38 : wct_ofs = (wct_ofs + 3) & ~3;
2626 : }
2627 22580 : return wct_ofs;
2628 : }
2629 :
2630 953056 : NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
2631 : {
2632 8249 : struct smbXcli_req_state *first_state =
2633 953056 : tevent_req_data(reqs[0],
2634 : struct smbXcli_req_state);
2635 8249 : struct smbXcli_req_state *state;
2636 8249 : size_t wct_offset;
2637 953056 : size_t chain_padding = 0;
2638 8249 : int i, iovlen;
2639 953056 : struct iovec *iov = NULL;
2640 8249 : struct iovec *this_iov;
2641 8249 : NTSTATUS status;
2642 8249 : ssize_t nbt_len;
2643 :
2644 953056 : if (num_reqs == 1) {
2645 953013 : return smb1cli_req_writev_submit(reqs[0], first_state,
2646 953013 : first_state->smb1.iov,
2647 : first_state->smb1.iov_count);
2648 : }
2649 :
2650 40 : iovlen = 0;
2651 139 : for (i=0; i<num_reqs; i++) {
2652 96 : if (!tevent_req_is_in_progress(reqs[i])) {
2653 0 : return NT_STATUS_INTERNAL_ERROR;
2654 : }
2655 :
2656 96 : state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2657 :
2658 96 : if (state->smb1.iov_count < 4) {
2659 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
2660 : }
2661 :
2662 96 : if (i == 0) {
2663 : /*
2664 : * The NBT and SMB header
2665 : */
2666 43 : iovlen += 2;
2667 : } else {
2668 : /*
2669 : * Chain padding
2670 : */
2671 53 : iovlen += 1;
2672 : }
2673 :
2674 : /*
2675 : * words and bytes
2676 : */
2677 96 : iovlen += state->smb1.iov_count - 2;
2678 : }
2679 :
2680 43 : iov = talloc_zero_array(first_state, struct iovec, iovlen);
2681 43 : if (iov == NULL) {
2682 0 : return NT_STATUS_NO_MEMORY;
2683 : }
2684 :
2685 43 : first_state->smb1.chained_requests = (struct tevent_req **)talloc_memdup(
2686 : first_state, reqs, sizeof(*reqs) * num_reqs);
2687 43 : if (first_state->smb1.chained_requests == NULL) {
2688 0 : TALLOC_FREE(iov);
2689 0 : return NT_STATUS_NO_MEMORY;
2690 : }
2691 :
2692 40 : wct_offset = HDR_WCT;
2693 40 : this_iov = iov;
2694 :
2695 139 : for (i=0; i<num_reqs; i++) {
2696 96 : size_t next_padding = 0;
2697 6 : uint16_t *vwv;
2698 :
2699 96 : state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2700 :
2701 96 : if (i < num_reqs-1) {
2702 53 : if (!smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))
2703 53 : || CVAL(state->smb1.hdr, HDR_WCT) < 2) {
2704 0 : TALLOC_FREE(iov);
2705 0 : TALLOC_FREE(first_state->smb1.chained_requests);
2706 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
2707 : }
2708 : }
2709 :
2710 192 : wct_offset += smbXcli_iov_len(state->smb1.iov+2,
2711 96 : state->smb1.iov_count-2) + 1;
2712 96 : if ((wct_offset % 4) != 0) {
2713 75 : next_padding = 4 - (wct_offset % 4);
2714 : }
2715 96 : wct_offset += next_padding;
2716 96 : vwv = state->smb1.vwv;
2717 :
2718 96 : if (i < num_reqs-1) {
2719 3 : struct smbXcli_req_state *next_state =
2720 53 : tevent_req_data(reqs[i+1],
2721 : struct smbXcli_req_state);
2722 53 : SCVAL(vwv+0, 0, CVAL(next_state->smb1.hdr, HDR_COM));
2723 53 : SCVAL(vwv+0, 1, 0);
2724 53 : SSVAL(vwv+1, 0, wct_offset);
2725 43 : } else if (smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))) {
2726 : /* properly end the chain */
2727 33 : SCVAL(vwv+0, 0, 0xff);
2728 33 : SCVAL(vwv+0, 1, 0xff);
2729 33 : SSVAL(vwv+1, 0, 0);
2730 : }
2731 :
2732 96 : if (i == 0) {
2733 : /*
2734 : * The NBT and SMB header
2735 : */
2736 43 : this_iov[0] = state->smb1.iov[0];
2737 43 : this_iov[1] = state->smb1.iov[1];
2738 43 : this_iov += 2;
2739 : } else {
2740 : /*
2741 : * This one is a bit subtle. We have to add
2742 : * chain_padding bytes between the requests, and we
2743 : * have to also include the wct field of the
2744 : * subsequent requests. We use the subsequent header
2745 : * for the padding, it contains the wct field in its
2746 : * last byte.
2747 : */
2748 53 : this_iov[0].iov_len = chain_padding+1;
2749 53 : this_iov[0].iov_base = (void *)&state->smb1.hdr[
2750 53 : sizeof(state->smb1.hdr) - this_iov[0].iov_len];
2751 53 : memset(this_iov[0].iov_base, 0, this_iov[0].iov_len-1);
2752 53 : this_iov += 1;
2753 : }
2754 :
2755 : /*
2756 : * copy the words and bytes
2757 : */
2758 96 : memcpy(this_iov, state->smb1.iov+2,
2759 96 : sizeof(struct iovec) * (state->smb1.iov_count-2));
2760 96 : this_iov += state->smb1.iov_count - 2;
2761 96 : chain_padding = next_padding;
2762 : }
2763 :
2764 43 : nbt_len = iov_buflen(&iov[1], iovlen-1);
2765 43 : if ((nbt_len == -1) || (nbt_len > first_state->conn->smb1.max_xmit)) {
2766 0 : TALLOC_FREE(iov);
2767 0 : TALLOC_FREE(first_state->smb1.chained_requests);
2768 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
2769 : }
2770 :
2771 43 : status = smb1cli_req_writev_submit(reqs[0], first_state, iov, iovlen);
2772 43 : if (!NT_STATUS_IS_OK(status)) {
2773 0 : TALLOC_FREE(iov);
2774 0 : TALLOC_FREE(first_state->smb1.chained_requests);
2775 0 : return status;
2776 : }
2777 :
2778 43 : return NT_STATUS_OK;
2779 : }
2780 :
2781 42 : struct tevent_queue *smbXcli_conn_send_queue(struct smbXcli_conn *conn)
2782 : {
2783 42 : return conn->outgoing;
2784 : }
2785 :
2786 567099 : bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
2787 : {
2788 567099 : return ((tevent_queue_length(conn->outgoing) != 0)
2789 567099 : || (talloc_array_length(conn->pending) != 0));
2790 : }
2791 :
2792 1078681 : bool smbXcli_conn_dfs_supported(struct smbXcli_conn *conn)
2793 : {
2794 1078681 : if (conn->protocol >= PROTOCOL_SMB2_02) {
2795 142726 : return (smb2cli_conn_server_capabilities(conn) & SMB2_CAP_DFS);
2796 : }
2797 :
2798 935955 : return (smb1cli_conn_capabilities(conn) & CAP_DFS);
2799 : }
2800 :
2801 23357 : bool smb2cli_conn_req_possible(struct smbXcli_conn *conn, uint32_t *max_dyn_len)
2802 : {
2803 23357 : uint16_t credits = 1;
2804 :
2805 23357 : if (conn->smb2.cur_credits == 0) {
2806 0 : if (max_dyn_len != NULL) {
2807 0 : *max_dyn_len = 0;
2808 : }
2809 0 : return false;
2810 : }
2811 :
2812 23357 : if (conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2813 22119 : credits = conn->smb2.cur_credits;
2814 : }
2815 :
2816 23357 : if (max_dyn_len != NULL) {
2817 23357 : *max_dyn_len = credits * 65536;
2818 : }
2819 :
2820 23357 : return true;
2821 : }
2822 :
2823 143351 : uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
2824 : {
2825 143351 : return conn->smb2.server.capabilities;
2826 : }
2827 :
2828 0 : uint16_t smb2cli_conn_server_security_mode(struct smbXcli_conn *conn)
2829 : {
2830 0 : return conn->smb2.server.security_mode;
2831 : }
2832 :
2833 406 : uint16_t smb2cli_conn_server_signing_algo(struct smbXcli_conn *conn)
2834 : {
2835 406 : return conn->smb2.server.sign_algo;
2836 : }
2837 :
2838 0 : uint16_t smb2cli_conn_server_encryption_algo(struct smbXcli_conn *conn)
2839 : {
2840 0 : return conn->smb2.server.cipher;
2841 : }
2842 :
2843 18702 : uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
2844 : {
2845 18702 : return conn->smb2.server.max_trans_size;
2846 : }
2847 :
2848 2790 : uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
2849 : {
2850 2790 : return conn->smb2.server.max_read_size;
2851 : }
2852 :
2853 2614 : uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
2854 : {
2855 2614 : return conn->smb2.server.max_write_size;
2856 : }
2857 :
2858 14161 : void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
2859 : uint16_t max_credits)
2860 : {
2861 14161 : conn->smb2.max_credits = max_credits;
2862 14161 : }
2863 :
2864 30 : uint16_t smb2cli_conn_get_cur_credits(struct smbXcli_conn *conn)
2865 : {
2866 30 : return conn->smb2.cur_credits;
2867 : }
2868 :
2869 0 : uint8_t smb2cli_conn_get_io_priority(struct smbXcli_conn *conn)
2870 : {
2871 0 : if (conn->protocol < PROTOCOL_SMB3_11) {
2872 0 : return 0;
2873 : }
2874 :
2875 0 : return conn->smb2.io_priority;
2876 : }
2877 :
2878 0 : void smb2cli_conn_set_io_priority(struct smbXcli_conn *conn,
2879 : uint8_t io_priority)
2880 : {
2881 0 : conn->smb2.io_priority = io_priority;
2882 0 : }
2883 :
2884 0 : uint32_t smb2cli_conn_cc_chunk_len(struct smbXcli_conn *conn)
2885 : {
2886 0 : return conn->smb2.cc_chunk_len;
2887 : }
2888 :
2889 0 : void smb2cli_conn_set_cc_chunk_len(struct smbXcli_conn *conn,
2890 : uint32_t chunk_len)
2891 : {
2892 0 : conn->smb2.cc_chunk_len = chunk_len;
2893 0 : }
2894 :
2895 0 : uint32_t smb2cli_conn_cc_max_chunks(struct smbXcli_conn *conn)
2896 : {
2897 0 : return conn->smb2.cc_max_chunks;
2898 : }
2899 :
2900 0 : void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
2901 : uint32_t max_chunks)
2902 : {
2903 0 : conn->smb2.cc_max_chunks = max_chunks;
2904 0 : }
2905 :
2906 : static void smb2cli_req_cancel_done(struct tevent_req *subreq);
2907 :
2908 1620 : static bool smb2cli_req_cancel(struct tevent_req *req)
2909 : {
2910 16 : struct smbXcli_req_state *state =
2911 1620 : tevent_req_data(req,
2912 : struct smbXcli_req_state);
2913 1620 : struct smbXcli_tcon *tcon = state->tcon;
2914 1620 : struct smbXcli_session *session = state->session;
2915 1620 : uint8_t *fixed = state->smb2.pad;
2916 1620 : uint16_t fixed_len = 4;
2917 16 : struct tevent_req *subreq;
2918 16 : struct smbXcli_req_state *substate;
2919 16 : NTSTATUS status;
2920 :
2921 1620 : if (state->smb2.cancel_mid == UINT64_MAX) {
2922 : /*
2923 : * We already send a cancel,
2924 : * make sure we don't do it
2925 : * twice, otherwise we may
2926 : * expose the same NONCE for
2927 : * AES-128-GMAC signing
2928 : */
2929 0 : return true;
2930 : }
2931 :
2932 1620 : SSVAL(fixed, 0, 0x04);
2933 1620 : SSVAL(fixed, 2, 0);
2934 :
2935 1620 : subreq = smb2cli_req_create(state, state->ev,
2936 : state->conn,
2937 : SMB2_OP_CANCEL,
2938 : 0, 0, /* flags */
2939 : 0, /* timeout */
2940 : tcon, session,
2941 : fixed, fixed_len,
2942 : NULL, 0, 0);
2943 1620 : if (subreq == NULL) {
2944 0 : return false;
2945 : }
2946 1620 : substate = tevent_req_data(subreq, struct smbXcli_req_state);
2947 :
2948 1620 : substate->smb2.cancel_mid = BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID);
2949 :
2950 1620 : SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, state->smb2.cancel_flags);
2951 1620 : SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, state->smb2.cancel_mid);
2952 1620 : SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, state->smb2.cancel_aid);
2953 :
2954 : /*
2955 : * remember that we don't send a cancel again
2956 : */
2957 1620 : state->smb2.cancel_mid = UINT64_MAX;
2958 :
2959 1620 : status = smb2cli_req_compound_submit(&subreq, 1);
2960 1620 : if (!NT_STATUS_IS_OK(status)) {
2961 0 : TALLOC_FREE(subreq);
2962 0 : return false;
2963 : }
2964 :
2965 1620 : tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2966 :
2967 1620 : return true;
2968 : }
2969 :
2970 0 : static void smb2cli_req_cancel_done(struct tevent_req *subreq)
2971 : {
2972 : /* we do not care about the result */
2973 0 : TALLOC_FREE(subreq);
2974 0 : }
2975 :
2976 1633 : struct timeval smbXcli_req_endtime(struct tevent_req *req)
2977 : {
2978 1633 : struct smbXcli_req_state *state = tevent_req_data(
2979 : req, struct smbXcli_req_state);
2980 :
2981 1633 : return state->endtime;
2982 : }
2983 :
2984 1884244 : struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
2985 : struct tevent_context *ev,
2986 : struct smbXcli_conn *conn,
2987 : uint16_t cmd,
2988 : uint32_t additional_flags,
2989 : uint32_t clear_flags,
2990 : uint32_t timeout_msec,
2991 : struct smbXcli_tcon *tcon,
2992 : struct smbXcli_session *session,
2993 : const uint8_t *fixed,
2994 : uint16_t fixed_len,
2995 : const uint8_t *dyn,
2996 : uint32_t dyn_len,
2997 : uint32_t max_dyn_len)
2998 : {
2999 11863 : struct tevent_req *req;
3000 11863 : struct smbXcli_req_state *state;
3001 1884244 : uint32_t flags = 0;
3002 1884244 : uint32_t tid = 0;
3003 1884244 : uint64_t uid = 0;
3004 1884244 : bool use_channel_sequence = conn->smb2.force_channel_sequence;
3005 1884244 : uint16_t channel_sequence = 0;
3006 1884244 : bool use_replay_flag = false;
3007 1884244 : enum protocol_types proto = smbXcli_conn_protocol(conn);
3008 :
3009 1884244 : req = tevent_req_create(mem_ctx, &state,
3010 : struct smbXcli_req_state);
3011 1884244 : if (req == NULL) {
3012 0 : return NULL;
3013 : }
3014 :
3015 1884244 : if ((proto > PROTOCOL_NONE) && (proto < PROTOCOL_SMB2_02)) {
3016 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3017 0 : return req;
3018 : }
3019 :
3020 1884244 : state->ev = ev;
3021 1884244 : state->conn = conn;
3022 1884244 : state->session = session;
3023 1884244 : state->tcon = tcon;
3024 :
3025 1884244 : if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
3026 0 : use_channel_sequence = true;
3027 1884244 : } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
3028 1370945 : use_channel_sequence = true;
3029 : }
3030 :
3031 1884244 : if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_00) {
3032 1370941 : use_replay_flag = true;
3033 : }
3034 :
3035 1884244 : if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
3036 1370153 : flags |= SMB2_PRIORITY_VALUE_TO_MASK(conn->smb2.io_priority);
3037 : }
3038 :
3039 1884244 : if (session) {
3040 1855115 : uid = session->smb2->session_id;
3041 :
3042 1855115 : if (use_channel_sequence) {
3043 1367575 : channel_sequence = session->smb2->channel_sequence;
3044 : }
3045 :
3046 1855115 : if (use_replay_flag && session->smb2->replay_active) {
3047 722 : additional_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3048 : }
3049 :
3050 1855115 : state->smb2.should_sign = session->smb2->should_sign;
3051 1855115 : state->smb2.should_encrypt = session->smb2->should_encrypt;
3052 1855115 : state->smb2.require_signed_response =
3053 1855115 : session->smb2->require_signed_response;
3054 :
3055 1856278 : if (cmd == SMB2_OP_SESSSETUP &&
3056 100455 : !smb2_signing_key_valid(session->smb2_channel.signing_key) &&
3057 50082 : smb2_signing_key_valid(session->smb2->signing_key))
3058 : {
3059 : /*
3060 : * a session bind needs to be signed
3061 : */
3062 2834 : state->smb2.should_sign = true;
3063 : }
3064 :
3065 1856278 : if (cmd == SMB2_OP_SESSSETUP &&
3066 50373 : !smb2_signing_key_valid(session->smb2_channel.signing_key)) {
3067 50082 : state->smb2.should_encrypt = false;
3068 : }
3069 :
3070 1855115 : if (additional_flags & SMB2_HDR_FLAG_SIGNED) {
3071 41075 : if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
3072 0 : tevent_req_nterror(req, NT_STATUS_NO_USER_SESSION_KEY);
3073 0 : return req;
3074 : }
3075 :
3076 41075 : additional_flags &= ~SMB2_HDR_FLAG_SIGNED;
3077 41075 : state->smb2.should_sign = true;
3078 : }
3079 : }
3080 :
3081 1884244 : if (tcon) {
3082 1762275 : tid = tcon->smb2.tcon_id;
3083 :
3084 1762275 : if (tcon->smb2.should_sign) {
3085 1076112 : state->smb2.should_sign = true;
3086 : }
3087 1762275 : if (tcon->smb2.should_encrypt) {
3088 6577 : state->smb2.should_encrypt = true;
3089 : }
3090 : }
3091 :
3092 1884244 : if (state->smb2.should_encrypt) {
3093 7511 : state->smb2.should_sign = false;
3094 : }
3095 :
3096 1884244 : state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
3097 1884244 : if (tevent_req_nomem(state->smb2.recv_iov, req)) {
3098 0 : return req;
3099 : }
3100 :
3101 1884244 : flags |= additional_flags;
3102 1884244 : flags &= ~clear_flags;
3103 :
3104 1884244 : state->smb2.fixed = fixed;
3105 1884244 : state->smb2.fixed_len = fixed_len;
3106 1884244 : state->smb2.dyn = dyn;
3107 1884244 : state->smb2.dyn_len = dyn_len;
3108 1884244 : state->smb2.max_dyn_len = max_dyn_len;
3109 :
3110 1884244 : if (state->smb2.should_encrypt) {
3111 7511 : SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3112 7511 : SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
3113 : }
3114 :
3115 1884244 : SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
3116 1884244 : SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
3117 1884244 : SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE, cmd);
3118 1884244 : SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
3119 1884244 : SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS, flags);
3120 1884244 : SIVAL(state->smb2.hdr, SMB2_HDR_PID, 0); /* reserved */
3121 1884244 : SIVAL(state->smb2.hdr, SMB2_HDR_TID, tid);
3122 1884244 : SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID, uid);
3123 :
3124 1884244 : switch (cmd) {
3125 1620 : case SMB2_OP_CANCEL:
3126 1620 : state->one_way = true;
3127 1620 : break;
3128 2188 : case SMB2_OP_BREAK:
3129 : /*
3130 : * If this is a dummy request, it will have
3131 : * UINT64_MAX as message id.
3132 : * If we send on break acknowledgement,
3133 : * this gets overwritten later.
3134 : */
3135 2188 : SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
3136 2188 : break;
3137 : }
3138 :
3139 1884244 : if (timeout_msec > 0) {
3140 1878998 : state->endtime = timeval_current_ofs_msec(timeout_msec);
3141 1878998 : if (!tevent_req_set_endtime(req, ev, state->endtime)) {
3142 0 : return req;
3143 : }
3144 : }
3145 :
3146 1872381 : return req;
3147 : }
3148 :
3149 1153460 : void smb2cli_req_set_notify_async(struct tevent_req *req)
3150 : {
3151 906 : struct smbXcli_req_state *state =
3152 1153460 : tevent_req_data(req,
3153 : struct smbXcli_req_state);
3154 :
3155 1153460 : state->smb2.notify_async = true;
3156 1153460 : }
3157 :
3158 : static void smb2cli_req_writev_done(struct tevent_req *subreq);
3159 : static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3160 : TALLOC_CTX *tmp_mem,
3161 : uint8_t *inbuf);
3162 :
3163 1882060 : NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
3164 : int num_reqs)
3165 : {
3166 11863 : struct smbXcli_req_state *state;
3167 11863 : struct tevent_req *subreq;
3168 11863 : struct iovec *iov;
3169 11863 : int i, num_iov, nbt_len;
3170 1882060 : int tf_iov = -1;
3171 1882060 : struct smb2_signing_key *encryption_key = NULL;
3172 1882060 : uint64_t encryption_session_id = 0;
3173 1882060 : uint64_t nonce_high = UINT64_MAX;
3174 1882060 : uint64_t nonce_low = UINT64_MAX;
3175 :
3176 : /*
3177 : * 1 for the nbt length, optional TRANSFORM
3178 : * per request: HDR, fixed, dyn, padding
3179 : * -1 because the last one does not need padding
3180 : */
3181 :
3182 1882060 : iov = talloc_array(reqs[0], struct iovec, 1 + 1 + 4*num_reqs - 1);
3183 1882060 : if (iov == NULL) {
3184 0 : return NT_STATUS_NO_MEMORY;
3185 : }
3186 :
3187 1893409 : num_iov = 1;
3188 1893409 : nbt_len = 0;
3189 :
3190 : /*
3191 : * the session of the first request that requires encryption
3192 : * specifies the encryption key.
3193 : */
3194 3756911 : for (i=0; i<num_reqs; i++) {
3195 1882386 : if (!tevent_req_is_in_progress(reqs[i])) {
3196 0 : return NT_STATUS_INTERNAL_ERROR;
3197 : }
3198 :
3199 1882386 : state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3200 :
3201 1882386 : if (!smbXcli_conn_is_connected(state->conn)) {
3202 38 : return NT_STATUS_CONNECTION_DISCONNECTED;
3203 : }
3204 :
3205 1882348 : if ((state->conn->protocol != PROTOCOL_NONE) &&
3206 1845552 : (state->conn->protocol < PROTOCOL_SMB2_02)) {
3207 0 : return NT_STATUS_REVISION_MISMATCH;
3208 : }
3209 :
3210 1882348 : if (state->session == NULL) {
3211 27271 : continue;
3212 : }
3213 :
3214 1855077 : if (!state->smb2.should_encrypt) {
3215 1847580 : continue;
3216 : }
3217 :
3218 7497 : encryption_key = state->session->smb2->encryption_key;
3219 7497 : if (!smb2_signing_key_valid(encryption_key)) {
3220 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
3221 : }
3222 :
3223 7497 : encryption_session_id = state->session->smb2->session_id;
3224 :
3225 7497 : state->session->smb2->nonce_low += 1;
3226 7497 : if (state->session->smb2->nonce_low == 0) {
3227 0 : state->session->smb2->nonce_high += 1;
3228 0 : state->session->smb2->nonce_low += 1;
3229 : }
3230 :
3231 : /*
3232 : * CCM and GCM algorithms must never have their
3233 : * nonce wrap, or the security of the whole
3234 : * communication and the keys is destroyed.
3235 : * We must drop the connection once we have
3236 : * transferred too much data.
3237 : *
3238 : * NOTE: We assume nonces greater than 8 bytes.
3239 : */
3240 7497 : if (state->session->smb2->nonce_high >=
3241 7497 : state->session->smb2->nonce_high_max)
3242 : {
3243 0 : return NT_STATUS_ENCRYPTION_FAILED;
3244 : }
3245 :
3246 7497 : nonce_high = state->session->smb2->nonce_high_random;
3247 7497 : nonce_high += state->session->smb2->nonce_high;
3248 7497 : nonce_low = state->session->smb2->nonce_low;
3249 :
3250 7497 : tf_iov = num_iov;
3251 7497 : iov[num_iov].iov_base = state->smb2.transform;
3252 7497 : iov[num_iov].iov_len = sizeof(state->smb2.transform);
3253 7497 : num_iov += 1;
3254 :
3255 7497 : SBVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3256 7497 : SBVAL(state->smb2.transform, SMB2_TF_NONCE,
3257 : nonce_low);
3258 7497 : SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
3259 : nonce_high);
3260 7497 : SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID,
3261 : encryption_session_id);
3262 :
3263 7497 : nbt_len += SMB2_TF_HDR_SIZE;
3264 7497 : break;
3265 : }
3266 :
3267 3764370 : for (i=0; i<num_reqs; i++) {
3268 11862 : int hdr_iov;
3269 11862 : size_t reqlen;
3270 11862 : bool ret;
3271 11862 : uint16_t opcode;
3272 11862 : uint64_t avail;
3273 11862 : uint16_t charge;
3274 11862 : uint16_t credits;
3275 11862 : uint64_t mid;
3276 1882348 : struct smb2_signing_key *signing_key = NULL;
3277 :
3278 1882348 : if (!tevent_req_is_in_progress(reqs[i])) {
3279 0 : return NT_STATUS_INTERNAL_ERROR;
3280 : }
3281 :
3282 1882348 : state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3283 :
3284 1882348 : if (!smbXcli_conn_is_connected(state->conn)) {
3285 0 : return NT_STATUS_CONNECTION_DISCONNECTED;
3286 : }
3287 :
3288 1882348 : if ((state->conn->protocol != PROTOCOL_NONE) &&
3289 1845552 : (state->conn->protocol < PROTOCOL_SMB2_02)) {
3290 0 : return NT_STATUS_REVISION_MISMATCH;
3291 : }
3292 :
3293 1882348 : opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3294 1882348 : if (opcode == SMB2_OP_CANCEL) {
3295 1620 : goto skip_credits;
3296 : }
3297 :
3298 1880728 : avail = UINT64_MAX - state->conn->smb2.mid;
3299 1880728 : if (avail < 1) {
3300 0 : return NT_STATUS_CONNECTION_ABORTED;
3301 : }
3302 :
3303 1880728 : if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3304 1437102 : uint32_t max_dyn_len = 1;
3305 :
3306 1437102 : max_dyn_len = MAX(max_dyn_len, state->smb2.dyn_len);
3307 1437102 : max_dyn_len = MAX(max_dyn_len, state->smb2.max_dyn_len);
3308 :
3309 1437102 : charge = (max_dyn_len - 1)/ 65536 + 1;
3310 : } else {
3311 442878 : charge = 1;
3312 : }
3313 :
3314 1880728 : charge = MAX(state->smb2.credit_charge, charge);
3315 :
3316 1880728 : avail = MIN(avail, state->conn->smb2.cur_credits);
3317 1880728 : if (avail < charge) {
3318 0 : DBG_ERR("Insufficient credits. "
3319 : "%"PRIu64" available, %"PRIu16" needed\n",
3320 : avail, charge);
3321 0 : return NT_STATUS_INTERNAL_ERROR;
3322 : }
3323 :
3324 1880728 : credits = 0;
3325 1880728 : if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
3326 121298 : credits = state->conn->smb2.max_credits -
3327 119385 : state->conn->smb2.cur_credits;
3328 : }
3329 1880728 : if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
3330 1776020 : credits += 1;
3331 : }
3332 :
3333 1880728 : mid = state->conn->smb2.mid;
3334 1880728 : state->conn->smb2.mid += charge;
3335 1880728 : state->conn->smb2.cur_credits -= charge;
3336 :
3337 1880728 : if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3338 1437102 : SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
3339 : }
3340 1880728 : SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
3341 1880728 : SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
3342 :
3343 1880728 : state->smb2.cancel_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3344 1880728 : state->smb2.cancel_flags &= ~SMB2_HDR_FLAG_CHAINED;
3345 1880728 : if (state->conn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) {
3346 1364507 : state->smb2.cancel_mid = mid;
3347 : } else {
3348 516221 : state->smb2.cancel_mid = 0;
3349 : }
3350 1880728 : state->smb2.cancel_aid = 0;
3351 :
3352 1882348 : skip_credits:
3353 1882348 : if (state->session && encryption_key == NULL) {
3354 : /*
3355 : * We prefer the channel signing key if it is
3356 : * already there.
3357 : */
3358 1847580 : if (state->smb2.should_sign) {
3359 1113086 : signing_key = state->session->smb2_channel.signing_key;
3360 : }
3361 :
3362 : /*
3363 : * If it is a channel binding, we already have the main
3364 : * signing key and try that one.
3365 : */
3366 1856458 : if (signing_key != NULL &&
3367 1113086 : !smb2_signing_key_valid(signing_key)) {
3368 2926 : signing_key = state->session->smb2->signing_key;
3369 : }
3370 :
3371 : /*
3372 : * If we do not have any session key yet, we skip the
3373 : * signing of SMB2_OP_SESSSETUP requests.
3374 : */
3375 1857330 : if (signing_key != NULL &&
3376 1113086 : !smb2_signing_key_valid(signing_key)) {
3377 0 : signing_key = NULL;
3378 : }
3379 : }
3380 :
3381 1882348 : hdr_iov = num_iov;
3382 1882348 : iov[num_iov].iov_base = state->smb2.hdr;
3383 1882348 : iov[num_iov].iov_len = sizeof(state->smb2.hdr);
3384 1882348 : num_iov += 1;
3385 :
3386 1882348 : iov[num_iov].iov_base = discard_const(state->smb2.fixed);
3387 1882348 : iov[num_iov].iov_len = state->smb2.fixed_len;
3388 1882348 : num_iov += 1;
3389 :
3390 1882348 : if (state->smb2.dyn != NULL) {
3391 1787669 : iov[num_iov].iov_base = discard_const(state->smb2.dyn);
3392 1787669 : iov[num_iov].iov_len = state->smb2.dyn_len;
3393 1787669 : num_iov += 1;
3394 : }
3395 :
3396 1882348 : reqlen = sizeof(state->smb2.hdr);
3397 1882348 : reqlen += state->smb2.fixed_len;
3398 1882348 : reqlen += state->smb2.dyn_len;
3399 :
3400 1882348 : if (i < num_reqs-1) {
3401 326 : if ((reqlen % 8) > 0) {
3402 170 : uint8_t pad = 8 - (reqlen % 8);
3403 170 : iov[num_iov].iov_base = state->smb2.pad;
3404 170 : iov[num_iov].iov_len = pad;
3405 170 : num_iov += 1;
3406 170 : reqlen += pad;
3407 : }
3408 326 : SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
3409 : }
3410 :
3411 1882348 : state->smb2.encryption_session_id = encryption_session_id;
3412 :
3413 1882348 : if (signing_key != NULL) {
3414 9750 : NTSTATUS status;
3415 :
3416 1113086 : status = smb2_signing_sign_pdu(signing_key,
3417 1103336 : &iov[hdr_iov], num_iov - hdr_iov);
3418 1113086 : if (!NT_STATUS_IS_OK(status)) {
3419 0 : return status;
3420 : }
3421 : }
3422 :
3423 1882348 : nbt_len += reqlen;
3424 :
3425 1882348 : ret = smbXcli_req_set_pending(reqs[i]);
3426 1882348 : if (!ret) {
3427 0 : return NT_STATUS_NO_MEMORY;
3428 : }
3429 : }
3430 :
3431 1882022 : state = tevent_req_data(reqs[0], struct smbXcli_req_state);
3432 1882022 : _smb_setlen_tcp(state->length_hdr, nbt_len);
3433 1882022 : iov[0].iov_base = state->length_hdr;
3434 1882022 : iov[0].iov_len = sizeof(state->length_hdr);
3435 :
3436 1882022 : if (encryption_key != NULL) {
3437 513 : NTSTATUS status;
3438 7497 : size_t buflen = nbt_len - SMB2_TF_HDR_SIZE;
3439 513 : uint8_t *buf;
3440 513 : int vi;
3441 :
3442 7497 : buf = talloc_array(iov, uint8_t, buflen);
3443 7497 : if (buf == NULL) {
3444 0 : return NT_STATUS_NO_MEMORY;
3445 : }
3446 :
3447 : /*
3448 : * We copy the buffers before encrypting them,
3449 : * this is at least currently needed for the
3450 : * to keep state->smb2.hdr.
3451 : *
3452 : * Also the callers may expect there buffers
3453 : * to be const.
3454 : */
3455 28859 : for (vi = tf_iov + 1; vi < num_iov; vi++) {
3456 21362 : struct iovec *v = &iov[vi];
3457 21362 : const uint8_t *o = (const uint8_t *)v->iov_base;
3458 :
3459 21362 : memcpy(buf, o, v->iov_len);
3460 21362 : v->iov_base = (void *)buf;
3461 21362 : buf += v->iov_len;
3462 : }
3463 :
3464 7497 : status = smb2_signing_encrypt_pdu(encryption_key,
3465 7497 : &iov[tf_iov], num_iov - tf_iov);
3466 7497 : if (!NT_STATUS_IS_OK(status)) {
3467 0 : return status;
3468 : }
3469 : }
3470 :
3471 1882022 : if (state->conn->dispatch_incoming == NULL) {
3472 0 : state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3473 : }
3474 :
3475 1882022 : subreq = writev_send(state, state->ev, state->conn->outgoing,
3476 1870160 : state->conn->sock_fd, false, iov, num_iov);
3477 1882022 : if (subreq == NULL) {
3478 0 : return NT_STATUS_NO_MEMORY;
3479 : }
3480 1882022 : tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
3481 1882022 : state->write_req = subreq;
3482 :
3483 1882022 : return NT_STATUS_OK;
3484 : }
3485 :
3486 24050 : void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
3487 : {
3488 358 : struct smbXcli_req_state *state =
3489 24050 : tevent_req_data(req,
3490 : struct smbXcli_req_state);
3491 :
3492 24050 : state->smb2.credit_charge = charge;
3493 24050 : }
3494 :
3495 727306 : struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
3496 : struct tevent_context *ev,
3497 : struct smbXcli_conn *conn,
3498 : uint16_t cmd,
3499 : uint32_t additional_flags,
3500 : uint32_t clear_flags,
3501 : uint32_t timeout_msec,
3502 : struct smbXcli_tcon *tcon,
3503 : struct smbXcli_session *session,
3504 : const uint8_t *fixed,
3505 : uint16_t fixed_len,
3506 : const uint8_t *dyn,
3507 : uint32_t dyn_len,
3508 : uint32_t max_dyn_len)
3509 : {
3510 10941 : struct tevent_req *req;
3511 10941 : NTSTATUS status;
3512 :
3513 727306 : req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
3514 : additional_flags, clear_flags,
3515 : timeout_msec,
3516 : tcon, session,
3517 : fixed, fixed_len,
3518 : dyn, dyn_len,
3519 : max_dyn_len);
3520 727306 : if (req == NULL) {
3521 0 : return NULL;
3522 : }
3523 727306 : if (!tevent_req_is_in_progress(req)) {
3524 0 : return tevent_req_post(req, ev);
3525 : }
3526 727306 : status = smb2cli_req_compound_submit(&req, 1);
3527 727306 : if (tevent_req_nterror(req, status)) {
3528 3 : return tevent_req_post(req, ev);
3529 : }
3530 727303 : return req;
3531 : }
3532 :
3533 1875343 : static void smb2cli_req_writev_done(struct tevent_req *subreq)
3534 : {
3535 11400 : struct tevent_req *req =
3536 1875343 : tevent_req_callback_data(subreq,
3537 : struct tevent_req);
3538 11400 : struct smbXcli_req_state *state =
3539 1875343 : tevent_req_data(req,
3540 : struct smbXcli_req_state);
3541 11400 : ssize_t nwritten;
3542 11400 : int err;
3543 :
3544 1875343 : state->write_req = NULL;
3545 :
3546 1875343 : nwritten = writev_recv(subreq, &err);
3547 1875343 : TALLOC_FREE(subreq);
3548 1875343 : if (nwritten == -1) {
3549 : /* here, we need to notify all pending requests */
3550 1 : NTSTATUS status = map_nt_error_from_unix_common(err);
3551 1 : smbXcli_conn_disconnect(state->conn, status);
3552 1 : return;
3553 : }
3554 : }
3555 :
3556 7485 : static struct smbXcli_session* smbXcli_session_by_uid(struct smbXcli_conn *conn,
3557 : uint64_t uid)
3558 : {
3559 7485 : struct smbXcli_session *s = conn->sessions;
3560 :
3561 11795 : for (; s; s = s->next) {
3562 11795 : if (s->smb2->session_id != uid) {
3563 4310 : continue;
3564 : }
3565 6976 : break;
3566 : }
3567 :
3568 7485 : return s;
3569 : }
3570 :
3571 2007405 : static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
3572 : uint8_t *buf,
3573 : size_t buflen,
3574 : TALLOC_CTX *mem_ctx,
3575 : struct iovec **piov,
3576 : size_t *pnum_iov)
3577 : {
3578 14672 : struct iovec *iov;
3579 2007405 : int num_iov = 0;
3580 2007405 : size_t taken = 0;
3581 2007405 : uint8_t *first_hdr = buf;
3582 2007405 : size_t verified_buflen = 0;
3583 2007405 : uint8_t *tf = NULL;
3584 2007405 : size_t tf_len = 0;
3585 :
3586 2007405 : iov = talloc_array(mem_ctx, struct iovec, num_iov);
3587 2007405 : if (iov == NULL) {
3588 0 : return NT_STATUS_NO_MEMORY;
3589 : }
3590 :
3591 4015118 : while (taken < buflen) {
3592 2007713 : size_t len = buflen - taken;
3593 2007713 : uint8_t *hdr = first_hdr + taken;
3594 14672 : struct iovec *cur;
3595 14672 : size_t full_size;
3596 14672 : size_t next_command_ofs;
3597 14672 : uint16_t body_size;
3598 14672 : struct iovec *iov_tmp;
3599 :
3600 2007713 : if (verified_buflen > taken) {
3601 0 : len = verified_buflen - taken;
3602 : } else {
3603 1993041 : tf = NULL;
3604 1993041 : tf_len = 0;
3605 : }
3606 :
3607 2007713 : if (len < 4) {
3608 0 : DEBUG(10, ("%d bytes left, expected at least %d\n",
3609 : (int)len, 4));
3610 0 : goto inval;
3611 : }
3612 2007713 : if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
3613 509 : struct smbXcli_session *s;
3614 509 : uint64_t uid;
3615 509 : struct iovec tf_iov[2];
3616 509 : size_t enc_len;
3617 509 : NTSTATUS status;
3618 :
3619 7477 : if (len < SMB2_TF_HDR_SIZE) {
3620 0 : DEBUG(10, ("%d bytes left, expected at least %d\n",
3621 : (int)len, SMB2_TF_HDR_SIZE));
3622 0 : goto inval;
3623 : }
3624 7477 : tf = hdr;
3625 7477 : tf_len = SMB2_TF_HDR_SIZE;
3626 7477 : taken += tf_len;
3627 :
3628 7477 : hdr = first_hdr + taken;
3629 7477 : enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
3630 7477 : uid = BVAL(tf, SMB2_TF_SESSION_ID);
3631 :
3632 7477 : if (len < SMB2_TF_HDR_SIZE + enc_len) {
3633 0 : DEBUG(10, ("%d bytes left, expected at least %d\n",
3634 : (int)len,
3635 : (int)(SMB2_TF_HDR_SIZE + enc_len)));
3636 0 : goto inval;
3637 : }
3638 :
3639 7477 : s = smbXcli_session_by_uid(conn, uid);
3640 7477 : if (s == NULL) {
3641 0 : DEBUG(10, ("unknown session_id %llu\n",
3642 : (unsigned long long)uid));
3643 0 : goto inval;
3644 : }
3645 :
3646 7477 : tf_iov[0].iov_base = (void *)tf;
3647 7477 : tf_iov[0].iov_len = tf_len;
3648 7477 : tf_iov[1].iov_base = (void *)hdr;
3649 7477 : tf_iov[1].iov_len = enc_len;
3650 :
3651 7477 : status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
3652 : tf_iov, 2);
3653 7477 : if (!NT_STATUS_IS_OK(status)) {
3654 0 : TALLOC_FREE(iov);
3655 0 : return status;
3656 : }
3657 :
3658 7477 : verified_buflen = taken + enc_len;
3659 7477 : len = enc_len;
3660 : }
3661 :
3662 : /*
3663 : * We need the header plus the body length field
3664 : */
3665 :
3666 2007713 : if (len < SMB2_HDR_BODY + 2) {
3667 0 : DEBUG(10, ("%d bytes left, expected at least %d\n",
3668 : (int)len, SMB2_HDR_BODY));
3669 0 : goto inval;
3670 : }
3671 2007713 : if (IVAL(hdr, 0) != SMB2_MAGIC) {
3672 0 : DEBUG(10, ("Got non-SMB2 PDU: %x\n",
3673 : IVAL(hdr, 0)));
3674 0 : goto inval;
3675 : }
3676 2007713 : if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
3677 0 : DEBUG(10, ("Got HDR len %d, expected %d\n",
3678 : SVAL(hdr, 4), SMB2_HDR_BODY));
3679 0 : goto inval;
3680 : }
3681 :
3682 2007713 : full_size = len;
3683 2007713 : next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
3684 2007713 : body_size = SVAL(hdr, SMB2_HDR_BODY);
3685 :
3686 2007713 : if (next_command_ofs != 0) {
3687 308 : if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
3688 0 : goto inval;
3689 : }
3690 308 : if (next_command_ofs > full_size) {
3691 0 : goto inval;
3692 : }
3693 308 : full_size = next_command_ofs;
3694 : }
3695 2007713 : if (body_size < 2) {
3696 0 : goto inval;
3697 : }
3698 2007713 : body_size &= 0xfffe;
3699 :
3700 2007713 : if (body_size > (full_size - SMB2_HDR_BODY)) {
3701 0 : goto inval;
3702 : }
3703 :
3704 2007713 : iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
3705 : num_iov + 4);
3706 2007713 : if (iov_tmp == NULL) {
3707 0 : TALLOC_FREE(iov);
3708 0 : return NT_STATUS_NO_MEMORY;
3709 : }
3710 2007713 : iov = iov_tmp;
3711 2007713 : cur = &iov[num_iov];
3712 2007713 : num_iov += 4;
3713 :
3714 2007713 : cur[0].iov_base = tf;
3715 2007713 : cur[0].iov_len = tf_len;
3716 2007713 : cur[1].iov_base = hdr;
3717 2007713 : cur[1].iov_len = SMB2_HDR_BODY;
3718 2007713 : cur[2].iov_base = hdr + SMB2_HDR_BODY;
3719 2007713 : cur[2].iov_len = body_size;
3720 2007713 : cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
3721 2007713 : cur[3].iov_len = full_size - (SMB2_HDR_BODY + body_size);
3722 :
3723 2007713 : taken += full_size;
3724 : }
3725 :
3726 2007405 : *piov = iov;
3727 2007405 : *pnum_iov = num_iov;
3728 2007405 : return NT_STATUS_OK;
3729 :
3730 0 : inval:
3731 0 : TALLOC_FREE(iov);
3732 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3733 : }
3734 :
3735 2007713 : static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
3736 : uint64_t mid)
3737 : {
3738 2007713 : size_t num_pending = talloc_array_length(conn->pending);
3739 14672 : size_t i;
3740 :
3741 2017006 : for (i=0; i<num_pending; i++) {
3742 2017004 : struct tevent_req *req = conn->pending[i];
3743 14688 : struct smbXcli_req_state *state =
3744 2017004 : tevent_req_data(req,
3745 : struct smbXcli_req_state);
3746 :
3747 2017004 : if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
3748 2007711 : return req;
3749 : }
3750 : }
3751 2 : return NULL;
3752 : }
3753 :
3754 2007405 : static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3755 : TALLOC_CTX *tmp_mem,
3756 : uint8_t *inbuf)
3757 : {
3758 14672 : struct tevent_req *req;
3759 2007405 : struct smbXcli_req_state *state = NULL;
3760 2007405 : struct iovec *iov = NULL;
3761 2007405 : size_t i, num_iov = 0;
3762 14672 : NTSTATUS status;
3763 2007405 : bool defer = true;
3764 2007405 : struct smbXcli_session *last_session = NULL;
3765 2007405 : size_t inbuf_len = smb_len_tcp(inbuf);
3766 :
3767 2007405 : status = smb2cli_inbuf_parse_compound(conn,
3768 : inbuf + NBT_HDR_SIZE,
3769 : inbuf_len,
3770 : tmp_mem,
3771 : &iov, &num_iov);
3772 2007405 : if (!NT_STATUS_IS_OK(status)) {
3773 0 : return status;
3774 : }
3775 :
3776 4015111 : for (i=0; i<num_iov; i+=4) {
3777 2007713 : uint8_t *inbuf_ref = NULL;
3778 2007713 : struct iovec *cur = &iov[i];
3779 2007713 : uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
3780 2007713 : uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3781 2007713 : uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3782 2007713 : uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3783 14672 : uint16_t req_opcode;
3784 14672 : uint32_t req_flags;
3785 2007713 : uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
3786 14672 : uint32_t new_credits;
3787 2007713 : struct smbXcli_session *session = NULL;
3788 2007713 : struct smb2_signing_key *signing_key = NULL;
3789 2007713 : bool was_encrypted = false;
3790 :
3791 2007713 : new_credits = conn->smb2.cur_credits;
3792 2007713 : new_credits += credits;
3793 2007713 : if (new_credits > UINT16_MAX) {
3794 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3795 : }
3796 2007713 : conn->smb2.cur_credits += credits;
3797 :
3798 2007713 : req = smb2cli_conn_find_pending(conn, mid);
3799 2007713 : if (req == NULL) {
3800 2 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3801 : }
3802 2007711 : state = tevent_req_data(req, struct smbXcli_req_state);
3803 :
3804 2007711 : req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3805 2007711 : if (opcode != req_opcode) {
3806 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3807 : }
3808 2007711 : req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3809 :
3810 2007711 : if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
3811 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3812 : }
3813 :
3814 2007711 : status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
3815 2007711 : if ((flags & SMB2_HDR_FLAG_ASYNC) &&
3816 227344 : NT_STATUS_EQUAL(status, NT_STATUS_PENDING)) {
3817 115158 : uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
3818 :
3819 115158 : if (state->smb2.got_async) {
3820 : /* We only expect one STATUS_PENDING response */
3821 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3822 : }
3823 115158 : state->smb2.got_async = true;
3824 :
3825 : /*
3826 : * async interim responses are not signed,
3827 : * even if the SMB2_HDR_FLAG_SIGNED flag
3828 : * is set.
3829 : */
3830 115158 : state->smb2.cancel_flags |= SMB2_HDR_FLAG_ASYNC;
3831 115158 : state->smb2.cancel_aid = async_id;
3832 :
3833 115158 : if (state->smb2.notify_async) {
3834 1633 : tevent_req_defer_callback(req, state->ev);
3835 1633 : tevent_req_notify_callback(req);
3836 : }
3837 115158 : continue;
3838 : }
3839 :
3840 1892553 : session = state->session;
3841 1892553 : if (req_flags & SMB2_HDR_FLAG_CHAINED) {
3842 270 : session = last_session;
3843 : }
3844 1892553 : last_session = session;
3845 :
3846 1892553 : if (flags & SMB2_HDR_FLAG_SIGNED) {
3847 1131276 : uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
3848 :
3849 1131276 : if (session == NULL) {
3850 8 : session = smbXcli_session_by_uid(state->conn,
3851 : uid);
3852 : }
3853 :
3854 1131276 : if (session == NULL) {
3855 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3856 : }
3857 :
3858 1131276 : last_session = session;
3859 1131276 : signing_key = session->smb2_channel.signing_key;
3860 : }
3861 :
3862 1892553 : if (opcode == SMB2_OP_SESSSETUP) {
3863 : /*
3864 : * We prefer the channel signing key, if it is
3865 : * already there.
3866 : *
3867 : * If we do not have a channel signing key yet,
3868 : * we try the main signing key, if it is not
3869 : * the final response.
3870 : */
3871 51349 : if (signing_key != NULL &&
3872 27579 : !smb2_signing_key_valid(signing_key) &&
3873 27382 : !NT_STATUS_IS_OK(status)) {
3874 2092 : signing_key = session->smb2->signing_key;
3875 : }
3876 :
3877 51349 : if (signing_key != NULL &&
3878 27579 : !smb2_signing_key_valid(signing_key)) {
3879 : /*
3880 : * If we do not have a session key to
3881 : * verify the signature, we defer the
3882 : * signing check to the caller.
3883 : *
3884 : * The caller gets NT_STATUS_OK, it
3885 : * has to call
3886 : * smb2cli_session_set_session_key()
3887 : * or
3888 : * smb2cli_session_set_channel_key()
3889 : * which will check the signature
3890 : * with the channel signing key.
3891 : */
3892 25498 : signing_key = NULL;
3893 : }
3894 :
3895 50373 : if (!NT_STATUS_IS_OK(status)) {
3896 : /*
3897 : * Only check the signature of the last response
3898 : * of a successful session auth. This matches
3899 : * Windows behaviour for NTLM auth and reauth.
3900 : */
3901 24049 : state->smb2.require_signed_response = false;
3902 : }
3903 : }
3904 :
3905 1892553 : if (state->smb2.should_sign ||
3906 785849 : state->smb2.require_signed_response)
3907 : {
3908 1106704 : if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
3909 0 : return NT_STATUS_ACCESS_DENIED;
3910 : }
3911 : }
3912 :
3913 1892553 : if (!smb2_signing_key_valid(signing_key) &&
3914 786867 : state->smb2.require_signed_response) {
3915 0 : signing_key = session->smb2_channel.signing_key;
3916 : }
3917 :
3918 1892553 : if (cur[0].iov_len == SMB2_TF_HDR_SIZE) {
3919 7389 : const uint8_t *tf = (const uint8_t *)cur[0].iov_base;
3920 7389 : uint64_t uid = BVAL(tf, SMB2_TF_SESSION_ID);
3921 :
3922 : /*
3923 : * If the response was encrypted in a SMB2_TRANSFORM
3924 : * pdu, which belongs to the correct session,
3925 : * we do not need to do signing checks
3926 : *
3927 : * It could be the session the response belongs to
3928 : * or the session that was used to encrypt the
3929 : * SMB2_TRANSFORM request.
3930 : */
3931 7389 : if ((session && session->smb2->session_id == uid) ||
3932 0 : (state->smb2.encryption_session_id == uid)) {
3933 7389 : signing_key = NULL;
3934 7389 : was_encrypted = true;
3935 : }
3936 : }
3937 :
3938 1892553 : if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
3939 : /*
3940 : * if the server returns NT_STATUS_USER_SESSION_DELETED
3941 : * the response is not signed and we should
3942 : * propagate the NT_STATUS_USER_SESSION_DELETED
3943 : * status to the caller.
3944 : */
3945 1084 : state->smb2.signing_skipped = true;
3946 1084 : signing_key = NULL;
3947 : }
3948 1892553 : if (NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_OUT_OF_SEQUENCE)) {
3949 : /*
3950 : * if the server returns
3951 : * NT_STATUS_REQUEST_OUT_OF_SEQUENCE for a session setup
3952 : * request, the response is not signed and we should
3953 : * propagate the NT_STATUS_REQUEST_OUT_OF_SEQUENCE
3954 : * status to the caller
3955 : */
3956 280 : if (opcode == SMB2_OP_SESSSETUP) {
3957 280 : state->smb2.signing_skipped = true;
3958 280 : signing_key = NULL;
3959 : }
3960 : }
3961 1892553 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
3962 : /*
3963 : * if the server returns NT_STATUS_NOT_SUPPORTED
3964 : * for a session setup request, the response is not
3965 : * signed and we should propagate the NT_STATUS_NOT_SUPPORTED
3966 : * status to the caller.
3967 : */
3968 297 : if (opcode == SMB2_OP_SESSSETUP) {
3969 280 : state->smb2.signing_skipped = true;
3970 280 : signing_key = NULL;
3971 : }
3972 : }
3973 1892553 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3974 : /*
3975 : * if the server returns
3976 : * NT_STATUS_ACCESS_DENIED for a session setup
3977 : * request, the response is not signed and we should
3978 : * propagate the NT_STATUS_ACCESS_DENIED
3979 : * status to the caller without disconnecting
3980 : * the connection because we where not able to
3981 : * verify the response signature.
3982 : */
3983 2098 : if (opcode == SMB2_OP_SESSSETUP) {
3984 80 : state->smb2.signing_skipped = true;
3985 80 : signing_key = NULL;
3986 : }
3987 : }
3988 :
3989 1892553 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3990 : /*
3991 : * if the server returns
3992 : * NT_STATUS_INVALID_PARAMETER
3993 : * the response might not be encrypted.
3994 : */
3995 2837 : if (state->smb2.should_encrypt && !was_encrypted) {
3996 0 : state->smb2.signing_skipped = true;
3997 0 : signing_key = NULL;
3998 : }
3999 : }
4000 :
4001 1892553 : if (state->smb2.should_encrypt && !was_encrypted) {
4002 16 : if (!state->smb2.signing_skipped) {
4003 0 : return NT_STATUS_ACCESS_DENIED;
4004 : }
4005 : }
4006 :
4007 1892553 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
4008 1892396 : NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
4009 1877181 : (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
4010 2098 : session != NULL &&
4011 13850 : session->smb2->no_signing_disconnect) ||
4012 1877153 : NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4013 : /*
4014 : * if the server returns
4015 : * NT_STATUS_NETWORK_NAME_DELETED
4016 : * NT_STATUS_FILE_CLOSED
4017 : * NT_STATUS_INVALID_PARAMETER
4018 : * the response might not be signed
4019 : * as this happens before the signing checks.
4020 : *
4021 : * If server echos the signature (or all zeros)
4022 : * we should report the status from the server
4023 : * to the caller.
4024 : */
4025 6469 : if (signing_key) {
4026 28 : bool cmp;
4027 :
4028 2008 : cmp = mem_equal_const_time(inhdr+SMB2_HDR_SIGNATURE,
4029 1980 : state->smb2.hdr+SMB2_HDR_SIGNATURE,
4030 : 16);
4031 2008 : if (cmp) {
4032 14 : state->smb2.signing_skipped = true;
4033 14 : signing_key = NULL;
4034 : }
4035 : }
4036 6469 : if (signing_key) {
4037 28 : bool zero;
4038 1994 : zero = all_zero(inhdr+SMB2_HDR_SIGNATURE, 16);
4039 1994 : if (zero) {
4040 0 : state->smb2.signing_skipped = true;
4041 0 : signing_key = NULL;
4042 : }
4043 : }
4044 : }
4045 :
4046 1892553 : if (signing_key) {
4047 9053 : NTSTATUS signing_status;
4048 :
4049 1113621 : signing_status = smb2_signing_check_pdu(signing_key,
4050 1104568 : &cur[1], 3);
4051 1104568 : if (!NT_STATUS_IS_OK(signing_status)) {
4052 : /*
4053 : * If the signing check fails, we disconnect
4054 : * the connection.
4055 : *
4056 : * Unless
4057 : * smb2cli_session_torture_no_signing_disconnect
4058 : * was called in torture tests
4059 : */
4060 :
4061 12 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4062 0 : return signing_status;
4063 : }
4064 :
4065 12 : if (!NT_STATUS_EQUAL(status, signing_status)) {
4066 0 : return signing_status;
4067 : }
4068 :
4069 12 : if (session == NULL) {
4070 0 : return signing_status;
4071 : }
4072 :
4073 12 : if (!session->smb2->no_signing_disconnect) {
4074 0 : return signing_status;
4075 : }
4076 :
4077 12 : state->smb2.signing_skipped = true;
4078 : }
4079 : }
4080 :
4081 1892553 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
4082 169 : (session != NULL) && session->disconnect_expired)
4083 : {
4084 : /*
4085 : * this should be a short term hack
4086 : * until the upper layers have implemented
4087 : * re-authentication.
4088 : */
4089 5 : return status;
4090 : }
4091 :
4092 1892548 : smbXcli_req_unset_pending(req);
4093 :
4094 : /*
4095 : * There might be more than one response
4096 : * we need to defer the notifications
4097 : */
4098 1892548 : if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
4099 0 : defer = false;
4100 : }
4101 :
4102 1892548 : if (defer) {
4103 1892548 : tevent_req_defer_callback(req, state->ev);
4104 : }
4105 :
4106 : /*
4107 : * Note: here we use talloc_reference() in a way
4108 : * that does not expose it to the caller.
4109 : */
4110 1892548 : inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
4111 1892548 : if (tevent_req_nomem(inbuf_ref, req)) {
4112 0 : continue;
4113 : }
4114 :
4115 : /* copy the related buffers */
4116 1892548 : state->smb2.recv_iov[0] = cur[1];
4117 1892548 : state->smb2.recv_iov[1] = cur[2];
4118 1892548 : state->smb2.recv_iov[2] = cur[3];
4119 :
4120 1892548 : tevent_req_done(req);
4121 : }
4122 :
4123 2007398 : if (defer) {
4124 2007398 : return NT_STATUS_RETRY;
4125 : }
4126 :
4127 0 : return NT_STATUS_OK;
4128 : }
4129 :
4130 1894782 : NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
4131 : struct iovec **piov,
4132 : const struct smb2cli_req_expected_response *expected,
4133 : size_t num_expected)
4134 : {
4135 11790 : struct smbXcli_req_state *state =
4136 1894782 : tevent_req_data(req,
4137 : struct smbXcli_req_state);
4138 11790 : NTSTATUS status;
4139 11790 : size_t body_size;
4140 1894782 : bool found_status = false;
4141 1894782 : bool found_size = false;
4142 11790 : size_t i;
4143 :
4144 1894782 : if (piov != NULL) {
4145 1800677 : *piov = NULL;
4146 : }
4147 :
4148 1894782 : if (tevent_req_is_in_progress(req) && state->smb2.got_async) {
4149 1633 : return NT_STATUS_PENDING;
4150 : }
4151 :
4152 1893149 : if (tevent_req_is_nterror(req, &status)) {
4153 645 : for (i=0; i < num_expected; i++) {
4154 38 : if (NT_STATUS_EQUAL(status, expected[i].status)) {
4155 0 : return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
4156 : }
4157 : }
4158 :
4159 607 : return status;
4160 : }
4161 :
4162 1892542 : if (num_expected == 0) {
4163 1153984 : found_status = true;
4164 1153984 : found_size = true;
4165 : }
4166 :
4167 1892542 : status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
4168 1892542 : body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
4169 :
4170 2010073 : for (i=0; i < num_expected; i++) {
4171 824070 : if (!NT_STATUS_EQUAL(status, expected[i].status)) {
4172 117531 : continue;
4173 : }
4174 :
4175 706539 : found_status = true;
4176 706539 : if (expected[i].body_size == 0) {
4177 0 : found_size = true;
4178 0 : break;
4179 : }
4180 :
4181 706539 : if (expected[i].body_size == body_size) {
4182 695988 : found_size = true;
4183 695988 : break;
4184 : }
4185 : }
4186 :
4187 1892542 : if (!found_status) {
4188 32019 : return status;
4189 : }
4190 :
4191 1860523 : if (state->smb2.signing_skipped) {
4192 280 : if (num_expected > 0) {
4193 0 : return NT_STATUS_ACCESS_DENIED;
4194 : }
4195 280 : if (!NT_STATUS_IS_ERR(status)) {
4196 0 : return NT_STATUS_ACCESS_DENIED;
4197 : }
4198 : }
4199 :
4200 1860523 : if (!found_size) {
4201 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
4202 : }
4203 :
4204 1860523 : if (piov != NULL) {
4205 1766778 : *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
4206 : }
4207 :
4208 1860523 : return status;
4209 : }
4210 :
4211 69169 : NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
4212 : struct iovec *sent_iov)
4213 : {
4214 1537 : struct smbXcli_req_state *state =
4215 69169 : tevent_req_data(req,
4216 : struct smbXcli_req_state);
4217 :
4218 69169 : if (tevent_req_is_in_progress(req)) {
4219 0 : return NT_STATUS_PENDING;
4220 : }
4221 :
4222 69169 : sent_iov[0].iov_base = state->smb2.hdr;
4223 69169 : sent_iov[0].iov_len = sizeof(state->smb2.hdr);
4224 :
4225 69169 : sent_iov[1].iov_base = discard_const(state->smb2.fixed);
4226 69169 : sent_iov[1].iov_len = state->smb2.fixed_len;
4227 :
4228 69169 : if (state->smb2.dyn != NULL) {
4229 69169 : sent_iov[2].iov_base = discard_const(state->smb2.dyn);
4230 69169 : sent_iov[2].iov_len = state->smb2.dyn_len;
4231 : } else {
4232 0 : sent_iov[2].iov_base = NULL;
4233 0 : sent_iov[2].iov_len = 0;
4234 : }
4235 :
4236 69169 : return NT_STATUS_OK;
4237 : }
4238 :
4239 : static const struct {
4240 : enum protocol_types proto;
4241 : const char *smb1_name;
4242 : } smb1cli_prots[] = {
4243 : {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
4244 : {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
4245 : {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
4246 : {PROTOCOL_LANMAN1, "LANMAN1.0"},
4247 : {PROTOCOL_LANMAN2, "LM1.2X002"},
4248 : {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
4249 : {PROTOCOL_LANMAN2, "LANMAN2.1"},
4250 : {PROTOCOL_LANMAN2, "Samba"},
4251 : {PROTOCOL_NT1, "NT LANMAN 1.0"},
4252 : {PROTOCOL_NT1, "NT LM 0.12"},
4253 : {PROTOCOL_SMB2_02, "SMB 2.002"},
4254 : {PROTOCOL_SMB2_10, "SMB 2.???"},
4255 : };
4256 :
4257 : static const struct {
4258 : enum protocol_types proto;
4259 : uint16_t smb2_dialect;
4260 : } smb2cli_prots[] = {
4261 : {PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202},
4262 : {PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210},
4263 : {PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300},
4264 : {PROTOCOL_SMB3_02, SMB3_DIALECT_REVISION_302},
4265 : {PROTOCOL_SMB3_11, SMB3_DIALECT_REVISION_311},
4266 : };
4267 :
4268 : struct smbXcli_negprot_state {
4269 : struct smbXcli_conn *conn;
4270 : struct tevent_context *ev;
4271 : struct smb2_negotiate_contexts *in_ctx;
4272 : struct smb2_negotiate_contexts *out_ctx;
4273 : uint32_t timeout_msec;
4274 :
4275 : struct {
4276 : uint8_t fixed[36];
4277 : } smb2;
4278 : };
4279 :
4280 : static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
4281 : static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
4282 : static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
4283 : static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
4284 : static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
4285 : static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
4286 : TALLOC_CTX *frame,
4287 : uint8_t *inbuf);
4288 :
4289 34593 : struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
4290 : struct tevent_context *ev,
4291 : struct smbXcli_conn *conn,
4292 : uint32_t timeout_msec,
4293 : enum protocol_types min_protocol,
4294 : enum protocol_types max_protocol,
4295 : uint16_t max_credits,
4296 : struct smb2_negotiate_contexts *in_ctx)
4297 : {
4298 862 : struct tevent_req *req, *subreq;
4299 862 : struct smbXcli_negprot_state *state;
4300 :
4301 34593 : req = tevent_req_create(mem_ctx, &state,
4302 : struct smbXcli_negprot_state);
4303 34593 : if (req == NULL) {
4304 0 : return NULL;
4305 : }
4306 34593 : state->conn = conn;
4307 34593 : state->ev = ev;
4308 34593 : state->in_ctx = in_ctx;
4309 34593 : state->timeout_msec = timeout_msec;
4310 :
4311 34593 : if (min_protocol == PROTOCOL_NONE) {
4312 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4313 0 : return tevent_req_post(req, ev);
4314 : }
4315 :
4316 34593 : if (max_protocol == PROTOCOL_NONE) {
4317 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4318 0 : return tevent_req_post(req, ev);
4319 : }
4320 :
4321 34593 : if (min_protocol > max_protocol) {
4322 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4323 0 : return tevent_req_post(req, ev);
4324 : }
4325 :
4326 34593 : conn->min_protocol = min_protocol;
4327 34593 : conn->max_protocol = max_protocol;
4328 34593 : conn->protocol = PROTOCOL_NONE;
4329 :
4330 34593 : if (max_protocol >= PROTOCOL_SMB2_02) {
4331 26836 : conn->smb2.max_credits = max_credits;
4332 : }
4333 :
4334 34593 : if ((min_protocol < PROTOCOL_SMB2_02) &&
4335 862 : (max_protocol < PROTOCOL_SMB2_02)) {
4336 : /*
4337 : * SMB1 only...
4338 : */
4339 7757 : conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4340 :
4341 7757 : subreq = smbXcli_negprot_smb1_subreq(state);
4342 7757 : if (tevent_req_nomem(subreq, req)) {
4343 0 : return tevent_req_post(req, ev);
4344 : }
4345 7757 : tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4346 7757 : return req;
4347 : }
4348 :
4349 26836 : if ((min_protocol >= PROTOCOL_SMB2_02) &&
4350 721 : (max_protocol >= PROTOCOL_SMB2_02)) {
4351 : /*
4352 : * SMB2 only...
4353 : */
4354 8863 : conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4355 :
4356 8863 : subreq = smbXcli_negprot_smb2_subreq(state);
4357 8863 : if (tevent_req_nomem(subreq, req)) {
4358 0 : return tevent_req_post(req, ev);
4359 : }
4360 8863 : tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4361 8863 : return req;
4362 : }
4363 :
4364 : /*
4365 : * We send an SMB1 negprot with the SMB2 dialects
4366 : * and expect a SMB1 or a SMB2 response.
4367 : *
4368 : * smbXcli_negprot_dispatch_incoming() will fix the
4369 : * callback to match protocol of the response.
4370 : */
4371 17973 : conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
4372 :
4373 17973 : subreq = smbXcli_negprot_smb1_subreq(state);
4374 17973 : if (tevent_req_nomem(subreq, req)) {
4375 0 : return tevent_req_post(req, ev);
4376 : }
4377 17973 : tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
4378 17973 : return req;
4379 : }
4380 :
4381 0 : static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
4382 : {
4383 0 : struct tevent_req *req =
4384 0 : tevent_req_callback_data(subreq,
4385 : struct tevent_req);
4386 0 : NTSTATUS status;
4387 :
4388 : /*
4389 : * we just want the low level error
4390 : */
4391 0 : status = tevent_req_simple_recv_ntstatus(subreq);
4392 0 : TALLOC_FREE(subreq);
4393 0 : if (tevent_req_nterror(req, status)) {
4394 0 : return;
4395 : }
4396 :
4397 : /* this should never happen */
4398 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
4399 : }
4400 :
4401 25730 : static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
4402 : {
4403 531 : size_t i;
4404 25730 : DATA_BLOB bytes = data_blob_null;
4405 531 : uint8_t flags;
4406 531 : uint16_t flags2;
4407 :
4408 : /* setup the protocol strings */
4409 334490 : for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4410 308760 : uint8_t c = 2;
4411 6372 : bool ok;
4412 :
4413 308760 : if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4414 73388 : continue;
4415 : }
4416 :
4417 250984 : if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4418 15612 : continue;
4419 : }
4420 :
4421 235372 : ok = data_blob_append(state, &bytes, &c, sizeof(c));
4422 235372 : if (!ok) {
4423 0 : return NULL;
4424 : }
4425 :
4426 : /*
4427 : * We know it is already ascii and
4428 : * we want NULL termination.
4429 : */
4430 238342 : ok = data_blob_append(state, &bytes,
4431 232402 : smb1cli_prots[i].smb1_name,
4432 235372 : strlen(smb1cli_prots[i].smb1_name)+1);
4433 235372 : if (!ok) {
4434 0 : return NULL;
4435 : }
4436 : }
4437 :
4438 26261 : smb1cli_req_flags(state->conn->max_protocol,
4439 25730 : state->conn->smb1.client.capabilities,
4440 : SMBnegprot,
4441 : 0, 0, &flags,
4442 : 0, 0, &flags2);
4443 :
4444 25730 : return smb1cli_req_send(state, state->ev, state->conn,
4445 : SMBnegprot,
4446 : flags, ~flags,
4447 : flags2, ~flags2,
4448 : state->timeout_msec,
4449 : 0xFFFE, 0, NULL, /* pid, tid, session */
4450 : 0, NULL, /* wct, vwv */
4451 25730 : bytes.length, bytes.data);
4452 : }
4453 :
4454 7757 : static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
4455 : {
4456 141 : struct tevent_req *req =
4457 7757 : tevent_req_callback_data(subreq,
4458 : struct tevent_req);
4459 141 : struct smbXcli_negprot_state *state =
4460 7757 : tevent_req_data(req,
4461 : struct smbXcli_negprot_state);
4462 7757 : struct smbXcli_conn *conn = state->conn;
4463 7757 : struct iovec *recv_iov = NULL;
4464 7757 : uint8_t *inhdr = NULL;
4465 141 : uint8_t wct;
4466 141 : uint16_t *vwv;
4467 141 : uint32_t num_bytes;
4468 141 : uint8_t *bytes;
4469 141 : NTSTATUS status;
4470 141 : uint16_t protnum;
4471 141 : size_t i;
4472 7757 : size_t num_prots = 0;
4473 141 : uint8_t flags;
4474 7757 : uint32_t client_capabilities = conn->smb1.client.capabilities;
4475 141 : uint32_t both_capabilities;
4476 7757 : uint32_t server_capabilities = 0;
4477 141 : uint32_t capabilities;
4478 7757 : uint32_t client_max_xmit = conn->smb1.client.max_xmit;
4479 7757 : uint32_t server_max_xmit = 0;
4480 141 : uint32_t max_xmit;
4481 7757 : uint32_t server_max_mux = 0;
4482 7757 : uint16_t server_security_mode = 0;
4483 7757 : uint32_t server_session_key = 0;
4484 7757 : bool server_readbraw = false;
4485 7757 : bool server_writebraw = false;
4486 7757 : bool server_lockread = false;
4487 7757 : bool server_writeunlock = false;
4488 7757 : struct GUID server_guid = GUID_zero();
4489 7757 : DATA_BLOB server_gss_blob = data_blob_null;
4490 141 : uint8_t server_challenge[8];
4491 7757 : char *server_workgroup = NULL;
4492 7757 : char *server_name = NULL;
4493 7757 : int server_time_zone = 0;
4494 7757 : NTTIME server_system_time = 0;
4495 141 : static const struct smb1cli_req_expected_response expected[] = {
4496 : {
4497 : .status = NT_STATUS_OK,
4498 : .wct = 0x11, /* NT1 */
4499 : },
4500 : {
4501 : .status = NT_STATUS_OK,
4502 : .wct = 0x0D, /* LM */
4503 : },
4504 : {
4505 : .status = NT_STATUS_OK,
4506 : .wct = 0x01, /* CORE */
4507 : }
4508 : };
4509 :
4510 7757 : ZERO_STRUCT(server_challenge);
4511 :
4512 7757 : status = smb1cli_req_recv(subreq, state,
4513 : &recv_iov,
4514 : &inhdr,
4515 : &wct,
4516 : &vwv,
4517 : NULL, /* pvwv_offset */
4518 : &num_bytes,
4519 : &bytes,
4520 : NULL, /* pbytes_offset */
4521 : NULL, /* pinbuf */
4522 : expected, ARRAY_SIZE(expected));
4523 7757 : TALLOC_FREE(subreq);
4524 7757 : if (tevent_req_nterror(req, status)) {
4525 1088 : return;
4526 : }
4527 7163 : if (inhdr == NULL) {
4528 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
4529 0 : return;
4530 : }
4531 :
4532 7163 : flags = CVAL(inhdr, HDR_FLG);
4533 :
4534 7163 : protnum = SVAL(vwv, 0);
4535 :
4536 66375 : for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4537 65881 : if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4538 1040 : continue;
4539 : }
4540 :
4541 64841 : if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4542 1006 : continue;
4543 : }
4544 :
4545 63835 : if (protnum != num_prots) {
4546 57166 : num_prots++;
4547 57166 : continue;
4548 : }
4549 :
4550 6669 : conn->protocol = smb1cli_prots[i].proto;
4551 6669 : break;
4552 : }
4553 :
4554 7163 : if (conn->protocol == PROTOCOL_NONE) {
4555 494 : DBG_ERR("No compatible protocol selected by server.\n");
4556 494 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4557 494 : return;
4558 : }
4559 :
4560 6669 : if ((conn->protocol < PROTOCOL_NT1) && conn->mandatory_signing) {
4561 0 : DEBUG(0,("smbXcli_negprot: SMB signing is mandatory "
4562 : "and the selected protocol level doesn't support it.\n"));
4563 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4564 0 : return;
4565 : }
4566 :
4567 6669 : if (flags & FLAG_SUPPORT_LOCKREAD) {
4568 26 : server_lockread = true;
4569 26 : server_writeunlock = true;
4570 : }
4571 :
4572 6669 : if (conn->protocol >= PROTOCOL_NT1) {
4573 6641 : const char *client_signing = NULL;
4574 6641 : bool server_mandatory = false;
4575 6641 : bool server_allowed = false;
4576 6641 : const char *server_signing = NULL;
4577 133 : bool ok;
4578 133 : uint8_t key_len;
4579 :
4580 6641 : if (wct != 0x11) {
4581 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4582 0 : return;
4583 : }
4584 :
4585 : /* NT protocol */
4586 6641 : server_security_mode = CVAL(vwv + 1, 0);
4587 6641 : server_max_mux = SVAL(vwv + 1, 1);
4588 6641 : server_max_xmit = IVAL(vwv + 3, 1);
4589 6641 : server_session_key = IVAL(vwv + 7, 1);
4590 6641 : server_time_zone = SVALS(vwv + 15, 1);
4591 6641 : server_time_zone *= 60;
4592 : /* this time arrives in real GMT */
4593 6641 : server_system_time = BVAL(vwv + 11, 1);
4594 6641 : server_capabilities = IVAL(vwv + 9, 1);
4595 :
4596 6641 : key_len = CVAL(vwv + 16, 1);
4597 :
4598 6641 : if (server_capabilities & CAP_RAW_MODE) {
4599 5844 : server_readbraw = true;
4600 5844 : server_writebraw = true;
4601 : }
4602 6641 : if (server_capabilities & CAP_LOCK_AND_READ) {
4603 6641 : server_lockread = true;
4604 : }
4605 :
4606 6641 : if (server_capabilities & CAP_EXTENDED_SECURITY) {
4607 133 : DATA_BLOB blob1, blob2;
4608 :
4609 6556 : if (num_bytes < 16) {
4610 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4611 0 : return;
4612 : }
4613 :
4614 6556 : blob1 = data_blob_const(bytes, 16);
4615 6556 : status = GUID_from_data_blob(&blob1, &server_guid);
4616 6556 : if (tevent_req_nterror(req, status)) {
4617 0 : return;
4618 : }
4619 :
4620 6556 : blob1 = data_blob_const(bytes+16, num_bytes-16);
4621 6556 : blob2 = data_blob_dup_talloc(state, blob1);
4622 13112 : if (blob1.length > 0 &&
4623 6556 : tevent_req_nomem(blob2.data, req)) {
4624 0 : return;
4625 : }
4626 6556 : server_gss_blob = blob2;
4627 : } else {
4628 0 : DATA_BLOB blob1, blob2;
4629 :
4630 85 : if (num_bytes < key_len) {
4631 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4632 0 : return;
4633 : }
4634 :
4635 85 : if (key_len != 0 && key_len != 8) {
4636 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4637 0 : return;
4638 : }
4639 :
4640 85 : if (key_len == 8) {
4641 85 : memcpy(server_challenge, bytes, 8);
4642 : }
4643 :
4644 85 : blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4645 85 : blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
4646 85 : if (blob1.length > 0) {
4647 0 : size_t len;
4648 :
4649 85 : len = utf16_null_terminated_len_n(blob1.data,
4650 : blob1.length);
4651 85 : blob1.length = len;
4652 :
4653 85 : ok = convert_string_talloc(state,
4654 : CH_UTF16LE,
4655 : CH_UNIX,
4656 85 : blob1.data,
4657 : blob1.length,
4658 : &server_workgroup,
4659 : &len);
4660 85 : if (!ok) {
4661 0 : status = map_nt_error_from_unix_common(errno);
4662 0 : tevent_req_nterror(req, status);
4663 0 : return;
4664 : }
4665 : }
4666 :
4667 85 : blob2.data += blob1.length;
4668 85 : blob2.length -= blob1.length;
4669 85 : if (blob2.length > 0) {
4670 0 : size_t len;
4671 :
4672 85 : ok = convert_string_talloc(state,
4673 : CH_UTF16LE,
4674 : CH_UNIX,
4675 85 : blob2.data,
4676 : blob2.length,
4677 : &server_name,
4678 : &len);
4679 85 : if (!ok) {
4680 0 : status = map_nt_error_from_unix_common(errno);
4681 0 : tevent_req_nterror(req, status);
4682 0 : return;
4683 : }
4684 : }
4685 : }
4686 :
4687 6641 : client_signing = "disabled";
4688 6641 : if (conn->allow_signing) {
4689 6635 : client_signing = "allowed";
4690 : }
4691 6641 : if (conn->mandatory_signing) {
4692 303 : client_signing = "required";
4693 : }
4694 :
4695 6641 : server_signing = "not supported";
4696 6641 : if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
4697 1590 : server_signing = "supported";
4698 1590 : server_allowed = true;
4699 4918 : } else if (conn->mandatory_signing) {
4700 : /*
4701 : * We have mandatory signing as client
4702 : * lets assume the server will look at our
4703 : * FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
4704 : * flag in the session setup
4705 : */
4706 290 : server_signing = "not announced";
4707 290 : server_allowed = true;
4708 : }
4709 6641 : if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
4710 1629 : server_signing = "required";
4711 1629 : server_mandatory = true;
4712 : }
4713 :
4714 6641 : ok = smb1_signing_set_negotiated(conn->smb1.signing,
4715 : server_allowed,
4716 : server_mandatory);
4717 6641 : if (!ok) {
4718 0 : DEBUG(1,("cli_negprot: SMB signing is required, "
4719 : "but client[%s] and server[%s] mismatch\n",
4720 : client_signing, server_signing));
4721 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4722 0 : return;
4723 : }
4724 :
4725 28 : } else if (conn->protocol >= PROTOCOL_LANMAN1) {
4726 0 : DATA_BLOB blob1;
4727 0 : uint8_t key_len;
4728 0 : time_t t;
4729 :
4730 28 : if (wct != 0x0D) {
4731 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4732 0 : return;
4733 : }
4734 :
4735 28 : server_security_mode = SVAL(vwv + 1, 0);
4736 28 : server_max_xmit = SVAL(vwv + 2, 0);
4737 28 : server_max_mux = SVAL(vwv + 3, 0);
4738 28 : server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
4739 28 : server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
4740 28 : server_session_key = IVAL(vwv + 6, 0);
4741 28 : server_time_zone = SVALS(vwv + 10, 0);
4742 28 : server_time_zone *= 60;
4743 : /* this time is converted to GMT by make_unix_date */
4744 28 : t = pull_dos_date((const uint8_t *)(vwv + 8), server_time_zone);
4745 28 : unix_to_nt_time(&server_system_time, t);
4746 28 : key_len = SVAL(vwv + 11, 0);
4747 :
4748 28 : if (num_bytes < key_len) {
4749 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4750 0 : return;
4751 : }
4752 :
4753 28 : if (key_len != 0 && key_len != 8) {
4754 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4755 0 : return;
4756 : }
4757 :
4758 28 : if (key_len == 8) {
4759 28 : memcpy(server_challenge, bytes, 8);
4760 : }
4761 :
4762 28 : blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4763 28 : if (blob1.length > 0) {
4764 0 : size_t len;
4765 0 : bool ok;
4766 :
4767 2 : len = utf16_null_terminated_len_n(blob1.data,
4768 : blob1.length);
4769 2 : blob1.length = len;
4770 :
4771 2 : ok = convert_string_talloc(state,
4772 : CH_DOS,
4773 : CH_UNIX,
4774 2 : blob1.data,
4775 : blob1.length,
4776 : &server_workgroup,
4777 : &len);
4778 2 : if (!ok) {
4779 0 : status = map_nt_error_from_unix_common(errno);
4780 0 : tevent_req_nterror(req, status);
4781 0 : return;
4782 : }
4783 : }
4784 :
4785 : } else {
4786 : /* the old core protocol */
4787 0 : server_time_zone = get_time_zone(time(NULL));
4788 0 : server_max_xmit = 1024;
4789 0 : server_max_mux = 1;
4790 : }
4791 :
4792 6669 : if (server_max_xmit < 1024) {
4793 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4794 0 : return;
4795 : }
4796 :
4797 6669 : if (server_max_mux < 1) {
4798 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4799 0 : return;
4800 : }
4801 :
4802 : /*
4803 : * Now calculate the negotiated capabilities
4804 : * based on the mask for:
4805 : * - client only flags
4806 : * - flags used in both directions
4807 : * - server only flags
4808 : */
4809 6669 : both_capabilities = client_capabilities & server_capabilities;
4810 6669 : capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
4811 6669 : capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
4812 6669 : capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
4813 :
4814 6669 : max_xmit = MIN(client_max_xmit, server_max_xmit);
4815 :
4816 6669 : conn->smb1.server.capabilities = server_capabilities;
4817 6669 : conn->smb1.capabilities = capabilities;
4818 :
4819 6669 : conn->smb1.server.max_xmit = server_max_xmit;
4820 6669 : conn->smb1.max_xmit = max_xmit;
4821 :
4822 6669 : conn->smb1.server.max_mux = server_max_mux;
4823 :
4824 6669 : conn->smb1.server.security_mode = server_security_mode;
4825 :
4826 6669 : conn->smb1.server.readbraw = server_readbraw;
4827 6669 : conn->smb1.server.writebraw = server_writebraw;
4828 6669 : conn->smb1.server.lockread = server_lockread;
4829 6669 : conn->smb1.server.writeunlock = server_writeunlock;
4830 :
4831 6669 : conn->smb1.server.session_key = server_session_key;
4832 :
4833 6669 : talloc_steal(conn, server_gss_blob.data);
4834 6669 : conn->smb1.server.gss_blob = server_gss_blob;
4835 6669 : conn->smb1.server.guid = server_guid;
4836 6669 : memcpy(conn->smb1.server.challenge, server_challenge, 8);
4837 6669 : conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
4838 6669 : conn->smb1.server.name = talloc_move(conn, &server_name);
4839 :
4840 6669 : conn->smb1.server.time_zone = server_time_zone;
4841 6669 : conn->smb1.server.system_time = server_system_time;
4842 :
4843 6669 : tevent_req_done(req);
4844 : }
4845 :
4846 25343 : static size_t smbXcli_padding_helper(uint32_t offset, size_t n)
4847 : {
4848 25343 : if ((offset & (n-1)) == 0) return 0;
4849 25343 : return n - (offset & (n-1));
4850 : }
4851 :
4852 25655 : static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state)
4853 : {
4854 721 : size_t i;
4855 721 : uint8_t *buf;
4856 25655 : uint16_t dialect_count = 0;
4857 25655 : DATA_BLOB dyn = data_blob_null;
4858 :
4859 153930 : for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4860 3605 : bool ok;
4861 3605 : uint8_t val[2];
4862 :
4863 128275 : if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4864 4765 : continue;
4865 : }
4866 :
4867 124286 : if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4868 776 : continue;
4869 : }
4870 :
4871 123510 : SSVAL(val, 0, smb2cli_prots[i].smb2_dialect);
4872 :
4873 123510 : ok = data_blob_append(state, &dyn, val, sizeof(val));
4874 123510 : if (!ok) {
4875 0 : return NULL;
4876 : }
4877 :
4878 123510 : dialect_count++;
4879 : }
4880 :
4881 25655 : buf = state->smb2.fixed;
4882 25655 : SSVAL(buf, 0, 36);
4883 25655 : SSVAL(buf, 2, dialect_count);
4884 25655 : SSVAL(buf, 4, state->conn->smb2.client.security_mode);
4885 25655 : SSVAL(buf, 6, 0); /* Reserved */
4886 25655 : if (state->conn->max_protocol >= PROTOCOL_SMB3_00) {
4887 25447 : SIVAL(buf, 8, state->conn->smb2.client.capabilities);
4888 : } else {
4889 208 : SIVAL(buf, 8, 0); /* Capabilities */
4890 : }
4891 25655 : if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
4892 25607 : struct GUID_ndr_buf guid_buf = { .buf = {0}, };
4893 :
4894 25607 : GUID_to_ndr_buf(&state->conn->smb2.client.guid, &guid_buf);
4895 25607 : memcpy(buf+12, guid_buf.buf, 16); /* ClientGuid */
4896 : } else {
4897 48 : memset(buf+12, 0, 16); /* ClientGuid */
4898 : }
4899 :
4900 25655 : if (state->conn->max_protocol >= PROTOCOL_SMB3_11) {
4901 25343 : const struct smb3_signing_capabilities *client_sign_algos =
4902 24662 : &state->conn->smb2.client.smb3_capabilities.signing;
4903 25343 : const struct smb3_encryption_capabilities *client_ciphers =
4904 24662 : &state->conn->smb2.client.smb3_capabilities.encryption;
4905 681 : NTSTATUS status;
4906 25343 : struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4907 25343 : uint8_t *netname_utf16 = NULL;
4908 25343 : size_t netname_utf16_len = 0;
4909 681 : uint32_t offset;
4910 681 : DATA_BLOB b;
4911 681 : uint8_t p[38];
4912 25343 : const uint8_t zeros[8] = {0, };
4913 681 : size_t pad;
4914 681 : bool ok;
4915 :
4916 25343 : SSVAL(p, 0, 1); /* HashAlgorithmCount */
4917 25343 : SSVAL(p, 2, 32); /* SaltLength */
4918 25343 : SSVAL(p, 4, SMB2_PREAUTH_INTEGRITY_SHA512);
4919 25343 : generate_random_buffer(p + 6, 32);
4920 :
4921 25343 : status = smb2_negotiate_context_add(
4922 : state, &c, SMB2_PREAUTH_INTEGRITY_CAPABILITIES, p, 38);
4923 25343 : if (!NT_STATUS_IS_OK(status)) {
4924 0 : return NULL;
4925 : }
4926 :
4927 25343 : if (client_ciphers->num_algos > 0) {
4928 25343 : size_t ofs = 0;
4929 25343 : SSVAL(p, ofs, client_ciphers->num_algos);
4930 25343 : ofs += 2;
4931 :
4932 125851 : for (i = 0; i < client_ciphers->num_algos; i++) {
4933 100508 : size_t next_ofs = ofs + 2;
4934 100508 : SMB_ASSERT(next_ofs < ARRAY_SIZE(p));
4935 100508 : SSVAL(p, ofs, client_ciphers->algos[i]);
4936 100508 : ofs = next_ofs;
4937 : }
4938 :
4939 25343 : status = smb2_negotiate_context_add(
4940 : state, &c, SMB2_ENCRYPTION_CAPABILITIES, p, ofs);
4941 25343 : if (!NT_STATUS_IS_OK(status)) {
4942 0 : return NULL;
4943 : }
4944 : }
4945 :
4946 25343 : if (client_sign_algos->num_algos > 0) {
4947 25343 : size_t ofs = 0;
4948 25343 : SSVAL(p, ofs, client_sign_algos->num_algos);
4949 25343 : ofs += 2;
4950 :
4951 100048 : for (i = 0; i < client_sign_algos->num_algos; i++) {
4952 74705 : size_t next_ofs = ofs + 2;
4953 74705 : SMB_ASSERT(next_ofs < ARRAY_SIZE(p));
4954 74705 : SSVAL(p, ofs, client_sign_algos->algos[i]);
4955 74705 : ofs = next_ofs;
4956 : }
4957 :
4958 25343 : status = smb2_negotiate_context_add(
4959 : state, &c, SMB2_SIGNING_CAPABILITIES, p, ofs);
4960 25343 : if (!NT_STATUS_IS_OK(status)) {
4961 0 : return NULL;
4962 : }
4963 : }
4964 :
4965 26024 : ok = convert_string_talloc(state, CH_UNIX, CH_UTF16,
4966 24662 : state->conn->remote_name,
4967 25343 : strlen(state->conn->remote_name),
4968 : &netname_utf16, &netname_utf16_len);
4969 25343 : if (!ok) {
4970 0 : return NULL;
4971 : }
4972 :
4973 25343 : status = smb2_negotiate_context_add(state, &c,
4974 : SMB2_NETNAME_NEGOTIATE_CONTEXT_ID,
4975 : netname_utf16, netname_utf16_len);
4976 25343 : if (!NT_STATUS_IS_OK(status)) {
4977 0 : return NULL;
4978 : }
4979 :
4980 25343 : if (state->in_ctx != NULL) {
4981 13440 : struct smb2_negotiate_contexts *ctxs = state->in_ctx;
4982 :
4983 22079 : for (i=0; i<ctxs->num_contexts; i++) {
4984 8639 : struct smb2_negotiate_context *ctx =
4985 8639 : &ctxs->contexts[i];
4986 :
4987 8639 : status = smb2_negotiate_context_add(
4988 : state,
4989 : &c,
4990 8639 : ctx->type,
4991 8639 : ctx->data.data,
4992 : ctx->data.length);
4993 8639 : if (!NT_STATUS_IS_OK(status)) {
4994 0 : return NULL;
4995 : }
4996 : }
4997 : }
4998 :
4999 25343 : status = smb2_negotiate_context_push(state, &b, c);
5000 25343 : if (!NT_STATUS_IS_OK(status)) {
5001 0 : return NULL;
5002 : }
5003 :
5004 25343 : offset = SMB2_HDR_BODY + sizeof(state->smb2.fixed) + dyn.length;
5005 25343 : pad = smbXcli_padding_helper(offset, 8);
5006 :
5007 25343 : ok = data_blob_append(state, &dyn, zeros, pad);
5008 25343 : if (!ok) {
5009 0 : return NULL;
5010 : }
5011 25343 : offset += pad;
5012 :
5013 25343 : ok = data_blob_append(state, &dyn, b.data, b.length);
5014 25343 : if (!ok) {
5015 0 : return NULL;
5016 : }
5017 :
5018 25343 : SIVAL(buf, 28, offset); /* NegotiateContextOffset */
5019 25343 : SSVAL(buf, 32, c.num_contexts); /* NegotiateContextCount */
5020 25343 : SSVAL(buf, 34, 0); /* Reserved */
5021 : } else {
5022 312 : SBVAL(buf, 28, 0); /* Reserved/ClientStartTime */
5023 : }
5024 :
5025 25655 : return smb2cli_req_send(state, state->ev,
5026 : state->conn, SMB2_OP_NEGPROT,
5027 : 0, 0, /* flags */
5028 : state->timeout_msec,
5029 : NULL, NULL, /* tcon, session */
5030 24934 : state->smb2.fixed, sizeof(state->smb2.fixed),
5031 25655 : dyn.data, dyn.length,
5032 : UINT16_MAX); /* max_dyn_len */
5033 : }
5034 :
5035 : static NTSTATUS smbXcli_negprot_smb3_check_capabilities(struct tevent_req *req);
5036 :
5037 43628 : static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
5038 : {
5039 1111 : struct tevent_req *req =
5040 43628 : tevent_req_callback_data(subreq,
5041 : struct tevent_req);
5042 1111 : struct smbXcli_negprot_state *state =
5043 43628 : tevent_req_data(req,
5044 : struct smbXcli_negprot_state);
5045 43628 : struct smbXcli_conn *conn = state->conn;
5046 1111 : size_t security_offset, security_length;
5047 1111 : DATA_BLOB blob;
5048 1111 : NTSTATUS status;
5049 43628 : struct iovec *iov = NULL;
5050 1111 : uint8_t *body;
5051 1111 : size_t i;
5052 1111 : uint16_t dialect_revision;
5053 43628 : uint32_t negotiate_context_offset = 0;
5054 43628 : uint16_t negotiate_context_count = 0;
5055 43628 : DATA_BLOB negotiate_context_blob = data_blob_null;
5056 1111 : size_t avail;
5057 1111 : size_t ctx_ofs;
5058 1111 : size_t needed;
5059 43628 : struct smb2_negotiate_context *preauth = NULL;
5060 1111 : uint16_t hash_count;
5061 1111 : uint16_t salt_length;
5062 1111 : uint16_t hash_selected;
5063 43628 : gnutls_hash_hd_t hash_hnd = NULL;
5064 43628 : struct smb2_negotiate_context *sign_algo = NULL;
5065 43628 : struct smb2_negotiate_context *cipher = NULL;
5066 43628 : struct smb2_negotiate_context *posix = NULL;
5067 43628 : struct iovec sent_iov[3] = {{0}, {0}, {0}};
5068 1111 : static const struct smb2cli_req_expected_response expected[] = {
5069 : {
5070 : .status = NT_STATUS_OK,
5071 : .body_size = 0x41
5072 : }
5073 : };
5074 1111 : int rc;
5075 :
5076 43628 : status = smb2cli_req_recv(subreq, state, &iov,
5077 : expected, ARRAY_SIZE(expected));
5078 43628 : if (tevent_req_nterror(req, status)) {
5079 20766 : return;
5080 : }
5081 43622 : if (iov == NULL) {
5082 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5083 0 : return;
5084 : }
5085 :
5086 43622 : body = (uint8_t *)iov[1].iov_base;
5087 :
5088 43622 : dialect_revision = SVAL(body, 4);
5089 :
5090 221590 : for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5091 204798 : if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5092 3973 : continue;
5093 : }
5094 :
5095 200825 : if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5096 108 : continue;
5097 : }
5098 :
5099 200717 : if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
5100 173887 : continue;
5101 : }
5102 :
5103 26830 : conn->protocol = smb2cli_prots[i].proto;
5104 26830 : break;
5105 : }
5106 :
5107 43622 : if (conn->protocol == PROTOCOL_NONE) {
5108 16792 : TALLOC_FREE(subreq);
5109 :
5110 16792 : if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5111 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5112 0 : return;
5113 : }
5114 :
5115 16792 : if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
5116 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5117 0 : return;
5118 : }
5119 :
5120 : /* make sure we do not loop forever */
5121 16792 : state->conn->min_protocol = PROTOCOL_SMB2_02;
5122 :
5123 : /*
5124 : * send a SMB2 negprot, in order to negotiate
5125 : * the SMB2 dialect.
5126 : */
5127 16792 : subreq = smbXcli_negprot_smb2_subreq(state);
5128 16792 : if (tevent_req_nomem(subreq, req)) {
5129 0 : return;
5130 : }
5131 16792 : tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
5132 16792 : return;
5133 : }
5134 :
5135 26830 : conn->smb2.server.security_mode = SVAL(body, 2);
5136 26830 : if (conn->protocol >= PROTOCOL_SMB3_11) {
5137 22862 : negotiate_context_count = SVAL(body, 6);
5138 : }
5139 :
5140 26830 : blob = data_blob_const(body + 8, 16);
5141 26830 : status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
5142 26830 : if (tevent_req_nterror(req, status)) {
5143 0 : return;
5144 : }
5145 :
5146 26830 : conn->smb2.server.capabilities = IVAL(body, 24);
5147 26830 : conn->smb2.server.max_trans_size= IVAL(body, 28);
5148 26830 : conn->smb2.server.max_read_size = IVAL(body, 32);
5149 26830 : conn->smb2.server.max_write_size= IVAL(body, 36);
5150 26830 : conn->smb2.server.system_time = BVAL(body, 40);
5151 26830 : conn->smb2.server.start_time = BVAL(body, 48);
5152 :
5153 26830 : if (conn->smb2.server.max_trans_size == 0 ||
5154 26830 : conn->smb2.server.max_read_size == 0 ||
5155 26107 : conn->smb2.server.max_write_size == 0) {
5156 : /*
5157 : * We can't connect to servers we can't
5158 : * do any operations on.
5159 : */
5160 2 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5161 2 : return;
5162 : }
5163 :
5164 26828 : security_offset = SVAL(body, 56);
5165 26828 : security_length = SVAL(body, 58);
5166 :
5167 26828 : if (security_offset == 0) {
5168 : /*
5169 : * Azure sends security_offset = 0 and security_length = 0
5170 : *
5171 : * We just set security_offset to the expected value
5172 : * in order to allow the further logic to work
5173 : * as before.
5174 : */
5175 0 : if (security_length != 0) {
5176 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5177 0 : return;
5178 : }
5179 0 : security_offset = SMB2_HDR_BODY + iov[1].iov_len;
5180 : }
5181 :
5182 26828 : if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
5183 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5184 0 : return;
5185 : }
5186 :
5187 26828 : if (security_length > iov[2].iov_len) {
5188 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5189 0 : return;
5190 : }
5191 :
5192 26828 : conn->smb2.server.gss_blob = data_blob_talloc(conn,
5193 : iov[2].iov_base,
5194 : security_length);
5195 26828 : if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
5196 0 : return;
5197 : }
5198 :
5199 26828 : if (conn->protocol >= PROTOCOL_SMB3_00) {
5200 22966 : conn->smb2.server.sign_algo = SMB2_SIGNING_AES128_CMAC;
5201 : } else {
5202 3862 : conn->smb2.server.sign_algo = SMB2_SIGNING_HMAC_SHA256;
5203 : }
5204 :
5205 26828 : if (conn->protocol < PROTOCOL_SMB3_11) {
5206 3966 : TALLOC_FREE(subreq);
5207 :
5208 3966 : if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
5209 92 : conn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
5210 : }
5211 :
5212 3966 : status = smbXcli_negprot_smb3_check_capabilities(req);
5213 3966 : if (tevent_req_nterror(req, status)) {
5214 0 : return;
5215 : }
5216 :
5217 3966 : tevent_req_done(req);
5218 3966 : return;
5219 : }
5220 :
5221 : /*
5222 : * Here we are now at SMB3_11, so encryption should be
5223 : * negotiated via context, not capabilities.
5224 : */
5225 :
5226 22862 : if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
5227 : /*
5228 : * Server set SMB2_CAP_ENCRYPTION capability,
5229 : * but *SHOULD* not, not *MUST* not. Just mask it off.
5230 : * NetApp seems to do this:
5231 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13009
5232 : */
5233 0 : conn->smb2.server.capabilities &= ~SMB2_CAP_ENCRYPTION;
5234 : }
5235 :
5236 22862 : negotiate_context_offset = IVAL(body, 60);
5237 22862 : if (negotiate_context_offset < security_offset) {
5238 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5239 0 : return;
5240 : }
5241 :
5242 22862 : ctx_ofs = negotiate_context_offset - security_offset;
5243 22862 : if (ctx_ofs > iov[2].iov_len) {
5244 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5245 0 : return;
5246 : }
5247 22862 : avail = iov[2].iov_len - security_length;
5248 22862 : needed = iov[2].iov_len - ctx_ofs;
5249 22862 : if (needed > avail) {
5250 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5251 0 : return;
5252 : }
5253 :
5254 22862 : negotiate_context_blob.data = (uint8_t *)iov[2].iov_base;
5255 22862 : negotiate_context_blob.length = iov[2].iov_len;
5256 :
5257 22862 : negotiate_context_blob.data += ctx_ofs;
5258 22862 : negotiate_context_blob.length -= ctx_ofs;
5259 :
5260 22862 : state->out_ctx = talloc_zero(state, struct smb2_negotiate_contexts);
5261 22862 : if (tevent_req_nomem(state->out_ctx, req)) {
5262 0 : return;
5263 : }
5264 :
5265 22862 : status = smb2_negotiate_context_parse(state->out_ctx,
5266 : negotiate_context_blob,
5267 : negotiate_context_count,
5268 : state->out_ctx);
5269 22862 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5270 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
5271 : }
5272 22862 : if (tevent_req_nterror(req, status)) {
5273 0 : return;
5274 : }
5275 :
5276 23543 : preauth = smb2_negotiate_context_find(
5277 22862 : state->out_ctx, SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
5278 22862 : if (preauth == NULL) {
5279 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5280 0 : return;
5281 : }
5282 :
5283 22862 : if (preauth->data.length < 6) {
5284 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5285 0 : return;
5286 : }
5287 :
5288 22862 : hash_count = SVAL(preauth->data.data, 0);
5289 22862 : salt_length = SVAL(preauth->data.data, 2);
5290 22862 : hash_selected = SVAL(preauth->data.data, 4);
5291 :
5292 22862 : if (hash_count != 1) {
5293 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5294 0 : return;
5295 : }
5296 :
5297 22862 : if (preauth->data.length != (6 + salt_length)) {
5298 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5299 0 : return;
5300 : }
5301 :
5302 22862 : if (hash_selected != SMB2_PREAUTH_INTEGRITY_SHA512) {
5303 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5304 0 : return;
5305 : }
5306 :
5307 23543 : sign_algo = smb2_negotiate_context_find(
5308 22862 : state->out_ctx, SMB2_SIGNING_CAPABILITIES);
5309 22862 : if (sign_algo != NULL) {
5310 22862 : const struct smb3_signing_capabilities *client_sign_algos =
5311 22862 : &state->conn->smb2.client.smb3_capabilities.signing;
5312 22862 : bool found_selected = false;
5313 681 : uint16_t sign_algo_count;
5314 681 : uint16_t sign_algo_selected;
5315 :
5316 22862 : if (client_sign_algos->num_algos == 0) {
5317 : /*
5318 : * We didn't ask for SMB2_ENCRYPTION_CAPABILITIES
5319 : */
5320 0 : tevent_req_nterror(req,
5321 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5322 0 : return;
5323 : }
5324 :
5325 22862 : if (sign_algo->data.length < 2) {
5326 0 : tevent_req_nterror(req,
5327 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5328 0 : return;
5329 : }
5330 :
5331 22862 : sign_algo_count = SVAL(sign_algo->data.data, 0);
5332 22862 : if (sign_algo_count != 1) {
5333 0 : tevent_req_nterror(req,
5334 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5335 0 : return;
5336 : }
5337 :
5338 22862 : if (sign_algo->data.length < (2 + 2 * sign_algo_count)) {
5339 0 : tevent_req_nterror(req,
5340 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5341 0 : return;
5342 : }
5343 22862 : sign_algo_selected = SVAL(sign_algo->data.data, 2);
5344 :
5345 22862 : for (i = 0; i < client_sign_algos->num_algos; i++) {
5346 22862 : if (client_sign_algos->algos[i] == sign_algo_selected) {
5347 : /*
5348 : * We found a match
5349 : */
5350 22181 : found_selected = true;
5351 22181 : break;
5352 : }
5353 : }
5354 :
5355 22862 : if (!found_selected) {
5356 : /*
5357 : * The server send a sign_algo we didn't offer.
5358 : */
5359 0 : tevent_req_nterror(req,
5360 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5361 0 : return;
5362 : }
5363 :
5364 22862 : conn->smb2.server.sign_algo = sign_algo_selected;
5365 : }
5366 :
5367 23543 : cipher = smb2_negotiate_context_find(
5368 22862 : state->out_ctx, SMB2_ENCRYPTION_CAPABILITIES);
5369 22862 : if (cipher != NULL) {
5370 22661 : const struct smb3_encryption_capabilities *client_ciphers =
5371 22661 : &state->conn->smb2.client.smb3_capabilities.encryption;
5372 22661 : bool found_selected = false;
5373 681 : uint16_t cipher_count;
5374 681 : uint16_t cipher_selected;
5375 :
5376 22661 : if (client_ciphers->num_algos == 0) {
5377 : /*
5378 : * We didn't ask for SMB2_ENCRYPTION_CAPABILITIES
5379 : */
5380 0 : tevent_req_nterror(req,
5381 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5382 0 : return;
5383 : }
5384 :
5385 22661 : if (cipher->data.length < 2) {
5386 0 : tevent_req_nterror(req,
5387 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5388 0 : return;
5389 : }
5390 :
5391 22661 : cipher_count = SVAL(cipher->data.data, 0);
5392 22661 : if (cipher_count != 1) {
5393 0 : tevent_req_nterror(req,
5394 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5395 0 : return;
5396 : }
5397 :
5398 22661 : if (cipher->data.length < (2 + 2 * cipher_count)) {
5399 0 : tevent_req_nterror(req,
5400 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5401 0 : return;
5402 : }
5403 22661 : cipher_selected = SVAL(cipher->data.data, 2);
5404 :
5405 22661 : for (i = 0; i < client_ciphers->num_algos; i++) {
5406 22661 : if (cipher_selected == SMB2_ENCRYPTION_NONE) {
5407 : /*
5408 : * encryption not supported
5409 : */
5410 0 : found_selected = true;
5411 0 : break;
5412 : }
5413 22661 : if (client_ciphers->algos[i] == cipher_selected) {
5414 : /*
5415 : * We found a match
5416 : */
5417 21980 : found_selected = true;
5418 21980 : break;
5419 : }
5420 : }
5421 :
5422 22661 : if (!found_selected) {
5423 : /*
5424 : * The server send a cipher we didn't offer.
5425 : */
5426 0 : tevent_req_nterror(req,
5427 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5428 0 : return;
5429 : }
5430 :
5431 22661 : conn->smb2.server.cipher = cipher_selected;
5432 : }
5433 :
5434 23543 : posix = smb2_negotiate_context_find(
5435 22862 : state->out_ctx, SMB2_POSIX_EXTENSIONS_AVAILABLE);
5436 22862 : if (posix != NULL) {
5437 5890 : DATA_BLOB posix_blob = data_blob_const(
5438 : SMB2_CREATE_TAG_POSIX, strlen(SMB2_CREATE_TAG_POSIX));
5439 5890 : int cmp = data_blob_cmp(&posix->data, &posix_blob);
5440 :
5441 5890 : conn->smb2.server.smb311_posix = (cmp == 0);
5442 : }
5443 :
5444 :
5445 : /* First we hash the request */
5446 22862 : smb2cli_req_get_sent_iov(subreq, sent_iov);
5447 :
5448 22862 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
5449 22862 : if (rc < 0) {
5450 0 : tevent_req_nterror(req,
5451 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5452 0 : return;
5453 : }
5454 :
5455 23543 : rc = gnutls_hash(hash_hnd,
5456 22862 : conn->smb2.preauth_sha512,
5457 : sizeof(conn->smb2.preauth_sha512));
5458 22862 : if (rc < 0) {
5459 0 : gnutls_hash_deinit(hash_hnd, NULL);
5460 0 : tevent_req_nterror(req,
5461 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5462 0 : return;
5463 : }
5464 91448 : for (i = 0; i < 3; i++) {
5465 70629 : rc = gnutls_hash(hash_hnd,
5466 68586 : sent_iov[i].iov_base,
5467 : sent_iov[i].iov_len);
5468 68586 : if (rc < 0) {
5469 0 : gnutls_hash_deinit(hash_hnd, NULL);
5470 0 : tevent_req_nterror(req,
5471 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5472 0 : return;
5473 : }
5474 : }
5475 :
5476 : /* This resets the hash state */
5477 22862 : gnutls_hash_output(hash_hnd, conn->smb2.preauth_sha512);
5478 22862 : TALLOC_FREE(subreq);
5479 :
5480 : /* And now we hash the response */
5481 22862 : rc = gnutls_hash(hash_hnd,
5482 22181 : conn->smb2.preauth_sha512,
5483 : sizeof(conn->smb2.preauth_sha512));
5484 22862 : if (rc < 0) {
5485 0 : gnutls_hash_deinit(hash_hnd, NULL);
5486 0 : tevent_req_nterror(req,
5487 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5488 0 : return;
5489 : }
5490 91448 : for (i = 0; i < 3; i++) {
5491 70629 : rc = gnutls_hash(hash_hnd,
5492 68586 : iov[i].iov_base,
5493 68586 : iov[i].iov_len);
5494 68586 : if (rc < 0) {
5495 0 : gnutls_hash_deinit(hash_hnd, NULL);
5496 0 : tevent_req_nterror(req,
5497 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5498 0 : return;
5499 : }
5500 : }
5501 22862 : gnutls_hash_deinit(hash_hnd, conn->smb2.preauth_sha512);
5502 22862 : if (rc < 0) {
5503 0 : tevent_req_nterror(req,
5504 : NT_STATUS_UNSUCCESSFUL);
5505 0 : return;
5506 : }
5507 :
5508 22862 : status = smbXcli_negprot_smb3_check_capabilities(req);
5509 22862 : if (tevent_req_nterror(req, status)) {
5510 0 : return;
5511 : }
5512 :
5513 22862 : tevent_req_done(req);
5514 : }
5515 :
5516 26828 : static NTSTATUS smbXcli_negprot_smb3_check_capabilities(struct tevent_req *req)
5517 : {
5518 721 : struct smbXcli_negprot_state *state =
5519 26828 : tevent_req_data(req,
5520 : struct smbXcli_negprot_state);
5521 26828 : struct smbXcli_conn *conn = state->conn;
5522 :
5523 53656 : return smb311_capabilities_check(&conn->smb2.client.smb3_capabilities,
5524 : "smbXcli_negprot",
5525 : DBGLVL_ERR,
5526 26828 : NT_STATUS_ACCESS_DENIED,
5527 : "client",
5528 : conn->protocol,
5529 26828 : conn->smb2.server.sign_algo,
5530 26828 : conn->smb2.server.cipher);
5531 : }
5532 :
5533 17973 : static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
5534 : TALLOC_CTX *tmp_mem,
5535 : uint8_t *inbuf)
5536 : {
5537 17973 : size_t num_pending = talloc_array_length(conn->pending);
5538 390 : struct tevent_req *subreq;
5539 390 : struct smbXcli_req_state *substate;
5540 390 : struct tevent_req *req;
5541 390 : uint32_t protocol_magic;
5542 17973 : size_t inbuf_len = smb_len_nbt(inbuf);
5543 :
5544 17973 : if (num_pending != 1) {
5545 0 : return NT_STATUS_INTERNAL_ERROR;
5546 : }
5547 :
5548 17973 : if (inbuf_len < 4) {
5549 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
5550 : }
5551 :
5552 17973 : subreq = conn->pending[0];
5553 17973 : substate = tevent_req_data(subreq, struct smbXcli_req_state);
5554 17973 : req = tevent_req_callback_data(subreq, struct tevent_req);
5555 :
5556 17973 : protocol_magic = IVAL(inbuf, 4);
5557 :
5558 17973 : switch (protocol_magic) {
5559 0 : case SMB_MAGIC:
5560 0 : tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
5561 0 : conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
5562 0 : return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5563 :
5564 17973 : case SMB2_MAGIC:
5565 17973 : if (substate->smb2.recv_iov == NULL) {
5566 : /*
5567 : * For the SMB1 negprot we have move it.
5568 : */
5569 17973 : substate->smb2.recv_iov = substate->smb1.recv_iov;
5570 17973 : substate->smb1.recv_iov = NULL;
5571 : }
5572 :
5573 : /*
5574 : * we got an SMB2 answer, which consumed sequence number 0
5575 : * so we need to use 1 as the next one.
5576 : *
5577 : * we also need to set the current credits to 0
5578 : * as we consumed the initial one. The SMB2 answer
5579 : * hopefully grant us a new credit.
5580 : */
5581 17973 : conn->smb2.mid = 1;
5582 17973 : conn->smb2.cur_credits = 0;
5583 17973 : tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
5584 17973 : conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
5585 17973 : return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5586 : }
5587 :
5588 0 : DEBUG(10, ("Got non-SMB PDU\n"));
5589 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
5590 : }
5591 :
5592 34593 : NTSTATUS smbXcli_negprot_recv(
5593 : struct tevent_req *req,
5594 : TALLOC_CTX *mem_ctx,
5595 : struct smb2_negotiate_contexts **out_ctx)
5596 : {
5597 34593 : struct smbXcli_negprot_state *state = tevent_req_data(
5598 : req, struct smbXcli_negprot_state);
5599 862 : NTSTATUS status;
5600 :
5601 34593 : if (tevent_req_is_nterror(req, &status)) {
5602 1096 : tevent_req_received(req);
5603 1096 : return status;
5604 : }
5605 :
5606 33497 : if (out_ctx != NULL) {
5607 12028 : *out_ctx = talloc_move(mem_ctx, &state->out_ctx);
5608 : }
5609 :
5610 33497 : tevent_req_received(req);
5611 33497 : return NT_STATUS_OK;
5612 : }
5613 :
5614 12607 : NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
5615 : uint32_t timeout_msec,
5616 : enum protocol_types min_protocol,
5617 : enum protocol_types max_protocol,
5618 : struct smb2_negotiate_contexts *in_ctx,
5619 : TALLOC_CTX *mem_ctx,
5620 : struct smb2_negotiate_contexts **out_ctx)
5621 : {
5622 12607 : TALLOC_CTX *frame = talloc_stackframe();
5623 0 : struct tevent_context *ev;
5624 0 : struct tevent_req *req;
5625 12607 : NTSTATUS status = NT_STATUS_NO_MEMORY;
5626 0 : bool ok;
5627 :
5628 12607 : if (smbXcli_conn_has_async_calls(conn)) {
5629 : /*
5630 : * Can't use sync call while an async call is in flight
5631 : */
5632 0 : status = NT_STATUS_INVALID_PARAMETER_MIX;
5633 0 : goto fail;
5634 : }
5635 12607 : ev = samba_tevent_context_init(frame);
5636 12607 : if (ev == NULL) {
5637 0 : goto fail;
5638 : }
5639 12607 : req = smbXcli_negprot_send(
5640 : frame,
5641 : ev,
5642 : conn,
5643 : timeout_msec,
5644 : min_protocol,
5645 : max_protocol,
5646 : WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
5647 : in_ctx);
5648 12607 : if (req == NULL) {
5649 0 : goto fail;
5650 : }
5651 12607 : ok = tevent_req_poll_ntstatus(req, ev, &status);
5652 12607 : if (!ok) {
5653 0 : goto fail;
5654 : }
5655 12607 : status = smbXcli_negprot_recv(req, mem_ctx, out_ctx);
5656 12607 : fail:
5657 12607 : TALLOC_FREE(frame);
5658 12607 : return status;
5659 : }
5660 :
5661 : struct smb2cli_validate_negotiate_info_state {
5662 : struct smbXcli_conn *conn;
5663 : DATA_BLOB in_input_buffer;
5664 : DATA_BLOB in_output_buffer;
5665 : DATA_BLOB out_input_buffer;
5666 : DATA_BLOB out_output_buffer;
5667 : uint16_t dialect;
5668 : };
5669 :
5670 : static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq);
5671 :
5672 4018 : struct tevent_req *smb2cli_validate_negotiate_info_send(TALLOC_CTX *mem_ctx,
5673 : struct tevent_context *ev,
5674 : struct smbXcli_conn *conn,
5675 : uint32_t timeout_msec,
5676 : struct smbXcli_session *session,
5677 : struct smbXcli_tcon *tcon)
5678 : {
5679 22 : struct tevent_req *req;
5680 22 : struct smb2cli_validate_negotiate_info_state *state;
5681 22 : uint8_t *buf;
5682 4018 : uint16_t dialect_count = 0;
5683 22 : struct tevent_req *subreq;
5684 22 : bool _save_should_sign;
5685 22 : size_t i;
5686 :
5687 4018 : req = tevent_req_create(mem_ctx, &state,
5688 : struct smb2cli_validate_negotiate_info_state);
5689 4018 : if (req == NULL) {
5690 0 : return NULL;
5691 : }
5692 4018 : state->conn = conn;
5693 :
5694 4018 : state->in_input_buffer = data_blob_talloc_zero(state,
5695 : 4 + 16 + 1 + 1 + 2);
5696 4018 : if (tevent_req_nomem(state->in_input_buffer.data, req)) {
5697 0 : return tevent_req_post(req, ev);
5698 : }
5699 4018 : buf = state->in_input_buffer.data;
5700 :
5701 4018 : if (state->conn->max_protocol >= PROTOCOL_SMB3_00) {
5702 3822 : SIVAL(buf, 0, conn->smb2.client.capabilities);
5703 : } else {
5704 196 : SIVAL(buf, 0, 0); /* Capabilities */
5705 : }
5706 4018 : if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
5707 3964 : struct GUID_ndr_buf guid_buf = { .buf = {0}, };
5708 :
5709 3964 : GUID_to_ndr_buf(&conn->smb2.client.guid, &guid_buf);
5710 3964 : memcpy(buf+4, guid_buf.buf, 16); /* ClientGuid */
5711 : } else {
5712 54 : memset(buf+4, 0, 16); /* ClientGuid */
5713 : }
5714 4018 : if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5715 2864 : SCVAL(buf, 20, conn->smb2.client.security_mode);
5716 : } else {
5717 1154 : SCVAL(buf, 20, 0);
5718 : }
5719 4018 : SCVAL(buf, 21, 0); /* reserved */
5720 :
5721 24108 : for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5722 110 : bool ok;
5723 110 : size_t ofs;
5724 :
5725 20090 : if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5726 389 : continue;
5727 : }
5728 :
5729 19701 : if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5730 750 : continue;
5731 : }
5732 :
5733 18951 : if (smb2cli_prots[i].proto == state->conn->protocol) {
5734 4018 : state->dialect = smb2cli_prots[i].smb2_dialect;
5735 : }
5736 :
5737 18951 : ofs = state->in_input_buffer.length;
5738 18951 : ok = data_blob_realloc(state, &state->in_input_buffer,
5739 : ofs + 2);
5740 18951 : if (!ok) {
5741 0 : tevent_req_oom(req);
5742 0 : return tevent_req_post(req, ev);
5743 : }
5744 :
5745 18951 : buf = state->in_input_buffer.data;
5746 18951 : SSVAL(buf, ofs, smb2cli_prots[i].smb2_dialect);
5747 :
5748 18951 : dialect_count++;
5749 : }
5750 4018 : buf = state->in_input_buffer.data;
5751 4018 : SSVAL(buf, 22, dialect_count);
5752 :
5753 4018 : _save_should_sign = smb2cli_tcon_is_signing_on(tcon);
5754 4018 : smb2cli_tcon_should_sign(tcon, true);
5755 4040 : subreq = smb2cli_ioctl_send(state, ev, conn,
5756 : timeout_msec, session, tcon,
5757 : UINT64_MAX, /* in_fid_persistent */
5758 : UINT64_MAX, /* in_fid_volatile */
5759 : FSCTL_VALIDATE_NEGOTIATE_INFO,
5760 : 0, /* in_max_input_length */
5761 4018 : &state->in_input_buffer,
5762 : 24, /* in_max_output_length */
5763 4018 : &state->in_output_buffer,
5764 : SMB2_IOCTL_FLAG_IS_FSCTL);
5765 4018 : smb2cli_tcon_should_sign(tcon, _save_should_sign);
5766 4018 : if (tevent_req_nomem(subreq, req)) {
5767 0 : return tevent_req_post(req, ev);
5768 : }
5769 4018 : tevent_req_set_callback(subreq,
5770 : smb2cli_validate_negotiate_info_done,
5771 : req);
5772 :
5773 4018 : return req;
5774 : }
5775 :
5776 4018 : static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
5777 : {
5778 22 : struct tevent_req *req =
5779 4018 : tevent_req_callback_data(subreq,
5780 : struct tevent_req);
5781 22 : struct smb2cli_validate_negotiate_info_state *state =
5782 4018 : tevent_req_data(req,
5783 : struct smb2cli_validate_negotiate_info_state);
5784 22 : NTSTATUS status;
5785 22 : const uint8_t *buf;
5786 22 : uint32_t capabilities;
5787 22 : DATA_BLOB guid_blob;
5788 22 : struct GUID server_guid;
5789 22 : uint16_t security_mode;
5790 22 : uint16_t dialect;
5791 :
5792 4018 : status = smb2cli_ioctl_recv(subreq, state,
5793 : &state->out_input_buffer,
5794 : &state->out_output_buffer);
5795 4018 : TALLOC_FREE(subreq);
5796 :
5797 : /*
5798 : * This response must be signed correctly for
5799 : * these "normal" error codes to be processed.
5800 : * If the packet wasn't signed correctly we will get
5801 : * NT_STATUS_ACCESS_DENIED or NT_STATUS_HMAC_NOT_SUPPORTED,
5802 : * or NT_STATUS_INVALID_NETWORK_RESPONSE
5803 : * from smb2_signing_check_pdu().
5804 : *
5805 : * We must never ignore the above errors here.
5806 : */
5807 :
5808 4018 : if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
5809 : /*
5810 : * The response was signed, but not supported
5811 : *
5812 : * Older Windows and Samba releases return
5813 : * NT_STATUS_FILE_CLOSED.
5814 : */
5815 64 : tevent_req_done(req);
5816 64 : return;
5817 : }
5818 3954 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
5819 : /*
5820 : * The response was signed, but not supported
5821 : *
5822 : * This is returned by the NTVFS based Samba 4.x file server
5823 : * for file shares.
5824 : */
5825 568 : tevent_req_done(req);
5826 568 : return;
5827 : }
5828 3386 : if (NT_STATUS_EQUAL(status, NT_STATUS_FS_DRIVER_REQUIRED)) {
5829 : /*
5830 : * The response was signed, but not supported
5831 : *
5832 : * This is returned by the NTVFS based Samba 4.x file server
5833 : * for ipc shares.
5834 : */
5835 912 : tevent_req_done(req);
5836 912 : return;
5837 : }
5838 2474 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
5839 : /*
5840 : * The response was signed, but not supported
5841 : *
5842 : * This might be returned by older Windows versions or by
5843 : * NetApp SMB server implementations.
5844 : *
5845 : * See
5846 : *
5847 : * https://blogs.msdn.microsoft.com/openspecification/2012/06/28/smb3-secure-dialect-negotiation/
5848 : *
5849 : */
5850 0 : tevent_req_done(req);
5851 0 : return;
5852 : }
5853 2474 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5854 : /*
5855 : * The response was signed, but not supported
5856 : *
5857 : * This might be returned by NetApp Ontap 7.3.7 SMB server
5858 : * implementations.
5859 : *
5860 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
5861 : *
5862 : */
5863 0 : tevent_req_done(req);
5864 0 : return;
5865 : }
5866 2474 : if (tevent_req_nterror(req, status)) {
5867 0 : return;
5868 : }
5869 :
5870 2474 : if (state->out_output_buffer.length != 24) {
5871 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5872 0 : return;
5873 : }
5874 :
5875 2474 : buf = state->out_output_buffer.data;
5876 :
5877 2474 : capabilities = IVAL(buf, 0);
5878 2474 : guid_blob = data_blob_const(buf + 4, 16);
5879 2474 : status = GUID_from_data_blob(&guid_blob, &server_guid);
5880 2474 : if (tevent_req_nterror(req, status)) {
5881 0 : return;
5882 : }
5883 2474 : security_mode = CVAL(buf, 20);
5884 2474 : dialect = SVAL(buf, 22);
5885 :
5886 2474 : if (capabilities != state->conn->smb2.server.capabilities) {
5887 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5888 0 : return;
5889 : }
5890 :
5891 2474 : if (!GUID_equal(&server_guid, &state->conn->smb2.server.guid)) {
5892 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5893 0 : return;
5894 : }
5895 :
5896 2474 : if (security_mode != state->conn->smb2.server.security_mode) {
5897 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5898 0 : return;
5899 : }
5900 :
5901 2474 : if (dialect != state->dialect) {
5902 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5903 0 : return;
5904 : }
5905 :
5906 2474 : tevent_req_done(req);
5907 : }
5908 :
5909 4018 : NTSTATUS smb2cli_validate_negotiate_info_recv(struct tevent_req *req)
5910 : {
5911 4018 : return tevent_req_simple_recv_ntstatus(req);
5912 : }
5913 :
5914 51591 : static int smbXcli_session_destructor(struct smbXcli_session *session)
5915 : {
5916 51591 : if (session->conn == NULL) {
5917 536 : return 0;
5918 : }
5919 :
5920 50971 : DLIST_REMOVE(session->conn->sessions, session);
5921 49872 : return 0;
5922 : }
5923 :
5924 51883 : struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
5925 : struct smbXcli_conn *conn)
5926 : {
5927 940 : struct smbXcli_session *session;
5928 940 : NTSTATUS status;
5929 :
5930 51883 : session = talloc_zero(mem_ctx, struct smbXcli_session);
5931 51883 : if (session == NULL) {
5932 0 : return NULL;
5933 : }
5934 51883 : session->smb2 = talloc_zero(session, struct smb2cli_session);
5935 51883 : if (session->smb2 == NULL) {
5936 0 : talloc_free(session);
5937 0 : return NULL;
5938 : }
5939 51883 : talloc_set_destructor(session, smbXcli_session_destructor);
5940 :
5941 52823 : status = smb2_signing_key_sign_create(session->smb2,
5942 51883 : conn->smb2.server.sign_algo,
5943 : NULL, /* no master key */
5944 : NULL, /* derivations */
5945 51883 : &session->smb2->signing_key);
5946 51883 : if (!NT_STATUS_IS_OK(status)) {
5947 0 : talloc_free(session);
5948 0 : return NULL;
5949 : }
5950 :
5951 51883 : DLIST_ADD_END(conn->sessions, session);
5952 51883 : session->conn = conn;
5953 :
5954 52823 : status = smb2_signing_key_sign_create(session,
5955 51883 : conn->smb2.server.sign_algo,
5956 : NULL, /* no master key */
5957 : NULL, /* derivations */
5958 : &session->smb2_channel.signing_key);
5959 51883 : if (!NT_STATUS_IS_OK(status)) {
5960 0 : talloc_free(session);
5961 0 : return NULL;
5962 : }
5963 :
5964 51883 : memcpy(session->smb2_channel.preauth_sha512,
5965 51883 : conn->smb2.preauth_sha512,
5966 : sizeof(session->smb2_channel.preauth_sha512));
5967 :
5968 51883 : return session;
5969 : }
5970 :
5971 18 : struct smbXcli_session *smbXcli_session_shallow_copy(TALLOC_CTX *mem_ctx,
5972 : struct smbXcli_session *src)
5973 : {
5974 0 : struct smbXcli_session *session;
5975 0 : struct timespec ts;
5976 0 : NTTIME nt;
5977 :
5978 18 : session = talloc_zero(mem_ctx, struct smbXcli_session);
5979 18 : if (session == NULL) {
5980 0 : return NULL;
5981 : }
5982 18 : session->smb2 = talloc_zero(session, struct smb2cli_session);
5983 18 : if (session->smb2 == NULL) {
5984 0 : talloc_free(session);
5985 0 : return NULL;
5986 : }
5987 :
5988 : /*
5989 : * Note we keep a pointer to the session keys of the
5990 : * main session and rely on the caller to free the
5991 : * shallow copy first!
5992 : */
5993 18 : session->conn = src->conn;
5994 18 : *session->smb2 = *src->smb2;
5995 18 : session->smb2_channel = src->smb2_channel;
5996 18 : session->disconnect_expired = src->disconnect_expired;
5997 :
5998 : /*
5999 : * This is only supposed to be called in test code
6000 : * but we should not reuse nonces!
6001 : *
6002 : * Add the current timestamp as NTTIME to nonce_high
6003 : * and set nonce_low to a value we can recognize in captures.
6004 : */
6005 18 : clock_gettime_mono(&ts);
6006 18 : nt = unix_timespec_to_nt_time(ts);
6007 18 : nt &= session->smb2->nonce_high_max;
6008 18 : if (nt == session->smb2->nonce_high_max || nt < UINT8_MAX) {
6009 0 : talloc_free(session);
6010 0 : return NULL;
6011 : }
6012 18 : session->smb2->nonce_high += nt;
6013 18 : session->smb2->nonce_low = UINT32_MAX;
6014 :
6015 18 : DLIST_ADD_END(src->conn->sessions, session);
6016 18 : talloc_set_destructor(session, smbXcli_session_destructor);
6017 :
6018 18 : return session;
6019 : }
6020 :
6021 17587 : bool smbXcli_session_is_guest(struct smbXcli_session *session)
6022 : {
6023 17587 : if (session == NULL) {
6024 0 : return false;
6025 : }
6026 :
6027 17587 : if (session->conn == NULL) {
6028 0 : return false;
6029 : }
6030 :
6031 17587 : if (session->conn->mandatory_signing) {
6032 3622 : return false;
6033 : }
6034 :
6035 13965 : if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6036 10444 : if (session->smb2->session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
6037 19 : return true;
6038 : }
6039 10425 : return false;
6040 : }
6041 :
6042 3521 : if (session->smb1.action & SMB_SETUP_GUEST) {
6043 3 : return true;
6044 : }
6045 :
6046 3518 : return false;
6047 : }
6048 :
6049 84426 : bool smbXcli_session_is_authenticated(struct smbXcli_session *session)
6050 : {
6051 1306 : const DATA_BLOB *application_key;
6052 :
6053 84426 : if (session == NULL) {
6054 0 : return false;
6055 : }
6056 :
6057 84426 : if (session->conn == NULL) {
6058 0 : return false;
6059 : }
6060 :
6061 : /*
6062 : * If we have an application key we had a session key negotiated
6063 : * at auth time.
6064 : */
6065 84426 : if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6066 84426 : if (!smb2_signing_key_valid(session->smb2->application_key)) {
6067 2360 : return false;
6068 : }
6069 82032 : application_key = &session->smb2->application_key->blob;
6070 : } else {
6071 0 : application_key = &session->smb1.application_key;
6072 : }
6073 :
6074 82032 : if (application_key->length == 0) {
6075 0 : return false;
6076 : }
6077 :
6078 80760 : return true;
6079 : }
6080 :
6081 0 : NTSTATUS smb2cli_session_signing_key(struct smbXcli_session *session,
6082 : TALLOC_CTX *mem_ctx,
6083 : DATA_BLOB *key)
6084 : {
6085 0 : const struct smb2_signing_key *sig = NULL;
6086 :
6087 0 : if (session->conn == NULL) {
6088 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6089 : }
6090 :
6091 : /*
6092 : * Use channel signing key if there is one, otherwise fallback
6093 : * to session.
6094 : */
6095 :
6096 0 : if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6097 0 : sig = session->smb2_channel.signing_key;
6098 0 : } else if (smb2_signing_key_valid(session->smb2->signing_key)) {
6099 0 : sig = session->smb2->signing_key;
6100 : } else {
6101 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6102 : }
6103 :
6104 0 : *key = data_blob_dup_talloc(mem_ctx, sig->blob);
6105 0 : if (key->data == NULL) {
6106 0 : return NT_STATUS_NO_MEMORY;
6107 : }
6108 :
6109 0 : return NT_STATUS_OK;
6110 : }
6111 :
6112 0 : NTSTATUS smb2cli_session_encryption_key(struct smbXcli_session *session,
6113 : TALLOC_CTX *mem_ctx,
6114 : DATA_BLOB *key)
6115 : {
6116 0 : if (session->conn == NULL) {
6117 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6118 : }
6119 :
6120 0 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6121 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6122 : }
6123 :
6124 0 : if (!smb2_signing_key_valid(session->smb2->encryption_key)) {
6125 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6126 : }
6127 :
6128 0 : *key = data_blob_dup_talloc(mem_ctx, session->smb2->encryption_key->blob);
6129 0 : if (key->data == NULL) {
6130 0 : return NT_STATUS_NO_MEMORY;
6131 : }
6132 :
6133 0 : return NT_STATUS_OK;
6134 : }
6135 :
6136 0 : NTSTATUS smb2cli_session_decryption_key(struct smbXcli_session *session,
6137 : TALLOC_CTX *mem_ctx,
6138 : DATA_BLOB *key)
6139 : {
6140 0 : if (session->conn == NULL) {
6141 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6142 : }
6143 :
6144 0 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6145 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6146 : }
6147 :
6148 0 : if (!smb2_signing_key_valid(session->smb2->decryption_key)) {
6149 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6150 : }
6151 :
6152 0 : *key = data_blob_dup_talloc(mem_ctx, session->smb2->decryption_key->blob);
6153 0 : if (key->data == NULL) {
6154 0 : return NT_STATUS_NO_MEMORY;
6155 : }
6156 :
6157 0 : return NT_STATUS_OK;
6158 : }
6159 :
6160 18339 : NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
6161 : TALLOC_CTX *mem_ctx,
6162 : DATA_BLOB *key)
6163 : {
6164 620 : const DATA_BLOB *application_key;
6165 :
6166 18339 : *key = data_blob_null;
6167 :
6168 18339 : if (session->conn == NULL) {
6169 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6170 : }
6171 :
6172 18339 : if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6173 17978 : if (!smb2_signing_key_valid(session->smb2->application_key)) {
6174 520 : return NT_STATUS_NO_USER_SESSION_KEY;
6175 : }
6176 17458 : application_key = &session->smb2->application_key->blob;
6177 : } else {
6178 361 : application_key = &session->smb1.application_key;
6179 : }
6180 :
6181 17819 : if (application_key->length == 0) {
6182 16 : return NT_STATUS_NO_USER_SESSION_KEY;
6183 : }
6184 :
6185 17803 : *key = data_blob_dup_talloc(mem_ctx, *application_key);
6186 17803 : if (key->data == NULL) {
6187 0 : return NT_STATUS_NO_MEMORY;
6188 : }
6189 :
6190 17803 : return NT_STATUS_OK;
6191 : }
6192 :
6193 5 : void smbXcli_session_set_disconnect_expired(struct smbXcli_session *session)
6194 : {
6195 5 : session->disconnect_expired = true;
6196 5 : }
6197 :
6198 847 : uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
6199 : {
6200 847 : return session->smb1.session_id;
6201 : }
6202 :
6203 522937 : void smb1cli_session_set_id(struct smbXcli_session *session,
6204 : uint16_t session_id)
6205 : {
6206 522937 : session->smb1.session_id = session_id;
6207 522937 : }
6208 :
6209 7673 : void smb1cli_session_set_action(struct smbXcli_session *session,
6210 : uint16_t action)
6211 : {
6212 7673 : session->smb1.action = action;
6213 7673 : }
6214 :
6215 6560 : NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
6216 : const DATA_BLOB _session_key)
6217 : {
6218 6560 : struct smbXcli_conn *conn = session->conn;
6219 133 : uint8_t session_key[16];
6220 :
6221 6560 : if (conn == NULL) {
6222 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6223 : }
6224 :
6225 6560 : if (session->smb1.application_key.length != 0) {
6226 : /*
6227 : * TODO: do not allow this...
6228 : *
6229 : * return NT_STATUS_INVALID_PARAMETER_MIX;
6230 : */
6231 27 : data_blob_clear_free(&session->smb1.application_key);
6232 27 : session->smb1.protected_key = false;
6233 : }
6234 :
6235 6560 : if (_session_key.length == 0) {
6236 0 : return NT_STATUS_OK;
6237 : }
6238 :
6239 6560 : ZERO_STRUCT(session_key);
6240 6560 : memcpy(session_key, _session_key.data,
6241 6560 : MIN(_session_key.length, sizeof(session_key)));
6242 :
6243 6560 : session->smb1.application_key = data_blob_talloc(session,
6244 : session_key,
6245 : sizeof(session_key));
6246 6560 : ZERO_STRUCT(session_key);
6247 6560 : if (session->smb1.application_key.data == NULL) {
6248 0 : return NT_STATUS_NO_MEMORY;
6249 : }
6250 :
6251 6560 : session->smb1.protected_key = false;
6252 :
6253 6560 : return NT_STATUS_OK;
6254 : }
6255 :
6256 5591 : NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
6257 : {
6258 133 : NTSTATUS status;
6259 :
6260 5591 : if (session->smb1.protected_key) {
6261 : /* already protected */
6262 0 : return NT_STATUS_OK;
6263 : }
6264 :
6265 5591 : if (session->smb1.application_key.length != 16) {
6266 41 : return NT_STATUS_INVALID_PARAMETER_MIX;
6267 : }
6268 :
6269 5550 : status = smb1_key_derivation(session->smb1.application_key.data,
6270 : session->smb1.application_key.length,
6271 : session->smb1.application_key.data);
6272 5550 : if (!NT_STATUS_IS_OK(status)) {
6273 0 : return status;
6274 : }
6275 :
6276 5550 : session->smb1.protected_key = true;
6277 :
6278 5550 : return NT_STATUS_OK;
6279 : }
6280 :
6281 50375 : uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
6282 : {
6283 50375 : struct smbXcli_conn *conn = session->conn;
6284 50375 : uint8_t security_mode = 0;
6285 :
6286 50375 : if (conn == NULL) {
6287 0 : return security_mode;
6288 : }
6289 :
6290 50375 : security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
6291 50375 : if (conn->mandatory_signing) {
6292 16044 : security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
6293 : }
6294 50375 : if (session->smb2->should_sign) {
6295 1979 : security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
6296 : }
6297 :
6298 49212 : return security_mode;
6299 : }
6300 :
6301 65157 : uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
6302 : {
6303 65157 : return session->smb2->session_id;
6304 : }
6305 :
6306 464 : uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
6307 : {
6308 464 : return session->smb2->session_flags;
6309 : }
6310 :
6311 46790 : void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
6312 : uint64_t session_id,
6313 : uint16_t session_flags)
6314 : {
6315 46790 : session->smb2->session_id = session_id;
6316 46790 : session->smb2->session_flags = session_flags;
6317 46790 : }
6318 :
6319 980 : void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
6320 : {
6321 980 : session->smb2->channel_sequence += 1;
6322 980 : }
6323 :
6324 628 : uint16_t smb2cli_session_reset_channel_sequence(struct smbXcli_session *session,
6325 : uint16_t channel_sequence)
6326 : {
6327 0 : uint16_t prev_cs;
6328 :
6329 628 : prev_cs = session->smb2->channel_sequence;
6330 628 : session->smb2->channel_sequence = channel_sequence;
6331 :
6332 628 : return prev_cs;
6333 : }
6334 :
6335 408 : uint16_t smb2cli_session_current_channel_sequence(struct smbXcli_session *session)
6336 : {
6337 408 : return session->smb2->channel_sequence;
6338 : }
6339 :
6340 466 : void smb2cli_session_start_replay(struct smbXcli_session *session)
6341 : {
6342 466 : session->smb2->replay_active = true;
6343 466 : }
6344 :
6345 426 : void smb2cli_session_stop_replay(struct smbXcli_session *session)
6346 : {
6347 426 : session->smb2->replay_active = false;
6348 426 : }
6349 :
6350 50 : void smb2cli_session_require_signed_response(struct smbXcli_session *session,
6351 : bool require_signed_response)
6352 : {
6353 50 : session->smb2->require_signed_response = require_signed_response;
6354 50 : }
6355 :
6356 24 : void smb2cli_session_torture_anonymous_signing(struct smbXcli_session *session,
6357 : bool anonymous_signing)
6358 : {
6359 24 : session->smb2->anonymous_signing = anonymous_signing;
6360 24 : }
6361 :
6362 36 : void smb2cli_session_torture_anonymous_encryption(struct smbXcli_session *session,
6363 : bool anonymous_encryption)
6364 : {
6365 36 : session->smb2->anonymous_encryption = anonymous_encryption;
6366 36 : }
6367 :
6368 24 : void smb2cli_session_torture_no_signing_disconnect(struct smbXcli_session *session)
6369 : {
6370 24 : session->smb2->no_signing_disconnect = true;
6371 24 : }
6372 :
6373 66290 : NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
6374 : const struct iovec *iov)
6375 : {
6376 66290 : gnutls_hash_hd_t hash_hnd = NULL;
6377 1021 : size_t i;
6378 1021 : int rc;
6379 :
6380 66290 : if (session->conn == NULL) {
6381 0 : return NT_STATUS_INTERNAL_ERROR;
6382 : }
6383 :
6384 66290 : if (session->conn->protocol < PROTOCOL_SMB3_11) {
6385 6043 : return NT_STATUS_OK;
6386 : }
6387 :
6388 60247 : if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6389 366 : return NT_STATUS_OK;
6390 : }
6391 :
6392 59881 : rc = gnutls_hash_init(&hash_hnd,
6393 : GNUTLS_DIG_SHA512);
6394 59881 : if (rc < 0) {
6395 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6396 : }
6397 :
6398 60798 : rc = gnutls_hash(hash_hnd,
6399 59881 : session->smb2_channel.preauth_sha512,
6400 : sizeof(session->smb2_channel.preauth_sha512));
6401 59881 : if (rc < 0) {
6402 0 : gnutls_hash_deinit(hash_hnd, NULL);
6403 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6404 : }
6405 239524 : for (i = 0; i < 3; i++) {
6406 182394 : rc = gnutls_hash(hash_hnd,
6407 179643 : iov[i].iov_base,
6408 179643 : iov[i].iov_len);
6409 179643 : if (rc < 0) {
6410 0 : gnutls_hash_deinit(hash_hnd, NULL);
6411 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6412 : }
6413 : }
6414 59881 : gnutls_hash_deinit(hash_hnd, session->smb2_channel.preauth_sha512);
6415 :
6416 59881 : return NT_STATUS_OK;
6417 : }
6418 :
6419 24402 : NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
6420 : const DATA_BLOB _session_key,
6421 : const struct iovec *recv_iov)
6422 : {
6423 24402 : struct smbXcli_conn *conn = session->conn;
6424 24402 : uint16_t no_sign_flags = 0;
6425 24402 : bool check_signature = true;
6426 647 : uint32_t hdr_flags;
6427 647 : NTSTATUS status;
6428 24402 : struct smb2_signing_derivations derivations = {
6429 : .signing = NULL,
6430 : };
6431 24402 : DATA_BLOB preauth_hash = data_blob_null;
6432 24402 : size_t nonce_size = 0;
6433 :
6434 24402 : if (conn == NULL) {
6435 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6436 : }
6437 :
6438 24402 : if (recv_iov[0].iov_len != SMB2_HDR_BODY) {
6439 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6440 : }
6441 :
6442 24402 : if (!conn->mandatory_signing) {
6443 : /*
6444 : * only allow guest sessions without
6445 : * mandatory signing.
6446 : *
6447 : * If we try an authentication with username != ""
6448 : * and the server let us in without verifying the
6449 : * password we don't have a negotiated session key
6450 : * for signing.
6451 : */
6452 14533 : no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST;
6453 : }
6454 :
6455 24402 : if (session->smb2->session_flags & no_sign_flags) {
6456 2 : session->smb2->should_sign = false;
6457 2 : return NT_STATUS_OK;
6458 : }
6459 :
6460 24400 : if (smb2_signing_key_valid(session->smb2->signing_key)) {
6461 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6462 : }
6463 :
6464 24400 : if (conn->protocol >= PROTOCOL_SMB3_11) {
6465 20638 : preauth_hash = data_blob_const(session->smb2_channel.preauth_sha512,
6466 : sizeof(session->smb2_channel.preauth_sha512));
6467 : }
6468 :
6469 24400 : smb2_signing_derivations_fill_const_stack(&derivations,
6470 : conn->protocol,
6471 : preauth_hash);
6472 :
6473 24400 : if (session->smb2->anonymous_encryption) {
6474 36 : goto skip_signing_key;
6475 : }
6476 :
6477 25005 : status = smb2_signing_key_sign_create(session->smb2,
6478 24364 : conn->smb2.server.sign_algo,
6479 : &_session_key,
6480 : derivations.signing,
6481 23723 : &session->smb2->signing_key);
6482 24364 : if (!NT_STATUS_IS_OK(status)) {
6483 0 : return status;
6484 : }
6485 :
6486 24364 : if (session->smb2->anonymous_signing) {
6487 : /*
6488 : * skip encryption and application keys
6489 : */
6490 24 : goto skip_application_key;
6491 : }
6492 :
6493 24340 : skip_signing_key:
6494 :
6495 25019 : status = smb2_signing_key_cipher_create(session->smb2,
6496 24376 : conn->smb2.server.cipher,
6497 : &_session_key,
6498 : derivations.cipher_c2s,
6499 24376 : &session->smb2->encryption_key);
6500 24376 : if (!NT_STATUS_IS_OK(status)) {
6501 0 : return status;
6502 : }
6503 :
6504 25019 : status = smb2_signing_key_cipher_create(session->smb2,
6505 24376 : conn->smb2.server.cipher,
6506 : &_session_key,
6507 : derivations.cipher_s2c,
6508 24376 : &session->smb2->decryption_key);
6509 24376 : if (!NT_STATUS_IS_OK(status)) {
6510 0 : return status;
6511 : }
6512 :
6513 24376 : if (session->smb2->anonymous_encryption) {
6514 36 : goto skip_application_key;
6515 : }
6516 :
6517 24977 : status = smb2_signing_key_sign_create(session->smb2,
6518 24340 : conn->smb2.server.sign_algo,
6519 : &_session_key,
6520 : derivations.application,
6521 23703 : &session->smb2->application_key);
6522 24340 : if (!NT_STATUS_IS_OK(status)) {
6523 0 : return status;
6524 : }
6525 :
6526 24340 : skip_application_key:
6527 :
6528 25047 : status = smb2_signing_key_copy(session,
6529 24400 : session->smb2->signing_key,
6530 : &session->smb2_channel.signing_key);
6531 24400 : if (!NT_STATUS_IS_OK(status)) {
6532 0 : return status;
6533 : }
6534 :
6535 24400 : check_signature = conn->mandatory_signing;
6536 :
6537 24400 : if (conn->protocol >= PROTOCOL_SMB3_11) {
6538 20638 : check_signature = true;
6539 : }
6540 :
6541 24400 : if (session->smb2->anonymous_signing) {
6542 24 : check_signature = false;
6543 : }
6544 :
6545 24400 : if (session->smb2->anonymous_encryption) {
6546 36 : check_signature = false;
6547 : }
6548 :
6549 24400 : hdr_flags = IVAL(recv_iov[0].iov_base, SMB2_HDR_FLAGS);
6550 24400 : if (hdr_flags & SMB2_HDR_FLAG_SIGNED) {
6551 : /*
6552 : * Sadly some vendors don't sign the
6553 : * final SMB2 session setup response
6554 : *
6555 : * At least Windows and Samba are always doing this
6556 : * if there's a session key available.
6557 : *
6558 : * We only check the signature if it's mandatory
6559 : * or SMB2_HDR_FLAG_SIGNED is provided.
6560 : */
6561 23703 : check_signature = true;
6562 : }
6563 :
6564 23763 : if (check_signature) {
6565 24340 : status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
6566 : recv_iov, 3);
6567 24340 : if (!NT_STATUS_IS_OK(status)) {
6568 0 : return status;
6569 : }
6570 : }
6571 :
6572 24400 : session->smb2->should_sign = false;
6573 24400 : session->smb2->should_encrypt = false;
6574 :
6575 24400 : if (conn->desire_signing) {
6576 9869 : session->smb2->should_sign = true;
6577 : }
6578 :
6579 24400 : if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
6580 9233 : session->smb2->should_sign = true;
6581 : }
6582 :
6583 24400 : if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
6584 0 : session->smb2->should_encrypt = true;
6585 : }
6586 :
6587 24400 : if (conn->protocol < PROTOCOL_SMB3_00) {
6588 3682 : session->smb2->should_encrypt = false;
6589 : }
6590 :
6591 24400 : if (conn->smb2.server.cipher == 0) {
6592 3874 : session->smb2->should_encrypt = false;
6593 : }
6594 :
6595 24400 : if (session->smb2->anonymous_signing) {
6596 24 : session->smb2->should_sign = true;
6597 : }
6598 :
6599 24400 : if (session->smb2->anonymous_encryption) {
6600 36 : session->smb2->should_encrypt = true;
6601 36 : session->smb2->should_sign = false;
6602 : }
6603 :
6604 : /*
6605 : * CCM and GCM algorithms must never have their
6606 : * nonce wrap, or the security of the whole
6607 : * communication and the keys is destroyed.
6608 : * We must drop the connection once we have
6609 : * transferred too much data.
6610 : *
6611 : * NOTE: We assume nonces greater than 8 bytes.
6612 : */
6613 24400 : generate_nonce_buffer((uint8_t *)&session->smb2->nonce_high_random,
6614 : sizeof(session->smb2->nonce_high_random));
6615 24400 : switch (conn->smb2.server.cipher) {
6616 110 : case SMB2_ENCRYPTION_AES128_CCM:
6617 110 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
6618 110 : break;
6619 20374 : case SMB2_ENCRYPTION_AES128_GCM:
6620 20374 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
6621 20374 : break;
6622 10 : case SMB2_ENCRYPTION_AES256_CCM:
6623 10 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
6624 10 : break;
6625 12 : case SMB2_ENCRYPTION_AES256_GCM:
6626 12 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
6627 12 : break;
6628 3860 : default:
6629 3860 : nonce_size = 0;
6630 3860 : break;
6631 : }
6632 24400 : session->smb2->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
6633 24400 : session->smb2->nonce_high = 0;
6634 24400 : session->smb2->nonce_low = 0;
6635 :
6636 24400 : return NT_STATUS_OK;
6637 : }
6638 :
6639 2262 : NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
6640 : struct smbXcli_session *session1,
6641 : struct smbXcli_conn *conn,
6642 : struct smbXcli_session **_session2)
6643 : {
6644 248 : struct smbXcli_session *session2;
6645 248 : NTSTATUS status;
6646 :
6647 2262 : if (!smb2_signing_key_valid(session1->smb2->signing_key)) {
6648 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6649 : }
6650 :
6651 2262 : if (conn == NULL) {
6652 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6653 : }
6654 :
6655 2262 : session2 = talloc_zero(mem_ctx, struct smbXcli_session);
6656 2262 : if (session2 == NULL) {
6657 0 : return NT_STATUS_NO_MEMORY;
6658 : }
6659 2262 : session2->smb2 = talloc_reference(session2, session1->smb2);
6660 2262 : if (session2->smb2 == NULL) {
6661 0 : talloc_free(session2);
6662 0 : return NT_STATUS_NO_MEMORY;
6663 : }
6664 :
6665 2262 : talloc_set_destructor(session2, smbXcli_session_destructor);
6666 2262 : DLIST_ADD_END(conn->sessions, session2);
6667 2262 : session2->conn = conn;
6668 :
6669 2262 : status = smb2_signing_key_sign_create(session2,
6670 2262 : conn->smb2.server.sign_algo,
6671 : NULL, /* no master key */
6672 : NULL, /* derivations */
6673 : &session2->smb2_channel.signing_key);
6674 2262 : if (!NT_STATUS_IS_OK(status)) {
6675 0 : talloc_free(session2);
6676 0 : return NT_STATUS_NO_MEMORY;
6677 : }
6678 :
6679 2262 : memcpy(session2->smb2_channel.preauth_sha512,
6680 2262 : conn->smb2.preauth_sha512,
6681 : sizeof(session2->smb2_channel.preauth_sha512));
6682 :
6683 2262 : *_session2 = session2;
6684 2262 : return NT_STATUS_OK;
6685 : }
6686 :
6687 950 : NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
6688 : const DATA_BLOB _channel_key,
6689 : const struct iovec *recv_iov)
6690 : {
6691 950 : struct smbXcli_conn *conn = session->conn;
6692 18 : uint8_t channel_key[16];
6693 18 : NTSTATUS status;
6694 18 : struct _derivation {
6695 : DATA_BLOB label;
6696 : DATA_BLOB context;
6697 : };
6698 18 : struct {
6699 : struct _derivation signing;
6700 950 : } derivation = {
6701 : .signing.label.length = 0,
6702 : };
6703 :
6704 950 : if (conn == NULL) {
6705 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6706 : }
6707 :
6708 950 : if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6709 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6710 : }
6711 :
6712 950 : if (conn->protocol >= PROTOCOL_SMB3_11) {
6713 18 : struct _derivation *d;
6714 18 : DATA_BLOB p;
6715 :
6716 950 : p = data_blob_const(session->smb2_channel.preauth_sha512,
6717 : sizeof(session->smb2_channel.preauth_sha512));
6718 :
6719 950 : d = &derivation.signing;
6720 950 : d->label = data_blob_string_const_null("SMBSigningKey");
6721 950 : d->context = p;
6722 0 : } else if (conn->protocol >= PROTOCOL_SMB3_00) {
6723 0 : struct _derivation *d;
6724 :
6725 0 : d = &derivation.signing;
6726 0 : d->label = data_blob_string_const_null("SMB2AESCMAC");
6727 0 : d->context = data_blob_string_const_null("SmbSign");
6728 : }
6729 :
6730 950 : ZERO_STRUCT(channel_key);
6731 950 : memcpy(channel_key, _channel_key.data,
6732 950 : MIN(_channel_key.length, sizeof(channel_key)));
6733 :
6734 950 : session->smb2_channel.signing_key->blob =
6735 950 : data_blob_talloc(session->smb2_channel.signing_key,
6736 : channel_key,
6737 : sizeof(channel_key));
6738 950 : if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6739 0 : ZERO_STRUCT(channel_key);
6740 0 : return NT_STATUS_NO_MEMORY;
6741 : }
6742 :
6743 950 : if (conn->protocol >= PROTOCOL_SMB3_00) {
6744 950 : struct _derivation *d = &derivation.signing;
6745 :
6746 968 : status = samba_gnutls_sp800_108_derive_key(
6747 : channel_key,
6748 : sizeof(channel_key),
6749 : NULL,
6750 : 0,
6751 932 : d->label.data,
6752 : d->label.length,
6753 932 : d->context.data,
6754 : d->context.length,
6755 : GNUTLS_MAC_SHA256,
6756 932 : session->smb2_channel.signing_key->blob.data,
6757 950 : session->smb2_channel.signing_key->blob.length);
6758 950 : if (!NT_STATUS_IS_OK(status)) {
6759 0 : return status;
6760 : }
6761 : }
6762 950 : ZERO_STRUCT(channel_key);
6763 :
6764 950 : status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
6765 : recv_iov, 3);
6766 950 : if (!NT_STATUS_IS_OK(status)) {
6767 0 : return status;
6768 : }
6769 :
6770 950 : return NT_STATUS_OK;
6771 : }
6772 :
6773 759 : NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
6774 : {
6775 759 : if (session->smb2->anonymous_signing) {
6776 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6777 : }
6778 :
6779 759 : if (session->smb2->anonymous_encryption) {
6780 0 : SMB_ASSERT(session->smb2->should_encrypt);
6781 0 : SMB_ASSERT(!session->smb2->should_sign);
6782 0 : return NT_STATUS_OK;
6783 : }
6784 :
6785 759 : if (!session->smb2->should_sign) {
6786 : /*
6787 : * We need required signing on the session
6788 : * in order to prevent man in the middle attacks.
6789 : */
6790 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6791 : }
6792 :
6793 759 : if (session->smb2->should_encrypt) {
6794 140 : return NT_STATUS_OK;
6795 : }
6796 :
6797 619 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6798 2 : return NT_STATUS_NOT_SUPPORTED;
6799 : }
6800 :
6801 617 : if (session->conn->smb2.server.cipher == 0) {
6802 36 : return NT_STATUS_NOT_SUPPORTED;
6803 : }
6804 :
6805 581 : if (!smb2_signing_key_valid(session->smb2->signing_key)) {
6806 0 : return NT_STATUS_NOT_SUPPORTED;
6807 : }
6808 581 : session->smb2->should_encrypt = true;
6809 581 : return NT_STATUS_OK;
6810 : }
6811 :
6812 7628 : uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session)
6813 : {
6814 7628 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6815 2152 : return 0;
6816 : }
6817 :
6818 5476 : if (!session->smb2->should_encrypt) {
6819 4851 : return 0;
6820 : }
6821 :
6822 5 : return session->conn->smb2.server.cipher;
6823 : }
6824 :
6825 53839 : struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
6826 : {
6827 871 : struct smbXcli_tcon *tcon;
6828 :
6829 53839 : tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
6830 53839 : if (tcon == NULL) {
6831 0 : return NULL;
6832 : }
6833 :
6834 52968 : return tcon;
6835 : }
6836 :
6837 : /*
6838 : * Return a deep structure copy of a struct smbXcli_tcon *
6839 : */
6840 :
6841 4 : struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
6842 : const struct smbXcli_tcon *tcon_in)
6843 : {
6844 0 : struct smbXcli_tcon *tcon;
6845 :
6846 4 : tcon = talloc_memdup(mem_ctx, tcon_in, sizeof(struct smbXcli_tcon));
6847 4 : if (tcon == NULL) {
6848 0 : return NULL;
6849 : }
6850 :
6851 : /* Deal with the SMB1 strings. */
6852 4 : if (tcon_in->smb1.service != NULL) {
6853 0 : tcon->smb1.service = talloc_strdup(tcon, tcon_in->smb1.service);
6854 0 : if (tcon->smb1.service == NULL) {
6855 0 : TALLOC_FREE(tcon);
6856 0 : return NULL;
6857 : }
6858 : }
6859 4 : if (tcon->smb1.fs_type != NULL) {
6860 0 : tcon->smb1.fs_type = talloc_strdup(tcon, tcon_in->smb1.fs_type);
6861 0 : if (tcon->smb1.fs_type == NULL) {
6862 0 : TALLOC_FREE(tcon);
6863 0 : return NULL;
6864 : }
6865 : }
6866 4 : return tcon;
6867 : }
6868 :
6869 82 : void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
6870 : uint32_t fs_attributes)
6871 : {
6872 82 : tcon->fs_attributes = fs_attributes;
6873 82 : }
6874 :
6875 0 : uint32_t smbXcli_tcon_get_fs_attributes(struct smbXcli_tcon *tcon)
6876 : {
6877 0 : return tcon->fs_attributes;
6878 : }
6879 :
6880 1090690 : bool smbXcli_tcon_is_dfs_share(struct smbXcli_tcon *tcon)
6881 : {
6882 1090690 : if (tcon == NULL) {
6883 4 : return false;
6884 : }
6885 :
6886 1090686 : if (tcon->is_smb1) {
6887 938918 : if (tcon->smb1.optional_support & SMB_SHARE_IN_DFS) {
6888 4794 : return true;
6889 : }
6890 :
6891 934124 : return false;
6892 : }
6893 :
6894 151768 : if (tcon->smb2.capabilities & SMB2_SHARE_CAP_DFS) {
6895 37710 : return true;
6896 : }
6897 :
6898 113438 : return false;
6899 : }
6900 :
6901 3392 : uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
6902 : {
6903 3392 : return tcon->smb1.tcon_id;
6904 : }
6905 :
6906 512846 : void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
6907 : {
6908 512846 : tcon->is_smb1 = true;
6909 512846 : tcon->smb1.tcon_id = tcon_id;
6910 512846 : }
6911 :
6912 7267 : bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
6913 : uint16_t tcon_id,
6914 : uint16_t optional_support,
6915 : uint32_t maximal_access,
6916 : uint32_t guest_maximal_access,
6917 : const char *service,
6918 : const char *fs_type)
6919 : {
6920 7267 : tcon->is_smb1 = true;
6921 7267 : tcon->fs_attributes = 0;
6922 7267 : tcon->smb1.tcon_id = tcon_id;
6923 7267 : tcon->smb1.optional_support = optional_support;
6924 7267 : tcon->smb1.maximal_access = maximal_access;
6925 7267 : tcon->smb1.guest_maximal_access = guest_maximal_access;
6926 :
6927 7267 : TALLOC_FREE(tcon->smb1.service);
6928 7267 : tcon->smb1.service = talloc_strdup(tcon, service);
6929 7267 : if (service != NULL && tcon->smb1.service == NULL) {
6930 0 : return false;
6931 : }
6932 :
6933 7267 : TALLOC_FREE(tcon->smb1.fs_type);
6934 7267 : tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
6935 7267 : if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
6936 0 : return false;
6937 : }
6938 :
6939 7267 : return true;
6940 : }
6941 :
6942 19488 : uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
6943 : {
6944 19488 : return tcon->smb2.tcon_id;
6945 : }
6946 :
6947 20 : void smb2cli_tcon_set_id(struct smbXcli_tcon *tcon, uint32_t tcon_id)
6948 : {
6949 20 : tcon->smb2.tcon_id = tcon_id;
6950 20 : }
6951 :
6952 144 : uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
6953 : {
6954 144 : return tcon->smb2.capabilities;
6955 : }
6956 :
6957 8 : uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon)
6958 : {
6959 8 : return tcon->smb2.flags;
6960 : }
6961 :
6962 69357 : void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
6963 : struct smbXcli_session *session,
6964 : uint32_t tcon_id,
6965 : uint8_t type,
6966 : uint32_t flags,
6967 : uint32_t capabilities,
6968 : uint32_t maximal_access)
6969 : {
6970 69357 : tcon->is_smb1 = false;
6971 69357 : tcon->fs_attributes = 0;
6972 69357 : tcon->smb2.tcon_id = tcon_id;
6973 69357 : tcon->smb2.type = type;
6974 69357 : tcon->smb2.flags = flags;
6975 69357 : tcon->smb2.capabilities = capabilities;
6976 69357 : tcon->smb2.maximal_access = maximal_access;
6977 :
6978 69357 : tcon->smb2.should_sign = false;
6979 69357 : tcon->smb2.should_encrypt = false;
6980 :
6981 69357 : if (session == NULL) {
6982 27253 : return;
6983 : }
6984 :
6985 42104 : tcon->smb2.should_sign = session->smb2->should_sign;
6986 42104 : tcon->smb2.should_encrypt = session->smb2->should_encrypt;
6987 :
6988 42104 : if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
6989 232 : tcon->smb2.should_encrypt = true;
6990 : }
6991 : }
6992 :
6993 8090 : void smb2cli_tcon_should_sign(struct smbXcli_tcon *tcon,
6994 : bool should_sign)
6995 : {
6996 8090 : tcon->smb2.should_sign = should_sign;
6997 8090 : }
6998 :
6999 4018 : bool smb2cli_tcon_is_signing_on(struct smbXcli_tcon *tcon)
7000 : {
7001 4018 : if (tcon->smb2.should_encrypt) {
7002 24 : return true;
7003 : }
7004 :
7005 3990 : return tcon->smb2.should_sign;
7006 : }
7007 :
7008 0 : void smb2cli_tcon_should_encrypt(struct smbXcli_tcon *tcon,
7009 : bool should_encrypt)
7010 : {
7011 0 : tcon->smb2.should_encrypt = should_encrypt;
7012 0 : }
7013 :
7014 253 : bool smb2cli_tcon_is_encryption_on(struct smbXcli_tcon *tcon)
7015 : {
7016 253 : return tcon->smb2.should_encrypt;
7017 : }
7018 :
7019 18 : void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid)
7020 : {
7021 18 : conn->smb2.mid = mid;
7022 18 : }
7023 :
7024 6 : uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
7025 : {
7026 6 : return conn->smb2.mid;
7027 : }
7028 :
7029 757353 : NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
7030 : const DATA_BLOB dyn_buffer,
7031 : uint32_t min_offset,
7032 : uint32_t buffer_offset,
7033 : uint32_t buffer_length,
7034 : uint32_t max_length,
7035 : uint32_t *next_offset,
7036 : DATA_BLOB *buffer)
7037 : {
7038 14378 : uint32_t offset;
7039 14378 : bool oob;
7040 :
7041 757353 : *buffer = data_blob_null;
7042 757353 : *next_offset = dyn_offset;
7043 :
7044 757353 : if (buffer_offset == 0) {
7045 : /*
7046 : * If the offset is 0, we better ignore
7047 : * the buffer_length field.
7048 : */
7049 47012 : return NT_STATUS_OK;
7050 : }
7051 :
7052 710341 : if (buffer_length == 0) {
7053 : /*
7054 : * If the length is 0, we better ignore
7055 : * the buffer_offset field.
7056 : */
7057 326280 : return NT_STATUS_OK;
7058 : }
7059 :
7060 384061 : if ((buffer_offset % 8) != 0) {
7061 : /*
7062 : * The offset needs to be 8 byte aligned.
7063 : */
7064 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
7065 : }
7066 :
7067 : /*
7068 : * We used to enforce buffer_offset to be
7069 : * an exact match of the expected minimum,
7070 : * but the NetApp Ontap 7.3.7 SMB server
7071 : * gets the padding wrong and aligns the
7072 : * input_buffer_offset by a value of 8.
7073 : *
7074 : * So we just enforce that the offset is
7075 : * not lower than the expected value.
7076 : */
7077 384061 : SMB_ASSERT(min_offset >= dyn_offset);
7078 384061 : if (buffer_offset < min_offset) {
7079 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
7080 : }
7081 :
7082 : /*
7083 : * Make [input|output]_buffer_offset relative to "dyn_buffer"
7084 : */
7085 384061 : offset = buffer_offset - dyn_offset;
7086 384061 : oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
7087 384061 : if (oob) {
7088 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
7089 : }
7090 :
7091 : /*
7092 : * Give the caller a hint what we consumed,
7093 : * the caller may need to add possible padding.
7094 : */
7095 384061 : *next_offset = buffer_offset + buffer_length;
7096 :
7097 384061 : if (max_length == 0) {
7098 : /*
7099 : * If max_input_length is 0 we ignore the
7100 : * input_buffer_length, because Windows 2008 echos the
7101 : * DCERPC request from the requested input_buffer to
7102 : * the response input_buffer.
7103 : *
7104 : * We just use the same logic also for max_output_length...
7105 : */
7106 0 : buffer_length = 0;
7107 : }
7108 :
7109 384061 : if (buffer_length > max_length) {
7110 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
7111 : }
7112 :
7113 384061 : *buffer = (DATA_BLOB) {
7114 384061 : .data = dyn_buffer.data + offset,
7115 : .length = buffer_length,
7116 : };
7117 384061 : return NT_STATUS_OK;
7118 : }
|