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