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