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 29788 : static int smbXcli_conn_destructor(struct smbXcli_conn *conn)
307 : {
308 : /*
309 : * NT_STATUS_OK, means we do not notify the callers
310 : */
311 29788 : smbXcli_conn_disconnect(conn, NT_STATUS_OK);
312 :
313 30294 : while (conn->sessions) {
314 584 : conn->sessions->conn = NULL;
315 1421 : DLIST_REMOVE(conn->sessions, conn->sessions);
316 : }
317 :
318 29788 : if (conn->smb1.trans_enc) {
319 260 : TALLOC_FREE(conn->smb1.trans_enc);
320 : }
321 :
322 29788 : return 0;
323 : }
324 :
325 33385 : 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 33385 : struct smbXcli_conn *conn = NULL;
335 33385 : void *ss = NULL;
336 33385 : struct sockaddr *sa = NULL;
337 842 : socklen_t sa_length;
338 842 : int ret;
339 :
340 33385 : if (smb3_capabilities != NULL) {
341 30544 : const struct smb3_signing_capabilities *sign_algos =
342 : &smb3_capabilities->signing;
343 30544 : const struct smb3_encryption_capabilities *ciphers =
344 : &smb3_capabilities->encryption;
345 :
346 30544 : SMB_ASSERT(sign_algos->num_algos <= SMB3_SIGNING_CAPABILITIES_MAX_ALGOS);
347 30544 : SMB_ASSERT(ciphers->num_algos <= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS);
348 : }
349 :
350 33385 : conn = talloc_zero(mem_ctx, struct smbXcli_conn);
351 33385 : if (!conn) {
352 0 : return NULL;
353 : }
354 :
355 33385 : ret = set_blocking(fd, false);
356 33385 : if (ret < 0) {
357 0 : goto error;
358 : }
359 33385 : conn->sock_fd = fd;
360 :
361 33385 : conn->remote_name = talloc_strdup(conn, remote_name);
362 33385 : if (conn->remote_name == NULL) {
363 0 : goto error;
364 : }
365 :
366 33385 : ss = (void *)&conn->local_ss;
367 33385 : sa = (struct sockaddr *)ss;
368 33385 : sa_length = sizeof(conn->local_ss);
369 33385 : ret = getsockname(fd, sa, &sa_length);
370 33385 : if (ret == -1) {
371 0 : goto error;
372 : }
373 33385 : ss = (void *)&conn->remote_ss;
374 33385 : sa = (struct sockaddr *)ss;
375 33385 : sa_length = sizeof(conn->remote_ss);
376 33385 : ret = getpeername(fd, sa, &sa_length);
377 33385 : if (ret == -1) {
378 0 : goto error;
379 : }
380 :
381 33385 : conn->outgoing = tevent_queue_create(conn, "smbXcli_outgoing");
382 33385 : if (conn->outgoing == NULL) {
383 0 : goto error;
384 : }
385 33385 : conn->pending = NULL;
386 :
387 33385 : conn->min_protocol = PROTOCOL_NONE;
388 33385 : conn->max_protocol = PROTOCOL_NONE;
389 33385 : conn->protocol = PROTOCOL_NONE;
390 :
391 33385 : 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 21888 : case SMB_SIGNING_DEFAULT:
399 : case SMB_SIGNING_IF_REQUIRED:
400 : /* if the server requires it */
401 21888 : conn->allow_signing = true;
402 21888 : conn->desire_signing = false;
403 21888 : conn->mandatory_signing = false;
404 21888 : 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 11333 : case SMB_SIGNING_IPC_DEFAULT:
412 : case SMB_SIGNING_REQUIRED:
413 : /* always */
414 11333 : conn->allow_signing = true;
415 11333 : conn->desire_signing = true;
416 11333 : conn->mandatory_signing = true;
417 11333 : break;
418 : }
419 :
420 33385 : conn->smb1.client.capabilities = smb1_capabilities;
421 33385 : conn->smb1.client.max_xmit = UINT16_MAX;
422 :
423 33385 : conn->smb1.capabilities = conn->smb1.client.capabilities;
424 33385 : conn->smb1.max_xmit = 1024;
425 :
426 33385 : conn->smb1.mid = 1;
427 :
428 : /* initialise signing */
429 66770 : conn->smb1.signing = smb1_signing_init(conn,
430 33385 : conn->allow_signing,
431 33385 : conn->desire_signing,
432 33385 : conn->mandatory_signing);
433 33385 : if (!conn->smb1.signing) {
434 0 : goto error;
435 : }
436 :
437 33385 : conn->smb2.client.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
438 33385 : if (conn->mandatory_signing) {
439 11333 : conn->smb2.client.security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
440 : }
441 33385 : if (client_guid) {
442 30544 : conn->smb2.client.guid = *client_guid;
443 : }
444 33385 : conn->smb2.client.capabilities = smb2_capabilities;
445 33385 : if (smb3_capabilities != NULL) {
446 30544 : conn->smb2.client.smb3_capabilities = *smb3_capabilities;
447 : }
448 :
449 33385 : conn->smb2.cur_credits = 1;
450 33385 : conn->smb2.max_credits = 0;
451 33385 : 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 33385 : conn->smb2.cc_chunk_len = 1024 * 1024;
458 33385 : conn->smb2.cc_max_chunks = 16;
459 :
460 33385 : talloc_set_destructor(conn, smbXcli_conn_destructor);
461 33385 : return conn;
462 :
463 0 : error:
464 0 : TALLOC_FREE(conn);
465 0 : return NULL;
466 : }
467 :
468 9065613 : bool smbXcli_conn_is_connected(struct smbXcli_conn *conn)
469 : {
470 9065613 : if (conn == NULL) {
471 13843 : return false;
472 : }
473 :
474 9050664 : if (conn->sock_fd == -1) {
475 79 : return false;
476 : }
477 :
478 8978354 : return true;
479 : }
480 :
481 6453279 : enum protocol_types smbXcli_conn_protocol(struct smbXcli_conn *conn)
482 : {
483 6453279 : return conn->protocol;
484 : }
485 :
486 161500 : bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn)
487 : {
488 161500 : if (conn->protocol >= PROTOCOL_SMB2_02) {
489 11608 : return true;
490 : }
491 :
492 149892 : if (conn->smb1.capabilities & CAP_UNICODE) {
493 149764 : 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 9084 : bool smbXcli_conn_have_posix(struct smbXcli_conn *conn)
505 : {
506 9084 : if (conn->protocol >= PROTOCOL_SMB3_11) {
507 7087 : return conn->smb2.server.smb311_posix;
508 : }
509 1997 : if (conn->protocol <= PROTOCOL_NT1) {
510 358 : 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 10134 : const struct sockaddr_storage *smbXcli_conn_remote_sockaddr(struct smbXcli_conn *conn)
543 : {
544 10134 : return &conn->remote_ss;
545 : }
546 :
547 215817 : const char *smbXcli_conn_remote_name(struct smbXcli_conn *conn)
548 : {
549 215817 : return conn->remote_name;
550 : }
551 :
552 10166 : uint16_t smbXcli_conn_max_requests(struct smbXcli_conn *conn)
553 : {
554 10166 : if (conn->protocol >= PROTOCOL_SMB2_02) {
555 : /*
556 : * TODO...
557 : */
558 0 : return 1;
559 : }
560 :
561 10166 : 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 36894 : const DATA_BLOB *smbXcli_conn_server_gss_blob(struct smbXcli_conn *conn)
574 : {
575 36894 : if (conn->protocol >= PROTOCOL_SMB2_02) {
576 30044 : return &conn->smb2.server.gss_blob;
577 : }
578 :
579 6850 : 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 987780 : uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn)
740 : {
741 987780 : return conn->smb1.capabilities;
742 : }
743 :
744 118560 : uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn)
745 : {
746 118560 : return conn->smb1.max_xmit;
747 : }
748 :
749 13831 : bool smb1cli_conn_req_possible(struct smbXcli_conn *conn)
750 : {
751 13831 : size_t pending = talloc_array_length(conn->pending);
752 13831 : uint16_t possible = conn->smb1.server.max_mux;
753 :
754 13831 : if (pending >= possible) {
755 3296 : return false;
756 : }
757 :
758 10535 : return true;
759 : }
760 :
761 10186 : uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn)
762 : {
763 10186 : 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 27062 : uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn)
772 : {
773 27062 : 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 5319 : int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn)
797 : {
798 5319 : return conn->smb1.server.time_zone;
799 : }
800 :
801 6423 : bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
802 : const DATA_BLOB user_session_key,
803 : const DATA_BLOB response)
804 : {
805 6423 : return smb1_signing_activate(conn->smb1.signing,
806 : user_session_key,
807 : response);
808 : }
809 :
810 3076 : bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
811 : const uint8_t *buf, uint32_t seqnum)
812 : {
813 3076 : const uint8_t *hdr = buf + NBT_HDR_SIZE;
814 3076 : size_t len = smb_len_nbt(buf);
815 :
816 3076 : return smb1_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
817 : }
818 :
819 22815 : bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
820 : {
821 22815 : 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 7479 : bool smb1cli_conn_encryption_on(struct smbXcli_conn *conn)
835 : {
836 7479 : return common_encryption_on(conn->smb1.trans_enc);
837 : }
838 :
839 :
840 1859800 : static NTSTATUS smb1cli_pull_raw_error(const uint8_t *hdr)
841 : {
842 1859800 : uint32_t flags2 = SVAL(hdr, HDR_FLG2);
843 1859800 : NTSTATUS status = NT_STATUS(IVAL(hdr, HDR_RCLS));
844 :
845 1859800 : if (NT_STATUS_IS_OK(status)) {
846 928536 : return NT_STATUS_OK;
847 : }
848 :
849 931264 : if (flags2 & FLAGS2_32_BIT_ERROR_CODES) {
850 275392 : 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 1737416 : bool smb1cli_is_andx_req(uint8_t cmd)
862 : {
863 1737416 : switch (cmd) {
864 615555 : case SMBtconX:
865 : case SMBlockingX:
866 : case SMBopenX:
867 : case SMBreadX:
868 : case SMBwriteX:
869 : case SMBsesssetupX:
870 : case SMBulogoffX:
871 : case SMBntcreateX:
872 615555 : return true;
873 13721 : break;
874 1105966 : default:
875 1119687 : break;
876 : }
877 :
878 1119687 : return false;
879 : }
880 :
881 948303 : static uint16_t smb1cli_alloc_mid(struct smbXcli_conn *conn)
882 : {
883 948303 : size_t num_pending = talloc_array_length(conn->pending);
884 8249 : uint16_t result;
885 :
886 948303 : 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 24581 : return 0;
892 : }
893 :
894 7728 : while (true) {
895 7718 : size_t i;
896 :
897 923201 : result = conn->smb1.mid++;
898 923201 : if ((result == 0) || (result == 0xffff)) {
899 10 : continue;
900 : }
901 :
902 1295753 : for (i=0; i<num_pending; i++) {
903 372562 : if (result == smb1cli_req_mid(conn->pending[i])) {
904 0 : break;
905 : }
906 : }
907 :
908 923191 : if (i == num_pending) {
909 923191 : return result;
910 : }
911 : }
912 : }
913 :
914 3014809 : static NTSTATUS smbXcli_req_cancel_write_req(struct tevent_req *req)
915 : {
916 22305 : struct smbXcli_req_state *state =
917 3014809 : tevent_req_data(req,
918 : struct smbXcli_req_state);
919 3014809 : struct smbXcli_conn *conn = state->conn;
920 3014809 : size_t num_pending = talloc_array_length(conn->pending);
921 22305 : ssize_t ret;
922 22305 : int err;
923 22305 : bool ok;
924 :
925 3014809 : if (state->write_req == NULL) {
926 3007824 : 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 6985 : ok = tevent_req_cancel(state->write_req);
935 6985 : if (ok) {
936 505 : TALLOC_FREE(state->write_req);
937 :
938 505 : if (conn->protocol >= PROTOCOL_SMB2_02) {
939 : /*
940 : * SMB2 has a sane signing state.
941 : */
942 503 : 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 6480 : ret = writev_recv(state->write_req, &err);
970 6480 : TALLOC_FREE(state->write_req);
971 6480 : if (ret == -1) {
972 0 : return map_nt_error_from_unix_common(err);
973 : }
974 :
975 6480 : return NT_STATUS_OK;
976 : }
977 :
978 2918887 : void smbXcli_req_unset_pending(struct tevent_req *req)
979 : {
980 21022 : struct smbXcli_req_state *state =
981 2918887 : tevent_req_data(req,
982 : struct smbXcli_req_state);
983 2918887 : struct smbXcli_conn *conn = state->conn;
984 2918887 : size_t num_pending = talloc_array_length(conn->pending);
985 21022 : size_t i;
986 21022 : NTSTATUS cancel_status;
987 :
988 2918887 : cancel_status = smbXcli_req_cancel_write_req(req);
989 :
990 2918887 : if (state->smb1.mid != 0) {
991 : /*
992 : * This is a [nt]trans[2] request which waits
993 : * for more than one reply.
994 : */
995 94303 : 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 93020 : return;
1004 : }
1005 :
1006 2824584 : tevent_req_set_cleanup_fn(req, NULL);
1007 :
1008 2824584 : 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 2726313 : TALLOC_FREE(conn->pending);
1016 2726313 : conn->read_smb_req = NULL;
1017 :
1018 2726313 : 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 2706771 : return;
1027 : }
1028 :
1029 182366 : for (i=0; i<num_pending; i++) {
1030 182310 : if (req == conn->pending[i]) {
1031 98021 : break;
1032 : }
1033 : }
1034 98271 : 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 431791 : for (; i < (num_pending - 1); i++) {
1056 333576 : 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 98215 : conn->pending = talloc_realloc(NULL, conn->pending, struct tevent_req *,
1064 : num_pending - 1);
1065 :
1066 98215 : 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 98019 : return;
1075 : }
1076 :
1077 106390 : 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 106390 : tevent_req_data(req,
1082 : struct smbXcli_req_state);
1083 106390 : struct smbXcli_conn *conn = state->conn;
1084 1761 : NTSTATUS cancel_status;
1085 :
1086 106390 : switch (req_state) {
1087 10468 : 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 10468 : state->smb1.mid = 0;
1096 10468 : smbXcli_req_unset_pending(req);
1097 10468 : return;
1098 95922 : default:
1099 95922 : cancel_status = smbXcli_req_cancel_write_req(req);
1100 95922 : 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 94639 : 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 1620 : return smb2cli_req_cancel(req);
1131 : }
1132 :
1133 1517 : return smb1cli_req_cancel(req);
1134 : }
1135 :
1136 : static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
1137 :
1138 2824540 : bool smbXcli_req_set_pending(struct tevent_req *req)
1139 : {
1140 19736 : struct smbXcli_req_state *state =
1141 2824540 : tevent_req_data(req,
1142 : struct smbXcli_req_state);
1143 19736 : struct smbXcli_conn *conn;
1144 19736 : struct tevent_req **pending;
1145 19736 : size_t num_pending;
1146 :
1147 2824540 : conn = state->conn;
1148 :
1149 2824540 : if (!smbXcli_conn_is_connected(conn)) {
1150 8 : return false;
1151 : }
1152 :
1153 2824532 : num_pending = talloc_array_length(conn->pending);
1154 :
1155 2824532 : pending = talloc_realloc(conn, conn->pending, struct tevent_req *,
1156 : num_pending+1);
1157 2824532 : if (pending == NULL) {
1158 0 : return false;
1159 : }
1160 2824532 : pending[num_pending] = req;
1161 2824532 : conn->pending = pending;
1162 2824532 : tevent_req_set_cleanup_fn(req, smbXcli_req_cleanup);
1163 2824532 : tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1164 :
1165 2824532 : 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 2804796 : return true;
1178 : }
1179 :
1180 : static void smbXcli_conn_received(struct tevent_req *subreq);
1181 :
1182 4986183 : static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
1183 : {
1184 4986183 : size_t num_pending = talloc_array_length(conn->pending);
1185 35283 : struct tevent_req *req;
1186 35283 : struct smbXcli_req_state *state;
1187 :
1188 4986183 : if (conn->read_smb_req != NULL) {
1189 98021 : return true;
1190 : }
1191 :
1192 4887968 : if (num_pending == 0) {
1193 1869417 : if (conn->smb2.mid < UINT64_MAX) {
1194 : /* no more pending requests, so we are done for now */
1195 1858109 : 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 3018551 : req = conn->pending[0];
1208 3018551 : 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 3018551 : conn->read_smb_req = read_smb_send(conn->pending,
1215 : state->ev,
1216 : conn->sock_fd);
1217 3018551 : if (conn->read_smb_req == NULL) {
1218 0 : return false;
1219 : }
1220 3018551 : tevent_req_set_callback(conn->read_smb_req, smbXcli_conn_received, conn);
1221 3018551 : return true;
1222 : }
1223 :
1224 60776 : void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
1225 : {
1226 1685 : struct smbXcli_session *session;
1227 60776 : int sock_fd = conn->sock_fd;
1228 :
1229 60776 : tevent_queue_stop(conn->outgoing);
1230 :
1231 60776 : conn->sock_fd = -1;
1232 :
1233 60776 : session = conn->sessions;
1234 60776 : 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 59043 : session = NULL;
1240 : }
1241 61718 : for (; session; session = session->next) {
1242 942 : smb2cli_session_increment_channel_sequence(session);
1243 : }
1244 :
1245 60776 : 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 63984 : 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 60776 : if (sock_fd != -1) {
1346 29801 : close(sock_fd);
1347 : }
1348 60776 : }
1349 :
1350 : /*
1351 : * Fetch a smb request's mid. Only valid after the request has been sent by
1352 : * smb1cli_req_send().
1353 : */
1354 1469382 : uint16_t smb1cli_req_mid(struct tevent_req *req)
1355 : {
1356 9194 : struct smbXcli_req_state *state =
1357 1469382 : tevent_req_data(req,
1358 : struct smbXcli_req_state);
1359 :
1360 1469382 : if (state->smb1.mid != 0) {
1361 280509 : return state->smb1.mid;
1362 : }
1363 :
1364 1187538 : return SVAL(state->smb1.hdr, HDR_MID);
1365 : }
1366 :
1367 191739 : void smb1cli_req_set_mid(struct tevent_req *req, uint16_t mid)
1368 : {
1369 2568 : struct smbXcli_req_state *state =
1370 191739 : tevent_req_data(req,
1371 : struct smbXcli_req_state);
1372 :
1373 191739 : state->smb1.mid = mid;
1374 191739 : }
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 975466 : 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 975466 : uint8_t flags = 0;
1413 975466 : uint16_t flags2 = 0;
1414 :
1415 974935 : if (protocol >= PROTOCOL_LANMAN1) {
1416 950352 : flags |= FLAG_CASELESS_PATHNAMES;
1417 950352 : flags |= FLAG_CANONICAL_PATHNAMES;
1418 : }
1419 :
1420 975466 : if (protocol >= PROTOCOL_LANMAN2) {
1421 950332 : flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
1422 950332 : flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
1423 : }
1424 :
1425 975466 : if (protocol >= PROTOCOL_NT1) {
1426 950240 : flags2 |= FLAGS2_IS_LONG_NAME;
1427 :
1428 950240 : if (smb1_capabilities & CAP_UNICODE) {
1429 950230 : flags2 |= FLAGS2_UNICODE_STRINGS;
1430 : }
1431 950240 : if (smb1_capabilities & CAP_STATUS32) {
1432 950062 : flags2 |= FLAGS2_32_BIT_ERROR_CODES;
1433 : }
1434 950240 : if (smb1_capabilities & CAP_EXTENDED_SECURITY) {
1435 949324 : flags2 |= FLAGS2_EXTENDED_SECURITY;
1436 : }
1437 : }
1438 :
1439 975466 : flags |= additional_flags;
1440 975466 : flags &= ~clear_flags;
1441 975466 : flags2 |= additional_flags2;
1442 975466 : flags2 &= ~clear_flags2;
1443 :
1444 975466 : *_flags = flags;
1445 975466 : *_flags2 = flags2;
1446 974935 : }
1447 :
1448 : static void smb1cli_req_cancel_done(struct tevent_req *subreq);
1449 :
1450 1517 : static bool smb1cli_req_cancel(struct tevent_req *req)
1451 : {
1452 0 : struct smbXcli_req_state *state =
1453 1517 : 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 1517 : flags = CVAL(state->smb1.hdr, HDR_FLG);
1463 1517 : flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
1464 1517 : pid = SVAL(state->smb1.hdr, HDR_PID);
1465 1517 : pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
1466 1517 : mid = SVAL(state->smb1.hdr, HDR_MID);
1467 :
1468 1517 : 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 1517 : if (subreq == NULL) {
1480 0 : return false;
1481 : }
1482 1517 : smb1cli_req_set_mid(subreq, mid);
1483 :
1484 1517 : status = smb1cli_req_chain_submit(&subreq, 1);
1485 1517 : if (!NT_STATUS_IS_OK(status)) {
1486 0 : TALLOC_FREE(subreq);
1487 0 : return false;
1488 : }
1489 1517 : smb1cli_req_set_mid(subreq, 0);
1490 :
1491 1517 : tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
1492 :
1493 1517 : return true;
1494 : }
1495 :
1496 1517 : static void smb1cli_req_cancel_done(struct tevent_req *subreq)
1497 : {
1498 : /* we do not care about the result */
1499 1517 : TALLOC_FREE(subreq);
1500 1517 : }
1501 :
1502 950394 : 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 950394 : uint8_t flags = 0;
1521 950394 : uint16_t flags2 = 0;
1522 950394 : uint16_t uid = 0;
1523 950394 : uint16_t tid = 0;
1524 8254 : ssize_t num_bytes;
1525 :
1526 950394 : if (iov_count > MAX_SMB_IOV) {
1527 : /*
1528 : * Should not happen :-)
1529 : */
1530 0 : return NULL;
1531 : }
1532 :
1533 950394 : req = tevent_req_create(mem_ctx, &state,
1534 : struct smbXcli_req_state);
1535 950394 : if (req == NULL) {
1536 0 : return NULL;
1537 : }
1538 950394 : state->ev = ev;
1539 950394 : state->conn = conn;
1540 950394 : state->session = session;
1541 950394 : state->tcon = tcon;
1542 :
1543 950394 : if (session) {
1544 924771 : uid = session->smb1.session_id;
1545 : }
1546 :
1547 950394 : if (tcon) {
1548 908016 : tid = tcon->smb1.tcon_id;
1549 :
1550 908016 : if (tcon->fs_attributes & FILE_CASE_SENSITIVE_SEARCH) {
1551 907 : clear_flags |= FLAG_CASELESS_PATHNAMES;
1552 : } else {
1553 : /* Default setting, case insensitive. */
1554 907109 : additional_flags |= FLAG_CASELESS_PATHNAMES;
1555 : }
1556 :
1557 1815574 : if (smbXcli_conn_dfs_supported(conn) &&
1558 907558 : smbXcli_tcon_is_dfs_share(tcon))
1559 : {
1560 1776 : additional_flags2 |= FLAGS2_DFS_PATHNAMES;
1561 : }
1562 : }
1563 :
1564 950394 : state->smb1.recv_cmd = 0xFF;
1565 950394 : state->smb1.recv_status = NT_STATUS_INTERNAL_ERROR;
1566 950394 : state->smb1.recv_iov = talloc_zero_array(state, struct iovec, 3);
1567 950394 : if (state->smb1.recv_iov == NULL) {
1568 0 : TALLOC_FREE(req);
1569 0 : return NULL;
1570 : }
1571 :
1572 950394 : 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 950394 : SIVAL(state->smb1.hdr, 0, SMB_MAGIC);
1583 950394 : SCVAL(state->smb1.hdr, HDR_COM, smb_command);
1584 950394 : SIVAL(state->smb1.hdr, HDR_RCLS, NT_STATUS_V(NT_STATUS_OK));
1585 950394 : SCVAL(state->smb1.hdr, HDR_FLG, flags);
1586 950394 : SSVAL(state->smb1.hdr, HDR_FLG2, flags2);
1587 950394 : SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);
1588 950394 : SSVAL(state->smb1.hdr, HDR_TID, tid);
1589 950394 : SSVAL(state->smb1.hdr, HDR_PID, pid);
1590 950394 : SSVAL(state->smb1.hdr, HDR_UID, uid);
1591 950394 : SSVAL(state->smb1.hdr, HDR_MID, 0); /* this comes later */
1592 950394 : SCVAL(state->smb1.hdr, HDR_WCT, wct);
1593 :
1594 950394 : state->smb1.vwv = vwv;
1595 :
1596 950394 : num_bytes = iov_buflen(bytes_iov, iov_count);
1597 950394 : 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 950394 : SSVAL(state->smb1.bytecount_buf, 0, num_bytes);
1607 :
1608 950394 : state->smb1.iov[0].iov_base = (void *)state->length_hdr;
1609 950394 : state->smb1.iov[0].iov_len = sizeof(state->length_hdr);
1610 950394 : state->smb1.iov[1].iov_base = (void *)state->smb1.hdr;
1611 950394 : state->smb1.iov[1].iov_len = sizeof(state->smb1.hdr);
1612 950394 : state->smb1.iov[2].iov_base = (void *)state->smb1.vwv;
1613 950394 : state->smb1.iov[2].iov_len = wct * sizeof(uint16_t);
1614 950394 : state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;
1615 950394 : state->smb1.iov[3].iov_len = sizeof(uint16_t);
1616 :
1617 950394 : if (iov_count != 0) {
1618 936941 : memcpy(&state->smb1.iov[4], bytes_iov,
1619 : iov_count * sizeof(*bytes_iov));
1620 : }
1621 950394 : state->smb1.iov_count = iov_count + 4;
1622 :
1623 950394 : if (timeout_msec > 0) {
1624 948358 : state->endtime = timeval_current_ofs_msec(timeout_msec);
1625 948358 : if (!tevent_req_set_endtime(req, ev, state->endtime)) {
1626 0 : return req;
1627 : }
1628 : }
1629 :
1630 950394 : switch (smb_command) {
1631 0 : case SMBtranss:
1632 : case SMBtranss2:
1633 : case SMBnttranss:
1634 0 : state->one_way = true;
1635 0 : break;
1636 1517 : case SMBntcancel:
1637 1517 : state->one_way = true;
1638 1517 : state->smb1.one_way_seqnum = true;
1639 1517 : break;
1640 6932 : case SMBlockingX:
1641 6932 : if ((wct == 8) &&
1642 6932 : (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
1643 144 : state->one_way = true;
1644 : }
1645 6917 : break;
1646 : }
1647 :
1648 942140 : return req;
1649 : }
1650 :
1651 949820 : 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 949820 : 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 949820 : if (iov_count < 4) {
1666 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1667 : }
1668 949820 : if (iov[0].iov_len != NBT_HDR_SIZE) {
1669 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1670 : }
1671 949820 : if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1672 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1673 : }
1674 949820 : if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1675 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1676 : }
1677 949820 : if (iov[3].iov_len != sizeof(uint16_t)) {
1678 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1679 : }
1680 :
1681 949820 : frame = talloc_stackframe();
1682 :
1683 949820 : buf = iov_concat(frame, &iov[1], iov_count - 1);
1684 949820 : if (buf == NULL) {
1685 0 : return NT_STATUS_NO_MEMORY;
1686 : }
1687 :
1688 949820 : *seqnum = smb1_signing_next_seqnum(conn->smb1.signing,
1689 : one_way_seqnum);
1690 949820 : status = smb1_signing_sign_pdu(conn->smb1.signing,
1691 : buf,
1692 : talloc_get_size(buf),
1693 : *seqnum);
1694 949820 : if (!NT_STATUS_IS_OK(status)) {
1695 0 : return status;
1696 : }
1697 949820 : memcpy(iov[1].iov_base, buf, iov[1].iov_len);
1698 :
1699 949820 : TALLOC_FREE(frame);
1700 949820 : 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 949828 : 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 949828 : if (!smbXcli_conn_is_connected(state->conn)) {
1719 8 : return NT_STATUS_CONNECTION_DISCONNECTED;
1720 : }
1721 :
1722 949820 : if (state->conn->protocol > PROTOCOL_NT1) {
1723 0 : 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 0 : return NT_STATUS_REVISION_MISMATCH;
1727 : }
1728 :
1729 949820 : if (iov_count < 4) {
1730 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1731 : }
1732 949820 : if (iov[0].iov_len != NBT_HDR_SIZE) {
1733 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1734 : }
1735 949820 : if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1736 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1737 : }
1738 949820 : if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1739 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1740 : }
1741 949820 : if (iov[3].iov_len != sizeof(uint16_t)) {
1742 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1743 : }
1744 :
1745 949820 : cmd = CVAL(iov[1].iov_base, HDR_COM);
1746 949820 : 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 949820 : if (state->smb1.mid != 0) {
1754 1517 : mid = state->smb1.mid;
1755 : } else {
1756 948303 : mid = smb1cli_alloc_mid(state->conn);
1757 : }
1758 949820 : SSVAL(iov[1].iov_base, HDR_MID, mid);
1759 :
1760 949820 : nbtlen = iov_buflen(&iov[1], iov_count-1);
1761 949820 : if ((nbtlen == -1) || (nbtlen > 0x1FFFF)) {
1762 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1763 : }
1764 :
1765 949820 : _smb_setlen_nbt(iov[0].iov_base, nbtlen);
1766 :
1767 958069 : status = smb1cli_conn_signv(state->conn, iov, iov_count,
1768 : &state->smb1.seqnum,
1769 949820 : state->smb1.one_way_seqnum);
1770 :
1771 949820 : 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 949820 : if (common_encryption_on(state->conn->smb1.trans_enc)) {
1780 0 : char *buf, *enc_buf;
1781 :
1782 149425 : buf = (char *)iov_concat(talloc_tos(), iov, iov_count);
1783 149425 : if (buf == NULL) {
1784 0 : return NT_STATUS_NO_MEMORY;
1785 : }
1786 149425 : status = common_encrypt_buffer(state->conn->smb1.trans_enc,
1787 : (char *)buf, &enc_buf);
1788 149425 : TALLOC_FREE(buf);
1789 149425 : 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 149425 : buf = (char *)talloc_memdup(state, enc_buf,
1795 : smb_len_nbt(enc_buf)+4);
1796 149425 : SAFE_FREE(enc_buf);
1797 149425 : if (buf == NULL) {
1798 0 : return NT_STATUS_NO_MEMORY;
1799 : }
1800 149425 : iov[0].iov_base = (void *)buf;
1801 149425 : iov[0].iov_len = talloc_get_size(buf);
1802 149425 : iov_count = 1;
1803 : }
1804 :
1805 949820 : if (state->conn->dispatch_incoming == NULL) {
1806 28 : state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
1807 : }
1808 :
1809 949820 : if (!smbXcli_req_set_pending(req)) {
1810 0 : return NT_STATUS_NO_MEMORY;
1811 : }
1812 :
1813 949820 : tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1814 :
1815 958069 : subreq = writev_send(state, state->ev, state->conn->outgoing,
1816 949820 : state->conn->sock_fd, false, iov, iov_count);
1817 949820 : if (subreq == NULL) {
1818 0 : return NT_STATUS_NO_MEMORY;
1819 : }
1820 949820 : tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
1821 949820 : state->write_req = subreq;
1822 :
1823 949820 : return NT_STATUS_OK;
1824 : }
1825 :
1826 377061 : 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 377061 : iov.iov_base = discard_const_p(void, bytes);
1847 377061 : iov.iov_len = num_bytes;
1848 :
1849 377061 : 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 377061 : if (req == NULL) {
1856 0 : return NULL;
1857 : }
1858 377061 : if (!tevent_req_is_in_progress(req)) {
1859 0 : return tevent_req_post(req, ev);
1860 : }
1861 377061 : status = smb1cli_req_chain_submit(&req, 1);
1862 377061 : if (tevent_req_nterror(req, status)) {
1863 0 : return tevent_req_post(req, ev);
1864 : }
1865 377061 : return req;
1866 : }
1867 :
1868 949726 : static void smb1cli_req_writev_done(struct tevent_req *subreq)
1869 : {
1870 8249 : struct tevent_req *req =
1871 949726 : tevent_req_callback_data(subreq,
1872 : struct tevent_req);
1873 8249 : struct smbXcli_req_state *state =
1874 949726 : tevent_req_data(req,
1875 : struct smbXcli_req_state);
1876 8249 : ssize_t nwritten;
1877 8249 : int err;
1878 :
1879 949726 : state->write_req = NULL;
1880 :
1881 949726 : nwritten = writev_recv(subreq, &err);
1882 949726 : TALLOC_FREE(subreq);
1883 949726 : 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 949726 : if (state->one_way) {
1891 1661 : state->inbuf = NULL;
1892 1661 : tevent_req_done(req);
1893 1661 : return;
1894 : }
1895 : }
1896 :
1897 2924012 : static void smbXcli_conn_received(struct tevent_req *subreq)
1898 : {
1899 22109 : struct smbXcli_conn *conn =
1900 2924012 : tevent_req_callback_data(subreq,
1901 : struct smbXcli_conn);
1902 2924012 : TALLOC_CTX *frame = talloc_stackframe();
1903 22109 : NTSTATUS status;
1904 22109 : uint8_t *inbuf;
1905 22109 : ssize_t received;
1906 22109 : int err;
1907 :
1908 2924012 : 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 2924012 : conn->read_smb_req = NULL;
1916 :
1917 2924012 : received = read_smb_recv(subreq, frame, &inbuf, &err);
1918 2924012 : TALLOC_FREE(subreq);
1919 2924012 : 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 2923770 : status = conn->dispatch_incoming(conn, frame, inbuf);
1927 2923770 : TALLOC_FREE(frame);
1928 2923770 : 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 755549 : return;
1935 : }
1936 :
1937 2161660 : 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 2161651 : if (!smbXcli_conn_receive_next(conn)) {
1950 0 : smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1951 : }
1952 : }
1953 :
1954 929900 : 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 929900 : size_t min_size = MIN_SMB_SIZE;
1967 :
1968 929900 : buflen = smb_len_tcp(buf);
1969 929900 : taken = 0;
1970 :
1971 929900 : hdr = buf + NBT_HDR_SIZE;
1972 :
1973 929900 : status = smb1cli_pull_raw_error(hdr);
1974 929900 : 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 465371 : min_size -= sizeof(uint16_t);
1983 : }
1984 :
1985 929900 : 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 929900 : num_iov = 1;
2004 :
2005 929900 : iov = talloc_array(mem_ctx, struct iovec, num_iov);
2006 929900 : if (iov == NULL) {
2007 0 : return NT_STATUS_NO_MEMORY;
2008 : }
2009 929900 : iov[0].iov_base = hdr;
2010 929900 : iov[0].iov_len = HDR_WCT;
2011 929900 : taken += HDR_WCT;
2012 :
2013 929900 : cmd = CVAL(hdr, HDR_COM);
2014 929900 : wct_ofs = HDR_WCT;
2015 :
2016 7897 : while (true) {
2017 929938 : 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 929938 : needed = sizeof(uint8_t);
2029 929938 : 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 929938 : wct = CVAL(hdr, wct_ofs);
2039 929938 : needed += wct * sizeof(uint16_t);
2040 929938 : 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 929938 : 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 929938 : needed += sizeof(uint16_t);
2080 929938 : 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 929938 : bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
2090 929938 : bcc = SVAL(hdr, bcc_ofs);
2091 929938 : needed += bcc * sizeof(uint8_t);
2092 929938 : 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 929938 : iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2102 : num_iov + 2);
2103 929938 : if (iov_tmp == NULL) {
2104 0 : TALLOC_FREE(iov);
2105 0 : return NT_STATUS_NO_MEMORY;
2106 : }
2107 929938 : iov = iov_tmp;
2108 929938 : cur = &iov[num_iov];
2109 929938 : num_iov += 2;
2110 :
2111 929938 : cur[0].iov_len = wct * sizeof(uint16_t);
2112 929938 : cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2113 929938 : cur[1].iov_len = bcc * sizeof(uint8_t);
2114 929938 : cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
2115 :
2116 929938 : taken += needed;
2117 :
2118 929938 : if (!smb1cli_is_andx_req(cmd)) {
2119 : /*
2120 : * If the current command does not have AndX chanining
2121 : * we are done.
2122 : */
2123 672961 : break;
2124 : }
2125 :
2126 250122 : if (wct == 0 && bcc == 0) {
2127 : /*
2128 : * An empty response also ends the chain,
2129 : * most likely with an error.
2130 : */
2131 47279 : break;
2132 : }
2133 :
2134 202476 : 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 202476 : cmd = CVAL(cur[0].iov_base, 0);
2140 202476 : if (cmd == 0xFF) {
2141 : /*
2142 : * If it is the end of the chain we are also done.
2143 : */
2144 201801 : 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 929900 : remaining = buflen - taken;
2163 :
2164 929900 : 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 968 : iov[num_iov-1].iov_len += remaining;
2171 : }
2172 :
2173 929900 : *piov = iov;
2174 929900 : *pnum_iov = num_iov;
2175 929900 : return NT_STATUS_OK;
2176 :
2177 0 : inval:
2178 0 : TALLOC_FREE(iov);
2179 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2180 : }
2181 :
2182 929976 : 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 929976 : uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
2195 929976 : size_t len = smb_len_tcp(inbuf);
2196 929976 : struct iovec *iov = NULL;
2197 929976 : int num_iov = 0;
2198 929976 : struct tevent_req **chain = NULL;
2199 929976 : size_t num_chained = 0;
2200 929976 : size_t num_responses = 0;
2201 :
2202 929976 : 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 929916 : if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
2237 149429 : && (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 929916 : if (common_encryption_on(conn->smb1.trans_enc)
2247 149429 : && (CVAL(inbuf, 0) == 0)) {
2248 0 : uint16_t enc_ctx_num;
2249 :
2250 149429 : status = get_enc_ctx_num(inbuf, &enc_ctx_num);
2251 149429 : 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 149429 : 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 149429 : status = common_decrypt_buffer(conn->smb1.trans_enc,
2265 : (char *)inbuf);
2266 149429 : 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 149429 : inhdr = inbuf + NBT_HDR_SIZE;
2272 149429 : len = smb_len_nbt(inbuf);
2273 : }
2274 :
2275 929916 : mid = SVAL(inhdr, HDR_MID);
2276 929916 : num_pending = talloc_array_length(conn->pending);
2277 :
2278 1002738 : for (i=0; i<num_pending; i++) {
2279 1002724 : if (mid == smb1cli_req_mid(conn->pending[i])) {
2280 922043 : break;
2281 : }
2282 : }
2283 929916 : if (i == num_pending) {
2284 : /* Dump unexpected reply */
2285 14 : return NT_STATUS_RETRY;
2286 : }
2287 :
2288 929902 : oplock_break = false;
2289 :
2290 929902 : 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 929902 : req = conn->pending[i];
2307 929902 : state = tevent_req_data(req, struct smbXcli_req_state);
2308 :
2309 929902 : if (!oplock_break /* oplock breaks are not signed */
2310 929734 : && !smb1_signing_check_pdu(conn->smb1.signing,
2311 929734 : 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 929900 : status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
2317 : &iov, &num_iov);
2318 929900 : 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 929900 : cmd = CVAL(inhdr, HDR_COM);
2325 929900 : status = smb1cli_pull_raw_error(inhdr);
2326 :
2327 929900 : 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 929900 : if (state->smb1.chained_requests == NULL) {
2339 929857 : if (num_iov != 3) {
2340 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2341 : }
2342 :
2343 929857 : smbXcli_req_unset_pending(req);
2344 :
2345 929857 : 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 929857 : state->smb1.recv_cmd = cmd;
2360 929857 : state->smb1.recv_status = status;
2361 929857 : state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2362 :
2363 929857 : state->smb1.recv_iov[0] = iov[0];
2364 929857 : state->smb1.recv_iov[1] = iov[1];
2365 929857 : state->smb1.recv_iov[2] = iov[2];
2366 :
2367 929857 : if (talloc_array_length(conn->pending) == 0) {
2368 762050 : tevent_req_done(req);
2369 762050 : return NT_STATUS_OK;
2370 : }
2371 :
2372 167807 : tevent_req_defer_callback(req, state->ev);
2373 167807 : tevent_req_done(req);
2374 167807 : 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 930776 : 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 930776 : tevent_req_data(req,
2471 : struct smbXcli_req_state);
2472 930776 : NTSTATUS status = NT_STATUS_OK;
2473 930776 : struct iovec *recv_iov = NULL;
2474 930776 : uint8_t *hdr = NULL;
2475 930776 : uint8_t wct = 0;
2476 930776 : uint32_t vwv_offset = 0;
2477 930776 : uint16_t *vwv = NULL;
2478 930776 : uint32_t num_bytes = 0;
2479 930776 : uint32_t bytes_offset = 0;
2480 930776 : uint8_t *bytes = NULL;
2481 7861 : size_t i;
2482 930776 : bool found_status = false;
2483 930776 : bool found_size = false;
2484 :
2485 930776 : if (piov != NULL) {
2486 930475 : *piov = NULL;
2487 : }
2488 930776 : if (phdr != NULL) {
2489 551179 : *phdr = 0;
2490 : }
2491 930776 : if (pwct != NULL) {
2492 930296 : *pwct = 0;
2493 : }
2494 930776 : if (pvwv != NULL) {
2495 930450 : *pvwv = NULL;
2496 : }
2497 930776 : if (pvwv_offset != NULL) {
2498 94138 : *pvwv_offset = 0;
2499 : }
2500 930776 : if (pnum_bytes != NULL) {
2501 929838 : *pnum_bytes = 0;
2502 : }
2503 930776 : if (pbytes != NULL) {
2504 929838 : *pbytes = NULL;
2505 : }
2506 930776 : if (pbytes_offset != NULL) {
2507 94172 : *pbytes_offset = 0;
2508 : }
2509 930776 : if (pinbuf != NULL) {
2510 828020 : *pinbuf = NULL;
2511 : }
2512 :
2513 930776 : if (state->inbuf != NULL) {
2514 929998 : recv_iov = state->smb1.recv_iov;
2515 929998 : state->smb1.recv_iov = NULL;
2516 929998 : if (state->smb1.recv_cmd != SMBreadBraw) {
2517 929938 : hdr = (uint8_t *)recv_iov[0].iov_base;
2518 929938 : wct = recv_iov[1].iov_len/2;
2519 929938 : vwv = (uint16_t *)recv_iov[1].iov_base;
2520 929938 : vwv_offset = PTR_DIFF(vwv, hdr);
2521 929938 : num_bytes = recv_iov[2].iov_len;
2522 929938 : bytes = (uint8_t *)recv_iov[2].iov_base;
2523 929938 : bytes_offset = PTR_DIFF(bytes, hdr);
2524 : }
2525 : }
2526 :
2527 930776 : 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 930142 : if (num_expected == 0) {
2543 914745 : found_status = true;
2544 914745 : found_size = true;
2545 : }
2546 :
2547 930142 : status = state->smb1.recv_status;
2548 :
2549 935058 : for (i=0; i < num_expected; i++) {
2550 20192 : if (!NT_STATUS_EQUAL(status, expected[i].status)) {
2551 3912 : continue;
2552 : }
2553 :
2554 16280 : found_status = true;
2555 16280 : if (expected[i].wct == 0) {
2556 274 : found_size = true;
2557 274 : break;
2558 : }
2559 :
2560 16006 : if (expected[i].wct == wct) {
2561 14861 : found_size = true;
2562 14861 : break;
2563 : }
2564 : }
2565 :
2566 930142 : if (!found_status) {
2567 121 : return status;
2568 : }
2569 :
2570 930021 : if (!found_size) {
2571 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
2572 : }
2573 :
2574 930021 : if (piov != NULL) {
2575 929745 : *piov = talloc_move(mem_ctx, &recv_iov);
2576 : }
2577 :
2578 930021 : if (phdr != NULL) {
2579 550528 : *phdr = hdr;
2580 : }
2581 930021 : if (pwct != NULL) {
2582 929566 : *pwct = wct;
2583 : }
2584 930021 : if (pvwv != NULL) {
2585 929720 : *pvwv = vwv;
2586 : }
2587 930021 : if (pvwv_offset != NULL) {
2588 94135 : *pvwv_offset = vwv_offset;
2589 : }
2590 930021 : if (pnum_bytes != NULL) {
2591 929156 : *pnum_bytes = num_bytes;
2592 : }
2593 930021 : if (pbytes != NULL) {
2594 929156 : *pbytes = bytes;
2595 : }
2596 930021 : if (pbytes_offset != NULL) {
2597 94169 : *pbytes_offset = bytes_offset;
2598 : }
2599 930021 : if (pinbuf != NULL) {
2600 827935 : *pinbuf = state->inbuf;
2601 : }
2602 :
2603 930021 : return status;
2604 : }
2605 :
2606 22484 : 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 22484 : wct_ofs = HDR_WCT;
2612 :
2613 22522 : 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 22484 : return wct_ofs;
2621 : }
2622 :
2623 949828 : NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
2624 : {
2625 8249 : struct smbXcli_req_state *first_state =
2626 949828 : tevent_req_data(reqs[0],
2627 : struct smbXcli_req_state);
2628 8249 : struct smbXcli_req_state *state;
2629 8249 : size_t wct_offset;
2630 949828 : size_t chain_padding = 0;
2631 8249 : int i, iovlen;
2632 949828 : struct iovec *iov = NULL;
2633 8249 : struct iovec *this_iov;
2634 8249 : NTSTATUS status;
2635 8249 : ssize_t nbt_len;
2636 :
2637 949828 : if (num_reqs == 1) {
2638 949785 : return smb1cli_req_writev_submit(reqs[0], first_state,
2639 949785 : 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 555131 : bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
2780 : {
2781 555131 : return ((tevent_queue_length(conn->outgoing) != 0)
2782 555131 : || (talloc_array_length(conn->pending) != 0));
2783 : }
2784 :
2785 1069753 : bool smbXcli_conn_dfs_supported(struct smbXcli_conn *conn)
2786 : {
2787 1069753 : if (conn->protocol >= PROTOCOL_SMB2_02) {
2788 137458 : return (smb2cli_conn_server_capabilities(conn) & SMB2_CAP_DFS);
2789 : }
2790 :
2791 932295 : return (smb1cli_conn_capabilities(conn) & CAP_DFS);
2792 : }
2793 :
2794 22878 : bool smb2cli_conn_req_possible(struct smbXcli_conn *conn, uint32_t *max_dyn_len)
2795 : {
2796 22878 : uint16_t credits = 1;
2797 :
2798 22878 : 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 22878 : if (conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2806 21668 : credits = conn->smb2.cur_credits;
2807 : }
2808 :
2809 22878 : if (max_dyn_len != NULL) {
2810 22878 : *max_dyn_len = credits * 65536;
2811 : }
2812 :
2813 22878 : return true;
2814 : }
2815 :
2816 138071 : uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
2817 : {
2818 138071 : 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 16495 : uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
2837 : {
2838 16495 : return conn->smb2.server.max_trans_size;
2839 : }
2840 :
2841 2705 : uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
2842 : {
2843 2705 : return conn->smb2.server.max_read_size;
2844 : }
2845 :
2846 2545 : uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
2847 : {
2848 2545 : return conn->smb2.server.max_write_size;
2849 : }
2850 :
2851 13576 : void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
2852 : uint16_t max_credits)
2853 : {
2854 13576 : conn->smb2.max_credits = max_credits;
2855 13576 : }
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 1620 : static bool smb2cli_req_cancel(struct tevent_req *req)
2902 : {
2903 16 : struct smbXcli_req_state *state =
2904 1620 : tevent_req_data(req,
2905 : struct smbXcli_req_state);
2906 1620 : struct smbXcli_tcon *tcon = state->tcon;
2907 1620 : struct smbXcli_session *session = state->session;
2908 1620 : uint8_t *fixed = state->smb2.pad;
2909 1620 : uint16_t fixed_len = 4;
2910 16 : struct tevent_req *subreq;
2911 16 : struct smbXcli_req_state *substate;
2912 16 : NTSTATUS status;
2913 :
2914 1620 : 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 1620 : SSVAL(fixed, 0, 0x04);
2926 1620 : SSVAL(fixed, 2, 0);
2927 :
2928 1620 : 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 1620 : if (subreq == NULL) {
2937 0 : return false;
2938 : }
2939 1620 : substate = tevent_req_data(subreq, struct smbXcli_req_state);
2940 :
2941 1620 : substate->smb2.cancel_mid = BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID);
2942 :
2943 1620 : SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, state->smb2.cancel_flags);
2944 1620 : SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, state->smb2.cancel_mid);
2945 1620 : 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 1620 : state->smb2.cancel_mid = UINT64_MAX;
2951 :
2952 1620 : status = smb2cli_req_compound_submit(&subreq, 1);
2953 1620 : if (!NT_STATUS_IS_OK(status)) {
2954 0 : TALLOC_FREE(subreq);
2955 0 : return false;
2956 : }
2957 :
2958 1620 : tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2959 :
2960 1620 : 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 1626 : struct timeval smbXcli_req_endtime(struct tevent_req *req)
2970 : {
2971 1626 : struct smbXcli_req_state *state = tevent_req_data(
2972 : req, struct smbXcli_req_state);
2973 :
2974 1626 : return state->endtime;
2975 : }
2976 :
2977 1874246 : 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 11486 : struct tevent_req *req;
2993 11486 : struct smbXcli_req_state *state;
2994 1874246 : uint32_t flags = 0;
2995 1874246 : uint32_t tid = 0;
2996 1874246 : uint64_t uid = 0;
2997 1874246 : bool use_channel_sequence = conn->smb2.force_channel_sequence;
2998 1874246 : uint16_t channel_sequence = 0;
2999 1874246 : bool use_replay_flag = false;
3000 1874246 : enum protocol_types proto = smbXcli_conn_protocol(conn);
3001 :
3002 1874246 : req = tevent_req_create(mem_ctx, &state,
3003 : struct smbXcli_req_state);
3004 1874246 : if (req == NULL) {
3005 0 : return NULL;
3006 : }
3007 :
3008 1874246 : 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 1874246 : state->ev = ev;
3014 1874246 : state->conn = conn;
3015 1874246 : state->session = session;
3016 1874246 : state->tcon = tcon;
3017 :
3018 1874246 : if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
3019 0 : use_channel_sequence = true;
3020 1874246 : } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
3021 1358199 : use_channel_sequence = true;
3022 : }
3023 :
3024 1874246 : if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_00) {
3025 1358195 : use_replay_flag = true;
3026 : }
3027 :
3028 1874246 : if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
3029 1357407 : flags |= SMB2_PRIORITY_VALUE_TO_MASK(conn->smb2.io_priority);
3030 : }
3031 :
3032 1874246 : if (session) {
3033 1845654 : uid = session->smb2->session_id;
3034 :
3035 1845654 : if (use_channel_sequence) {
3036 1354816 : channel_sequence = session->smb2->channel_sequence;
3037 : }
3038 :
3039 1845654 : if (use_replay_flag && session->smb2->replay_active) {
3040 722 : additional_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3041 : }
3042 :
3043 1845654 : state->smb2.should_sign = session->smb2->should_sign;
3044 1845654 : state->smb2.should_encrypt = session->smb2->should_encrypt;
3045 1845654 : state->smb2.require_signed_response =
3046 1845654 : session->smb2->require_signed_response;
3047 :
3048 1846776 : if (cmd == SMB2_OP_SESSSETUP &&
3049 98431 : !smb2_signing_key_valid(session->smb2_channel.signing_key) &&
3050 49070 : 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 1846776 : if (cmd == SMB2_OP_SESSSETUP &&
3059 49361 : !smb2_signing_key_valid(session->smb2_channel.signing_key)) {
3060 49070 : state->smb2.should_encrypt = false;
3061 : }
3062 :
3063 1845654 : if (additional_flags & SMB2_HDR_FLAG_SIGNED) {
3064 39665 : 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 39665 : additional_flags &= ~SMB2_HDR_FLAG_SIGNED;
3070 39665 : state->smb2.should_sign = true;
3071 : }
3072 : }
3073 :
3074 1874246 : if (tcon) {
3075 1755442 : tid = tcon->smb2.tcon_id;
3076 :
3077 1755442 : if (tcon->smb2.should_sign) {
3078 1078027 : state->smb2.should_sign = true;
3079 : }
3080 1755442 : if (tcon->smb2.should_encrypt) {
3081 6487 : state->smb2.should_encrypt = true;
3082 : }
3083 : }
3084 :
3085 1874246 : if (state->smb2.should_encrypt) {
3086 7361 : state->smb2.should_sign = false;
3087 : }
3088 :
3089 1874246 : state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
3090 1874246 : if (tevent_req_nomem(state->smb2.recv_iov, req)) {
3091 0 : return req;
3092 : }
3093 :
3094 1874246 : flags |= additional_flags;
3095 1874246 : flags &= ~clear_flags;
3096 :
3097 1874246 : state->smb2.fixed = fixed;
3098 1874246 : state->smb2.fixed_len = fixed_len;
3099 1874246 : state->smb2.dyn = dyn;
3100 1874246 : state->smb2.dyn_len = dyn_len;
3101 1874246 : state->smb2.max_dyn_len = max_dyn_len;
3102 :
3103 1874246 : if (state->smb2.should_encrypt) {
3104 7361 : SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3105 7361 : SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
3106 : }
3107 :
3108 1874246 : SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
3109 1874246 : SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
3110 1874246 : SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE, cmd);
3111 1874246 : SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
3112 1874246 : SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS, flags);
3113 1874246 : SIVAL(state->smb2.hdr, SMB2_HDR_PID, 0); /* reserved */
3114 1874246 : SIVAL(state->smb2.hdr, SMB2_HDR_TID, tid);
3115 1874246 : SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID, uid);
3116 :
3117 1874246 : switch (cmd) {
3118 1620 : case SMB2_OP_CANCEL:
3119 1620 : state->one_way = true;
3120 1620 : 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 1874246 : if (timeout_msec > 0) {
3133 1869000 : state->endtime = timeval_current_ofs_msec(timeout_msec);
3134 1869000 : if (!tevent_req_set_endtime(req, ev, state->endtime)) {
3135 0 : return req;
3136 : }
3137 : }
3138 :
3139 1862760 : return req;
3140 : }
3141 :
3142 1159399 : void smb2cli_req_set_notify_async(struct tevent_req *req)
3143 : {
3144 898 : struct smbXcli_req_state *state =
3145 1159399 : tevent_req_data(req,
3146 : struct smbXcli_req_state);
3147 :
3148 1159399 : state->smb2.notify_async = true;
3149 1159399 : }
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 1872062 : NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
3157 : int num_reqs)
3158 : {
3159 11486 : struct smbXcli_req_state *state;
3160 11486 : struct tevent_req *subreq;
3161 11486 : struct iovec *iov;
3162 11486 : int i, num_iov, nbt_len;
3163 1872062 : int tf_iov = -1;
3164 1872062 : struct smb2_signing_key *encryption_key = NULL;
3165 1872062 : uint64_t encryption_session_id = 0;
3166 1872062 : uint64_t nonce_high = UINT64_MAX;
3167 1872062 : 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 1872062 : iov = talloc_array(reqs[0], struct iovec, 1 + 1 + 4*num_reqs - 1);
3176 1872062 : if (iov == NULL) {
3177 0 : return NT_STATUS_NO_MEMORY;
3178 : }
3179 :
3180 1883052 : num_iov = 1;
3181 1883052 : nbt_len = 0;
3182 :
3183 : /*
3184 : * the session of the first request that requires encryption
3185 : * specifies the encryption key.
3186 : */
3187 3737064 : for (i=0; i<num_reqs; i++) {
3188 1872388 : if (!tevent_req_is_in_progress(reqs[i])) {
3189 0 : return NT_STATUS_INTERNAL_ERROR;
3190 : }
3191 :
3192 1872388 : state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3193 :
3194 1872388 : if (!smbXcli_conn_is_connected(state->conn)) {
3195 39 : return NT_STATUS_CONNECTION_DISCONNECTED;
3196 : }
3197 :
3198 1872349 : if ((state->conn->protocol != PROTOCOL_NONE) &&
3199 1836460 : (state->conn->protocol < PROTOCOL_SMB2_02)) {
3200 0 : return NT_STATUS_REVISION_MISMATCH;
3201 : }
3202 :
3203 1872349 : if (state->session == NULL) {
3204 26734 : continue;
3205 : }
3206 :
3207 1845615 : if (!state->smb2.should_encrypt) {
3208 1838268 : continue;
3209 : }
3210 :
3211 7347 : encryption_key = state->session->smb2->encryption_key;
3212 7347 : if (!smb2_signing_key_valid(encryption_key)) {
3213 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
3214 : }
3215 :
3216 7347 : encryption_session_id = state->session->smb2->session_id;
3217 :
3218 7347 : state->session->smb2->nonce_low += 1;
3219 7347 : 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 7347 : if (state->session->smb2->nonce_high >=
3234 7347 : state->session->smb2->nonce_high_max)
3235 : {
3236 0 : return NT_STATUS_ENCRYPTION_FAILED;
3237 : }
3238 :
3239 7347 : nonce_high = state->session->smb2->nonce_high_random;
3240 7347 : nonce_high += state->session->smb2->nonce_high;
3241 7347 : nonce_low = state->session->smb2->nonce_low;
3242 :
3243 7347 : tf_iov = num_iov;
3244 7347 : iov[num_iov].iov_base = state->smb2.transform;
3245 7347 : iov[num_iov].iov_len = sizeof(state->smb2.transform);
3246 7347 : num_iov += 1;
3247 :
3248 7347 : SBVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3249 7347 : SBVAL(state->smb2.transform, SMB2_TF_NONCE,
3250 : nonce_low);
3251 7347 : SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
3252 : nonce_high);
3253 7347 : SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID,
3254 : encryption_session_id);
3255 :
3256 7347 : nbt_len += SMB2_TF_HDR_SIZE;
3257 7347 : break;
3258 : }
3259 :
3260 3744372 : for (i=0; i<num_reqs; i++) {
3261 11485 : int hdr_iov;
3262 11485 : size_t reqlen;
3263 11485 : bool ret;
3264 11485 : uint16_t opcode;
3265 11485 : uint64_t avail;
3266 11485 : uint16_t charge;
3267 11485 : uint16_t credits;
3268 11485 : uint64_t mid;
3269 1872349 : struct smb2_signing_key *signing_key = NULL;
3270 :
3271 1872349 : if (!tevent_req_is_in_progress(reqs[i])) {
3272 0 : return NT_STATUS_INTERNAL_ERROR;
3273 : }
3274 :
3275 1872349 : state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3276 :
3277 1872349 : if (!smbXcli_conn_is_connected(state->conn)) {
3278 0 : return NT_STATUS_CONNECTION_DISCONNECTED;
3279 : }
3280 :
3281 1872349 : if ((state->conn->protocol != PROTOCOL_NONE) &&
3282 1836460 : (state->conn->protocol < PROTOCOL_SMB2_02)) {
3283 0 : return NT_STATUS_REVISION_MISMATCH;
3284 : }
3285 :
3286 1872349 : opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3287 1872349 : if (opcode == SMB2_OP_CANCEL) {
3288 1620 : goto skip_credits;
3289 : }
3290 :
3291 1870729 : avail = UINT64_MAX - state->conn->smb2.mid;
3292 1870729 : if (avail < 1) {
3293 0 : return NT_STATUS_CONNECTION_ABORTED;
3294 : }
3295 :
3296 1870729 : if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3297 1426540 : uint32_t max_dyn_len = 1;
3298 :
3299 1426540 : max_dyn_len = MAX(max_dyn_len, state->smb2.dyn_len);
3300 1426540 : max_dyn_len = MAX(max_dyn_len, state->smb2.max_dyn_len);
3301 :
3302 1426540 : charge = (max_dyn_len - 1)/ 65536 + 1;
3303 : } else {
3304 443461 : charge = 1;
3305 : }
3306 :
3307 1870729 : charge = MAX(state->smb2.credit_charge, charge);
3308 :
3309 1870729 : avail = MIN(avail, state->conn->smb2.cur_credits);
3310 1870729 : 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 1870729 : credits = 0;
3318 1870729 : if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
3319 119501 : credits = state->conn->smb2.max_credits -
3320 117641 : state->conn->smb2.cur_credits;
3321 : }
3322 1870729 : if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
3323 1766015 : credits += 1;
3324 : }
3325 :
3326 1870729 : mid = state->conn->smb2.mid;
3327 1870729 : state->conn->smb2.mid += charge;
3328 1870729 : state->conn->smb2.cur_credits -= charge;
3329 :
3330 1870729 : if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3331 1426540 : SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
3332 : }
3333 1870729 : SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
3334 1870729 : SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
3335 :
3336 1870729 : state->smb2.cancel_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3337 1870729 : state->smb2.cancel_flags &= ~SMB2_HDR_FLAG_CHAINED;
3338 1870729 : if (state->conn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) {
3339 1351760 : state->smb2.cancel_mid = mid;
3340 : } else {
3341 518969 : state->smb2.cancel_mid = 0;
3342 : }
3343 1870729 : state->smb2.cancel_aid = 0;
3344 :
3345 1872349 : skip_credits:
3346 1872349 : if (state->session && encryption_key == NULL) {
3347 : /*
3348 : * We prefer the channel signing key if it is
3349 : * already there.
3350 : */
3351 1838268 : if (state->smb2.should_sign) {
3352 1113657 : 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 1846893 : if (signing_key != NULL &&
3360 1113657 : !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 1847722 : if (signing_key != NULL &&
3369 1113657 : !smb2_signing_key_valid(signing_key)) {
3370 0 : signing_key = NULL;
3371 : }
3372 : }
3373 :
3374 1872349 : hdr_iov = num_iov;
3375 1872349 : iov[num_iov].iov_base = state->smb2.hdr;
3376 1872349 : iov[num_iov].iov_len = sizeof(state->smb2.hdr);
3377 1872349 : num_iov += 1;
3378 :
3379 1872349 : iov[num_iov].iov_base = discard_const(state->smb2.fixed);
3380 1872349 : iov[num_iov].iov_len = state->smb2.fixed_len;
3381 1872349 : num_iov += 1;
3382 :
3383 1872349 : if (state->smb2.dyn != NULL) {
3384 1781468 : iov[num_iov].iov_base = discard_const(state->smb2.dyn);
3385 1781468 : iov[num_iov].iov_len = state->smb2.dyn_len;
3386 1781468 : num_iov += 1;
3387 : }
3388 :
3389 1872349 : reqlen = sizeof(state->smb2.hdr);
3390 1872349 : reqlen += state->smb2.fixed_len;
3391 1872349 : reqlen += state->smb2.dyn_len;
3392 :
3393 1872349 : 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 1872349 : state->smb2.encryption_session_id = encryption_session_id;
3405 :
3406 1872349 : if (signing_key != NULL) {
3407 9454 : NTSTATUS status;
3408 :
3409 1113657 : status = smb2_signing_sign_pdu(signing_key,
3410 1104203 : &iov[hdr_iov], num_iov - hdr_iov);
3411 1113657 : if (!NT_STATUS_IS_OK(status)) {
3412 0 : return status;
3413 : }
3414 : }
3415 :
3416 1872349 : nbt_len += reqlen;
3417 :
3418 1872349 : ret = smbXcli_req_set_pending(reqs[i]);
3419 1872349 : if (!ret) {
3420 0 : return NT_STATUS_NO_MEMORY;
3421 : }
3422 : }
3423 :
3424 1872023 : state = tevent_req_data(reqs[0], struct smbXcli_req_state);
3425 1872023 : _smb_setlen_tcp(state->length_hdr, nbt_len);
3426 1872023 : iov[0].iov_base = state->length_hdr;
3427 1872023 : iov[0].iov_len = sizeof(state->length_hdr);
3428 :
3429 1872023 : if (encryption_key != NULL) {
3430 495 : NTSTATUS status;
3431 7347 : size_t buflen = nbt_len - SMB2_TF_HDR_SIZE;
3432 495 : uint8_t *buf;
3433 495 : int vi;
3434 :
3435 7347 : buf = talloc_array(iov, uint8_t, buflen);
3436 7347 : 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 28263 : for (vi = tf_iov + 1; vi < num_iov; vi++) {
3449 20916 : struct iovec *v = &iov[vi];
3450 20916 : const uint8_t *o = (const uint8_t *)v->iov_base;
3451 :
3452 20916 : memcpy(buf, o, v->iov_len);
3453 20916 : v->iov_base = (void *)buf;
3454 20916 : buf += v->iov_len;
3455 : }
3456 :
3457 7347 : status = smb2_signing_encrypt_pdu(encryption_key,
3458 7347 : &iov[tf_iov], num_iov - tf_iov);
3459 7347 : if (!NT_STATUS_IS_OK(status)) {
3460 0 : return status;
3461 : }
3462 : }
3463 :
3464 1872023 : if (state->conn->dispatch_incoming == NULL) {
3465 0 : state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3466 : }
3467 :
3468 1872023 : subreq = writev_send(state, state->ev, state->conn->outgoing,
3469 1860538 : state->conn->sock_fd, false, iov, num_iov);
3470 1872023 : if (subreq == NULL) {
3471 0 : return NT_STATUS_NO_MEMORY;
3472 : }
3473 1872023 : tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
3474 1872023 : state->write_req = subreq;
3475 :
3476 1872023 : return NT_STATUS_OK;
3477 : }
3478 :
3479 24011 : void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
3480 : {
3481 350 : struct smbXcli_req_state *state =
3482 24011 : tevent_req_data(req,
3483 : struct smbXcli_req_state);
3484 :
3485 24011 : state->smb2.credit_charge = charge;
3486 24011 : }
3487 :
3488 711369 : 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 10572 : struct tevent_req *req;
3504 10572 : NTSTATUS status;
3505 :
3506 711369 : 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 711369 : if (req == NULL) {
3514 0 : return NULL;
3515 : }
3516 711369 : if (!tevent_req_is_in_progress(req)) {
3517 0 : return tevent_req_post(req, ev);
3518 : }
3519 711369 : status = smb2cli_req_compound_submit(&req, 1);
3520 711369 : if (tevent_req_nterror(req, status)) {
3521 4 : return tevent_req_post(req, ev);
3522 : }
3523 711365 : return req;
3524 : }
3525 :
3526 1865132 : static void smb2cli_req_writev_done(struct tevent_req *subreq)
3527 : {
3528 11023 : struct tevent_req *req =
3529 1865132 : tevent_req_callback_data(subreq,
3530 : struct tevent_req);
3531 11023 : struct smbXcli_req_state *state =
3532 1865132 : tevent_req_data(req,
3533 : struct smbXcli_req_state);
3534 11023 : ssize_t nwritten;
3535 11023 : int err;
3536 :
3537 1865132 : state->write_req = NULL;
3538 :
3539 1865132 : nwritten = writev_recv(subreq, &err);
3540 1865132 : TALLOC_FREE(subreq);
3541 1865132 : 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 7359 : static struct smbXcli_session* smbXcli_session_by_uid(struct smbXcli_conn *conn,
3550 : uint64_t uid)
3551 : {
3552 7359 : struct smbXcli_session *s = conn->sessions;
3553 :
3554 11591 : for (; s; s = s->next) {
3555 11591 : if (s->smb2->session_id != uid) {
3556 4232 : continue;
3557 : }
3558 6864 : break;
3559 : }
3560 :
3561 7359 : return s;
3562 : }
3563 :
3564 1993794 : 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 14250 : struct iovec *iov;
3572 1993794 : int num_iov = 0;
3573 1993794 : size_t taken = 0;
3574 1993794 : uint8_t *first_hdr = buf;
3575 1993794 : size_t verified_buflen = 0;
3576 1993794 : uint8_t *tf = NULL;
3577 1993794 : size_t tf_len = 0;
3578 :
3579 1993794 : iov = talloc_array(mem_ctx, struct iovec, num_iov);
3580 1993794 : if (iov == NULL) {
3581 0 : return NT_STATUS_NO_MEMORY;
3582 : }
3583 :
3584 3987896 : while (taken < buflen) {
3585 1994102 : size_t len = buflen - taken;
3586 1994102 : uint8_t *hdr = first_hdr + taken;
3587 14250 : struct iovec *cur;
3588 14250 : size_t full_size;
3589 14250 : size_t next_command_ofs;
3590 14250 : uint16_t body_size;
3591 14250 : struct iovec *iov_tmp;
3592 :
3593 1994102 : if (verified_buflen > taken) {
3594 0 : len = verified_buflen - taken;
3595 : } else {
3596 1979852 : tf = NULL;
3597 1979852 : tf_len = 0;
3598 : }
3599 :
3600 1994102 : 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 1994102 : 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 7351 : 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 7351 : tf = hdr;
3618 7351 : tf_len = SMB2_TF_HDR_SIZE;
3619 7351 : taken += tf_len;
3620 :
3621 7351 : hdr = first_hdr + taken;
3622 7351 : enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
3623 7351 : uid = BVAL(tf, SMB2_TF_SESSION_ID);
3624 :
3625 7351 : 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 7351 : s = smbXcli_session_by_uid(conn, uid);
3633 7351 : if (s == NULL) {
3634 0 : DEBUG(10, ("unknown session_id %llu\n",
3635 : (unsigned long long)uid));
3636 0 : goto inval;
3637 : }
3638 :
3639 7351 : tf_iov[0].iov_base = (void *)tf;
3640 7351 : tf_iov[0].iov_len = tf_len;
3641 7351 : tf_iov[1].iov_base = (void *)hdr;
3642 7351 : tf_iov[1].iov_len = enc_len;
3643 :
3644 7351 : status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
3645 : tf_iov, 2);
3646 7351 : if (!NT_STATUS_IS_OK(status)) {
3647 0 : TALLOC_FREE(iov);
3648 0 : return status;
3649 : }
3650 :
3651 7351 : verified_buflen = taken + enc_len;
3652 7351 : len = enc_len;
3653 : }
3654 :
3655 : /*
3656 : * We need the header plus the body length field
3657 : */
3658 :
3659 1994102 : 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 1994102 : 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 1994102 : 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 1994102 : full_size = len;
3676 1994102 : next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
3677 1994102 : body_size = SVAL(hdr, SMB2_HDR_BODY);
3678 :
3679 1994102 : 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 1994102 : if (body_size < 2) {
3689 0 : goto inval;
3690 : }
3691 1994102 : body_size &= 0xfffe;
3692 :
3693 1994102 : if (body_size > (full_size - SMB2_HDR_BODY)) {
3694 0 : goto inval;
3695 : }
3696 :
3697 1994102 : iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
3698 : num_iov + 4);
3699 1994102 : if (iov_tmp == NULL) {
3700 0 : TALLOC_FREE(iov);
3701 0 : return NT_STATUS_NO_MEMORY;
3702 : }
3703 1994102 : iov = iov_tmp;
3704 1994102 : cur = &iov[num_iov];
3705 1994102 : num_iov += 4;
3706 :
3707 1994102 : cur[0].iov_base = tf;
3708 1994102 : cur[0].iov_len = tf_len;
3709 1994102 : cur[1].iov_base = hdr;
3710 1994102 : cur[1].iov_len = SMB2_HDR_BODY;
3711 1994102 : cur[2].iov_base = hdr + SMB2_HDR_BODY;
3712 1994102 : cur[2].iov_len = body_size;
3713 1994102 : cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
3714 1994102 : cur[3].iov_len = full_size - (SMB2_HDR_BODY + body_size);
3715 :
3716 1994102 : taken += full_size;
3717 : }
3718 :
3719 1993794 : *piov = iov;
3720 1993794 : *pnum_iov = num_iov;
3721 1993794 : return NT_STATUS_OK;
3722 :
3723 0 : inval:
3724 0 : TALLOC_FREE(iov);
3725 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3726 : }
3727 :
3728 1994102 : static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
3729 : uint64_t mid)
3730 : {
3731 1994102 : size_t num_pending = talloc_array_length(conn->pending);
3732 14250 : size_t i;
3733 :
3734 2003384 : for (i=0; i<num_pending; i++) {
3735 2003382 : struct tevent_req *req = conn->pending[i];
3736 14266 : struct smbXcli_req_state *state =
3737 2003382 : tevent_req_data(req,
3738 : struct smbXcli_req_state);
3739 :
3740 2003382 : if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
3741 1994100 : return req;
3742 : }
3743 : }
3744 2 : return NULL;
3745 : }
3746 :
3747 1993794 : static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3748 : TALLOC_CTX *tmp_mem,
3749 : uint8_t *inbuf)
3750 : {
3751 14250 : struct tevent_req *req;
3752 1993794 : struct smbXcli_req_state *state = NULL;
3753 1993794 : struct iovec *iov = NULL;
3754 1993794 : size_t i, num_iov = 0;
3755 14250 : NTSTATUS status;
3756 1993794 : bool defer = true;
3757 1993794 : struct smbXcli_session *last_session = NULL;
3758 1993794 : size_t inbuf_len = smb_len_tcp(inbuf);
3759 :
3760 1993794 : status = smb2cli_inbuf_parse_compound(conn,
3761 : inbuf + NBT_HDR_SIZE,
3762 : inbuf_len,
3763 : tmp_mem,
3764 : &iov, &num_iov);
3765 1993794 : if (!NT_STATUS_IS_OK(status)) {
3766 0 : return status;
3767 : }
3768 :
3769 3987889 : for (i=0; i<num_iov; i+=4) {
3770 1994102 : uint8_t *inbuf_ref = NULL;
3771 1994102 : struct iovec *cur = &iov[i];
3772 1994102 : uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
3773 1994102 : uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3774 1994102 : uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3775 1994102 : uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3776 14250 : uint16_t req_opcode;
3777 14250 : uint32_t req_flags;
3778 1994102 : uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
3779 14250 : uint32_t new_credits;
3780 1994102 : struct smbXcli_session *session = NULL;
3781 1994102 : struct smb2_signing_key *signing_key = NULL;
3782 1994102 : bool was_encrypted = false;
3783 :
3784 1994102 : new_credits = conn->smb2.cur_credits;
3785 1994102 : new_credits += credits;
3786 1994102 : if (new_credits > UINT16_MAX) {
3787 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3788 : }
3789 1994102 : conn->smb2.cur_credits += credits;
3790 :
3791 1994102 : req = smb2cli_conn_find_pending(conn, mid);
3792 1994102 : if (req == NULL) {
3793 2 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3794 : }
3795 1994100 : state = tevent_req_data(req, struct smbXcli_req_state);
3796 :
3797 1994100 : req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3798 1994100 : if (opcode != req_opcode) {
3799 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3800 : }
3801 1994100 : req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3802 :
3803 1994100 : if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
3804 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3805 : }
3806 :
3807 1994100 : status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
3808 1994100 : if ((flags & SMB2_HDR_FLAG_ASYNC) &&
3809 221543 : NT_STATUS_EQUAL(status, NT_STATUS_PENDING)) {
3810 112233 : uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
3811 :
3812 112233 : if (state->smb2.got_async) {
3813 : /* We only expect one STATUS_PENDING response */
3814 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3815 : }
3816 112233 : 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 112233 : state->smb2.cancel_flags |= SMB2_HDR_FLAG_ASYNC;
3824 112233 : state->smb2.cancel_aid = async_id;
3825 :
3826 112233 : if (state->smb2.notify_async) {
3827 1626 : tevent_req_defer_callback(req, state->ev);
3828 1626 : tevent_req_notify_callback(req);
3829 : }
3830 112233 : continue;
3831 : }
3832 :
3833 1881867 : session = state->session;
3834 1881867 : if (req_flags & SMB2_HDR_FLAG_CHAINED) {
3835 270 : session = last_session;
3836 : }
3837 1881867 : last_session = session;
3838 :
3839 1881867 : if (flags & SMB2_HDR_FLAG_SIGNED) {
3840 1131199 : uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
3841 :
3842 1131199 : if (session == NULL) {
3843 8 : session = smbXcli_session_by_uid(state->conn,
3844 : uid);
3845 : }
3846 :
3847 1131199 : if (session == NULL) {
3848 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3849 : }
3850 :
3851 1131199 : last_session = session;
3852 1131199 : signing_key = session->smb2_channel.signing_key;
3853 : }
3854 :
3855 1881867 : 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 50323 : if (signing_key != NULL &&
3865 27269 : !smb2_signing_key_valid(signing_key) &&
3866 27072 : !NT_STATUS_IS_OK(status)) {
3867 2092 : signing_key = session->smb2->signing_key;
3868 : }
3869 :
3870 50323 : if (signing_key != NULL &&
3871 27269 : !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 25188 : signing_key = NULL;
3886 : }
3887 :
3888 49361 : 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 23541 : state->smb2.require_signed_response = false;
3895 : }
3896 : }
3897 :
3898 1881867 : if (state->smb2.should_sign ||
3899 774930 : state->smb2.require_signed_response)
3900 : {
3901 1106937 : if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
3902 0 : return NT_STATUS_ACCESS_DENIED;
3903 : }
3904 : }
3905 :
3906 1881867 : if (!smb2_signing_key_valid(signing_key) &&
3907 775948 : state->smb2.require_signed_response) {
3908 0 : signing_key = session->smb2_channel.signing_key;
3909 : }
3910 :
3911 1881867 : if (cur[0].iov_len == SMB2_TF_HDR_SIZE) {
3912 7263 : const uint8_t *tf = (const uint8_t *)cur[0].iov_base;
3913 7263 : 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 7263 : if ((session && session->smb2->session_id == uid) ||
3925 0 : (state->smb2.encryption_session_id == uid)) {
3926 7263 : signing_key = NULL;
3927 7263 : was_encrypted = true;
3928 : }
3929 : }
3930 :
3931 1881867 : 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 1881867 : 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 1881867 : 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 1881867 : 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 2077 : if (opcode == SMB2_OP_SESSSETUP) {
3977 80 : state->smb2.signing_skipped = true;
3978 80 : signing_key = NULL;
3979 : }
3980 : }
3981 :
3982 1881867 : 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 1881867 : 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 1881867 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
4001 1881710 : NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
4002 1866850 : 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 1881867 : if (signing_key) {
4037 8757 : NTSTATUS signing_status;
4038 :
4039 1104801 : signing_status = smb2_signing_check_pdu(signing_key,
4040 1104801 : &cur[1], 3);
4041 1104801 : 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 1881867 : 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 1881862 : smbXcli_req_unset_pending(req);
4062 :
4063 : /*
4064 : * There might be more than one response
4065 : * we need to defer the notifications
4066 : */
4067 1881862 : if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
4068 0 : defer = false;
4069 : }
4070 :
4071 1881862 : if (defer) {
4072 1881862 : 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 1881862 : inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
4080 1881862 : if (tevent_req_nomem(inbuf_ref, req)) {
4081 0 : continue;
4082 : }
4083 :
4084 : /* copy the related buffers */
4085 1881862 : state->smb2.recv_iov[0] = cur[1];
4086 1881862 : state->smb2.recv_iov[1] = cur[2];
4087 1881862 : state->smb2.recv_iov[2] = cur[3];
4088 :
4089 1881862 : tevent_req_done(req);
4090 : }
4091 :
4092 1993787 : if (defer) {
4093 1993787 : return NT_STATUS_RETRY;
4094 : }
4095 :
4096 0 : return NT_STATUS_OK;
4097 : }
4098 :
4099 1884067 : 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 11413 : struct smbXcli_req_state *state =
4105 1884067 : tevent_req_data(req,
4106 : struct smbXcli_req_state);
4107 11413 : NTSTATUS status;
4108 11413 : size_t body_size;
4109 1884067 : bool found_status = false;
4110 1884067 : bool found_size = false;
4111 11413 : size_t i;
4112 :
4113 1884067 : if (piov != NULL) {
4114 1794167 : *piov = NULL;
4115 : }
4116 :
4117 1884067 : if (tevent_req_is_in_progress(req) && state->smb2.got_async) {
4118 1626 : return NT_STATUS_PENDING;
4119 : }
4120 :
4121 1882441 : 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 1881856 : if (num_expected == 0) {
4132 1159923 : found_status = true;
4133 1159923 : found_size = true;
4134 : }
4135 :
4136 1881856 : status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
4137 1881856 : body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
4138 :
4139 1997062 : for (i=0; i < num_expected; i++) {
4140 805746 : if (!NT_STATUS_EQUAL(status, expected[i].status)) {
4141 115206 : continue;
4142 : }
4143 :
4144 690540 : found_status = true;
4145 690540 : if (expected[i].body_size == 0) {
4146 0 : found_size = true;
4147 0 : break;
4148 : }
4149 :
4150 690540 : if (expected[i].body_size == body_size) {
4151 680352 : found_size = true;
4152 680352 : break;
4153 : }
4154 : }
4155 :
4156 1881856 : if (!found_status) {
4157 31393 : return status;
4158 : }
4159 :
4160 1850463 : 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 1850463 : if (!found_size) {
4170 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
4171 : }
4172 :
4173 1850463 : if (piov != NULL) {
4174 1760921 : *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
4175 : }
4176 :
4177 1850463 : return status;
4178 : }
4179 :
4180 67292 : NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
4181 : struct iovec *sent_iov)
4182 : {
4183 1476 : struct smbXcli_req_state *state =
4184 67292 : tevent_req_data(req,
4185 : struct smbXcli_req_state);
4186 :
4187 67292 : if (tevent_req_is_in_progress(req)) {
4188 0 : return NT_STATUS_PENDING;
4189 : }
4190 :
4191 67292 : sent_iov[0].iov_base = state->smb2.hdr;
4192 67292 : sent_iov[0].iov_len = sizeof(state->smb2.hdr);
4193 :
4194 67292 : sent_iov[1].iov_base = discard_const(state->smb2.fixed);
4195 67292 : sent_iov[1].iov_len = state->smb2.fixed_len;
4196 :
4197 67292 : if (state->smb2.dyn != NULL) {
4198 67292 : sent_iov[2].iov_base = discard_const(state->smb2.dyn);
4199 67292 : 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 67292 : 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 33947 : 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 33947 : req = tevent_req_create(mem_ctx, &state,
4271 : struct smbXcli_negprot_state);
4272 33947 : if (req == NULL) {
4273 0 : return NULL;
4274 : }
4275 33947 : state->conn = conn;
4276 33947 : state->ev = ev;
4277 33947 : state->in_ctx = in_ctx;
4278 33947 : state->timeout_msec = timeout_msec;
4279 :
4280 33947 : 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 33947 : 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 33947 : 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 33947 : conn->min_protocol = min_protocol;
4296 33947 : conn->max_protocol = max_protocol;
4297 33947 : conn->protocol = PROTOCOL_NONE;
4298 :
4299 33947 : if (max_protocol >= PROTOCOL_SMB2_02) {
4300 26350 : conn->smb2.max_credits = max_credits;
4301 : }
4302 :
4303 33947 : if ((min_protocol < PROTOCOL_SMB2_02) &&
4304 842 : (max_protocol < PROTOCOL_SMB2_02)) {
4305 : /*
4306 : * SMB1 only...
4307 : */
4308 7597 : conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4309 :
4310 7597 : subreq = smbXcli_negprot_smb1_subreq(state);
4311 7597 : if (tevent_req_nomem(subreq, req)) {
4312 0 : return tevent_req_post(req, ev);
4313 : }
4314 7597 : tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4315 7597 : return req;
4316 : }
4317 :
4318 26350 : if ((min_protocol >= PROTOCOL_SMB2_02) &&
4319 701 : (max_protocol >= PROTOCOL_SMB2_02)) {
4320 : /*
4321 : * SMB2 only...
4322 : */
4323 8875 : conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4324 :
4325 8875 : subreq = smbXcli_negprot_smb2_subreq(state);
4326 8875 : if (tevent_req_nomem(subreq, req)) {
4327 0 : return tevent_req_post(req, ev);
4328 : }
4329 8875 : tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4330 8875 : 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 17475 : conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
4341 :
4342 17475 : subreq = smbXcli_negprot_smb1_subreq(state);
4343 17475 : if (tevent_req_nomem(subreq, req)) {
4344 0 : return tevent_req_post(req, ev);
4345 : }
4346 17475 : tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
4347 17475 : 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 25072 : static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
4371 : {
4372 531 : size_t i;
4373 25072 : DATA_BLOB bytes = data_blob_null;
4374 531 : uint8_t flags;
4375 531 : uint16_t flags2;
4376 :
4377 : /* setup the protocol strings */
4378 325936 : for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4379 300864 : uint8_t c = 2;
4380 6372 : bool ok;
4381 :
4382 300864 : if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4383 73660 : continue;
4384 : }
4385 :
4386 242496 : if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4387 15292 : continue;
4388 : }
4389 :
4390 227204 : ok = data_blob_append(state, &bytes, &c, sizeof(c));
4391 227204 : if (!ok) {
4392 0 : return NULL;
4393 : }
4394 :
4395 : /*
4396 : * We know it is already ascii and
4397 : * we want NULL termination.
4398 : */
4399 230174 : ok = data_blob_append(state, &bytes,
4400 224234 : smb1cli_prots[i].smb1_name,
4401 227204 : strlen(smb1cli_prots[i].smb1_name)+1);
4402 227204 : if (!ok) {
4403 0 : return NULL;
4404 : }
4405 : }
4406 :
4407 25603 : smb1cli_req_flags(state->conn->max_protocol,
4408 25072 : state->conn->smb1.client.capabilities,
4409 : SMBnegprot,
4410 : 0, 0, &flags,
4411 : 0, 0, &flags2);
4412 :
4413 25072 : 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 25072 : bytes.length, bytes.data);
4421 : }
4422 :
4423 7597 : static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
4424 : {
4425 141 : struct tevent_req *req =
4426 7597 : tevent_req_callback_data(subreq,
4427 : struct tevent_req);
4428 141 : struct smbXcli_negprot_state *state =
4429 7597 : tevent_req_data(req,
4430 : struct smbXcli_negprot_state);
4431 7597 : struct smbXcli_conn *conn = state->conn;
4432 7597 : struct iovec *recv_iov = NULL;
4433 7597 : 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 7597 : size_t num_prots = 0;
4442 141 : uint8_t flags;
4443 7597 : uint32_t client_capabilities = conn->smb1.client.capabilities;
4444 141 : uint32_t both_capabilities;
4445 7597 : uint32_t server_capabilities = 0;
4446 141 : uint32_t capabilities;
4447 7597 : uint32_t client_max_xmit = conn->smb1.client.max_xmit;
4448 7597 : uint32_t server_max_xmit = 0;
4449 141 : uint32_t max_xmit;
4450 7597 : uint32_t server_max_mux = 0;
4451 7597 : uint16_t server_security_mode = 0;
4452 7597 : uint32_t server_session_key = 0;
4453 7597 : bool server_readbraw = false;
4454 7597 : bool server_writebraw = false;
4455 7597 : bool server_lockread = false;
4456 7597 : bool server_writeunlock = false;
4457 7597 : struct GUID server_guid = GUID_zero();
4458 7597 : DATA_BLOB server_gss_blob = data_blob_null;
4459 141 : uint8_t server_challenge[8];
4460 7597 : char *server_workgroup = NULL;
4461 7597 : char *server_name = NULL;
4462 7597 : int server_time_zone = 0;
4463 7597 : 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 7597 : ZERO_STRUCT(server_challenge);
4480 :
4481 7597 : 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 7597 : TALLOC_FREE(subreq);
4493 7597 : if (tevent_req_nterror(req, status)) {
4494 1082 : return;
4495 : }
4496 7003 : if (inhdr == NULL) {
4497 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
4498 0 : return;
4499 : }
4500 :
4501 7003 : flags = CVAL(inhdr, HDR_FLG);
4502 :
4503 7003 : protnum = SVAL(vwv, 0);
4504 :
4505 64911 : for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4506 64423 : if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4507 1032 : continue;
4508 : }
4509 :
4510 63391 : if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4511 994 : continue;
4512 : }
4513 :
4514 62397 : if (protnum != num_prots) {
4515 55882 : num_prots++;
4516 55882 : continue;
4517 : }
4518 :
4519 6515 : conn->protocol = smb1cli_prots[i].proto;
4520 6515 : break;
4521 : }
4522 :
4523 7003 : if (conn->protocol == PROTOCOL_NONE) {
4524 488 : DBG_ERR("No compatible protocol selected by server.\n");
4525 488 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4526 488 : return;
4527 : }
4528 :
4529 6515 : 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 6515 : if (flags & FLAG_SUPPORT_LOCKREAD) {
4537 26 : server_lockread = true;
4538 26 : server_writeunlock = true;
4539 : }
4540 :
4541 6515 : if (conn->protocol >= PROTOCOL_NT1) {
4542 6487 : const char *client_signing = NULL;
4543 6487 : bool server_mandatory = false;
4544 6487 : bool server_allowed = false;
4545 6487 : const char *server_signing = NULL;
4546 133 : bool ok;
4547 133 : uint8_t key_len;
4548 :
4549 6487 : if (wct != 0x11) {
4550 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4551 0 : return;
4552 : }
4553 :
4554 : /* NT protocol */
4555 6487 : server_security_mode = CVAL(vwv + 1, 0);
4556 6487 : server_max_mux = SVAL(vwv + 1, 1);
4557 6487 : server_max_xmit = IVAL(vwv + 3, 1);
4558 6487 : server_session_key = IVAL(vwv + 7, 1);
4559 6487 : server_time_zone = SVALS(vwv + 15, 1);
4560 6487 : server_time_zone *= 60;
4561 : /* this time arrives in real GMT */
4562 6487 : server_system_time = BVAL(vwv + 11, 1);
4563 6487 : server_capabilities = IVAL(vwv + 9, 1);
4564 :
4565 6487 : key_len = CVAL(vwv + 16, 1);
4566 :
4567 6487 : if (server_capabilities & CAP_RAW_MODE) {
4568 5690 : server_readbraw = true;
4569 5690 : server_writebraw = true;
4570 : }
4571 6487 : if (server_capabilities & CAP_LOCK_AND_READ) {
4572 6487 : server_lockread = true;
4573 : }
4574 :
4575 6487 : if (server_capabilities & CAP_EXTENDED_SECURITY) {
4576 133 : DATA_BLOB blob1, blob2;
4577 :
4578 6402 : if (num_bytes < 16) {
4579 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4580 0 : return;
4581 : }
4582 :
4583 6402 : blob1 = data_blob_const(bytes, 16);
4584 6402 : status = GUID_from_data_blob(&blob1, &server_guid);
4585 6402 : if (tevent_req_nterror(req, status)) {
4586 0 : return;
4587 : }
4588 :
4589 6402 : blob1 = data_blob_const(bytes+16, num_bytes-16);
4590 6402 : blob2 = data_blob_dup_talloc(state, blob1);
4591 12804 : if (blob1.length > 0 &&
4592 6402 : tevent_req_nomem(blob2.data, req)) {
4593 0 : return;
4594 : }
4595 6402 : 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 6487 : client_signing = "disabled";
4657 6487 : if (conn->allow_signing) {
4658 6481 : client_signing = "allowed";
4659 : }
4660 6487 : if (conn->mandatory_signing) {
4661 306 : client_signing = "required";
4662 : }
4663 :
4664 6487 : server_signing = "not supported";
4665 6487 : if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
4666 1590 : server_signing = "supported";
4667 1590 : server_allowed = true;
4668 4764 : } 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 293 : server_signing = "not announced";
4676 293 : server_allowed = true;
4677 : }
4678 6487 : if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
4679 1629 : server_signing = "required";
4680 1629 : server_mandatory = true;
4681 : }
4682 :
4683 6487 : ok = smb1_signing_set_negotiated(conn->smb1.signing,
4684 : server_allowed,
4685 : server_mandatory);
4686 6487 : 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 6515 : if (server_max_xmit < 1024) {
4762 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4763 0 : return;
4764 : }
4765 :
4766 6515 : 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 6515 : both_capabilities = client_capabilities & server_capabilities;
4779 6515 : capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
4780 6515 : capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
4781 6515 : capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
4782 :
4783 6515 : max_xmit = MIN(client_max_xmit, server_max_xmit);
4784 :
4785 6515 : conn->smb1.server.capabilities = server_capabilities;
4786 6515 : conn->smb1.capabilities = capabilities;
4787 :
4788 6515 : conn->smb1.server.max_xmit = server_max_xmit;
4789 6515 : conn->smb1.max_xmit = max_xmit;
4790 :
4791 6515 : conn->smb1.server.max_mux = server_max_mux;
4792 :
4793 6515 : conn->smb1.server.security_mode = server_security_mode;
4794 :
4795 6515 : conn->smb1.server.readbraw = server_readbraw;
4796 6515 : conn->smb1.server.writebraw = server_writebraw;
4797 6515 : conn->smb1.server.lockread = server_lockread;
4798 6515 : conn->smb1.server.writeunlock = server_writeunlock;
4799 :
4800 6515 : conn->smb1.server.session_key = server_session_key;
4801 :
4802 6515 : talloc_steal(conn, server_gss_blob.data);
4803 6515 : conn->smb1.server.gss_blob = server_gss_blob;
4804 6515 : conn->smb1.server.guid = server_guid;
4805 6515 : memcpy(conn->smb1.server.challenge, server_challenge, 8);
4806 6515 : conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
4807 6515 : conn->smb1.server.name = talloc_move(conn, &server_name);
4808 :
4809 6515 : conn->smb1.server.time_zone = server_time_zone;
4810 6515 : conn->smb1.server.system_time = server_system_time;
4811 :
4812 6515 : tevent_req_done(req);
4813 : }
4814 :
4815 24793 : static size_t smbXcli_padding_helper(uint32_t offset, size_t n)
4816 : {
4817 24793 : if ((offset & (n-1)) == 0) return 0;
4818 24793 : return n - (offset & (n-1));
4819 : }
4820 :
4821 25105 : 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 25105 : uint16_t dialect_count = 0;
4826 25105 : DATA_BLOB dyn = data_blob_null;
4827 :
4828 150630 : for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4829 3505 : bool ok;
4830 3505 : uint8_t val[2];
4831 :
4832 125525 : if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4833 4769 : continue;
4834 : }
4835 :
4836 121532 : if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4837 776 : continue;
4838 : }
4839 :
4840 120756 : SSVAL(val, 0, smb2cli_prots[i].smb2_dialect);
4841 :
4842 120756 : ok = data_blob_append(state, &dyn, val, sizeof(val));
4843 120756 : if (!ok) {
4844 0 : return NULL;
4845 : }
4846 :
4847 120756 : dialect_count++;
4848 : }
4849 :
4850 25105 : buf = state->smb2.fixed;
4851 25105 : SSVAL(buf, 0, 36);
4852 25105 : SSVAL(buf, 2, dialect_count);
4853 25105 : SSVAL(buf, 4, state->conn->smb2.client.security_mode);
4854 25105 : SSVAL(buf, 6, 0); /* Reserved */
4855 25105 : if (state->conn->max_protocol >= PROTOCOL_SMB3_00) {
4856 24897 : SIVAL(buf, 8, state->conn->smb2.client.capabilities);
4857 : } else {
4858 208 : SIVAL(buf, 8, 0); /* Capabilities */
4859 : }
4860 25105 : if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
4861 697 : NTSTATUS status;
4862 25057 : struct GUID_ndr_buf guid_buf = { .buf = {0}, };
4863 :
4864 25057 : status = GUID_to_ndr_buf(&state->conn->smb2.client.guid,
4865 : &guid_buf);
4866 25057 : if (!NT_STATUS_IS_OK(status)) {
4867 0 : return NULL;
4868 : }
4869 25057 : memcpy(buf+12, guid_buf.buf, 16); /* ClientGuid */
4870 : } else {
4871 48 : memset(buf+12, 0, 16); /* ClientGuid */
4872 : }
4873 :
4874 25105 : if (state->conn->max_protocol >= PROTOCOL_SMB3_11) {
4875 24793 : const struct smb3_signing_capabilities *client_sign_algos =
4876 24132 : &state->conn->smb2.client.smb3_capabilities.signing;
4877 24793 : const struct smb3_encryption_capabilities *client_ciphers =
4878 24132 : &state->conn->smb2.client.smb3_capabilities.encryption;
4879 661 : NTSTATUS status;
4880 24793 : struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4881 24793 : uint8_t *netname_utf16 = NULL;
4882 24793 : size_t netname_utf16_len = 0;
4883 661 : uint32_t offset;
4884 661 : DATA_BLOB b;
4885 661 : uint8_t p[38];
4886 24793 : const uint8_t zeros[8] = {0, };
4887 661 : size_t pad;
4888 661 : bool ok;
4889 :
4890 24793 : SSVAL(p, 0, 1); /* HashAlgorithmCount */
4891 24793 : SSVAL(p, 2, 32); /* SaltLength */
4892 24793 : SSVAL(p, 4, SMB2_PREAUTH_INTEGRITY_SHA512);
4893 24793 : generate_random_buffer(p + 6, 32);
4894 :
4895 24793 : status = smb2_negotiate_context_add(
4896 : state, &c, SMB2_PREAUTH_INTEGRITY_CAPABILITIES, p, 38);
4897 24793 : if (!NT_STATUS_IS_OK(status)) {
4898 0 : return NULL;
4899 : }
4900 :
4901 24793 : if (client_ciphers->num_algos > 0) {
4902 24793 : size_t ofs = 0;
4903 24793 : SSVAL(p, ofs, client_ciphers->num_algos);
4904 24793 : ofs += 2;
4905 :
4906 123101 : for (i = 0; i < client_ciphers->num_algos; i++) {
4907 98308 : size_t next_ofs = ofs + 2;
4908 98308 : SMB_ASSERT(next_ofs < ARRAY_SIZE(p));
4909 98308 : SSVAL(p, ofs, client_ciphers->algos[i]);
4910 98308 : ofs = next_ofs;
4911 : }
4912 :
4913 24793 : status = smb2_negotiate_context_add(
4914 : state, &c, SMB2_ENCRYPTION_CAPABILITIES, p, ofs);
4915 24793 : if (!NT_STATUS_IS_OK(status)) {
4916 0 : return NULL;
4917 : }
4918 : }
4919 :
4920 24793 : if (client_sign_algos->num_algos > 0) {
4921 24793 : size_t ofs = 0;
4922 24793 : SSVAL(p, ofs, client_sign_algos->num_algos);
4923 24793 : ofs += 2;
4924 :
4925 97848 : for (i = 0; i < client_sign_algos->num_algos; i++) {
4926 73055 : size_t next_ofs = ofs + 2;
4927 73055 : SMB_ASSERT(next_ofs < ARRAY_SIZE(p));
4928 73055 : SSVAL(p, ofs, client_sign_algos->algos[i]);
4929 73055 : ofs = next_ofs;
4930 : }
4931 :
4932 24793 : status = smb2_negotiate_context_add(
4933 : state, &c, SMB2_SIGNING_CAPABILITIES, p, ofs);
4934 24793 : if (!NT_STATUS_IS_OK(status)) {
4935 0 : return NULL;
4936 : }
4937 : }
4938 :
4939 25454 : ok = convert_string_talloc(state, CH_UNIX, CH_UTF16,
4940 24132 : state->conn->remote_name,
4941 24793 : strlen(state->conn->remote_name),
4942 : &netname_utf16, &netname_utf16_len);
4943 24793 : if (!ok) {
4944 0 : return NULL;
4945 : }
4946 :
4947 24793 : status = smb2_negotiate_context_add(state, &c,
4948 : SMB2_NETNAME_NEGOTIATE_CONTEXT_ID,
4949 : netname_utf16, netname_utf16_len);
4950 24793 : if (!NT_STATUS_IS_OK(status)) {
4951 0 : return NULL;
4952 : }
4953 :
4954 24793 : if (state->in_ctx != NULL) {
4955 12854 : struct smb2_negotiate_contexts *ctxs = state->in_ctx;
4956 :
4957 21087 : for (i=0; i<ctxs->num_contexts; i++) {
4958 8233 : struct smb2_negotiate_context *ctx =
4959 8233 : &ctxs->contexts[i];
4960 :
4961 8233 : status = smb2_negotiate_context_add(
4962 : state,
4963 : &c,
4964 8233 : ctx->type,
4965 8233 : ctx->data.data,
4966 : ctx->data.length);
4967 8233 : if (!NT_STATUS_IS_OK(status)) {
4968 0 : return NULL;
4969 : }
4970 : }
4971 : }
4972 :
4973 24793 : status = smb2_negotiate_context_push(state, &b, c);
4974 24793 : if (!NT_STATUS_IS_OK(status)) {
4975 0 : return NULL;
4976 : }
4977 :
4978 24793 : offset = SMB2_HDR_BODY + sizeof(state->smb2.fixed) + dyn.length;
4979 24793 : pad = smbXcli_padding_helper(offset, 8);
4980 :
4981 24793 : ok = data_blob_append(state, &dyn, zeros, pad);
4982 24793 : if (!ok) {
4983 0 : return NULL;
4984 : }
4985 24793 : offset += pad;
4986 :
4987 24793 : ok = data_blob_append(state, &dyn, b.data, b.length);
4988 24793 : if (!ok) {
4989 0 : return NULL;
4990 : }
4991 :
4992 24793 : SIVAL(buf, 28, offset); /* NegotiateContextOffset */
4993 24793 : SSVAL(buf, 32, c.num_contexts); /* NegotiateContextCount */
4994 24793 : SSVAL(buf, 34, 0); /* Reserved */
4995 : } else {
4996 312 : SBVAL(buf, 28, 0); /* Reserved/ClientStartTime */
4997 : }
4998 :
4999 25105 : return smb2cli_req_send(state, state->ev,
5000 : state->conn, SMB2_OP_NEGPROT,
5001 : 0, 0, /* flags */
5002 : state->timeout_msec,
5003 : NULL, NULL, /* tcon, session */
5004 24404 : state->smb2.fixed, sizeof(state->smb2.fixed),
5005 25105 : dyn.data, dyn.length,
5006 : UINT16_MAX); /* max_dyn_len */
5007 : }
5008 :
5009 : static NTSTATUS smbXcli_negprot_smb3_check_capabilities(struct tevent_req *req);
5010 :
5011 42580 : static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
5012 : {
5013 1091 : struct tevent_req *req =
5014 42580 : tevent_req_callback_data(subreq,
5015 : struct tevent_req);
5016 1091 : struct smbXcli_negprot_state *state =
5017 42580 : tevent_req_data(req,
5018 : struct smbXcli_negprot_state);
5019 42580 : struct smbXcli_conn *conn = state->conn;
5020 1091 : size_t security_offset, security_length;
5021 1091 : DATA_BLOB blob;
5022 1091 : NTSTATUS status;
5023 42580 : struct iovec *iov = NULL;
5024 1091 : uint8_t *body;
5025 1091 : size_t i;
5026 1091 : uint16_t dialect_revision;
5027 42580 : uint32_t negotiate_context_offset = 0;
5028 42580 : uint16_t negotiate_context_count = 0;
5029 42580 : DATA_BLOB negotiate_context_blob = data_blob_null;
5030 1091 : size_t avail;
5031 1091 : size_t ctx_ofs;
5032 1091 : size_t needed;
5033 42580 : struct smb2_negotiate_context *preauth = NULL;
5034 1091 : uint16_t hash_count;
5035 1091 : uint16_t salt_length;
5036 1091 : uint16_t hash_selected;
5037 42580 : gnutls_hash_hd_t hash_hnd = NULL;
5038 42580 : struct smb2_negotiate_context *sign_algo = NULL;
5039 42580 : struct smb2_negotiate_context *cipher = NULL;
5040 42580 : struct smb2_negotiate_context *posix = NULL;
5041 42580 : struct iovec sent_iov[3] = {{0}, {0}, {0}};
5042 1091 : static const struct smb2cli_req_expected_response expected[] = {
5043 : {
5044 : .status = NT_STATUS_OK,
5045 : .body_size = 0x41
5046 : }
5047 : };
5048 1091 : int rc;
5049 :
5050 42580 : status = smb2cli_req_recv(subreq, state, &iov,
5051 : expected, ARRAY_SIZE(expected));
5052 42580 : if (tevent_req_nterror(req, status)) {
5053 20450 : return;
5054 : }
5055 42574 : if (iov == NULL) {
5056 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5057 0 : return;
5058 : }
5059 :
5060 42574 : body = (uint8_t *)iov[1].iov_base;
5061 :
5062 42574 : dialect_revision = SVAL(body, 4);
5063 :
5064 214986 : for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5065 198756 : if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5066 3977 : continue;
5067 : }
5068 :
5069 194779 : if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5070 108 : continue;
5071 : }
5072 :
5073 194671 : if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
5074 168327 : continue;
5075 : }
5076 :
5077 26344 : conn->protocol = smb2cli_prots[i].proto;
5078 26344 : break;
5079 : }
5080 :
5081 42574 : if (conn->protocol == PROTOCOL_NONE) {
5082 16230 : TALLOC_FREE(subreq);
5083 :
5084 16230 : if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5085 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5086 0 : return;
5087 : }
5088 :
5089 16230 : if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
5090 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5091 0 : return;
5092 : }
5093 :
5094 : /* make sure we do not loop forever */
5095 16230 : state->conn->min_protocol = PROTOCOL_SMB2_02;
5096 :
5097 : /*
5098 : * send a SMB2 negprot, in order to negotiate
5099 : * the SMB2 dialect.
5100 : */
5101 16230 : subreq = smbXcli_negprot_smb2_subreq(state);
5102 16230 : if (tevent_req_nomem(subreq, req)) {
5103 0 : return;
5104 : }
5105 16230 : tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
5106 16230 : return;
5107 : }
5108 :
5109 26344 : conn->smb2.server.security_mode = SVAL(body, 2);
5110 26344 : if (conn->protocol >= PROTOCOL_SMB3_11) {
5111 22130 : negotiate_context_count = SVAL(body, 6);
5112 : }
5113 :
5114 26344 : blob = data_blob_const(body + 8, 16);
5115 26344 : status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
5116 26344 : if (tevent_req_nterror(req, status)) {
5117 0 : return;
5118 : }
5119 :
5120 26344 : conn->smb2.server.capabilities = IVAL(body, 24);
5121 26344 : conn->smb2.server.max_trans_size= IVAL(body, 28);
5122 26344 : conn->smb2.server.max_read_size = IVAL(body, 32);
5123 26344 : conn->smb2.server.max_write_size= IVAL(body, 36);
5124 26344 : conn->smb2.server.system_time = BVAL(body, 40);
5125 26344 : conn->smb2.server.start_time = BVAL(body, 48);
5126 :
5127 26344 : if (conn->smb2.server.max_trans_size == 0 ||
5128 26344 : conn->smb2.server.max_read_size == 0 ||
5129 25641 : conn->smb2.server.max_write_size == 0) {
5130 : /*
5131 : * We can't connect to servers we can't
5132 : * do any operations on.
5133 : */
5134 2 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5135 2 : return;
5136 : }
5137 :
5138 26342 : security_offset = SVAL(body, 56);
5139 26342 : security_length = SVAL(body, 58);
5140 :
5141 26342 : if (security_offset == 0) {
5142 : /*
5143 : * Azure sends security_offset = 0 and security_length = 0
5144 : *
5145 : * We just set security_offset to the expected value
5146 : * in order to allow the further logic to work
5147 : * as before.
5148 : */
5149 0 : if (security_length != 0) {
5150 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5151 0 : return;
5152 : }
5153 0 : security_offset = SMB2_HDR_BODY + iov[1].iov_len;
5154 : }
5155 :
5156 26342 : if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
5157 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5158 0 : return;
5159 : }
5160 :
5161 26342 : if (security_length > iov[2].iov_len) {
5162 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5163 0 : return;
5164 : }
5165 :
5166 26342 : conn->smb2.server.gss_blob = data_blob_talloc(conn,
5167 : iov[2].iov_base,
5168 : security_length);
5169 26342 : if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
5170 0 : return;
5171 : }
5172 :
5173 26342 : if (conn->protocol >= PROTOCOL_SMB3_00) {
5174 22234 : conn->smb2.server.sign_algo = SMB2_SIGNING_AES128_CMAC;
5175 : } else {
5176 4108 : conn->smb2.server.sign_algo = SMB2_SIGNING_HMAC_SHA256;
5177 : }
5178 :
5179 26342 : if (conn->protocol < PROTOCOL_SMB3_11) {
5180 4212 : TALLOC_FREE(subreq);
5181 :
5182 4212 : if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
5183 92 : conn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
5184 : }
5185 :
5186 4212 : status = smbXcli_negprot_smb3_check_capabilities(req);
5187 4212 : if (tevent_req_nterror(req, status)) {
5188 0 : return;
5189 : }
5190 :
5191 4212 : tevent_req_done(req);
5192 4212 : return;
5193 : }
5194 :
5195 : /*
5196 : * Here we are now at SMB3_11, so encryption should be
5197 : * negotiated via context, not capabilities.
5198 : */
5199 :
5200 22130 : if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
5201 : /*
5202 : * Server set SMB2_CAP_ENCRYPTION capability,
5203 : * but *SHOULD* not, not *MUST* not. Just mask it off.
5204 : * NetApp seems to do this:
5205 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13009
5206 : */
5207 0 : conn->smb2.server.capabilities &= ~SMB2_CAP_ENCRYPTION;
5208 : }
5209 :
5210 22130 : negotiate_context_offset = IVAL(body, 60);
5211 22130 : if (negotiate_context_offset < security_offset) {
5212 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5213 0 : return;
5214 : }
5215 :
5216 22130 : ctx_ofs = negotiate_context_offset - security_offset;
5217 22130 : if (ctx_ofs > iov[2].iov_len) {
5218 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5219 0 : return;
5220 : }
5221 22130 : avail = iov[2].iov_len - security_length;
5222 22130 : needed = iov[2].iov_len - ctx_ofs;
5223 22130 : if (needed > avail) {
5224 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5225 0 : return;
5226 : }
5227 :
5228 22130 : negotiate_context_blob.data = (uint8_t *)iov[2].iov_base;
5229 22130 : negotiate_context_blob.length = iov[2].iov_len;
5230 :
5231 22130 : negotiate_context_blob.data += ctx_ofs;
5232 22130 : negotiate_context_blob.length -= ctx_ofs;
5233 :
5234 22130 : state->out_ctx = talloc_zero(state, struct smb2_negotiate_contexts);
5235 22130 : if (tevent_req_nomem(state->out_ctx, req)) {
5236 0 : return;
5237 : }
5238 :
5239 22130 : status = smb2_negotiate_context_parse(state->out_ctx,
5240 : negotiate_context_blob,
5241 : negotiate_context_count,
5242 : state->out_ctx);
5243 22130 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5244 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
5245 : }
5246 22130 : if (tevent_req_nterror(req, status)) {
5247 0 : return;
5248 : }
5249 :
5250 22791 : preauth = smb2_negotiate_context_find(
5251 22130 : state->out_ctx, SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
5252 22130 : if (preauth == NULL) {
5253 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5254 0 : return;
5255 : }
5256 :
5257 22130 : if (preauth->data.length < 6) {
5258 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5259 0 : return;
5260 : }
5261 :
5262 22130 : hash_count = SVAL(preauth->data.data, 0);
5263 22130 : salt_length = SVAL(preauth->data.data, 2);
5264 22130 : hash_selected = SVAL(preauth->data.data, 4);
5265 :
5266 22130 : if (hash_count != 1) {
5267 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5268 0 : return;
5269 : }
5270 :
5271 22130 : if (preauth->data.length != (6 + salt_length)) {
5272 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5273 0 : return;
5274 : }
5275 :
5276 22130 : if (hash_selected != SMB2_PREAUTH_INTEGRITY_SHA512) {
5277 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5278 0 : return;
5279 : }
5280 :
5281 22791 : sign_algo = smb2_negotiate_context_find(
5282 22130 : state->out_ctx, SMB2_SIGNING_CAPABILITIES);
5283 22130 : if (sign_algo != NULL) {
5284 22130 : const struct smb3_signing_capabilities *client_sign_algos =
5285 22130 : &state->conn->smb2.client.smb3_capabilities.signing;
5286 22130 : bool found_selected = false;
5287 661 : uint16_t sign_algo_count;
5288 661 : uint16_t sign_algo_selected;
5289 :
5290 22130 : if (client_sign_algos->num_algos == 0) {
5291 : /*
5292 : * We didn't ask for SMB2_ENCRYPTION_CAPABILITIES
5293 : */
5294 0 : tevent_req_nterror(req,
5295 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5296 0 : return;
5297 : }
5298 :
5299 22130 : if (sign_algo->data.length < 2) {
5300 0 : tevent_req_nterror(req,
5301 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5302 0 : return;
5303 : }
5304 :
5305 22130 : sign_algo_count = SVAL(sign_algo->data.data, 0);
5306 22130 : if (sign_algo_count != 1) {
5307 0 : tevent_req_nterror(req,
5308 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5309 0 : return;
5310 : }
5311 :
5312 22130 : if (sign_algo->data.length < (2 + 2 * sign_algo_count)) {
5313 0 : tevent_req_nterror(req,
5314 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5315 0 : return;
5316 : }
5317 22130 : sign_algo_selected = SVAL(sign_algo->data.data, 2);
5318 :
5319 22130 : for (i = 0; i < client_sign_algos->num_algos; i++) {
5320 22130 : if (client_sign_algos->algos[i] == sign_algo_selected) {
5321 : /*
5322 : * We found a match
5323 : */
5324 21469 : found_selected = true;
5325 21469 : break;
5326 : }
5327 : }
5328 :
5329 22130 : if (!found_selected) {
5330 : /*
5331 : * The server send a sign_algo we didn't offer.
5332 : */
5333 0 : tevent_req_nterror(req,
5334 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5335 0 : return;
5336 : }
5337 :
5338 22130 : conn->smb2.server.sign_algo = sign_algo_selected;
5339 : }
5340 :
5341 22791 : cipher = smb2_negotiate_context_find(
5342 22130 : state->out_ctx, SMB2_ENCRYPTION_CAPABILITIES);
5343 22130 : if (cipher != NULL) {
5344 21928 : const struct smb3_encryption_capabilities *client_ciphers =
5345 21928 : &state->conn->smb2.client.smb3_capabilities.encryption;
5346 21928 : bool found_selected = false;
5347 661 : uint16_t cipher_count;
5348 661 : uint16_t cipher_selected;
5349 :
5350 21928 : if (client_ciphers->num_algos == 0) {
5351 : /*
5352 : * We didn't ask for SMB2_ENCRYPTION_CAPABILITIES
5353 : */
5354 0 : tevent_req_nterror(req,
5355 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5356 0 : return;
5357 : }
5358 :
5359 21928 : if (cipher->data.length < 2) {
5360 0 : tevent_req_nterror(req,
5361 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5362 0 : return;
5363 : }
5364 :
5365 21928 : cipher_count = SVAL(cipher->data.data, 0);
5366 21928 : if (cipher_count != 1) {
5367 0 : tevent_req_nterror(req,
5368 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5369 0 : return;
5370 : }
5371 :
5372 21928 : if (cipher->data.length < (2 + 2 * cipher_count)) {
5373 0 : tevent_req_nterror(req,
5374 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5375 0 : return;
5376 : }
5377 21928 : cipher_selected = SVAL(cipher->data.data, 2);
5378 :
5379 21928 : for (i = 0; i < client_ciphers->num_algos; i++) {
5380 21928 : if (cipher_selected == SMB2_ENCRYPTION_NONE) {
5381 : /*
5382 : * encryption not supported
5383 : */
5384 0 : found_selected = true;
5385 0 : break;
5386 : }
5387 21928 : if (client_ciphers->algos[i] == cipher_selected) {
5388 : /*
5389 : * We found a match
5390 : */
5391 21267 : found_selected = true;
5392 21267 : break;
5393 : }
5394 : }
5395 :
5396 21928 : if (!found_selected) {
5397 : /*
5398 : * The server send a cipher we didn't offer.
5399 : */
5400 0 : tevent_req_nterror(req,
5401 : NT_STATUS_INVALID_NETWORK_RESPONSE);
5402 0 : return;
5403 : }
5404 :
5405 21928 : conn->smb2.server.cipher = cipher_selected;
5406 : }
5407 :
5408 22791 : posix = smb2_negotiate_context_find(
5409 22130 : state->out_ctx, SMB2_POSIX_EXTENSIONS_AVAILABLE);
5410 22130 : if (posix != NULL) {
5411 5490 : DATA_BLOB posix_blob = data_blob_const(
5412 : SMB2_CREATE_TAG_POSIX, strlen(SMB2_CREATE_TAG_POSIX));
5413 5490 : int cmp = data_blob_cmp(&posix->data, &posix_blob);
5414 :
5415 5490 : conn->smb2.server.smb311_posix = (cmp == 0);
5416 : }
5417 :
5418 :
5419 : /* First we hash the request */
5420 22130 : smb2cli_req_get_sent_iov(subreq, sent_iov);
5421 :
5422 22130 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
5423 22130 : if (rc < 0) {
5424 0 : tevent_req_nterror(req,
5425 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5426 0 : return;
5427 : }
5428 :
5429 22791 : rc = gnutls_hash(hash_hnd,
5430 22130 : conn->smb2.preauth_sha512,
5431 : sizeof(conn->smb2.preauth_sha512));
5432 22130 : if (rc < 0) {
5433 0 : gnutls_hash_deinit(hash_hnd, NULL);
5434 0 : tevent_req_nterror(req,
5435 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5436 0 : return;
5437 : }
5438 88520 : for (i = 0; i < 3; i++) {
5439 68373 : rc = gnutls_hash(hash_hnd,
5440 66390 : sent_iov[i].iov_base,
5441 : sent_iov[i].iov_len);
5442 66390 : if (rc < 0) {
5443 0 : gnutls_hash_deinit(hash_hnd, NULL);
5444 0 : tevent_req_nterror(req,
5445 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5446 0 : return;
5447 : }
5448 : }
5449 :
5450 : /* This resets the hash state */
5451 22130 : gnutls_hash_output(hash_hnd, conn->smb2.preauth_sha512);
5452 22130 : TALLOC_FREE(subreq);
5453 :
5454 : /* And now we hash the response */
5455 22130 : rc = gnutls_hash(hash_hnd,
5456 21469 : conn->smb2.preauth_sha512,
5457 : sizeof(conn->smb2.preauth_sha512));
5458 22130 : if (rc < 0) {
5459 0 : gnutls_hash_deinit(hash_hnd, NULL);
5460 0 : tevent_req_nterror(req,
5461 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5462 0 : return;
5463 : }
5464 88520 : for (i = 0; i < 3; i++) {
5465 68373 : rc = gnutls_hash(hash_hnd,
5466 66390 : iov[i].iov_base,
5467 66390 : iov[i].iov_len);
5468 66390 : if (rc < 0) {
5469 0 : gnutls_hash_deinit(hash_hnd, NULL);
5470 0 : tevent_req_nterror(req,
5471 : gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
5472 0 : return;
5473 : }
5474 : }
5475 22130 : gnutls_hash_deinit(hash_hnd, conn->smb2.preauth_sha512);
5476 22130 : if (rc < 0) {
5477 0 : tevent_req_nterror(req,
5478 : NT_STATUS_UNSUCCESSFUL);
5479 0 : return;
5480 : }
5481 :
5482 22130 : status = smbXcli_negprot_smb3_check_capabilities(req);
5483 22130 : if (tevent_req_nterror(req, status)) {
5484 0 : return;
5485 : }
5486 :
5487 22130 : tevent_req_done(req);
5488 : }
5489 :
5490 26342 : static NTSTATUS smbXcli_negprot_smb3_check_capabilities(struct tevent_req *req)
5491 : {
5492 701 : struct smbXcli_negprot_state *state =
5493 26342 : tevent_req_data(req,
5494 : struct smbXcli_negprot_state);
5495 26342 : struct smbXcli_conn *conn = state->conn;
5496 :
5497 52684 : return smb311_capabilities_check(&conn->smb2.client.smb3_capabilities,
5498 : "smbXcli_negprot",
5499 : DBGLVL_ERR,
5500 26342 : NT_STATUS_ACCESS_DENIED,
5501 : "client",
5502 : conn->protocol,
5503 26342 : conn->smb2.server.sign_algo,
5504 26342 : conn->smb2.server.cipher);
5505 : }
5506 :
5507 17475 : static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
5508 : TALLOC_CTX *tmp_mem,
5509 : uint8_t *inbuf)
5510 : {
5511 17475 : size_t num_pending = talloc_array_length(conn->pending);
5512 390 : struct tevent_req *subreq;
5513 390 : struct smbXcli_req_state *substate;
5514 390 : struct tevent_req *req;
5515 390 : uint32_t protocol_magic;
5516 17475 : size_t inbuf_len = smb_len_nbt(inbuf);
5517 :
5518 17475 : if (num_pending != 1) {
5519 0 : return NT_STATUS_INTERNAL_ERROR;
5520 : }
5521 :
5522 17475 : if (inbuf_len < 4) {
5523 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
5524 : }
5525 :
5526 17475 : subreq = conn->pending[0];
5527 17475 : substate = tevent_req_data(subreq, struct smbXcli_req_state);
5528 17475 : req = tevent_req_callback_data(subreq, struct tevent_req);
5529 :
5530 17475 : protocol_magic = IVAL(inbuf, 4);
5531 :
5532 17475 : switch (protocol_magic) {
5533 0 : case SMB_MAGIC:
5534 0 : tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
5535 0 : conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
5536 0 : return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5537 :
5538 17475 : case SMB2_MAGIC:
5539 17475 : if (substate->smb2.recv_iov == NULL) {
5540 : /*
5541 : * For the SMB1 negprot we have move it.
5542 : */
5543 17475 : substate->smb2.recv_iov = substate->smb1.recv_iov;
5544 17475 : substate->smb1.recv_iov = NULL;
5545 : }
5546 :
5547 : /*
5548 : * we got an SMB2 answer, which consumed sequence number 0
5549 : * so we need to use 1 as the next one.
5550 : *
5551 : * we also need to set the current credits to 0
5552 : * as we consumed the initial one. The SMB2 answer
5553 : * hopefully grant us a new credit.
5554 : */
5555 17475 : conn->smb2.mid = 1;
5556 17475 : conn->smb2.cur_credits = 0;
5557 17475 : tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
5558 17475 : conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
5559 17475 : return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5560 : }
5561 :
5562 0 : DEBUG(10, ("Got non-SMB PDU\n"));
5563 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
5564 : }
5565 :
5566 33947 : NTSTATUS smbXcli_negprot_recv(
5567 : struct tevent_req *req,
5568 : TALLOC_CTX *mem_ctx,
5569 : struct smb2_negotiate_contexts **out_ctx)
5570 : {
5571 33947 : struct smbXcli_negprot_state *state = tevent_req_data(
5572 : req, struct smbXcli_negprot_state);
5573 842 : NTSTATUS status;
5574 :
5575 33947 : if (tevent_req_is_nterror(req, &status)) {
5576 1090 : tevent_req_received(req);
5577 1090 : return status;
5578 : }
5579 :
5580 32857 : if (out_ctx != NULL) {
5581 11465 : *out_ctx = talloc_move(mem_ctx, &state->out_ctx);
5582 : }
5583 :
5584 32857 : tevent_req_received(req);
5585 32857 : return NT_STATUS_OK;
5586 : }
5587 :
5588 12051 : NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
5589 : uint32_t timeout_msec,
5590 : enum protocol_types min_protocol,
5591 : enum protocol_types max_protocol,
5592 : struct smb2_negotiate_contexts *in_ctx,
5593 : TALLOC_CTX *mem_ctx,
5594 : struct smb2_negotiate_contexts **out_ctx)
5595 : {
5596 12051 : TALLOC_CTX *frame = talloc_stackframe();
5597 0 : struct tevent_context *ev;
5598 0 : struct tevent_req *req;
5599 12051 : NTSTATUS status = NT_STATUS_NO_MEMORY;
5600 0 : bool ok;
5601 :
5602 12051 : if (smbXcli_conn_has_async_calls(conn)) {
5603 : /*
5604 : * Can't use sync call while an async call is in flight
5605 : */
5606 0 : status = NT_STATUS_INVALID_PARAMETER_MIX;
5607 0 : goto fail;
5608 : }
5609 12051 : ev = samba_tevent_context_init(frame);
5610 12051 : if (ev == NULL) {
5611 0 : goto fail;
5612 : }
5613 12051 : req = smbXcli_negprot_send(
5614 : frame,
5615 : ev,
5616 : conn,
5617 : timeout_msec,
5618 : min_protocol,
5619 : max_protocol,
5620 : WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
5621 : in_ctx);
5622 12051 : if (req == NULL) {
5623 0 : goto fail;
5624 : }
5625 12051 : ok = tevent_req_poll_ntstatus(req, ev, &status);
5626 12051 : if (!ok) {
5627 0 : goto fail;
5628 : }
5629 12051 : status = smbXcli_negprot_recv(req, mem_ctx, out_ctx);
5630 12051 : fail:
5631 12051 : TALLOC_FREE(frame);
5632 12051 : return status;
5633 : }
5634 :
5635 : struct smb2cli_validate_negotiate_info_state {
5636 : struct smbXcli_conn *conn;
5637 : DATA_BLOB in_input_buffer;
5638 : DATA_BLOB in_output_buffer;
5639 : DATA_BLOB out_input_buffer;
5640 : DATA_BLOB out_output_buffer;
5641 : uint16_t dialect;
5642 : };
5643 :
5644 : static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq);
5645 :
5646 4272 : struct tevent_req *smb2cli_validate_negotiate_info_send(TALLOC_CTX *mem_ctx,
5647 : struct tevent_context *ev,
5648 : struct smbXcli_conn *conn,
5649 : uint32_t timeout_msec,
5650 : struct smbXcli_session *session,
5651 : struct smbXcli_tcon *tcon)
5652 : {
5653 22 : struct tevent_req *req;
5654 22 : struct smb2cli_validate_negotiate_info_state *state;
5655 22 : uint8_t *buf;
5656 4272 : uint16_t dialect_count = 0;
5657 22 : struct tevent_req *subreq;
5658 22 : bool _save_should_sign;
5659 22 : size_t i;
5660 :
5661 4272 : req = tevent_req_create(mem_ctx, &state,
5662 : struct smb2cli_validate_negotiate_info_state);
5663 4272 : if (req == NULL) {
5664 0 : return NULL;
5665 : }
5666 4272 : state->conn = conn;
5667 :
5668 4272 : state->in_input_buffer = data_blob_talloc_zero(state,
5669 : 4 + 16 + 1 + 1 + 2);
5670 4272 : if (tevent_req_nomem(state->in_input_buffer.data, req)) {
5671 0 : return tevent_req_post(req, ev);
5672 : }
5673 4272 : buf = state->in_input_buffer.data;
5674 :
5675 4272 : if (state->conn->max_protocol >= PROTOCOL_SMB3_00) {
5676 4076 : SIVAL(buf, 0, conn->smb2.client.capabilities);
5677 : } else {
5678 196 : SIVAL(buf, 0, 0); /* Capabilities */
5679 : }
5680 4272 : if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
5681 20 : NTSTATUS status;
5682 4218 : struct GUID_ndr_buf guid_buf = { .buf = {0}, };
5683 :
5684 4218 : status = GUID_to_ndr_buf(&conn->smb2.client.guid,
5685 : &guid_buf);
5686 4218 : if (!NT_STATUS_IS_OK(status)) {
5687 0 : return NULL;
5688 : }
5689 4218 : memcpy(buf+4, guid_buf.buf, 16); /* ClientGuid */
5690 : } else {
5691 54 : memset(buf+4, 0, 16); /* ClientGuid */
5692 : }
5693 4272 : if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5694 3054 : SCVAL(buf, 20, conn->smb2.client.security_mode);
5695 : } else {
5696 1218 : SCVAL(buf, 20, 0);
5697 : }
5698 4272 : SCVAL(buf, 21, 0); /* reserved */
5699 :
5700 25632 : for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5701 110 : bool ok;
5702 110 : size_t ofs;
5703 :
5704 21360 : if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5705 389 : continue;
5706 : }
5707 :
5708 20971 : if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5709 750 : continue;
5710 : }
5711 :
5712 20221 : if (smb2cli_prots[i].proto == state->conn->protocol) {
5713 4272 : state->dialect = smb2cli_prots[i].smb2_dialect;
5714 : }
5715 :
5716 20221 : ofs = state->in_input_buffer.length;
5717 20221 : ok = data_blob_realloc(state, &state->in_input_buffer,
5718 : ofs + 2);
5719 20221 : if (!ok) {
5720 0 : tevent_req_oom(req);
5721 0 : return tevent_req_post(req, ev);
5722 : }
5723 :
5724 20221 : buf = state->in_input_buffer.data;
5725 20221 : SSVAL(buf, ofs, smb2cli_prots[i].smb2_dialect);
5726 :
5727 20221 : dialect_count++;
5728 : }
5729 4272 : buf = state->in_input_buffer.data;
5730 4272 : SSVAL(buf, 22, dialect_count);
5731 :
5732 4272 : _save_should_sign = smb2cli_tcon_is_signing_on(tcon);
5733 4272 : smb2cli_tcon_should_sign(tcon, true);
5734 4294 : subreq = smb2cli_ioctl_send(state, ev, conn,
5735 : timeout_msec, session, tcon,
5736 : UINT64_MAX, /* in_fid_persistent */
5737 : UINT64_MAX, /* in_fid_volatile */
5738 : FSCTL_VALIDATE_NEGOTIATE_INFO,
5739 : 0, /* in_max_input_length */
5740 4272 : &state->in_input_buffer,
5741 : 24, /* in_max_output_length */
5742 4272 : &state->in_output_buffer,
5743 : SMB2_IOCTL_FLAG_IS_FSCTL);
5744 4272 : smb2cli_tcon_should_sign(tcon, _save_should_sign);
5745 4272 : if (tevent_req_nomem(subreq, req)) {
5746 0 : return tevent_req_post(req, ev);
5747 : }
5748 4272 : tevent_req_set_callback(subreq,
5749 : smb2cli_validate_negotiate_info_done,
5750 : req);
5751 :
5752 4272 : return req;
5753 : }
5754 :
5755 4272 : static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
5756 : {
5757 22 : struct tevent_req *req =
5758 4272 : tevent_req_callback_data(subreq,
5759 : struct tevent_req);
5760 22 : struct smb2cli_validate_negotiate_info_state *state =
5761 4272 : tevent_req_data(req,
5762 : struct smb2cli_validate_negotiate_info_state);
5763 22 : NTSTATUS status;
5764 22 : const uint8_t *buf;
5765 22 : uint32_t capabilities;
5766 22 : DATA_BLOB guid_blob;
5767 22 : struct GUID server_guid;
5768 22 : uint16_t security_mode;
5769 22 : uint16_t dialect;
5770 :
5771 4272 : status = smb2cli_ioctl_recv(subreq, state,
5772 : &state->out_input_buffer,
5773 : &state->out_output_buffer);
5774 4272 : TALLOC_FREE(subreq);
5775 :
5776 : /*
5777 : * This response must be signed correctly for
5778 : * these "normal" error codes to be processed.
5779 : * If the packet wasn't signed correctly we will get
5780 : * NT_STATUS_ACCESS_DENIED or NT_STATUS_HMAC_NOT_SUPPORTED,
5781 : * or NT_STATUS_INVALID_NETWORK_RESPONSE
5782 : * from smb2_signing_check_pdu().
5783 : *
5784 : * We must never ignore the above errors here.
5785 : */
5786 :
5787 4272 : if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
5788 : /*
5789 : * The response was signed, but not supported
5790 : *
5791 : * Older Windows and Samba releases return
5792 : * NT_STATUS_FILE_CLOSED.
5793 : */
5794 64 : tevent_req_done(req);
5795 64 : return;
5796 : }
5797 4208 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
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 file shares.
5803 : */
5804 568 : tevent_req_done(req);
5805 568 : return;
5806 : }
5807 3640 : if (NT_STATUS_EQUAL(status, NT_STATUS_FS_DRIVER_REQUIRED)) {
5808 : /*
5809 : * The response was signed, but not supported
5810 : *
5811 : * This is returned by the NTVFS based Samba 4.x file server
5812 : * for ipc shares.
5813 : */
5814 976 : tevent_req_done(req);
5815 976 : return;
5816 : }
5817 2664 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
5818 : /*
5819 : * The response was signed, but not supported
5820 : *
5821 : * This might be returned by older Windows versions or by
5822 : * NetApp SMB server implementations.
5823 : *
5824 : * See
5825 : *
5826 : * https://blogs.msdn.microsoft.com/openspecification/2012/06/28/smb3-secure-dialect-negotiation/
5827 : *
5828 : */
5829 0 : tevent_req_done(req);
5830 0 : return;
5831 : }
5832 2664 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5833 : /*
5834 : * The response was signed, but not supported
5835 : *
5836 : * This might be returned by NetApp Ontap 7.3.7 SMB server
5837 : * implementations.
5838 : *
5839 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
5840 : *
5841 : */
5842 0 : tevent_req_done(req);
5843 0 : return;
5844 : }
5845 2664 : if (tevent_req_nterror(req, status)) {
5846 0 : return;
5847 : }
5848 :
5849 2664 : if (state->out_output_buffer.length != 24) {
5850 0 : tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5851 0 : return;
5852 : }
5853 :
5854 2664 : buf = state->out_output_buffer.data;
5855 :
5856 2664 : capabilities = IVAL(buf, 0);
5857 2664 : guid_blob = data_blob_const(buf + 4, 16);
5858 2664 : status = GUID_from_data_blob(&guid_blob, &server_guid);
5859 2664 : if (tevent_req_nterror(req, status)) {
5860 0 : return;
5861 : }
5862 2664 : security_mode = CVAL(buf, 20);
5863 2664 : dialect = SVAL(buf, 22);
5864 :
5865 2664 : if (capabilities != state->conn->smb2.server.capabilities) {
5866 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5867 0 : return;
5868 : }
5869 :
5870 2664 : if (!GUID_equal(&server_guid, &state->conn->smb2.server.guid)) {
5871 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5872 0 : return;
5873 : }
5874 :
5875 2664 : if (security_mode != state->conn->smb2.server.security_mode) {
5876 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5877 0 : return;
5878 : }
5879 :
5880 2664 : if (dialect != state->dialect) {
5881 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5882 0 : return;
5883 : }
5884 :
5885 2664 : tevent_req_done(req);
5886 : }
5887 :
5888 4272 : NTSTATUS smb2cli_validate_negotiate_info_recv(struct tevent_req *req)
5889 : {
5890 4272 : return tevent_req_simple_recv_ntstatus(req);
5891 : }
5892 :
5893 46271 : static int smbXcli_session_destructor(struct smbXcli_session *session)
5894 : {
5895 46271 : if (session->conn == NULL) {
5896 506 : return 0;
5897 : }
5898 :
5899 45687 : DLIST_REMOVE(session->conn->sessions, session);
5900 44608 : return 0;
5901 : }
5902 :
5903 50818 : struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
5904 : struct smbXcli_conn *conn)
5905 : {
5906 914 : struct smbXcli_session *session;
5907 914 : NTSTATUS status;
5908 :
5909 50818 : session = talloc_zero(mem_ctx, struct smbXcli_session);
5910 50818 : if (session == NULL) {
5911 0 : return NULL;
5912 : }
5913 50818 : session->smb2 = talloc_zero(session, struct smb2cli_session);
5914 50818 : if (session->smb2 == NULL) {
5915 0 : talloc_free(session);
5916 0 : return NULL;
5917 : }
5918 50818 : talloc_set_destructor(session, smbXcli_session_destructor);
5919 :
5920 51732 : status = smb2_signing_key_sign_create(session->smb2,
5921 50818 : conn->smb2.server.sign_algo,
5922 : NULL, /* no master key */
5923 : NULL, /* derivations */
5924 50818 : &session->smb2->signing_key);
5925 50818 : if (!NT_STATUS_IS_OK(status)) {
5926 0 : talloc_free(session);
5927 0 : return NULL;
5928 : }
5929 :
5930 50818 : DLIST_ADD_END(conn->sessions, session);
5931 50818 : session->conn = conn;
5932 :
5933 51732 : status = smb2_signing_key_sign_create(session,
5934 50818 : conn->smb2.server.sign_algo,
5935 : NULL, /* no master key */
5936 : NULL, /* derivations */
5937 : &session->smb2_channel.signing_key);
5938 50818 : if (!NT_STATUS_IS_OK(status)) {
5939 0 : talloc_free(session);
5940 0 : return NULL;
5941 : }
5942 :
5943 50818 : memcpy(session->smb2_channel.preauth_sha512,
5944 50818 : conn->smb2.preauth_sha512,
5945 : sizeof(session->smb2_channel.preauth_sha512));
5946 :
5947 50818 : return session;
5948 : }
5949 :
5950 18 : struct smbXcli_session *smbXcli_session_shallow_copy(TALLOC_CTX *mem_ctx,
5951 : struct smbXcli_session *src)
5952 : {
5953 0 : struct smbXcli_session *session;
5954 0 : struct timespec ts;
5955 0 : NTTIME nt;
5956 :
5957 18 : session = talloc_zero(mem_ctx, struct smbXcli_session);
5958 18 : if (session == NULL) {
5959 0 : return NULL;
5960 : }
5961 18 : session->smb2 = talloc_zero(session, struct smb2cli_session);
5962 18 : if (session->smb2 == NULL) {
5963 0 : talloc_free(session);
5964 0 : return NULL;
5965 : }
5966 :
5967 : /*
5968 : * Note we keep a pointer to the session keys of the
5969 : * main session and rely on the caller to free the
5970 : * shallow copy first!
5971 : */
5972 18 : session->conn = src->conn;
5973 18 : *session->smb2 = *src->smb2;
5974 18 : session->smb2_channel = src->smb2_channel;
5975 18 : session->disconnect_expired = src->disconnect_expired;
5976 :
5977 : /*
5978 : * This is only supposed to be called in test code
5979 : * but we should not reuse nonces!
5980 : *
5981 : * Add the current timestamp as NTTIME to nonce_high
5982 : * and set nonce_low to a value we can recognize in captures.
5983 : */
5984 18 : clock_gettime_mono(&ts);
5985 18 : nt = unix_timespec_to_nt_time(ts);
5986 18 : nt &= session->smb2->nonce_high_max;
5987 18 : if (nt == session->smb2->nonce_high_max || nt < UINT8_MAX) {
5988 0 : talloc_free(session);
5989 0 : return NULL;
5990 : }
5991 18 : session->smb2->nonce_high += nt;
5992 18 : session->smb2->nonce_low = UINT32_MAX;
5993 :
5994 18 : DLIST_ADD_END(src->conn->sessions, session);
5995 18 : talloc_set_destructor(session, smbXcli_session_destructor);
5996 :
5997 18 : return session;
5998 : }
5999 :
6000 16856 : bool smbXcli_session_is_guest(struct smbXcli_session *session)
6001 : {
6002 16856 : if (session == NULL) {
6003 0 : return false;
6004 : }
6005 :
6006 16856 : if (session->conn == NULL) {
6007 0 : return false;
6008 : }
6009 :
6010 16856 : if (session->conn->mandatory_signing) {
6011 3617 : return false;
6012 : }
6013 :
6014 13239 : if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6015 9875 : if (session->smb2->session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
6016 19 : return true;
6017 : }
6018 9856 : return false;
6019 : }
6020 :
6021 3364 : if (session->smb1.action & SMB_SETUP_GUEST) {
6022 3 : return true;
6023 : }
6024 :
6025 3361 : return false;
6026 : }
6027 :
6028 81134 : bool smbXcli_session_is_authenticated(struct smbXcli_session *session)
6029 : {
6030 1244 : const DATA_BLOB *application_key;
6031 :
6032 81134 : if (session == NULL) {
6033 0 : return false;
6034 : }
6035 :
6036 81134 : if (session->conn == NULL) {
6037 0 : return false;
6038 : }
6039 :
6040 : /*
6041 : * If we have an application key we had a session key negotiated
6042 : * at auth time.
6043 : */
6044 81134 : if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6045 81134 : if (!smb2_signing_key_valid(session->smb2->application_key)) {
6046 1942 : return false;
6047 : }
6048 79188 : application_key = &session->smb2->application_key->blob;
6049 : } else {
6050 0 : application_key = &session->smb1.application_key;
6051 : }
6052 :
6053 79188 : if (application_key->length == 0) {
6054 0 : return false;
6055 : }
6056 :
6057 77948 : return true;
6058 : }
6059 :
6060 0 : NTSTATUS smb2cli_session_signing_key(struct smbXcli_session *session,
6061 : TALLOC_CTX *mem_ctx,
6062 : DATA_BLOB *key)
6063 : {
6064 0 : const struct smb2_signing_key *sig = NULL;
6065 :
6066 0 : if (session->conn == NULL) {
6067 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6068 : }
6069 :
6070 : /*
6071 : * Use channel signing key if there is one, otherwise fallback
6072 : * to session.
6073 : */
6074 :
6075 0 : if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6076 0 : sig = session->smb2_channel.signing_key;
6077 0 : } else if (smb2_signing_key_valid(session->smb2->signing_key)) {
6078 0 : sig = session->smb2->signing_key;
6079 : } else {
6080 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6081 : }
6082 :
6083 0 : *key = data_blob_dup_talloc(mem_ctx, sig->blob);
6084 0 : if (key->data == NULL) {
6085 0 : return NT_STATUS_NO_MEMORY;
6086 : }
6087 :
6088 0 : return NT_STATUS_OK;
6089 : }
6090 :
6091 0 : NTSTATUS smb2cli_session_encryption_key(struct smbXcli_session *session,
6092 : TALLOC_CTX *mem_ctx,
6093 : DATA_BLOB *key)
6094 : {
6095 0 : if (session->conn == NULL) {
6096 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6097 : }
6098 :
6099 0 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6100 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6101 : }
6102 :
6103 0 : if (!smb2_signing_key_valid(session->smb2->encryption_key)) {
6104 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6105 : }
6106 :
6107 0 : *key = data_blob_dup_talloc(mem_ctx, session->smb2->encryption_key->blob);
6108 0 : if (key->data == NULL) {
6109 0 : return NT_STATUS_NO_MEMORY;
6110 : }
6111 :
6112 0 : return NT_STATUS_OK;
6113 : }
6114 :
6115 0 : NTSTATUS smb2cli_session_decryption_key(struct smbXcli_session *session,
6116 : TALLOC_CTX *mem_ctx,
6117 : DATA_BLOB *key)
6118 : {
6119 0 : if (session->conn == NULL) {
6120 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6121 : }
6122 :
6123 0 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6124 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6125 : }
6126 :
6127 0 : if (!smb2_signing_key_valid(session->smb2->decryption_key)) {
6128 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6129 : }
6130 :
6131 0 : *key = data_blob_dup_talloc(mem_ctx, session->smb2->decryption_key->blob);
6132 0 : if (key->data == NULL) {
6133 0 : return NT_STATUS_NO_MEMORY;
6134 : }
6135 :
6136 0 : return NT_STATUS_OK;
6137 : }
6138 :
6139 17824 : NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
6140 : TALLOC_CTX *mem_ctx,
6141 : DATA_BLOB *key)
6142 : {
6143 620 : const DATA_BLOB *application_key;
6144 :
6145 17824 : *key = data_blob_null;
6146 :
6147 17824 : if (session->conn == NULL) {
6148 0 : return NT_STATUS_NO_USER_SESSION_KEY;
6149 : }
6150 :
6151 17824 : if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6152 17463 : if (!smb2_signing_key_valid(session->smb2->application_key)) {
6153 382 : return NT_STATUS_NO_USER_SESSION_KEY;
6154 : }
6155 17081 : application_key = &session->smb2->application_key->blob;
6156 : } else {
6157 361 : application_key = &session->smb1.application_key;
6158 : }
6159 :
6160 17442 : if (application_key->length == 0) {
6161 16 : return NT_STATUS_NO_USER_SESSION_KEY;
6162 : }
6163 :
6164 17426 : *key = data_blob_dup_talloc(mem_ctx, *application_key);
6165 17426 : if (key->data == NULL) {
6166 0 : return NT_STATUS_NO_MEMORY;
6167 : }
6168 :
6169 17426 : return NT_STATUS_OK;
6170 : }
6171 :
6172 9 : void smbXcli_session_set_disconnect_expired(struct smbXcli_session *session)
6173 : {
6174 9 : session->disconnect_expired = true;
6175 9 : }
6176 :
6177 834 : uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
6178 : {
6179 834 : return session->smb1.session_id;
6180 : }
6181 :
6182 522885 : void smb1cli_session_set_id(struct smbXcli_session *session,
6183 : uint16_t session_id)
6184 : {
6185 522885 : session->smb1.session_id = session_id;
6186 522885 : }
6187 :
6188 7368 : void smb1cli_session_set_action(struct smbXcli_session *session,
6189 : uint16_t action)
6190 : {
6191 7368 : session->smb1.action = action;
6192 7368 : }
6193 :
6194 6403 : NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
6195 : const DATA_BLOB _session_key)
6196 : {
6197 6403 : struct smbXcli_conn *conn = session->conn;
6198 133 : uint8_t session_key[16];
6199 :
6200 6403 : if (conn == NULL) {
6201 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6202 : }
6203 :
6204 6403 : if (session->smb1.application_key.length != 0) {
6205 : /*
6206 : * TODO: do not allow this...
6207 : *
6208 : * return NT_STATUS_INVALID_PARAMETER_MIX;
6209 : */
6210 27 : data_blob_clear_free(&session->smb1.application_key);
6211 27 : session->smb1.protected_key = false;
6212 : }
6213 :
6214 6403 : if (_session_key.length == 0) {
6215 0 : return NT_STATUS_OK;
6216 : }
6217 :
6218 6403 : ZERO_STRUCT(session_key);
6219 6403 : memcpy(session_key, _session_key.data,
6220 6403 : MIN(_session_key.length, sizeof(session_key)));
6221 :
6222 6403 : session->smb1.application_key = data_blob_talloc(session,
6223 : session_key,
6224 : sizeof(session_key));
6225 6403 : ZERO_STRUCT(session_key);
6226 6403 : if (session->smb1.application_key.data == NULL) {
6227 0 : return NT_STATUS_NO_MEMORY;
6228 : }
6229 :
6230 6403 : session->smb1.protected_key = false;
6231 :
6232 6403 : return NT_STATUS_OK;
6233 : }
6234 :
6235 5437 : NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
6236 : {
6237 133 : NTSTATUS status;
6238 :
6239 5437 : if (session->smb1.protected_key) {
6240 : /* already protected */
6241 0 : return NT_STATUS_OK;
6242 : }
6243 :
6244 5437 : if (session->smb1.application_key.length != 16) {
6245 44 : return NT_STATUS_INVALID_PARAMETER_MIX;
6246 : }
6247 :
6248 5393 : status = smb1_key_derivation(session->smb1.application_key.data,
6249 : session->smb1.application_key.length,
6250 : session->smb1.application_key.data);
6251 5393 : if (!NT_STATUS_IS_OK(status)) {
6252 0 : return status;
6253 : }
6254 :
6255 5393 : session->smb1.protected_key = true;
6256 :
6257 5393 : return NT_STATUS_OK;
6258 : }
6259 :
6260 49363 : uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
6261 : {
6262 49363 : struct smbXcli_conn *conn = session->conn;
6263 49363 : uint8_t security_mode = 0;
6264 :
6265 49363 : if (conn == NULL) {
6266 0 : return security_mode;
6267 : }
6268 :
6269 49363 : security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
6270 49363 : if (conn->mandatory_signing) {
6271 15979 : security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
6272 : }
6273 49363 : if (session->smb2->should_sign) {
6274 1979 : security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
6275 : }
6276 :
6277 48241 : return security_mode;
6278 : }
6279 :
6280 64349 : uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
6281 : {
6282 64349 : return session->smb2->session_id;
6283 : }
6284 :
6285 464 : uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
6286 : {
6287 464 : return session->smb2->session_flags;
6288 : }
6289 :
6290 45633 : void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
6291 : uint64_t session_id,
6292 : uint16_t session_flags)
6293 : {
6294 45633 : session->smb2->session_id = session_id;
6295 45633 : session->smb2->session_flags = session_flags;
6296 45633 : }
6297 :
6298 946 : void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
6299 : {
6300 946 : session->smb2->channel_sequence += 1;
6301 946 : }
6302 :
6303 628 : uint16_t smb2cli_session_reset_channel_sequence(struct smbXcli_session *session,
6304 : uint16_t channel_sequence)
6305 : {
6306 0 : uint16_t prev_cs;
6307 :
6308 628 : prev_cs = session->smb2->channel_sequence;
6309 628 : session->smb2->channel_sequence = channel_sequence;
6310 :
6311 628 : return prev_cs;
6312 : }
6313 :
6314 408 : uint16_t smb2cli_session_current_channel_sequence(struct smbXcli_session *session)
6315 : {
6316 408 : return session->smb2->channel_sequence;
6317 : }
6318 :
6319 466 : void smb2cli_session_start_replay(struct smbXcli_session *session)
6320 : {
6321 466 : session->smb2->replay_active = true;
6322 466 : }
6323 :
6324 426 : void smb2cli_session_stop_replay(struct smbXcli_session *session)
6325 : {
6326 426 : session->smb2->replay_active = false;
6327 426 : }
6328 :
6329 50 : void smb2cli_session_require_signed_response(struct smbXcli_session *session,
6330 : bool require_signed_response)
6331 : {
6332 50 : session->smb2->require_signed_response = require_signed_response;
6333 50 : }
6334 :
6335 64504 : NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
6336 : const struct iovec *iov)
6337 : {
6338 64504 : gnutls_hash_hd_t hash_hnd = NULL;
6339 963 : size_t i;
6340 963 : int rc;
6341 :
6342 64504 : if (session->conn == NULL) {
6343 0 : return NT_STATUS_INTERNAL_ERROR;
6344 : }
6345 :
6346 64504 : if (session->conn->protocol < PROTOCOL_SMB3_11) {
6347 5611 : return NT_STATUS_OK;
6348 : }
6349 :
6350 58893 : if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6351 366 : return NT_STATUS_OK;
6352 : }
6353 :
6354 58527 : rc = gnutls_hash_init(&hash_hnd,
6355 : GNUTLS_DIG_SHA512);
6356 58527 : if (rc < 0) {
6357 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6358 : }
6359 :
6360 59386 : rc = gnutls_hash(hash_hnd,
6361 58527 : session->smb2_channel.preauth_sha512,
6362 : sizeof(session->smb2_channel.preauth_sha512));
6363 58527 : if (rc < 0) {
6364 0 : gnutls_hash_deinit(hash_hnd, NULL);
6365 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6366 : }
6367 234108 : for (i = 0; i < 3; i++) {
6368 178158 : rc = gnutls_hash(hash_hnd,
6369 175581 : iov[i].iov_base,
6370 175581 : iov[i].iov_len);
6371 175581 : if (rc < 0) {
6372 0 : gnutls_hash_deinit(hash_hnd, NULL);
6373 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6374 : }
6375 : }
6376 58527 : gnutls_hash_deinit(hash_hnd, session->smb2_channel.preauth_sha512);
6377 :
6378 58527 : return NT_STATUS_OK;
6379 : }
6380 :
6381 24032 : NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
6382 : const DATA_BLOB _session_key,
6383 : const struct iovec *recv_iov)
6384 : {
6385 24032 : struct smbXcli_conn *conn = session->conn;
6386 24032 : uint16_t no_sign_flags = 0;
6387 24032 : bool check_signature = true;
6388 623 : uint32_t hdr_flags;
6389 623 : NTSTATUS status;
6390 24032 : struct smb2_signing_derivations derivations = {
6391 : .signing = NULL,
6392 : };
6393 24032 : DATA_BLOB preauth_hash = data_blob_null;
6394 24032 : size_t nonce_size = 0;
6395 :
6396 24032 : if (conn == NULL) {
6397 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6398 : }
6399 :
6400 24032 : if (recv_iov[0].iov_len != SMB2_HDR_BODY) {
6401 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6402 : }
6403 :
6404 24032 : if (!conn->mandatory_signing) {
6405 : /*
6406 : * only allow guest sessions without
6407 : * mandatory signing.
6408 : *
6409 : * If we try an authentication with username != ""
6410 : * and the server let us in without verifying the
6411 : * password we don't have a negotiated session key
6412 : * for signing.
6413 : */
6414 13912 : no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST;
6415 : }
6416 :
6417 24032 : if (session->smb2->session_flags & no_sign_flags) {
6418 2 : session->smb2->should_sign = false;
6419 2 : return NT_STATUS_OK;
6420 : }
6421 :
6422 24030 : if (smb2_signing_key_valid(session->smb2->signing_key)) {
6423 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6424 : }
6425 :
6426 24030 : if (conn->protocol >= PROTOCOL_SMB3_11) {
6427 20014 : preauth_hash = data_blob_const(session->smb2_channel.preauth_sha512,
6428 : sizeof(session->smb2_channel.preauth_sha512));
6429 : }
6430 :
6431 24030 : smb2_signing_derivations_fill_const_stack(&derivations,
6432 : conn->protocol,
6433 : preauth_hash);
6434 :
6435 24653 : status = smb2_signing_key_sign_create(session->smb2,
6436 24030 : conn->smb2.server.sign_algo,
6437 : &_session_key,
6438 : derivations.signing,
6439 24030 : &session->smb2->signing_key);
6440 24030 : if (!NT_STATUS_IS_OK(status)) {
6441 0 : return status;
6442 : }
6443 :
6444 24653 : status = smb2_signing_key_cipher_create(session->smb2,
6445 24030 : conn->smb2.server.cipher,
6446 : &_session_key,
6447 : derivations.cipher_c2s,
6448 24030 : &session->smb2->encryption_key);
6449 24030 : if (!NT_STATUS_IS_OK(status)) {
6450 0 : return status;
6451 : }
6452 :
6453 24653 : status = smb2_signing_key_cipher_create(session->smb2,
6454 24030 : conn->smb2.server.cipher,
6455 : &_session_key,
6456 : derivations.cipher_s2c,
6457 24030 : &session->smb2->decryption_key);
6458 24030 : if (!NT_STATUS_IS_OK(status)) {
6459 0 : return status;
6460 : }
6461 :
6462 24653 : status = smb2_signing_key_sign_create(session->smb2,
6463 24030 : conn->smb2.server.sign_algo,
6464 : &_session_key,
6465 : derivations.application,
6466 24030 : &session->smb2->application_key);
6467 24030 : if (!NT_STATUS_IS_OK(status)) {
6468 0 : return status;
6469 : }
6470 :
6471 24653 : status = smb2_signing_key_copy(session,
6472 24030 : session->smb2->signing_key,
6473 : &session->smb2_channel.signing_key);
6474 24030 : if (!NT_STATUS_IS_OK(status)) {
6475 0 : return status;
6476 : }
6477 :
6478 24030 : check_signature = conn->mandatory_signing;
6479 :
6480 24030 : hdr_flags = IVAL(recv_iov[0].iov_base, SMB2_HDR_FLAGS);
6481 24030 : if (hdr_flags & SMB2_HDR_FLAG_SIGNED) {
6482 : /*
6483 : * Sadly some vendors don't sign the
6484 : * final SMB2 session setup response
6485 : *
6486 : * At least Windows and Samba are always doing this
6487 : * if there's a session key available.
6488 : *
6489 : * We only check the signature if it's mandatory
6490 : * or SMB2_HDR_FLAG_SIGNED is provided.
6491 : */
6492 24030 : check_signature = true;
6493 : }
6494 :
6495 24030 : if (conn->protocol >= PROTOCOL_SMB3_11) {
6496 19413 : check_signature = true;
6497 : }
6498 :
6499 23429 : if (check_signature) {
6500 24030 : status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
6501 : recv_iov, 3);
6502 24030 : if (!NT_STATUS_IS_OK(status)) {
6503 0 : return status;
6504 : }
6505 : }
6506 :
6507 24030 : session->smb2->should_sign = false;
6508 24030 : session->smb2->should_encrypt = false;
6509 :
6510 24030 : if (conn->desire_signing) {
6511 10120 : session->smb2->should_sign = true;
6512 : }
6513 :
6514 24030 : if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
6515 9474 : session->smb2->should_sign = true;
6516 : }
6517 :
6518 24030 : if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
6519 0 : session->smb2->should_encrypt = true;
6520 : }
6521 :
6522 24030 : if (conn->protocol < PROTOCOL_SMB3_00) {
6523 3936 : session->smb2->should_encrypt = false;
6524 : }
6525 :
6526 24030 : if (conn->smb2.server.cipher == 0) {
6527 4129 : session->smb2->should_encrypt = false;
6528 : }
6529 :
6530 : /*
6531 : * CCM and GCM algorithms must never have their
6532 : * nonce wrap, or the security of the whole
6533 : * communication and the keys is destroyed.
6534 : * We must drop the connection once we have
6535 : * transferred too much data.
6536 : *
6537 : * NOTE: We assume nonces greater than 8 bytes.
6538 : */
6539 24030 : generate_nonce_buffer((uint8_t *)&session->smb2->nonce_high_random,
6540 : sizeof(session->smb2->nonce_high_random));
6541 24030 : switch (conn->smb2.server.cipher) {
6542 110 : case SMB2_ENCRYPTION_AES128_CCM:
6543 110 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
6544 110 : break;
6545 19749 : case SMB2_ENCRYPTION_AES128_GCM:
6546 19749 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
6547 19749 : break;
6548 10 : case SMB2_ENCRYPTION_AES256_CCM:
6549 10 : nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
6550 10 : break;
6551 12 : case SMB2_ENCRYPTION_AES256_GCM:
6552 12 : nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
6553 12 : break;
6554 4115 : default:
6555 4115 : nonce_size = 0;
6556 4115 : break;
6557 : }
6558 24030 : session->smb2->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
6559 24030 : session->smb2->nonce_high = 0;
6560 24030 : session->smb2->nonce_low = 0;
6561 :
6562 24030 : return NT_STATUS_OK;
6563 : }
6564 :
6565 2262 : NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
6566 : struct smbXcli_session *session1,
6567 : struct smbXcli_conn *conn,
6568 : struct smbXcli_session **_session2)
6569 : {
6570 248 : struct smbXcli_session *session2;
6571 248 : NTSTATUS status;
6572 :
6573 2262 : if (!smb2_signing_key_valid(session1->smb2->signing_key)) {
6574 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6575 : }
6576 :
6577 2262 : if (conn == NULL) {
6578 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6579 : }
6580 :
6581 2262 : session2 = talloc_zero(mem_ctx, struct smbXcli_session);
6582 2262 : if (session2 == NULL) {
6583 0 : return NT_STATUS_NO_MEMORY;
6584 : }
6585 2262 : session2->smb2 = talloc_reference(session2, session1->smb2);
6586 2262 : if (session2->smb2 == NULL) {
6587 0 : talloc_free(session2);
6588 0 : return NT_STATUS_NO_MEMORY;
6589 : }
6590 :
6591 2262 : talloc_set_destructor(session2, smbXcli_session_destructor);
6592 2262 : DLIST_ADD_END(conn->sessions, session2);
6593 2262 : session2->conn = conn;
6594 :
6595 2262 : status = smb2_signing_key_sign_create(session2,
6596 2262 : conn->smb2.server.sign_algo,
6597 : NULL, /* no master key */
6598 : NULL, /* derivations */
6599 : &session2->smb2_channel.signing_key);
6600 2262 : if (!NT_STATUS_IS_OK(status)) {
6601 0 : talloc_free(session2);
6602 0 : return NT_STATUS_NO_MEMORY;
6603 : }
6604 :
6605 2262 : memcpy(session2->smb2_channel.preauth_sha512,
6606 2262 : conn->smb2.preauth_sha512,
6607 : sizeof(session2->smb2_channel.preauth_sha512));
6608 :
6609 2262 : *_session2 = session2;
6610 2262 : return NT_STATUS_OK;
6611 : }
6612 :
6613 950 : NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
6614 : const DATA_BLOB _channel_key,
6615 : const struct iovec *recv_iov)
6616 : {
6617 950 : struct smbXcli_conn *conn = session->conn;
6618 18 : uint8_t channel_key[16];
6619 18 : NTSTATUS status;
6620 18 : struct _derivation {
6621 : DATA_BLOB label;
6622 : DATA_BLOB context;
6623 : };
6624 18 : struct {
6625 : struct _derivation signing;
6626 950 : } derivation = {
6627 : .signing.label.length = 0,
6628 : };
6629 :
6630 950 : if (conn == NULL) {
6631 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6632 : }
6633 :
6634 950 : if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6635 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6636 : }
6637 :
6638 950 : if (conn->protocol >= PROTOCOL_SMB3_11) {
6639 18 : struct _derivation *d;
6640 18 : DATA_BLOB p;
6641 :
6642 950 : p = data_blob_const(session->smb2_channel.preauth_sha512,
6643 : sizeof(session->smb2_channel.preauth_sha512));
6644 :
6645 950 : d = &derivation.signing;
6646 950 : d->label = data_blob_string_const_null("SMBSigningKey");
6647 950 : d->context = p;
6648 0 : } else if (conn->protocol >= PROTOCOL_SMB3_00) {
6649 0 : struct _derivation *d;
6650 :
6651 0 : d = &derivation.signing;
6652 0 : d->label = data_blob_string_const_null("SMB2AESCMAC");
6653 0 : d->context = data_blob_string_const_null("SmbSign");
6654 : }
6655 :
6656 950 : ZERO_STRUCT(channel_key);
6657 950 : memcpy(channel_key, _channel_key.data,
6658 950 : MIN(_channel_key.length, sizeof(channel_key)));
6659 :
6660 950 : session->smb2_channel.signing_key->blob =
6661 950 : data_blob_talloc(session->smb2_channel.signing_key,
6662 : channel_key,
6663 : sizeof(channel_key));
6664 950 : if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6665 0 : ZERO_STRUCT(channel_key);
6666 0 : return NT_STATUS_NO_MEMORY;
6667 : }
6668 :
6669 950 : if (conn->protocol >= PROTOCOL_SMB3_00) {
6670 950 : struct _derivation *d = &derivation.signing;
6671 :
6672 968 : status = samba_gnutls_sp800_108_derive_key(
6673 : channel_key,
6674 : sizeof(channel_key),
6675 : NULL,
6676 : 0,
6677 932 : d->label.data,
6678 : d->label.length,
6679 932 : d->context.data,
6680 : d->context.length,
6681 : GNUTLS_MAC_SHA256,
6682 932 : session->smb2_channel.signing_key->blob.data,
6683 950 : session->smb2_channel.signing_key->blob.length);
6684 950 : if (!NT_STATUS_IS_OK(status)) {
6685 0 : return status;
6686 : }
6687 : }
6688 950 : ZERO_STRUCT(channel_key);
6689 :
6690 950 : status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
6691 : recv_iov, 3);
6692 950 : if (!NT_STATUS_IS_OK(status)) {
6693 0 : return status;
6694 : }
6695 :
6696 950 : return NT_STATUS_OK;
6697 : }
6698 :
6699 735 : NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
6700 : {
6701 735 : if (!session->smb2->should_sign) {
6702 : /*
6703 : * We need required signing on the session
6704 : * in order to prevent man in the middle attacks.
6705 : */
6706 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
6707 : }
6708 :
6709 735 : if (session->smb2->should_encrypt) {
6710 140 : return NT_STATUS_OK;
6711 : }
6712 :
6713 595 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6714 2 : return NT_STATUS_NOT_SUPPORTED;
6715 : }
6716 :
6717 593 : if (session->conn->smb2.server.cipher == 0) {
6718 36 : return NT_STATUS_NOT_SUPPORTED;
6719 : }
6720 :
6721 557 : if (!smb2_signing_key_valid(session->smb2->signing_key)) {
6722 0 : return NT_STATUS_NOT_SUPPORTED;
6723 : }
6724 557 : session->smb2->should_encrypt = true;
6725 557 : return NT_STATUS_OK;
6726 : }
6727 :
6728 7841 : uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session)
6729 : {
6730 7841 : if (session->conn->protocol < PROTOCOL_SMB3_00) {
6731 2408 : return 0;
6732 : }
6733 :
6734 5433 : if (!session->smb2->should_encrypt) {
6735 4808 : return 0;
6736 : }
6737 :
6738 5 : return session->conn->smb2.server.cipher;
6739 : }
6740 :
6741 51921 : struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
6742 : {
6743 847 : struct smbXcli_tcon *tcon;
6744 :
6745 51921 : tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
6746 51921 : if (tcon == NULL) {
6747 0 : return NULL;
6748 : }
6749 :
6750 51074 : return tcon;
6751 : }
6752 :
6753 : /*
6754 : * Return a deep structure copy of a struct smbXcli_tcon *
6755 : */
6756 :
6757 4 : struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
6758 : const struct smbXcli_tcon *tcon_in)
6759 : {
6760 0 : struct smbXcli_tcon *tcon;
6761 :
6762 4 : tcon = talloc_memdup(mem_ctx, tcon_in, sizeof(struct smbXcli_tcon));
6763 4 : if (tcon == NULL) {
6764 0 : return NULL;
6765 : }
6766 :
6767 : /* Deal with the SMB1 strings. */
6768 4 : if (tcon_in->smb1.service != NULL) {
6769 0 : tcon->smb1.service = talloc_strdup(tcon, tcon_in->smb1.service);
6770 0 : if (tcon->smb1.service == NULL) {
6771 0 : TALLOC_FREE(tcon);
6772 0 : return NULL;
6773 : }
6774 : }
6775 4 : if (tcon->smb1.fs_type != NULL) {
6776 0 : tcon->smb1.fs_type = talloc_strdup(tcon, tcon_in->smb1.fs_type);
6777 0 : if (tcon->smb1.fs_type == NULL) {
6778 0 : TALLOC_FREE(tcon);
6779 0 : return NULL;
6780 : }
6781 : }
6782 4 : return tcon;
6783 : }
6784 :
6785 82 : void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
6786 : uint32_t fs_attributes)
6787 : {
6788 82 : tcon->fs_attributes = fs_attributes;
6789 82 : }
6790 :
6791 0 : uint32_t smbXcli_tcon_get_fs_attributes(struct smbXcli_tcon *tcon)
6792 : {
6793 0 : return tcon->fs_attributes;
6794 : }
6795 :
6796 1081058 : bool smbXcli_tcon_is_dfs_share(struct smbXcli_tcon *tcon)
6797 : {
6798 1081058 : if (tcon == NULL) {
6799 4 : return false;
6800 : }
6801 :
6802 1081054 : if (tcon->is_smb1) {
6803 935275 : if (tcon->smb1.optional_support & SMB_SHARE_IN_DFS) {
6804 4686 : return true;
6805 : }
6806 :
6807 930589 : return false;
6808 : }
6809 :
6810 145779 : if (tcon->smb2.capabilities & SMB2_SHARE_CAP_DFS) {
6811 35048 : return true;
6812 : }
6813 :
6814 110111 : return false;
6815 : }
6816 :
6817 3239 : uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
6818 : {
6819 3239 : return tcon->smb1.tcon_id;
6820 : }
6821 :
6822 512664 : void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
6823 : {
6824 512664 : tcon->is_smb1 = true;
6825 512664 : tcon->smb1.tcon_id = tcon_id;
6826 512664 : }
6827 :
6828 6953 : bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
6829 : uint16_t tcon_id,
6830 : uint16_t optional_support,
6831 : uint32_t maximal_access,
6832 : uint32_t guest_maximal_access,
6833 : const char *service,
6834 : const char *fs_type)
6835 : {
6836 6953 : tcon->is_smb1 = true;
6837 6953 : tcon->fs_attributes = 0;
6838 6953 : tcon->smb1.tcon_id = tcon_id;
6839 6953 : tcon->smb1.optional_support = optional_support;
6840 6953 : tcon->smb1.maximal_access = maximal_access;
6841 6953 : tcon->smb1.guest_maximal_access = guest_maximal_access;
6842 :
6843 6953 : TALLOC_FREE(tcon->smb1.service);
6844 6953 : tcon->smb1.service = talloc_strdup(tcon, service);
6845 6953 : if (service != NULL && tcon->smb1.service == NULL) {
6846 0 : return false;
6847 : }
6848 :
6849 6953 : TALLOC_FREE(tcon->smb1.fs_type);
6850 6953 : tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
6851 6953 : if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
6852 0 : return false;
6853 : }
6854 :
6855 6953 : return true;
6856 : }
6857 :
6858 18388 : uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
6859 : {
6860 18388 : return tcon->smb2.tcon_id;
6861 : }
6862 :
6863 20 : void smb2cli_tcon_set_id(struct smbXcli_tcon *tcon, uint32_t tcon_id)
6864 : {
6865 20 : tcon->smb2.tcon_id = tcon_id;
6866 20 : }
6867 :
6868 144 : uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
6869 : {
6870 144 : return tcon->smb2.capabilities;
6871 : }
6872 :
6873 8 : uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon)
6874 : {
6875 8 : return tcon->smb2.flags;
6876 : }
6877 :
6878 66306 : void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
6879 : struct smbXcli_session *session,
6880 : uint32_t tcon_id,
6881 : uint8_t type,
6882 : uint32_t flags,
6883 : uint32_t capabilities,
6884 : uint32_t maximal_access)
6885 : {
6886 66306 : tcon->is_smb1 = false;
6887 66306 : tcon->fs_attributes = 0;
6888 66306 : tcon->smb2.tcon_id = tcon_id;
6889 66306 : tcon->smb2.type = type;
6890 66306 : tcon->smb2.flags = flags;
6891 66306 : tcon->smb2.capabilities = capabilities;
6892 66306 : tcon->smb2.maximal_access = maximal_access;
6893 :
6894 66306 : tcon->smb2.should_sign = false;
6895 66306 : tcon->smb2.should_encrypt = false;
6896 :
6897 66306 : if (session == NULL) {
6898 25782 : return;
6899 : }
6900 :
6901 40524 : tcon->smb2.should_sign = session->smb2->should_sign;
6902 40524 : tcon->smb2.should_encrypt = session->smb2->should_encrypt;
6903 :
6904 40524 : if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
6905 222 : tcon->smb2.should_encrypt = true;
6906 : }
6907 : }
6908 :
6909 8598 : void smb2cli_tcon_should_sign(struct smbXcli_tcon *tcon,
6910 : bool should_sign)
6911 : {
6912 8598 : tcon->smb2.should_sign = should_sign;
6913 8598 : }
6914 :
6915 4272 : bool smb2cli_tcon_is_signing_on(struct smbXcli_tcon *tcon)
6916 : {
6917 4272 : if (tcon->smb2.should_encrypt) {
6918 24 : return true;
6919 : }
6920 :
6921 4244 : return tcon->smb2.should_sign;
6922 : }
6923 :
6924 0 : void smb2cli_tcon_should_encrypt(struct smbXcli_tcon *tcon,
6925 : bool should_encrypt)
6926 : {
6927 0 : tcon->smb2.should_encrypt = should_encrypt;
6928 0 : }
6929 :
6930 193 : bool smb2cli_tcon_is_encryption_on(struct smbXcli_tcon *tcon)
6931 : {
6932 193 : return tcon->smb2.should_encrypt;
6933 : }
6934 :
6935 18 : void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid)
6936 : {
6937 18 : conn->smb2.mid = mid;
6938 18 : }
6939 :
6940 6 : uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
6941 : {
6942 6 : return conn->smb2.mid;
6943 : }
6944 :
6945 748207 : NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
6946 : const DATA_BLOB dyn_buffer,
6947 : uint32_t min_offset,
6948 : uint32_t buffer_offset,
6949 : uint32_t buffer_length,
6950 : uint32_t max_length,
6951 : uint32_t *next_offset,
6952 : DATA_BLOB *buffer)
6953 : {
6954 13814 : uint32_t offset;
6955 13814 : bool oob;
6956 :
6957 748207 : *buffer = data_blob_null;
6958 748207 : *next_offset = dyn_offset;
6959 :
6960 748207 : if (buffer_offset == 0) {
6961 : /*
6962 : * If the offset is 0, we better ignore
6963 : * the buffer_length field.
6964 : */
6965 47428 : return NT_STATUS_OK;
6966 : }
6967 :
6968 700779 : if (buffer_length == 0) {
6969 : /*
6970 : * If the length is 0, we better ignore
6971 : * the buffer_offset field.
6972 : */
6973 321326 : return NT_STATUS_OK;
6974 : }
6975 :
6976 379453 : if ((buffer_offset % 8) != 0) {
6977 : /*
6978 : * The offset needs to be 8 byte aligned.
6979 : */
6980 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
6981 : }
6982 :
6983 : /*
6984 : * We used to enforce buffer_offset to be
6985 : * an exact match of the expected minimum,
6986 : * but the NetApp Ontap 7.3.7 SMB server
6987 : * gets the padding wrong and aligns the
6988 : * input_buffer_offset by a value of 8.
6989 : *
6990 : * So we just enforce that the offset is
6991 : * not lower than the expected value.
6992 : */
6993 379453 : SMB_ASSERT(min_offset >= dyn_offset);
6994 379453 : if (buffer_offset < min_offset) {
6995 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
6996 : }
6997 :
6998 : /*
6999 : * Make [input|output]_buffer_offset relative to "dyn_buffer"
7000 : */
7001 379453 : offset = buffer_offset - dyn_offset;
7002 379453 : oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
7003 379453 : if (oob) {
7004 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
7005 : }
7006 :
7007 : /*
7008 : * Give the caller a hint what we consumed,
7009 : * the caller may need to add possible padding.
7010 : */
7011 379453 : *next_offset = buffer_offset + buffer_length;
7012 :
7013 379453 : if (max_length == 0) {
7014 : /*
7015 : * If max_input_length is 0 we ignore the
7016 : * input_buffer_length, because Windows 2008 echos the
7017 : * DCERPC request from the requested input_buffer to
7018 : * the response input_buffer.
7019 : *
7020 : * We just use the same logic also for max_output_length...
7021 : */
7022 0 : buffer_length = 0;
7023 : }
7024 :
7025 379453 : if (buffer_length > max_length) {
7026 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
7027 : }
7028 :
7029 379453 : *buffer = (DATA_BLOB) {
7030 379453 : .data = dyn_buffer.data + offset,
7031 : .length = buffer_length,
7032 : };
7033 379453 : return NT_STATUS_OK;
7034 : }
|