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