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