source: vendor/current/libcli/smb/smbXcli_base.c

Last change on this file was 989, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.7

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