]> git.samba.org - obnox/samba/samba-obnox.git/blob - libcli/smb/smbXcli_base.c
libcli/smb: add smb1cli_session_protect_session_key()
[obnox/samba/samba-obnox.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 "../libcli/smb/smb_common.h"
29 #include "../libcli/smb/smb_seal.h"
30 #include "../libcli/smb/smb_signing.h"
31 #include "../libcli/smb/read_smb.h"
32 #include "smbXcli_base.h"
33 #include "librpc/ndr/libndr.h"
34
35 struct smbXcli_conn;
36 struct smbXcli_req;
37 struct smbXcli_session;
38 struct smbXcli_tcon;
39
40 struct smbXcli_conn {
41         int read_fd;
42         int write_fd;
43         struct sockaddr_storage local_ss;
44         struct sockaddr_storage remote_ss;
45         const char *remote_name;
46
47         struct tevent_queue *outgoing;
48         struct tevent_req **pending;
49         struct tevent_req *read_smb_req;
50
51         enum protocol_types protocol;
52         bool allow_signing;
53         bool desire_signing;
54         bool mandatory_signing;
55
56         /*
57          * The incoming dispatch function should return:
58          * - NT_STATUS_RETRY, if more incoming PDUs are expected.
59          * - NT_STATUS_OK, if no more processing is desired, e.g.
60          *                 the dispatch function called
61          *                 tevent_req_done().
62          * - All other return values disconnect the connection.
63          */
64         NTSTATUS (*dispatch_incoming)(struct smbXcli_conn *conn,
65                                       TALLOC_CTX *tmp_mem,
66                                       uint8_t *inbuf);
67
68         struct {
69                 struct {
70                         uint32_t capabilities;
71                         uint32_t max_xmit;
72                 } client;
73
74                 struct {
75                         uint32_t capabilities;
76                         uint32_t max_xmit;
77                         uint16_t max_mux;
78                         uint16_t security_mode;
79                         bool readbraw;
80                         bool writebraw;
81                         bool lockread;
82                         bool writeunlock;
83                         uint32_t session_key;
84                         struct GUID guid;
85                         DATA_BLOB gss_blob;
86                         uint8_t challenge[8];
87                         const char *workgroup;
88                         const char *name;
89                         int time_zone;
90                         NTTIME system_time;
91                 } server;
92
93                 uint32_t capabilities;
94                 uint32_t max_xmit;
95
96                 uint16_t mid;
97
98                 struct smb_signing_state *signing;
99                 struct smb_trans_enc_state *trans_enc;
100
101                 struct tevent_req *read_braw_req;
102         } smb1;
103
104         struct {
105                 struct {
106                         uint32_t capabilities;
107                         uint16_t security_mode;
108                         struct GUID guid;
109                 } client;
110
111                 struct {
112                         uint32_t capabilities;
113                         uint16_t security_mode;
114                         struct GUID guid;
115                         uint32_t max_trans_size;
116                         uint32_t max_read_size;
117                         uint32_t max_write_size;
118                         NTTIME system_time;
119                         NTTIME start_time;
120                         DATA_BLOB gss_blob;
121                 } server;
122
123                 uint64_t mid;
124                 uint16_t cur_credits;
125                 uint16_t max_credits;
126         } smb2;
127
128         struct smbXcli_session *sessions;
129 };
130
131 struct smb2cli_session {
132         uint64_t session_id;
133         uint16_t session_flags;
134         DATA_BLOB application_key;
135         DATA_BLOB signing_key;
136         bool should_sign;
137         bool should_encrypt;
138         DATA_BLOB encryption_key;
139         DATA_BLOB decryption_key;
140         uint64_t nonce_high;
141         uint64_t nonce_low;
142         uint16_t channel_sequence;
143 };
144
145 struct smbXcli_session {
146         struct smbXcli_session *prev, *next;
147         struct smbXcli_conn *conn;
148
149         struct {
150                 uint16_t session_id;
151                 DATA_BLOB application_key;
152                 bool protected_key;
153         } smb1;
154
155         struct smb2cli_session *smb2;
156
157         struct {
158                 DATA_BLOB signing_key;
159         } smb2_channel;
160 };
161
162 struct smbXcli_tcon {
163         struct {
164                 uint16_t tcon_id;
165                 uint16_t optional_support;
166                 uint32_t maximal_access;
167                 uint32_t guest_maximal_access;
168                 char *service;
169                 char *fs_type;
170         } smb1;
171
172         struct {
173                 uint32_t tcon_id;
174                 uint8_t type;
175                 uint32_t flags;
176                 uint32_t capabilities;
177                 uint32_t maximal_access;
178                 bool should_encrypt;
179         } smb2;
180 };
181
182 struct smbXcli_req_state {
183         struct tevent_context *ev;
184         struct smbXcli_conn *conn;
185         struct smbXcli_session *session; /* maybe NULL */
186         struct smbXcli_tcon *tcon; /* maybe NULL */
187
188         uint8_t length_hdr[4];
189
190         bool one_way;
191
192         uint8_t *inbuf;
193
194         struct {
195                 /* Space for the header including the wct */
196                 uint8_t hdr[HDR_VWV];
197
198                 /*
199                  * For normal requests, smb1cli_req_send chooses a mid.
200                  * SecondaryV trans requests need to use the mid of the primary
201                  * request, so we need a place to store it.
202                  * Assume it is set if != 0.
203                  */
204                 uint16_t mid;
205
206                 uint16_t *vwv;
207                 uint8_t bytecount_buf[2];
208
209 #define MAX_SMB_IOV 10
210                 /* length_hdr, hdr, words, byte_count, buffers */
211                 struct iovec iov[1 + 3 + MAX_SMB_IOV];
212                 int iov_count;
213
214                 bool one_way_seqnum;
215                 uint32_t seqnum;
216                 struct tevent_req **chained_requests;
217
218                 uint8_t recv_cmd;
219                 NTSTATUS recv_status;
220                 /* always an array of 3 talloc elements */
221                 struct iovec *recv_iov;
222         } smb1;
223
224         struct {
225                 const uint8_t *fixed;
226                 uint16_t fixed_len;
227                 const uint8_t *dyn;
228                 uint32_t dyn_len;
229
230                 uint8_t transform[SMB2_TF_HDR_SIZE];
231                 uint8_t hdr[SMB2_HDR_BODY];
232                 uint8_t pad[7]; /* padding space for compounding */
233
234                 /*
235                  * always an array of 3 talloc elements
236                  * (without a SMB2_TRANSFORM header!)
237                  *
238                  * HDR, BODY, DYN
239                  */
240                 struct iovec *recv_iov;
241
242                 uint16_t credit_charge;
243
244                 bool should_sign;
245                 bool should_encrypt;
246
247                 bool signing_skipped;
248                 bool notify_async;
249                 bool got_async;
250         } smb2;
251 };
252
253 static int smbXcli_conn_destructor(struct smbXcli_conn *conn)
254 {
255         /*
256          * NT_STATUS_OK, means we do not notify the callers
257          */
258         smbXcli_conn_disconnect(conn, NT_STATUS_OK);
259
260         while (conn->sessions) {
261                 conn->sessions->conn = NULL;
262                 DLIST_REMOVE(conn->sessions, conn->sessions);
263         }
264
265         if (conn->smb1.trans_enc) {
266                 TALLOC_FREE(conn->smb1.trans_enc);
267         }
268
269         return 0;
270 }
271
272 struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
273                                          int fd,
274                                          const char *remote_name,
275                                          enum smb_signing_setting signing_state,
276                                          uint32_t smb1_capabilities,
277                                          struct GUID *client_guid,
278                                          uint32_t smb2_capabilities)
279 {
280         struct smbXcli_conn *conn = NULL;
281         void *ss = NULL;
282         struct sockaddr *sa = NULL;
283         socklen_t sa_length;
284         int ret;
285
286         conn = talloc_zero(mem_ctx, struct smbXcli_conn);
287         if (!conn) {
288                 return NULL;
289         }
290
291         conn->read_fd = fd;
292         conn->write_fd = dup(fd);
293         if (conn->write_fd == -1) {
294                 goto error;
295         }
296
297         conn->remote_name = talloc_strdup(conn, remote_name);
298         if (conn->remote_name == NULL) {
299                 goto error;
300         }
301
302
303         ss = (void *)&conn->local_ss;
304         sa = (struct sockaddr *)ss;
305         sa_length = sizeof(conn->local_ss);
306         ret = getsockname(fd, sa, &sa_length);
307         if (ret == -1) {
308                 goto error;
309         }
310         ss = (void *)&conn->remote_ss;
311         sa = (struct sockaddr *)ss;
312         sa_length = sizeof(conn->remote_ss);
313         ret = getpeername(fd, sa, &sa_length);
314         if (ret == -1) {
315                 goto error;
316         }
317
318         conn->outgoing = tevent_queue_create(conn, "smbXcli_outgoing");
319         if (conn->outgoing == NULL) {
320                 goto error;
321         }
322         conn->pending = NULL;
323
324         conn->protocol = PROTOCOL_NONE;
325
326         switch (signing_state) {
327         case SMB_SIGNING_OFF:
328                 /* never */
329                 conn->allow_signing = false;
330                 conn->desire_signing = false;
331                 conn->mandatory_signing = false;
332                 break;
333         case SMB_SIGNING_DEFAULT:
334         case SMB_SIGNING_IF_REQUIRED:
335                 /* if the server requires it */
336                 conn->allow_signing = true;
337                 conn->desire_signing = false;
338                 conn->mandatory_signing = false;
339                 break;
340         case SMB_SIGNING_REQUIRED:
341                 /* always */
342                 conn->allow_signing = true;
343                 conn->desire_signing = true;
344                 conn->mandatory_signing = true;
345                 break;
346         }
347
348         conn->smb1.client.capabilities = smb1_capabilities;
349         conn->smb1.client.max_xmit = UINT16_MAX;
350
351         conn->smb1.capabilities = conn->smb1.client.capabilities;
352         conn->smb1.max_xmit = 1024;
353
354         conn->smb1.mid = 1;
355
356         /* initialise signing */
357         conn->smb1.signing = smb_signing_init(conn,
358                                               conn->allow_signing,
359                                               conn->desire_signing,
360                                               conn->mandatory_signing);
361         if (!conn->smb1.signing) {
362                 goto error;
363         }
364
365         conn->smb2.client.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
366         if (conn->mandatory_signing) {
367                 conn->smb2.client.security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
368         }
369         if (client_guid) {
370                 conn->smb2.client.guid = *client_guid;
371         }
372         conn->smb2.client.capabilities = smb2_capabilities;
373
374         conn->smb2.cur_credits = 1;
375         conn->smb2.max_credits = 0;
376
377         talloc_set_destructor(conn, smbXcli_conn_destructor);
378         return conn;
379
380  error:
381         if (conn->write_fd != -1) {
382                 close(conn->write_fd);
383         }
384         TALLOC_FREE(conn);
385         return NULL;
386 }
387
388 bool smbXcli_conn_is_connected(struct smbXcli_conn *conn)
389 {
390         if (conn == NULL) {
391                 return false;
392         }
393
394         if (conn->read_fd == -1) {
395                 return false;
396         }
397
398         return true;
399 }
400
401 enum protocol_types smbXcli_conn_protocol(struct smbXcli_conn *conn)
402 {
403         return conn->protocol;
404 }
405
406 bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn)
407 {
408         if (conn->protocol >= PROTOCOL_SMB2_02) {
409                 return true;
410         }
411
412         if (conn->smb1.capabilities & CAP_UNICODE) {
413                 return true;
414         }
415
416         return false;
417 }
418
419 void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options)
420 {
421         set_socket_options(conn->read_fd, options);
422 }
423
424 const struct sockaddr_storage *smbXcli_conn_local_sockaddr(struct smbXcli_conn *conn)
425 {
426         return &conn->local_ss;
427 }
428
429 const struct sockaddr_storage *smbXcli_conn_remote_sockaddr(struct smbXcli_conn *conn)
430 {
431         return &conn->remote_ss;
432 }
433
434 const char *smbXcli_conn_remote_name(struct smbXcli_conn *conn)
435 {
436         return conn->remote_name;
437 }
438
439 uint16_t smbXcli_conn_max_requests(struct smbXcli_conn *conn)
440 {
441         if (conn->protocol >= PROTOCOL_SMB2_02) {
442                 /*
443                  * TODO...
444                  */
445                 return 1;
446         }
447
448         return conn->smb1.server.max_mux;
449 }
450
451 NTTIME smbXcli_conn_server_system_time(struct smbXcli_conn *conn)
452 {
453         if (conn->protocol >= PROTOCOL_SMB2_02) {
454                 return conn->smb2.server.system_time;
455         }
456
457         return conn->smb1.server.system_time;
458 }
459
460 const DATA_BLOB *smbXcli_conn_server_gss_blob(struct smbXcli_conn *conn)
461 {
462         if (conn->protocol >= PROTOCOL_SMB2_02) {
463                 return &conn->smb2.server.gss_blob;
464         }
465
466         return &conn->smb1.server.gss_blob;
467 }
468
469 const struct GUID *smbXcli_conn_server_guid(struct smbXcli_conn *conn)
470 {
471         if (conn->protocol >= PROTOCOL_SMB2_02) {
472                 return &conn->smb2.server.guid;
473         }
474
475         return &conn->smb1.server.guid;
476 }
477
478 struct smbXcli_conn_samba_suicide_state {
479         struct smbXcli_conn *conn;
480         struct iovec iov;
481         uint8_t buf[9];
482 };
483
484 static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq);
485
486 struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx,
487                                                    struct tevent_context *ev,
488                                                    struct smbXcli_conn *conn,
489                                                    uint8_t exitcode)
490 {
491         struct tevent_req *req, *subreq;
492         struct smbXcli_conn_samba_suicide_state *state;
493
494         req = tevent_req_create(mem_ctx, &state,
495                                 struct smbXcli_conn_samba_suicide_state);
496         if (req == NULL) {
497                 return NULL;
498         }
499         state->conn = conn;
500         SIVAL(state->buf, 4, 0x74697865);
501         SCVAL(state->buf, 8, exitcode);
502         _smb_setlen_nbt(state->buf, sizeof(state->buf)-4);
503
504         state->iov.iov_base = state->buf;
505         state->iov.iov_len = sizeof(state->buf);
506
507         subreq = writev_send(state, ev, conn->outgoing, conn->write_fd,
508                              false, &state->iov, 1);
509         if (tevent_req_nomem(subreq, req)) {
510                 return tevent_req_post(req, ev);
511         }
512         tevent_req_set_callback(subreq, smbXcli_conn_samba_suicide_done, req);
513         return req;
514 }
515
516 static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq)
517 {
518         struct tevent_req *req = tevent_req_callback_data(
519                 subreq, struct tevent_req);
520         struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
521                 req, struct smbXcli_conn_samba_suicide_state);
522         ssize_t nwritten;
523         int err;
524
525         nwritten = writev_recv(subreq, &err);
526         TALLOC_FREE(subreq);
527         if (nwritten == -1) {
528                 NTSTATUS status = map_nt_error_from_unix_common(err);
529                 smbXcli_conn_disconnect(state->conn, status);
530                 return;
531         }
532         tevent_req_done(req);
533 }
534
535 NTSTATUS smbXcli_conn_samba_suicide_recv(struct tevent_req *req)
536 {
537         return tevent_req_simple_recv_ntstatus(req);
538 }
539
540 NTSTATUS smbXcli_conn_samba_suicide(struct smbXcli_conn *conn,
541                                     uint8_t exitcode)
542 {
543         TALLOC_CTX *frame = talloc_stackframe();
544         struct tevent_context *ev;
545         struct tevent_req *req;
546         NTSTATUS status = NT_STATUS_NO_MEMORY;
547         bool ok;
548
549         if (smbXcli_conn_has_async_calls(conn)) {
550                 /*
551                  * Can't use sync call while an async call is in flight
552                  */
553                 status = NT_STATUS_INVALID_PARAMETER_MIX;
554                 goto fail;
555         }
556         ev = tevent_context_init(frame);
557         if (ev == NULL) {
558                 goto fail;
559         }
560         req = smbXcli_conn_samba_suicide_send(frame, ev, conn, exitcode);
561         if (req == NULL) {
562                 goto fail;
563         }
564         ok = tevent_req_poll(req, ev);
565         if (!ok) {
566                 status = map_nt_error_from_unix_common(errno);
567                 goto fail;
568         }
569         status = smbXcli_conn_samba_suicide_recv(req);
570  fail:
571         TALLOC_FREE(frame);
572         return status;
573 }
574
575 uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn)
576 {
577         return conn->smb1.capabilities;
578 }
579
580 uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn)
581 {
582         return conn->smb1.max_xmit;
583 }
584
585 uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn)
586 {
587         return conn->smb1.server.session_key;
588 }
589
590 const uint8_t *smb1cli_conn_server_challenge(struct smbXcli_conn *conn)
591 {
592         return conn->smb1.server.challenge;
593 }
594
595 uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn)
596 {
597         return conn->smb1.server.security_mode;
598 }
599
600 bool smb1cli_conn_server_readbraw(struct smbXcli_conn *conn)
601 {
602         return conn->smb1.server.readbraw;
603 }
604
605 bool smb1cli_conn_server_writebraw(struct smbXcli_conn *conn)
606 {
607         return conn->smb1.server.writebraw;
608 }
609
610 bool smb1cli_conn_server_lockread(struct smbXcli_conn *conn)
611 {
612         return conn->smb1.server.lockread;
613 }
614
615 bool smb1cli_conn_server_writeunlock(struct smbXcli_conn *conn)
616 {
617         return conn->smb1.server.writeunlock;
618 }
619
620 int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn)
621 {
622         return conn->smb1.server.time_zone;
623 }
624
625 bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
626                                    const DATA_BLOB user_session_key,
627                                    const DATA_BLOB response)
628 {
629         return smb_signing_activate(conn->smb1.signing,
630                                     user_session_key,
631                                     response);
632 }
633
634 bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
635                                 const uint8_t *buf, uint32_t seqnum)
636 {
637         const uint8_t *hdr = buf + NBT_HDR_SIZE;
638         size_t len = smb_len_nbt(buf);
639
640         return smb_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
641 }
642
643 bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
644 {
645         return smb_signing_is_active(conn->smb1.signing);
646 }
647
648 void smb1cli_conn_set_encryption(struct smbXcli_conn *conn,
649                                  struct smb_trans_enc_state *es)
650 {
651         /* Replace the old state, if any. */
652         if (conn->smb1.trans_enc) {
653                 TALLOC_FREE(conn->smb1.trans_enc);
654         }
655         conn->smb1.trans_enc = es;
656 }
657
658 bool smb1cli_conn_encryption_on(struct smbXcli_conn *conn)
659 {
660         return common_encryption_on(conn->smb1.trans_enc);
661 }
662
663
664 static NTSTATUS smb1cli_pull_raw_error(const uint8_t *hdr)
665 {
666         uint32_t flags2 = SVAL(hdr, HDR_FLG2);
667         NTSTATUS status = NT_STATUS(IVAL(hdr, HDR_RCLS));
668
669         if (NT_STATUS_IS_OK(status)) {
670                 return NT_STATUS_OK;
671         }
672
673         if (flags2 & FLAGS2_32_BIT_ERROR_CODES) {
674                 return status;
675         }
676
677         return NT_STATUS_DOS(CVAL(hdr, HDR_RCLS), SVAL(hdr, HDR_ERR));
678 }
679
680 /**
681  * Is the SMB command able to hold an AND_X successor
682  * @param[in] cmd       The SMB command in question
683  * @retval Can we add a chained request after "cmd"?
684  */
685 bool smb1cli_is_andx_req(uint8_t cmd)
686 {
687         switch (cmd) {
688         case SMBtconX:
689         case SMBlockingX:
690         case SMBopenX:
691         case SMBreadX:
692         case SMBwriteX:
693         case SMBsesssetupX:
694         case SMBulogoffX:
695         case SMBntcreateX:
696                 return true;
697                 break;
698         default:
699                 break;
700         }
701
702         return false;
703 }
704
705 static uint16_t smb1cli_alloc_mid(struct smbXcli_conn *conn)
706 {
707         size_t num_pending = talloc_array_length(conn->pending);
708         uint16_t result;
709
710         while (true) {
711                 size_t i;
712
713                 result = conn->smb1.mid++;
714                 if ((result == 0) || (result == 0xffff)) {
715                         continue;
716                 }
717
718                 for (i=0; i<num_pending; i++) {
719                         if (result == smb1cli_req_mid(conn->pending[i])) {
720                                 break;
721                         }
722                 }
723
724                 if (i == num_pending) {
725                         return result;
726                 }
727         }
728 }
729
730 void smbXcli_req_unset_pending(struct tevent_req *req)
731 {
732         struct smbXcli_req_state *state =
733                 tevent_req_data(req,
734                 struct smbXcli_req_state);
735         struct smbXcli_conn *conn = state->conn;
736         size_t num_pending = talloc_array_length(conn->pending);
737         size_t i;
738
739         if (state->smb1.mid != 0) {
740                 /*
741                  * This is a [nt]trans[2] request which waits
742                  * for more than one reply.
743                  */
744                 return;
745         }
746
747         talloc_set_destructor(req, NULL);
748
749         if (num_pending == 1) {
750                 /*
751                  * The pending read_smb tevent_req is a child of
752                  * conn->pending. So if nothing is pending anymore, we need to
753                  * delete the socket read fde.
754                  */
755                 TALLOC_FREE(conn->pending);
756                 conn->read_smb_req = NULL;
757                 return;
758         }
759
760         for (i=0; i<num_pending; i++) {
761                 if (req == conn->pending[i]) {
762                         break;
763                 }
764         }
765         if (i == num_pending) {
766                 /*
767                  * Something's seriously broken. Just returning here is the
768                  * right thing nevertheless, the point of this routine is to
769                  * remove ourselves from conn->pending.
770                  */
771                 return;
772         }
773
774         /*
775          * Remove ourselves from the conn->pending array
776          */
777         for (; i < (num_pending - 1); i++) {
778                 conn->pending[i] = conn->pending[i+1];
779         }
780
781         /*
782          * No NULL check here, we're shrinking by sizeof(void *), and
783          * talloc_realloc just adjusts the size for this.
784          */
785         conn->pending = talloc_realloc(NULL, conn->pending, struct tevent_req *,
786                                        num_pending - 1);
787         return;
788 }
789
790 static int smbXcli_req_destructor(struct tevent_req *req)
791 {
792         struct smbXcli_req_state *state =
793                 tevent_req_data(req,
794                 struct smbXcli_req_state);
795
796         /*
797          * Make sure we really remove it from
798          * the pending array on destruction.
799          */
800         state->smb1.mid = 0;
801         smbXcli_req_unset_pending(req);
802         return 0;
803 }
804
805 static bool smb1cli_req_cancel(struct tevent_req *req);
806 static bool smb2cli_req_cancel(struct tevent_req *req);
807
808 static bool smbXcli_req_cancel(struct tevent_req *req)
809 {
810         struct smbXcli_req_state *state =
811                 tevent_req_data(req,
812                 struct smbXcli_req_state);
813
814         if (!smbXcli_conn_is_connected(state->conn)) {
815                 return false;
816         }
817
818         if (state->conn->protocol == PROTOCOL_NONE) {
819                 return false;
820         }
821
822         if (state->conn->protocol >= PROTOCOL_SMB2_02) {
823                 return smb2cli_req_cancel(req);
824         }
825
826         return smb1cli_req_cancel(req);
827 }
828
829 static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
830
831 bool smbXcli_req_set_pending(struct tevent_req *req)
832 {
833         struct smbXcli_req_state *state =
834                 tevent_req_data(req,
835                 struct smbXcli_req_state);
836         struct smbXcli_conn *conn;
837         struct tevent_req **pending;
838         size_t num_pending;
839
840         conn = state->conn;
841
842         if (!smbXcli_conn_is_connected(conn)) {
843                 return false;
844         }
845
846         num_pending = talloc_array_length(conn->pending);
847
848         pending = talloc_realloc(conn, conn->pending, struct tevent_req *,
849                                  num_pending+1);
850         if (pending == NULL) {
851                 return false;
852         }
853         pending[num_pending] = req;
854         conn->pending = pending;
855         talloc_set_destructor(req, smbXcli_req_destructor);
856         tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
857
858         if (!smbXcli_conn_receive_next(conn)) {
859                 /*
860                  * the caller should notify the current request
861                  *
862                  * And all other pending requests get notified
863                  * by smbXcli_conn_disconnect().
864                  */
865                 smbXcli_req_unset_pending(req);
866                 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
867                 return false;
868         }
869
870         return true;
871 }
872
873 static void smbXcli_conn_received(struct tevent_req *subreq);
874
875 static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
876 {
877         size_t num_pending = talloc_array_length(conn->pending);
878         struct tevent_req *req;
879         struct smbXcli_req_state *state;
880
881         if (conn->read_smb_req != NULL) {
882                 return true;
883         }
884
885         if (num_pending == 0) {
886                 if (conn->smb2.mid < UINT64_MAX) {
887                         /* no more pending requests, so we are done for now */
888                         return true;
889                 }
890
891                 /*
892                  * If there are no more SMB2 requests possible,
893                  * because we are out of message ids,
894                  * we need to disconnect.
895                  */
896                 smbXcli_conn_disconnect(conn, NT_STATUS_CONNECTION_ABORTED);
897                 return true;
898         }
899
900         req = conn->pending[0];
901         state = tevent_req_data(req, struct smbXcli_req_state);
902
903         /*
904          * We're the first ones, add the read_smb request that waits for the
905          * answer from the server
906          */
907         conn->read_smb_req = read_smb_send(conn->pending,
908                                            state->ev,
909                                            conn->read_fd);
910         if (conn->read_smb_req == NULL) {
911                 return false;
912         }
913         tevent_req_set_callback(conn->read_smb_req, smbXcli_conn_received, conn);
914         return true;
915 }
916
917 void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
918 {
919         struct smbXcli_session *session;
920
921         tevent_queue_stop(conn->outgoing);
922
923         if (conn->read_fd != -1) {
924                 close(conn->read_fd);
925         }
926         if (conn->write_fd != -1) {
927                 close(conn->write_fd);
928         }
929         conn->read_fd = -1;
930         conn->write_fd = -1;
931
932         session = conn->sessions;
933         if (talloc_array_length(conn->pending) == 0) {
934                 /*
935                  * if we do not have pending requests
936                  * there is no need to update the channel_sequence
937                  */
938                 session = NULL;
939         }
940         for (; session; session = session->next) {
941                 smb2cli_session_increment_channel_sequence(session);
942         }
943
944         /*
945          * Cancel all pending requests. We do not do a for-loop walking
946          * conn->pending because that array changes in
947          * smbXcli_req_unset_pending.
948          */
949         while (talloc_array_length(conn->pending) > 0) {
950                 struct tevent_req *req;
951                 struct smbXcli_req_state *state;
952                 struct tevent_req **chain;
953                 size_t num_chained;
954                 size_t i;
955
956                 req = conn->pending[0];
957                 state = tevent_req_data(req, struct smbXcli_req_state);
958
959                 if (state->smb1.chained_requests == NULL) {
960                         /*
961                          * We're dead. No point waiting for trans2
962                          * replies.
963                          */
964                         state->smb1.mid = 0;
965
966                         smbXcli_req_unset_pending(req);
967
968                         if (NT_STATUS_IS_OK(status)) {
969                                 /* do not notify the callers */
970                                 continue;
971                         }
972
973                         /*
974                          * we need to defer the callback, because we may notify
975                          * more then one caller.
976                          */
977                         tevent_req_defer_callback(req, state->ev);
978                         tevent_req_nterror(req, status);
979                         continue;
980                 }
981
982                 chain = talloc_move(conn, &state->smb1.chained_requests);
983                 num_chained = talloc_array_length(chain);
984
985                 for (i=0; i<num_chained; i++) {
986                         req = chain[i];
987                         state = tevent_req_data(req, struct smbXcli_req_state);
988
989                         /*
990                          * We're dead. No point waiting for trans2
991                          * replies.
992                          */
993                         state->smb1.mid = 0;
994
995                         smbXcli_req_unset_pending(req);
996
997                         if (NT_STATUS_IS_OK(status)) {
998                                 /* do not notify the callers */
999                                 continue;
1000                         }
1001
1002                         /*
1003                          * we need to defer the callback, because we may notify
1004                          * more than one caller.
1005                          */
1006                         tevent_req_defer_callback(req, state->ev);
1007                         tevent_req_nterror(req, status);
1008                 }
1009                 TALLOC_FREE(chain);
1010         }
1011 }
1012
1013 /*
1014  * Fetch a smb request's mid. Only valid after the request has been sent by
1015  * smb1cli_req_send().
1016  */
1017 uint16_t smb1cli_req_mid(struct tevent_req *req)
1018 {
1019         struct smbXcli_req_state *state =
1020                 tevent_req_data(req,
1021                 struct smbXcli_req_state);
1022
1023         if (state->smb1.mid != 0) {
1024                 return state->smb1.mid;
1025         }
1026
1027         return SVAL(state->smb1.hdr, HDR_MID);
1028 }
1029
1030 void smb1cli_req_set_mid(struct tevent_req *req, uint16_t mid)
1031 {
1032         struct smbXcli_req_state *state =
1033                 tevent_req_data(req,
1034                 struct smbXcli_req_state);
1035
1036         state->smb1.mid = mid;
1037 }
1038
1039 uint32_t smb1cli_req_seqnum(struct tevent_req *req)
1040 {
1041         struct smbXcli_req_state *state =
1042                 tevent_req_data(req,
1043                 struct smbXcli_req_state);
1044
1045         return state->smb1.seqnum;
1046 }
1047
1048 void smb1cli_req_set_seqnum(struct tevent_req *req, uint32_t seqnum)
1049 {
1050         struct smbXcli_req_state *state =
1051                 tevent_req_data(req,
1052                 struct smbXcli_req_state);
1053
1054         state->smb1.seqnum = seqnum;
1055 }
1056
1057 static size_t smbXcli_iov_len(const struct iovec *iov, int count)
1058 {
1059         size_t result = 0;
1060         int i;
1061         for (i=0; i<count; i++) {
1062                 result += iov[i].iov_len;
1063         }
1064         return result;
1065 }
1066
1067 static uint8_t *smbXcli_iov_concat(TALLOC_CTX *mem_ctx,
1068                                    const struct iovec *iov,
1069                                    int count)
1070 {
1071         size_t len = smbXcli_iov_len(iov, count);
1072         size_t copied;
1073         uint8_t *buf;
1074         int i;
1075
1076         buf = talloc_array(mem_ctx, uint8_t, len);
1077         if (buf == NULL) {
1078                 return NULL;
1079         }
1080         copied = 0;
1081         for (i=0; i<count; i++) {
1082                 memcpy(buf+copied, iov[i].iov_base, iov[i].iov_len);
1083                 copied += iov[i].iov_len;
1084         }
1085         return buf;
1086 }
1087
1088 static void smb1cli_req_flags(enum protocol_types protocol,
1089                               uint32_t smb1_capabilities,
1090                               uint8_t smb_command,
1091                               uint8_t additional_flags,
1092                               uint8_t clear_flags,
1093                               uint8_t *_flags,
1094                               uint16_t additional_flags2,
1095                               uint16_t clear_flags2,
1096                               uint16_t *_flags2)
1097 {
1098         uint8_t flags = 0;
1099         uint16_t flags2 = 0;
1100
1101         if (protocol >= PROTOCOL_LANMAN1) {
1102                 flags |= FLAG_CASELESS_PATHNAMES;
1103                 flags |= FLAG_CANONICAL_PATHNAMES;
1104         }
1105
1106         if (protocol >= PROTOCOL_LANMAN2) {
1107                 flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
1108                 flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
1109         }
1110
1111         if (protocol >= PROTOCOL_NT1) {
1112                 flags2 |= FLAGS2_IS_LONG_NAME;
1113
1114                 if (smb1_capabilities & CAP_UNICODE) {
1115                         flags2 |= FLAGS2_UNICODE_STRINGS;
1116                 }
1117                 if (smb1_capabilities & CAP_STATUS32) {
1118                         flags2 |= FLAGS2_32_BIT_ERROR_CODES;
1119                 }
1120                 if (smb1_capabilities & CAP_EXTENDED_SECURITY) {
1121                         flags2 |= FLAGS2_EXTENDED_SECURITY;
1122                 }
1123         }
1124
1125         flags |= additional_flags;
1126         flags &= ~clear_flags;
1127         flags2 |= additional_flags2;
1128         flags2 &= ~clear_flags2;
1129
1130         *_flags = flags;
1131         *_flags2 = flags2;
1132 }
1133
1134 static void smb1cli_req_cancel_done(struct tevent_req *subreq);
1135
1136 static bool smb1cli_req_cancel(struct tevent_req *req)
1137 {
1138         struct smbXcli_req_state *state =
1139                 tevent_req_data(req,
1140                 struct smbXcli_req_state);
1141         uint8_t flags;
1142         uint16_t flags2;
1143         uint32_t pid;
1144         uint16_t mid;
1145         struct tevent_req *subreq;
1146         NTSTATUS status;
1147
1148         flags = CVAL(state->smb1.hdr, HDR_FLG);
1149         flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
1150         pid  = SVAL(state->smb1.hdr, HDR_PID);
1151         pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
1152         mid = SVAL(state->smb1.hdr, HDR_MID);
1153
1154         subreq = smb1cli_req_create(state, state->ev,
1155                                     state->conn,
1156                                     SMBntcancel,
1157                                     flags, 0,
1158                                     flags2, 0,
1159                                     0, /* timeout */
1160                                     pid,
1161                                     state->tcon,
1162                                     state->session,
1163                                     0, NULL, /* vwv */
1164                                     0, NULL); /* bytes */
1165         if (subreq == NULL) {
1166                 return false;
1167         }
1168         smb1cli_req_set_mid(subreq, mid);
1169
1170         status = smb1cli_req_chain_submit(&subreq, 1);
1171         if (!NT_STATUS_IS_OK(status)) {
1172                 TALLOC_FREE(subreq);
1173                 return false;
1174         }
1175         smb1cli_req_set_mid(subreq, 0);
1176
1177         tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
1178
1179         return true;
1180 }
1181
1182 static void smb1cli_req_cancel_done(struct tevent_req *subreq)
1183 {
1184         /* we do not care about the result */
1185         TALLOC_FREE(subreq);
1186 }
1187
1188 struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
1189                                       struct tevent_context *ev,
1190                                       struct smbXcli_conn *conn,
1191                                       uint8_t smb_command,
1192                                       uint8_t additional_flags,
1193                                       uint8_t clear_flags,
1194                                       uint16_t additional_flags2,
1195                                       uint16_t clear_flags2,
1196                                       uint32_t timeout_msec,
1197                                       uint32_t pid,
1198                                       struct smbXcli_tcon *tcon,
1199                                       struct smbXcli_session *session,
1200                                       uint8_t wct, uint16_t *vwv,
1201                                       int iov_count,
1202                                       struct iovec *bytes_iov)
1203 {
1204         struct tevent_req *req;
1205         struct smbXcli_req_state *state;
1206         uint8_t flags = 0;
1207         uint16_t flags2 = 0;
1208         uint16_t uid = 0;
1209         uint16_t tid = 0;
1210
1211         if (iov_count > MAX_SMB_IOV) {
1212                 /*
1213                  * Should not happen :-)
1214                  */
1215                 return NULL;
1216         }
1217
1218         req = tevent_req_create(mem_ctx, &state,
1219                                 struct smbXcli_req_state);
1220         if (req == NULL) {
1221                 return NULL;
1222         }
1223         state->ev = ev;
1224         state->conn = conn;
1225         state->session = session;
1226         state->tcon = tcon;
1227
1228         if (session) {
1229                 uid = session->smb1.session_id;
1230         }
1231
1232         if (tcon) {
1233                 tid = tcon->smb1.tcon_id;
1234         }
1235
1236         state->smb1.recv_cmd = 0xFF;
1237         state->smb1.recv_status = NT_STATUS_INTERNAL_ERROR;
1238         state->smb1.recv_iov = talloc_zero_array(state, struct iovec, 3);
1239         if (state->smb1.recv_iov == NULL) {
1240                 TALLOC_FREE(req);
1241                 return NULL;
1242         }
1243
1244         smb1cli_req_flags(conn->protocol,
1245                           conn->smb1.capabilities,
1246                           smb_command,
1247                           additional_flags,
1248                           clear_flags,
1249                           &flags,
1250                           additional_flags2,
1251                           clear_flags2,
1252                           &flags2);
1253
1254         SIVAL(state->smb1.hdr, 0,           SMB_MAGIC);
1255         SCVAL(state->smb1.hdr, HDR_COM,     smb_command);
1256         SIVAL(state->smb1.hdr, HDR_RCLS,    NT_STATUS_V(NT_STATUS_OK));
1257         SCVAL(state->smb1.hdr, HDR_FLG,     flags);
1258         SSVAL(state->smb1.hdr, HDR_FLG2,    flags2);
1259         SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);
1260         SSVAL(state->smb1.hdr, HDR_TID,     tid);
1261         SSVAL(state->smb1.hdr, HDR_PID,     pid);
1262         SSVAL(state->smb1.hdr, HDR_UID,     uid);
1263         SSVAL(state->smb1.hdr, HDR_MID,     0); /* this comes later */
1264         SCVAL(state->smb1.hdr, HDR_WCT,     wct);
1265
1266         state->smb1.vwv = vwv;
1267
1268         SSVAL(state->smb1.bytecount_buf, 0, smbXcli_iov_len(bytes_iov, iov_count));
1269
1270         state->smb1.iov[0].iov_base = (void *)state->length_hdr;
1271         state->smb1.iov[0].iov_len  = sizeof(state->length_hdr);
1272         state->smb1.iov[1].iov_base = (void *)state->smb1.hdr;
1273         state->smb1.iov[1].iov_len  = sizeof(state->smb1.hdr);
1274         state->smb1.iov[2].iov_base = (void *)state->smb1.vwv;
1275         state->smb1.iov[2].iov_len  = wct * sizeof(uint16_t);
1276         state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;
1277         state->smb1.iov[3].iov_len  = sizeof(uint16_t);
1278
1279         if (iov_count != 0) {
1280                 memcpy(&state->smb1.iov[4], bytes_iov,
1281                        iov_count * sizeof(*bytes_iov));
1282         }
1283         state->smb1.iov_count = iov_count + 4;
1284
1285         if (timeout_msec > 0) {
1286                 struct timeval endtime;
1287
1288                 endtime = timeval_current_ofs_msec(timeout_msec);
1289                 if (!tevent_req_set_endtime(req, ev, endtime)) {
1290                         return req;
1291                 }
1292         }
1293
1294         switch (smb_command) {
1295         case SMBtranss:
1296         case SMBtranss2:
1297         case SMBnttranss:
1298                 state->one_way = true;
1299                 break;
1300         case SMBntcancel:
1301                 state->one_way = true;
1302                 state->smb1.one_way_seqnum = true;
1303                 break;
1304         case SMBlockingX:
1305                 if ((wct == 8) &&
1306                     (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
1307                         state->one_way = true;
1308                 }
1309                 break;
1310         }
1311
1312         return req;
1313 }
1314
1315 static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
1316                                    struct iovec *iov, int iov_count,
1317                                    uint32_t *seqnum,
1318                                    bool one_way_seqnum)
1319 {
1320         TALLOC_CTX *frame = NULL;
1321         uint8_t *buf;
1322
1323         /*
1324          * Obvious optimization: Make cli_calculate_sign_mac work with struct
1325          * iovec directly. MD5Update would do that just fine.
1326          */
1327
1328         if (iov_count < 4) {
1329                 return NT_STATUS_INVALID_PARAMETER_MIX;
1330         }
1331         if (iov[0].iov_len != NBT_HDR_SIZE) {
1332                 return NT_STATUS_INVALID_PARAMETER_MIX;
1333         }
1334         if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1335                 return NT_STATUS_INVALID_PARAMETER_MIX;
1336         }
1337         if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1338                 return NT_STATUS_INVALID_PARAMETER_MIX;
1339         }
1340         if (iov[3].iov_len != sizeof(uint16_t)) {
1341                 return NT_STATUS_INVALID_PARAMETER_MIX;
1342         }
1343
1344         frame = talloc_stackframe();
1345
1346         buf = smbXcli_iov_concat(frame, &iov[1], iov_count - 1);
1347         if (buf == NULL) {
1348                 return NT_STATUS_NO_MEMORY;
1349         }
1350
1351         *seqnum = smb_signing_next_seqnum(conn->smb1.signing,
1352                                           one_way_seqnum);
1353         smb_signing_sign_pdu(conn->smb1.signing,
1354                              buf, talloc_get_size(buf),
1355                              *seqnum);
1356         memcpy(iov[1].iov_base, buf, iov[1].iov_len);
1357
1358         TALLOC_FREE(frame);
1359         return NT_STATUS_OK;
1360 }
1361
1362 static void smb1cli_req_writev_done(struct tevent_req *subreq);
1363 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1364                                                TALLOC_CTX *tmp_mem,
1365                                                uint8_t *inbuf);
1366
1367 static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
1368                                           struct smbXcli_req_state *state,
1369                                           struct iovec *iov, int iov_count)
1370 {
1371         struct tevent_req *subreq;
1372         NTSTATUS status;
1373         uint8_t cmd;
1374         uint16_t mid;
1375
1376         if (!smbXcli_conn_is_connected(state->conn)) {
1377                 return NT_STATUS_CONNECTION_DISCONNECTED;
1378         }
1379
1380         if (state->conn->protocol > PROTOCOL_NT1) {
1381                 return NT_STATUS_REVISION_MISMATCH;
1382         }
1383
1384         if (iov_count < 4) {
1385                 return NT_STATUS_INVALID_PARAMETER_MIX;
1386         }
1387         if (iov[0].iov_len != NBT_HDR_SIZE) {
1388                 return NT_STATUS_INVALID_PARAMETER_MIX;
1389         }
1390         if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1391                 return NT_STATUS_INVALID_PARAMETER_MIX;
1392         }
1393         if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1394                 return NT_STATUS_INVALID_PARAMETER_MIX;
1395         }
1396         if (iov[3].iov_len != sizeof(uint16_t)) {
1397                 return NT_STATUS_INVALID_PARAMETER_MIX;
1398         }
1399
1400         cmd = CVAL(iov[1].iov_base, HDR_COM);
1401         if (cmd == SMBreadBraw) {
1402                 if (smbXcli_conn_has_async_calls(state->conn)) {
1403                         return NT_STATUS_INVALID_PARAMETER_MIX;
1404                 }
1405                 state->conn->smb1.read_braw_req = req;
1406         }
1407
1408         if (state->smb1.mid != 0) {
1409                 mid = state->smb1.mid;
1410         } else {
1411                 mid = smb1cli_alloc_mid(state->conn);
1412         }
1413         SSVAL(iov[1].iov_base, HDR_MID, mid);
1414
1415         _smb_setlen_nbt(iov[0].iov_base, smbXcli_iov_len(&iov[1], iov_count-1));
1416
1417         status = smb1cli_conn_signv(state->conn, iov, iov_count,
1418                                     &state->smb1.seqnum,
1419                                     state->smb1.one_way_seqnum);
1420
1421         if (!NT_STATUS_IS_OK(status)) {
1422                 return status;
1423         }
1424
1425         /*
1426          * If we supported multiple encrytion contexts
1427          * here we'd look up based on tid.
1428          */
1429         if (common_encryption_on(state->conn->smb1.trans_enc)) {
1430                 char *buf, *enc_buf;
1431
1432                 buf = (char *)smbXcli_iov_concat(talloc_tos(), iov, iov_count);
1433                 if (buf == NULL) {
1434                         return NT_STATUS_NO_MEMORY;
1435                 }
1436                 status = common_encrypt_buffer(state->conn->smb1.trans_enc,
1437                                                (char *)buf, &enc_buf);
1438                 TALLOC_FREE(buf);
1439                 if (!NT_STATUS_IS_OK(status)) {
1440                         DEBUG(0, ("Error in encrypting client message: %s\n",
1441                                   nt_errstr(status)));
1442                         return status;
1443                 }
1444                 buf = (char *)talloc_memdup(state, enc_buf,
1445                                             smb_len_nbt(enc_buf)+4);
1446                 SAFE_FREE(enc_buf);
1447                 if (buf == NULL) {
1448                         return NT_STATUS_NO_MEMORY;
1449                 }
1450                 iov[0].iov_base = (void *)buf;
1451                 iov[0].iov_len = talloc_get_size(buf);
1452                 iov_count = 1;
1453         }
1454
1455         if (state->conn->dispatch_incoming == NULL) {
1456                 state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
1457         }
1458
1459         tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1460
1461         subreq = writev_send(state, state->ev, state->conn->outgoing,
1462                              state->conn->write_fd, false, iov, iov_count);
1463         if (subreq == NULL) {
1464                 return NT_STATUS_NO_MEMORY;
1465         }
1466         tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
1467         return NT_STATUS_OK;
1468 }
1469
1470 struct tevent_req *smb1cli_req_send(TALLOC_CTX *mem_ctx,
1471                                     struct tevent_context *ev,
1472                                     struct smbXcli_conn *conn,
1473                                     uint8_t smb_command,
1474                                     uint8_t additional_flags,
1475                                     uint8_t clear_flags,
1476                                     uint16_t additional_flags2,
1477                                     uint16_t clear_flags2,
1478                                     uint32_t timeout_msec,
1479                                     uint32_t pid,
1480                                     struct smbXcli_tcon *tcon,
1481                                     struct smbXcli_session *session,
1482                                     uint8_t wct, uint16_t *vwv,
1483                                     uint32_t num_bytes,
1484                                     const uint8_t *bytes)
1485 {
1486         struct tevent_req *req;
1487         struct iovec iov;
1488         NTSTATUS status;
1489
1490         iov.iov_base = discard_const_p(void, bytes);
1491         iov.iov_len = num_bytes;
1492
1493         req = smb1cli_req_create(mem_ctx, ev, conn, smb_command,
1494                                  additional_flags, clear_flags,
1495                                  additional_flags2, clear_flags2,
1496                                  timeout_msec,
1497                                  pid, tcon, session,
1498                                  wct, vwv, 1, &iov);
1499         if (req == NULL) {
1500                 return NULL;
1501         }
1502         if (!tevent_req_is_in_progress(req)) {
1503                 return tevent_req_post(req, ev);
1504         }
1505         status = smb1cli_req_chain_submit(&req, 1);
1506         if (tevent_req_nterror(req, status)) {
1507                 return tevent_req_post(req, ev);
1508         }
1509         return req;
1510 }
1511
1512 static void smb1cli_req_writev_done(struct tevent_req *subreq)
1513 {
1514         struct tevent_req *req =
1515                 tevent_req_callback_data(subreq,
1516                 struct tevent_req);
1517         struct smbXcli_req_state *state =
1518                 tevent_req_data(req,
1519                 struct smbXcli_req_state);
1520         ssize_t nwritten;
1521         int err;
1522
1523         nwritten = writev_recv(subreq, &err);
1524         TALLOC_FREE(subreq);
1525         if (nwritten == -1) {
1526                 NTSTATUS status = map_nt_error_from_unix_common(err);
1527                 smbXcli_conn_disconnect(state->conn, status);
1528                 return;
1529         }
1530
1531         if (state->one_way) {
1532                 state->inbuf = NULL;
1533                 tevent_req_done(req);
1534                 return;
1535         }
1536
1537         if (!smbXcli_req_set_pending(req)) {
1538                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1539                 return;
1540         }
1541 }
1542
1543 static void smbXcli_conn_received(struct tevent_req *subreq)
1544 {
1545         struct smbXcli_conn *conn =
1546                 tevent_req_callback_data(subreq,
1547                 struct smbXcli_conn);
1548         TALLOC_CTX *frame = talloc_stackframe();
1549         NTSTATUS status;
1550         uint8_t *inbuf;
1551         ssize_t received;
1552         int err;
1553
1554         if (subreq != conn->read_smb_req) {
1555                 DEBUG(1, ("Internal error: cli_smb_received called with "
1556                           "unexpected subreq\n"));
1557                 status = NT_STATUS_INTERNAL_ERROR;
1558                 smbXcli_conn_disconnect(conn, status);
1559                 TALLOC_FREE(frame);
1560                 return;
1561         }
1562         conn->read_smb_req = NULL;
1563
1564         received = read_smb_recv(subreq, frame, &inbuf, &err);
1565         TALLOC_FREE(subreq);
1566         if (received == -1) {
1567                 status = map_nt_error_from_unix_common(err);
1568                 smbXcli_conn_disconnect(conn, status);
1569                 TALLOC_FREE(frame);
1570                 return;
1571         }
1572
1573         status = conn->dispatch_incoming(conn, frame, inbuf);
1574         TALLOC_FREE(frame);
1575         if (NT_STATUS_IS_OK(status)) {
1576                 /*
1577                  * We should not do any more processing
1578                  * as the dispatch function called
1579                  * tevent_req_done().
1580                  */
1581                 return;
1582         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1583                 /*
1584                  * We got an error, so notify all pending requests
1585                  */
1586                 smbXcli_conn_disconnect(conn, status);
1587                 return;
1588         }
1589
1590         /*
1591          * We got NT_STATUS_RETRY, so we may ask for a
1592          * next incoming pdu.
1593          */
1594         if (!smbXcli_conn_receive_next(conn)) {
1595                 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1596         }
1597 }
1598
1599 static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
1600                                           struct iovec **piov, int *pnum_iov)
1601 {
1602         struct iovec *iov;
1603         int num_iov;
1604         size_t buflen;
1605         size_t taken;
1606         size_t remaining;
1607         uint8_t *hdr;
1608         uint8_t cmd;
1609         uint32_t wct_ofs;
1610
1611         buflen = smb_len_nbt(buf);
1612         taken = 0;
1613
1614         hdr = buf + NBT_HDR_SIZE;
1615
1616         if (buflen < MIN_SMB_SIZE) {
1617                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1618         }
1619
1620         /*
1621          * This returns iovec elements in the following order:
1622          *
1623          * - SMB header
1624          *
1625          * - Parameter Block
1626          * - Data Block
1627          *
1628          * - Parameter Block
1629          * - Data Block
1630          *
1631          * - Parameter Block
1632          * - Data Block
1633          */
1634         num_iov = 1;
1635
1636         iov = talloc_array(mem_ctx, struct iovec, num_iov);
1637         if (iov == NULL) {
1638                 return NT_STATUS_NO_MEMORY;
1639         }
1640         iov[0].iov_base = hdr;
1641         iov[0].iov_len = HDR_WCT;
1642         taken += HDR_WCT;
1643
1644         cmd = CVAL(hdr, HDR_COM);
1645         wct_ofs = HDR_WCT;
1646
1647         while (true) {
1648                 size_t len = buflen - taken;
1649                 struct iovec *cur;
1650                 struct iovec *iov_tmp;
1651                 uint8_t wct;
1652                 uint32_t bcc_ofs;
1653                 uint16_t bcc;
1654                 size_t needed;
1655
1656                 /*
1657                  * we need at least WCT and BCC
1658                  */
1659                 needed = sizeof(uint8_t) + sizeof(uint16_t);
1660                 if (len < needed) {
1661                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1662                                    __location__, (int)len, (int)needed));
1663                         goto inval;
1664                 }
1665
1666                 /*
1667                  * Now we check if the specified words are there
1668                  */
1669                 wct = CVAL(hdr, wct_ofs);
1670                 needed += wct * sizeof(uint16_t);
1671                 if (len < needed) {
1672                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1673                                    __location__, (int)len, (int)needed));
1674                         goto inval;
1675                 }
1676
1677                 /*
1678                  * Now we check if the specified bytes are there
1679                  */
1680                 bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
1681                 bcc = SVAL(hdr, bcc_ofs);
1682                 needed += bcc * sizeof(uint8_t);
1683                 if (len < needed) {
1684                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1685                                    __location__, (int)len, (int)needed));
1686                         goto inval;
1687                 }
1688
1689                 /*
1690                  * we allocate 2 iovec structures for words and bytes
1691                  */
1692                 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
1693                                          num_iov + 2);
1694                 if (iov_tmp == NULL) {
1695                         TALLOC_FREE(iov);
1696                         return NT_STATUS_NO_MEMORY;
1697                 }
1698                 iov = iov_tmp;
1699                 cur = &iov[num_iov];
1700                 num_iov += 2;
1701
1702                 cur[0].iov_len = wct * sizeof(uint16_t);
1703                 cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
1704                 cur[1].iov_len = bcc * sizeof(uint8_t);
1705                 cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
1706
1707                 taken += needed;
1708
1709                 if (!smb1cli_is_andx_req(cmd)) {
1710                         /*
1711                          * If the current command does not have AndX chanining
1712                          * we are done.
1713                          */
1714                         break;
1715                 }
1716
1717                 if (wct == 0 && bcc == 0) {
1718                         /*
1719                          * An empty response also ends the chain,
1720                          * most likely with an error.
1721                          */
1722                         break;
1723                 }
1724
1725                 if (wct < 2) {
1726                         DEBUG(10, ("%s: wct[%d] < 2 for cmd[0x%02X]\n",
1727                                    __location__, (int)wct, (int)cmd));
1728                         goto inval;
1729                 }
1730                 cmd = CVAL(cur[0].iov_base, 0);
1731                 if (cmd == 0xFF) {
1732                         /*
1733                          * If it is the end of the chain we are also done.
1734                          */
1735                         break;
1736                 }
1737                 wct_ofs = SVAL(cur[0].iov_base, 2);
1738
1739                 if (wct_ofs < taken) {
1740                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1741                 }
1742                 if (wct_ofs > buflen) {
1743                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1744                 }
1745
1746                 /*
1747                  * we consumed everything up to the start of the next
1748                  * parameter block.
1749                  */
1750                 taken = wct_ofs;
1751         }
1752
1753         remaining = buflen - taken;
1754
1755         if (remaining > 0 && num_iov >= 3) {
1756                 /*
1757                  * The last DATA block gets the remaining
1758                  * bytes, this is needed to support
1759                  * CAP_LARGE_WRITEX and CAP_LARGE_READX.
1760                  */
1761                 iov[num_iov-1].iov_len += remaining;
1762         }
1763
1764         *piov = iov;
1765         *pnum_iov = num_iov;
1766         return NT_STATUS_OK;
1767
1768 inval:
1769         TALLOC_FREE(iov);
1770         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1771 }
1772
1773 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1774                                                TALLOC_CTX *tmp_mem,
1775                                                uint8_t *inbuf)
1776 {
1777         struct tevent_req *req;
1778         struct smbXcli_req_state *state;
1779         NTSTATUS status;
1780         size_t num_pending;
1781         size_t i;
1782         uint8_t cmd;
1783         uint16_t mid;
1784         bool oplock_break;
1785         uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
1786         size_t len = smb_len_nbt(inbuf);
1787         struct iovec *iov = NULL;
1788         int num_iov = 0;
1789         struct tevent_req **chain = NULL;
1790         size_t num_chained = 0;
1791         size_t num_responses = 0;
1792
1793         if (conn->smb1.read_braw_req != NULL) {
1794                 req = conn->smb1.read_braw_req;
1795                 conn->smb1.read_braw_req = NULL;
1796                 state = tevent_req_data(req, struct smbXcli_req_state);
1797
1798                 smbXcli_req_unset_pending(req);
1799
1800                 if (state->smb1.recv_iov == NULL) {
1801                         /*
1802                          * For requests with more than
1803                          * one response, we have to readd the
1804                          * recv_iov array.
1805                          */
1806                         state->smb1.recv_iov = talloc_zero_array(state,
1807                                                                  struct iovec,
1808                                                                  3);
1809                         if (tevent_req_nomem(state->smb1.recv_iov, req)) {
1810                                 return NT_STATUS_OK;
1811                         }
1812                 }
1813
1814                 state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
1815                 state->smb1.recv_iov[0].iov_len = len;
1816                 ZERO_STRUCT(state->smb1.recv_iov[1]);
1817                 ZERO_STRUCT(state->smb1.recv_iov[2]);
1818
1819                 state->smb1.recv_cmd = SMBreadBraw;
1820                 state->smb1.recv_status = NT_STATUS_OK;
1821                 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
1822
1823                 tevent_req_done(req);
1824                 return NT_STATUS_OK;
1825         }
1826
1827         if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
1828             && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
1829                 DEBUG(10, ("Got non-SMB PDU\n"));
1830                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1831         }
1832
1833         /*
1834          * If we supported multiple encrytion contexts
1835          * here we'd look up based on tid.
1836          */
1837         if (common_encryption_on(conn->smb1.trans_enc)
1838             && (CVAL(inbuf, 0) == 0)) {
1839                 uint16_t enc_ctx_num;
1840
1841                 status = get_enc_ctx_num(inbuf, &enc_ctx_num);
1842                 if (!NT_STATUS_IS_OK(status)) {
1843                         DEBUG(10, ("get_enc_ctx_num returned %s\n",
1844                                    nt_errstr(status)));
1845                         return status;
1846                 }
1847
1848                 if (enc_ctx_num != conn->smb1.trans_enc->enc_ctx_num) {
1849                         DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
1850                                    enc_ctx_num,
1851                                    conn->smb1.trans_enc->enc_ctx_num));
1852                         return NT_STATUS_INVALID_HANDLE;
1853                 }
1854
1855                 status = common_decrypt_buffer(conn->smb1.trans_enc,
1856                                                (char *)inbuf);
1857                 if (!NT_STATUS_IS_OK(status)) {
1858                         DEBUG(10, ("common_decrypt_buffer returned %s\n",
1859                                    nt_errstr(status)));
1860                         return status;
1861                 }
1862                 inhdr = inbuf + NBT_HDR_SIZE;
1863                 len = smb_len_nbt(inbuf);
1864         }
1865
1866         mid = SVAL(inhdr, HDR_MID);
1867         num_pending = talloc_array_length(conn->pending);
1868
1869         for (i=0; i<num_pending; i++) {
1870                 if (mid == smb1cli_req_mid(conn->pending[i])) {
1871                         break;
1872                 }
1873         }
1874         if (i == num_pending) {
1875                 /* Dump unexpected reply */
1876                 return NT_STATUS_RETRY;
1877         }
1878
1879         oplock_break = false;
1880
1881         if (mid == 0xffff) {
1882                 /*
1883                  * Paranoia checks that this is really an oplock break request.
1884                  */
1885                 oplock_break = (len == 51); /* hdr + 8 words */
1886                 oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
1887                 oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
1888                 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
1889                 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
1890
1891                 if (!oplock_break) {
1892                         /* Dump unexpected reply */
1893                         return NT_STATUS_RETRY;
1894                 }
1895         }
1896
1897         req = conn->pending[i];
1898         state = tevent_req_data(req, struct smbXcli_req_state);
1899
1900         if (!oplock_break /* oplock breaks are not signed */
1901             && !smb_signing_check_pdu(conn->smb1.signing,
1902                                       inhdr, len, state->smb1.seqnum+1)) {
1903                 DEBUG(10, ("cli_check_sign_mac failed\n"));
1904                 return NT_STATUS_ACCESS_DENIED;
1905         }
1906
1907         status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
1908                                            &iov, &num_iov);
1909         if (!NT_STATUS_IS_OK(status)) {
1910                 DEBUG(10,("smb1cli_inbuf_parse_chain - %s\n",
1911                           nt_errstr(status)));
1912                 return status;
1913         }
1914
1915         cmd = CVAL(inhdr, HDR_COM);
1916         status = smb1cli_pull_raw_error(inhdr);
1917
1918         if (state->smb1.chained_requests == NULL) {
1919                 if (num_iov != 3) {
1920                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1921                 }
1922
1923                 smbXcli_req_unset_pending(req);
1924
1925                 if (state->smb1.recv_iov == NULL) {
1926                         /*
1927                          * For requests with more than
1928                          * one response, we have to readd the
1929                          * recv_iov array.
1930                          */
1931                         state->smb1.recv_iov = talloc_zero_array(state,
1932                                                                  struct iovec,
1933                                                                  3);
1934                         if (tevent_req_nomem(state->smb1.recv_iov, req)) {
1935                                 return NT_STATUS_OK;
1936                         }
1937                 }
1938
1939                 state->smb1.recv_cmd = cmd;
1940                 state->smb1.recv_status = status;
1941                 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
1942
1943                 state->smb1.recv_iov[0] = iov[0];
1944                 state->smb1.recv_iov[1] = iov[1];
1945                 state->smb1.recv_iov[2] = iov[2];
1946
1947                 if (talloc_array_length(conn->pending) == 0) {
1948                         tevent_req_done(req);
1949                         return NT_STATUS_OK;
1950                 }
1951
1952                 tevent_req_defer_callback(req, state->ev);
1953                 tevent_req_done(req);
1954                 return NT_STATUS_RETRY;
1955         }
1956
1957         chain = talloc_move(tmp_mem, &state->smb1.chained_requests);
1958         num_chained = talloc_array_length(chain);
1959         num_responses = (num_iov - 1)/2;
1960
1961         if (num_responses > num_chained) {
1962                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1963         }
1964
1965         for (i=0; i<num_chained; i++) {
1966                 size_t iov_idx = 1 + (i*2);
1967                 struct iovec *cur = &iov[iov_idx];
1968                 uint8_t *inbuf_ref;
1969
1970                 req = chain[i];
1971                 state = tevent_req_data(req, struct smbXcli_req_state);
1972
1973                 smbXcli_req_unset_pending(req);
1974
1975                 /*
1976                  * as we finish multiple requests here
1977                  * we need to defer the callbacks as
1978                  * they could destroy our current stack state.
1979                  */
1980                 tevent_req_defer_callback(req, state->ev);
1981
1982                 if (i >= num_responses) {
1983                         tevent_req_nterror(req, NT_STATUS_REQUEST_ABORTED);
1984                         continue;
1985                 }
1986
1987                 if (state->smb1.recv_iov == NULL) {
1988                         /*
1989                          * For requests with more than
1990                          * one response, we have to readd the
1991                          * recv_iov array.
1992                          */
1993                         state->smb1.recv_iov = talloc_zero_array(state,
1994                                                                  struct iovec,
1995                                                                  3);
1996                         if (tevent_req_nomem(state->smb1.recv_iov, req)) {
1997                                 continue;
1998                         }
1999                 }
2000
2001                 state->smb1.recv_cmd = cmd;
2002
2003                 if (i == (num_responses - 1)) {
2004                         /*
2005                          * The last request in the chain gets the status
2006                          */
2007                         state->smb1.recv_status = status;
2008                 } else {
2009                         cmd = CVAL(cur[0].iov_base, 0);
2010                         state->smb1.recv_status = NT_STATUS_OK;
2011                 }
2012
2013                 state->inbuf = inbuf;
2014
2015                 /*
2016                  * Note: here we use talloc_reference() in a way
2017                  *       that does not expose it to the caller.
2018                  */
2019                 inbuf_ref = talloc_reference(state->smb1.recv_iov, inbuf);
2020                 if (tevent_req_nomem(inbuf_ref, req)) {
2021                         continue;
2022                 }
2023
2024                 /* copy the related buffers */
2025                 state->smb1.recv_iov[0] = iov[0];
2026                 state->smb1.recv_iov[1] = cur[0];
2027                 state->smb1.recv_iov[2] = cur[1];
2028
2029                 tevent_req_done(req);
2030         }
2031
2032         return NT_STATUS_RETRY;
2033 }
2034
2035 NTSTATUS smb1cli_req_recv(struct tevent_req *req,
2036                           TALLOC_CTX *mem_ctx,
2037                           struct iovec **piov,
2038                           uint8_t **phdr,
2039                           uint8_t *pwct,
2040                           uint16_t **pvwv,
2041                           uint32_t *pvwv_offset,
2042                           uint32_t *pnum_bytes,
2043                           uint8_t **pbytes,
2044                           uint32_t *pbytes_offset,
2045                           uint8_t **pinbuf,
2046                           const struct smb1cli_req_expected_response *expected,
2047                           size_t num_expected)
2048 {
2049         struct smbXcli_req_state *state =
2050                 tevent_req_data(req,
2051                 struct smbXcli_req_state);
2052         NTSTATUS status = NT_STATUS_OK;
2053         struct iovec *recv_iov = NULL;
2054         uint8_t *hdr = NULL;
2055         uint8_t wct = 0;
2056         uint32_t vwv_offset = 0;
2057         uint16_t *vwv = NULL;
2058         uint32_t num_bytes = 0;
2059         uint32_t bytes_offset = 0;
2060         uint8_t *bytes = NULL;
2061         size_t i;
2062         bool found_status = false;
2063         bool found_size = false;
2064
2065         if (piov != NULL) {
2066                 *piov = NULL;
2067         }
2068         if (phdr != NULL) {
2069                 *phdr = 0;
2070         }
2071         if (pwct != NULL) {
2072                 *pwct = 0;
2073         }
2074         if (pvwv != NULL) {
2075                 *pvwv = NULL;
2076         }
2077         if (pvwv_offset != NULL) {
2078                 *pvwv_offset = 0;
2079         }
2080         if (pnum_bytes != NULL) {
2081                 *pnum_bytes = 0;
2082         }
2083         if (pbytes != NULL) {
2084                 *pbytes = NULL;
2085         }
2086         if (pbytes_offset != NULL) {
2087                 *pbytes_offset = 0;
2088         }
2089         if (pinbuf != NULL) {
2090                 *pinbuf = NULL;
2091         }
2092
2093         if (state->inbuf != NULL) {
2094                 recv_iov = state->smb1.recv_iov;
2095                 state->smb1.recv_iov = NULL;
2096                 if (state->smb1.recv_cmd != SMBreadBraw) {
2097                         hdr = (uint8_t *)recv_iov[0].iov_base;
2098                         wct = recv_iov[1].iov_len/2;
2099                         vwv = (uint16_t *)recv_iov[1].iov_base;
2100                         vwv_offset = PTR_DIFF(vwv, hdr);
2101                         num_bytes = recv_iov[2].iov_len;
2102                         bytes = (uint8_t *)recv_iov[2].iov_base;
2103                         bytes_offset = PTR_DIFF(bytes, hdr);
2104                 }
2105         }
2106
2107         if (tevent_req_is_nterror(req, &status)) {
2108                 for (i=0; i < num_expected; i++) {
2109                         if (NT_STATUS_EQUAL(status, expected[i].status)) {
2110                                 found_status = true;
2111                                 break;
2112                         }
2113                 }
2114
2115                 if (found_status) {
2116                         return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2117                 }
2118
2119                 return status;
2120         }
2121
2122         if (num_expected == 0) {
2123                 found_status = true;
2124                 found_size = true;
2125         }
2126
2127         status = state->smb1.recv_status;
2128
2129         for (i=0; i < num_expected; i++) {
2130                 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
2131                         continue;
2132                 }
2133
2134                 found_status = true;
2135                 if (expected[i].wct == 0) {
2136                         found_size = true;
2137                         break;
2138                 }
2139
2140                 if (expected[i].wct == wct) {
2141                         found_size = true;
2142                         break;
2143                 }
2144         }
2145
2146         if (!found_status) {
2147                 return status;
2148         }
2149
2150         if (!found_size) {
2151                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2152         }
2153
2154         if (piov != NULL) {
2155                 *piov = talloc_move(mem_ctx, &recv_iov);
2156         }
2157
2158         if (phdr != NULL) {
2159                 *phdr = hdr;
2160         }
2161         if (pwct != NULL) {
2162                 *pwct = wct;
2163         }
2164         if (pvwv != NULL) {
2165                 *pvwv = vwv;
2166         }
2167         if (pvwv_offset != NULL) {
2168                 *pvwv_offset = vwv_offset;
2169         }
2170         if (pnum_bytes != NULL) {
2171                 *pnum_bytes = num_bytes;
2172         }
2173         if (pbytes != NULL) {
2174                 *pbytes = bytes;
2175         }
2176         if (pbytes_offset != NULL) {
2177                 *pbytes_offset = bytes_offset;
2178         }
2179         if (pinbuf != NULL) {
2180                 *pinbuf = state->inbuf;
2181         }
2182
2183         return status;
2184 }
2185
2186 size_t smb1cli_req_wct_ofs(struct tevent_req **reqs, int num_reqs)
2187 {
2188         size_t wct_ofs;
2189         int i;
2190
2191         wct_ofs = HDR_WCT;
2192
2193         for (i=0; i<num_reqs; i++) {
2194                 struct smbXcli_req_state *state;
2195                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2196                 wct_ofs += smbXcli_iov_len(state->smb1.iov+2,
2197                                            state->smb1.iov_count-2);
2198                 wct_ofs = (wct_ofs + 3) & ~3;
2199         }
2200         return wct_ofs;
2201 }
2202
2203 NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
2204 {
2205         struct smbXcli_req_state *first_state =
2206                 tevent_req_data(reqs[0],
2207                 struct smbXcli_req_state);
2208         struct smbXcli_req_state *state;
2209         size_t wct_offset;
2210         size_t chain_padding = 0;
2211         int i, iovlen;
2212         struct iovec *iov = NULL;
2213         struct iovec *this_iov;
2214         NTSTATUS status;
2215         size_t nbt_len;
2216
2217         if (num_reqs == 1) {
2218                 return smb1cli_req_writev_submit(reqs[0], first_state,
2219                                                  first_state->smb1.iov,
2220                                                  first_state->smb1.iov_count);
2221         }
2222
2223         iovlen = 0;
2224         for (i=0; i<num_reqs; i++) {
2225                 if (!tevent_req_is_in_progress(reqs[i])) {
2226                         return NT_STATUS_INTERNAL_ERROR;
2227                 }
2228
2229                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2230
2231                 if (state->smb1.iov_count < 4) {
2232                         return NT_STATUS_INVALID_PARAMETER_MIX;
2233                 }
2234
2235                 if (i == 0) {
2236                         /*
2237                          * The NBT and SMB header
2238                          */
2239                         iovlen += 2;
2240                 } else {
2241                         /*
2242                          * Chain padding
2243                          */
2244                         iovlen += 1;
2245                 }
2246
2247                 /*
2248                  * words and bytes
2249                  */
2250                 iovlen += state->smb1.iov_count - 2;
2251         }
2252
2253         iov = talloc_zero_array(first_state, struct iovec, iovlen);
2254         if (iov == NULL) {
2255                 return NT_STATUS_NO_MEMORY;
2256         }
2257
2258         first_state->smb1.chained_requests = (struct tevent_req **)talloc_memdup(
2259                 first_state, reqs, sizeof(*reqs) * num_reqs);
2260         if (first_state->smb1.chained_requests == NULL) {
2261                 TALLOC_FREE(iov);
2262                 return NT_STATUS_NO_MEMORY;
2263         }
2264
2265         wct_offset = HDR_WCT;
2266         this_iov = iov;
2267
2268         for (i=0; i<num_reqs; i++) {
2269                 size_t next_padding = 0;
2270                 uint16_t *vwv;
2271
2272                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2273
2274                 if (i < num_reqs-1) {
2275                         if (!smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))
2276                             || CVAL(state->smb1.hdr, HDR_WCT) < 2) {
2277                                 TALLOC_FREE(iov);
2278                                 TALLOC_FREE(first_state->smb1.chained_requests);
2279                                 return NT_STATUS_INVALID_PARAMETER_MIX;
2280                         }
2281                 }
2282
2283                 wct_offset += smbXcli_iov_len(state->smb1.iov+2,
2284                                               state->smb1.iov_count-2) + 1;
2285                 if ((wct_offset % 4) != 0) {
2286                         next_padding = 4 - (wct_offset % 4);
2287                 }
2288                 wct_offset += next_padding;
2289                 vwv = state->smb1.vwv;
2290
2291                 if (i < num_reqs-1) {
2292                         struct smbXcli_req_state *next_state =
2293                                 tevent_req_data(reqs[i+1],
2294                                 struct smbXcli_req_state);
2295                         SCVAL(vwv+0, 0, CVAL(next_state->smb1.hdr, HDR_COM));
2296                         SCVAL(vwv+0, 1, 0);
2297                         SSVAL(vwv+1, 0, wct_offset);
2298                 } else if (smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))) {
2299                         /* properly end the chain */
2300                         SCVAL(vwv+0, 0, 0xff);
2301                         SCVAL(vwv+0, 1, 0xff);
2302                         SSVAL(vwv+1, 0, 0);
2303                 }
2304
2305                 if (i == 0) {
2306                         /*
2307                          * The NBT and SMB header
2308                          */
2309                         this_iov[0] = state->smb1.iov[0];
2310                         this_iov[1] = state->smb1.iov[1];
2311                         this_iov += 2;
2312                 } else {
2313                         /*
2314                          * This one is a bit subtle. We have to add
2315                          * chain_padding bytes between the requests, and we
2316                          * have to also include the wct field of the
2317                          * subsequent requests. We use the subsequent header
2318                          * for the padding, it contains the wct field in its
2319                          * last byte.
2320                          */
2321                         this_iov[0].iov_len = chain_padding+1;
2322                         this_iov[0].iov_base = (void *)&state->smb1.hdr[
2323                                 sizeof(state->smb1.hdr) - this_iov[0].iov_len];
2324                         memset(this_iov[0].iov_base, 0, this_iov[0].iov_len-1);
2325                         this_iov += 1;
2326                 }
2327
2328                 /*
2329                  * copy the words and bytes
2330                  */
2331                 memcpy(this_iov, state->smb1.iov+2,
2332                        sizeof(struct iovec) * (state->smb1.iov_count-2));
2333                 this_iov += state->smb1.iov_count - 2;
2334                 chain_padding = next_padding;
2335         }
2336
2337         nbt_len = smbXcli_iov_len(&iov[1], iovlen-1);
2338         if (nbt_len > first_state->conn->smb1.max_xmit) {
2339                 TALLOC_FREE(iov);
2340                 TALLOC_FREE(first_state->smb1.chained_requests);
2341                 return NT_STATUS_INVALID_PARAMETER_MIX;
2342         }
2343
2344         status = smb1cli_req_writev_submit(reqs[0], first_state, iov, iovlen);
2345         if (!NT_STATUS_IS_OK(status)) {
2346                 TALLOC_FREE(iov);
2347                 TALLOC_FREE(first_state->smb1.chained_requests);
2348                 return status;
2349         }
2350
2351         return NT_STATUS_OK;
2352 }
2353
2354 bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
2355 {
2356         return ((tevent_queue_length(conn->outgoing) != 0)
2357                 || (talloc_array_length(conn->pending) != 0));
2358 }
2359
2360 uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
2361 {
2362         return conn->smb2.server.capabilities;
2363 }
2364
2365 uint16_t smb2cli_conn_server_security_mode(struct smbXcli_conn *conn)
2366 {
2367         return conn->smb2.server.security_mode;
2368 }
2369
2370 uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
2371 {
2372         return conn->smb2.server.max_trans_size;
2373 }
2374
2375 uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
2376 {
2377         return conn->smb2.server.max_read_size;
2378 }
2379
2380 uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
2381 {
2382         return conn->smb2.server.max_write_size;
2383 }
2384
2385 void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
2386                                   uint16_t max_credits)
2387 {
2388         conn->smb2.max_credits = max_credits;
2389 }
2390
2391 static void smb2cli_req_cancel_done(struct tevent_req *subreq);
2392
2393 static bool smb2cli_req_cancel(struct tevent_req *req)
2394 {
2395         struct smbXcli_req_state *state =
2396                 tevent_req_data(req,
2397                 struct smbXcli_req_state);
2398         uint32_t flags = IVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
2399         uint64_t mid = BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID);
2400         uint64_t aid = BVAL(state->smb2.hdr, SMB2_HDR_ASYNC_ID);
2401         struct smbXcli_tcon *tcon = state->tcon;
2402         struct smbXcli_session *session = state->session;
2403         uint8_t *fixed = state->smb2.pad;
2404         uint16_t fixed_len = 4;
2405         struct tevent_req *subreq;
2406         struct smbXcli_req_state *substate;
2407         NTSTATUS status;
2408
2409         SSVAL(fixed, 0, 0x04);
2410         SSVAL(fixed, 2, 0);
2411
2412         subreq = smb2cli_req_create(state, state->ev,
2413                                     state->conn,
2414                                     SMB2_OP_CANCEL,
2415                                     flags, 0,
2416                                     0, /* timeout */
2417                                     tcon, session,
2418                                     fixed, fixed_len,
2419                                     NULL, 0);
2420         if (subreq == NULL) {
2421                 return false;
2422         }
2423         substate = tevent_req_data(subreq, struct smbXcli_req_state);
2424
2425         if (flags & SMB2_HDR_FLAG_ASYNC) {
2426                 mid = 0;
2427         }
2428
2429         SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, flags);
2430         SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
2431         SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, aid);
2432
2433         status = smb2cli_req_compound_submit(&subreq, 1);
2434         if (!NT_STATUS_IS_OK(status)) {
2435                 TALLOC_FREE(subreq);
2436                 return false;
2437         }
2438
2439         tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2440
2441         return true;
2442 }
2443
2444 static void smb2cli_req_cancel_done(struct tevent_req *subreq)
2445 {
2446         /* we do not care about the result */
2447         TALLOC_FREE(subreq);
2448 }
2449
2450 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
2451                                       struct tevent_context *ev,
2452                                       struct smbXcli_conn *conn,
2453                                       uint16_t cmd,
2454                                       uint32_t additional_flags,
2455                                       uint32_t clear_flags,
2456                                       uint32_t timeout_msec,
2457                                       struct smbXcli_tcon *tcon,
2458                                       struct smbXcli_session *session,
2459                                       const uint8_t *fixed,
2460                                       uint16_t fixed_len,
2461                                       const uint8_t *dyn,
2462                                       uint32_t dyn_len)
2463 {
2464         struct tevent_req *req;
2465         struct smbXcli_req_state *state;
2466         uint32_t flags = 0;
2467         uint32_t tid = 0;
2468         uint64_t uid = 0;
2469         bool use_channel_sequence = false;
2470         uint16_t channel_sequence = 0;
2471
2472         req = tevent_req_create(mem_ctx, &state,
2473                                 struct smbXcli_req_state);
2474         if (req == NULL) {
2475                 return NULL;
2476         }
2477
2478         state->ev = ev;
2479         state->conn = conn;
2480         state->session = session;
2481         state->tcon = tcon;
2482
2483         if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
2484                 use_channel_sequence = true;
2485         } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
2486                 use_channel_sequence = true;
2487         }
2488
2489         if (session) {
2490                 uid = session->smb2->session_id;
2491
2492                 if (use_channel_sequence) {
2493                         channel_sequence = session->smb2->channel_sequence;
2494                 }
2495
2496                 state->smb2.should_sign = session->smb2->should_sign;
2497                 state->smb2.should_encrypt = session->smb2->should_encrypt;
2498
2499                 if (cmd == SMB2_OP_SESSSETUP &&
2500                     session->smb2->signing_key.length != 0) {
2501                         state->smb2.should_sign = true;
2502                 }
2503
2504                 if (cmd == SMB2_OP_SESSSETUP &&
2505                     session->smb2_channel.signing_key.length == 0) {
2506                         state->smb2.should_encrypt = false;
2507                 }
2508         }
2509
2510         if (tcon) {
2511                 tid = tcon->smb2.tcon_id;
2512
2513                 if (tcon->smb2.should_encrypt) {
2514                         state->smb2.should_encrypt = true;
2515                 }
2516         }
2517
2518         if (state->smb2.should_encrypt) {
2519                 state->smb2.should_sign = false;
2520         }
2521
2522         state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
2523         if (state->smb2.recv_iov == NULL) {
2524                 TALLOC_FREE(req);
2525                 return NULL;
2526         }
2527
2528         flags |= additional_flags;
2529         flags &= ~clear_flags;
2530
2531         state->smb2.fixed = fixed;
2532         state->smb2.fixed_len = fixed_len;
2533         state->smb2.dyn = dyn;
2534         state->smb2.dyn_len = dyn_len;
2535
2536         if (state->smb2.should_encrypt) {
2537                 SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2538                 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
2539         }
2540
2541         SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID,    SMB2_MAGIC);
2542         SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH,         SMB2_HDR_BODY);
2543         SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE,         cmd);
2544         SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
2545         SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS,          flags);
2546         SIVAL(state->smb2.hdr, SMB2_HDR_PID,            0); /* reserved */
2547         SIVAL(state->smb2.hdr, SMB2_HDR_TID,            tid);
2548         SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID,     uid);
2549
2550         switch (cmd) {
2551         case SMB2_OP_CANCEL:
2552                 state->one_way = true;
2553                 break;
2554         case SMB2_OP_BREAK:
2555                 /*
2556                  * If this is a dummy request, it will have
2557                  * UINT64_MAX as message id.
2558                  * If we send on break acknowledgement,
2559                  * this gets overwritten later.
2560                  */
2561                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
2562                 break;
2563         }
2564
2565         if (timeout_msec > 0) {
2566                 struct timeval endtime;
2567
2568                 endtime = timeval_current_ofs_msec(timeout_msec);
2569                 if (!tevent_req_set_endtime(req, ev, endtime)) {
2570                         return req;
2571                 }
2572         }
2573
2574         return req;
2575 }
2576
2577 void smb2cli_req_set_notify_async(struct tevent_req *req)
2578 {
2579         struct smbXcli_req_state *state =
2580                 tevent_req_data(req,
2581                 struct smbXcli_req_state);
2582
2583         state->smb2.notify_async = true;
2584 }
2585
2586 static void smb2cli_req_writev_done(struct tevent_req *subreq);
2587 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2588                                                TALLOC_CTX *tmp_mem,
2589                                                uint8_t *inbuf);
2590
2591 NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
2592                                      int num_reqs)
2593 {
2594         struct smbXcli_req_state *state;
2595         struct tevent_req *subreq;
2596         struct iovec *iov;
2597         int i, num_iov, nbt_len;
2598
2599         /*
2600          * 1 for the nbt length
2601          * per request: TRANSFORM, HDR, fixed, dyn, padding
2602          * -1 because the last one does not need padding
2603          */
2604
2605         iov = talloc_array(reqs[0], struct iovec, 1 + 5*num_reqs - 1);
2606         if (iov == NULL) {
2607                 return NT_STATUS_NO_MEMORY;
2608         }
2609
2610         num_iov = 1;
2611         nbt_len = 0;
2612
2613         for (i=0; i<num_reqs; i++) {
2614                 int tf_iov;
2615                 int hdr_iov;
2616                 size_t reqlen;
2617                 bool ret;
2618                 uint16_t opcode;
2619                 uint64_t avail;
2620                 uint16_t charge;
2621                 uint16_t credits;
2622                 uint64_t mid;
2623                 const DATA_BLOB *signing_key = NULL;
2624                 const DATA_BLOB *encryption_key = NULL;
2625
2626                 if (!tevent_req_is_in_progress(reqs[i])) {
2627                         return NT_STATUS_INTERNAL_ERROR;
2628                 }
2629
2630                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2631
2632                 if (!smbXcli_conn_is_connected(state->conn)) {
2633                         return NT_STATUS_CONNECTION_DISCONNECTED;
2634                 }
2635
2636                 if ((state->conn->protocol != PROTOCOL_NONE) &&
2637                     (state->conn->protocol < PROTOCOL_SMB2_02)) {
2638                         return NT_STATUS_REVISION_MISMATCH;
2639                 }
2640
2641                 opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
2642                 if (opcode == SMB2_OP_CANCEL) {
2643                         goto skip_credits;
2644                 }
2645
2646                 avail = UINT64_MAX - state->conn->smb2.mid;
2647                 if (avail < 1) {
2648                         return NT_STATUS_CONNECTION_ABORTED;
2649                 }
2650
2651                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2652                         charge = (MAX(state->smb2.dyn_len, 1) - 1)/ 65536 + 1;
2653                 } else {
2654                         charge = 1;
2655                 }
2656
2657                 charge = MAX(state->smb2.credit_charge, charge);
2658
2659                 avail = MIN(avail, state->conn->smb2.cur_credits);
2660                 if (avail < charge) {
2661                         return NT_STATUS_INTERNAL_ERROR;
2662                 }
2663
2664                 credits = 0;
2665                 if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
2666                         credits = state->conn->smb2.max_credits -
2667                                   state->conn->smb2.cur_credits;
2668                 }
2669                 if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
2670                         credits += 1;
2671                 }
2672
2673                 mid = state->conn->smb2.mid;
2674                 state->conn->smb2.mid += charge;
2675                 state->conn->smb2.cur_credits -= charge;
2676
2677                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2678                         SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
2679                 }
2680                 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
2681                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
2682
2683 skip_credits:
2684                 if (state->session) {
2685                         /*
2686                          * We prefer the channel signing key if it is
2687                          * already there.
2688                          */
2689                         if (state->smb2.should_sign) {
2690                                 signing_key = &state->session->smb2_channel.signing_key;
2691                         }
2692
2693                         /*
2694                          * If it is a channel binding, we already have the main
2695                          * signing key and try that one.
2696                          */
2697                         if (signing_key && signing_key->length == 0) {
2698                                 signing_key = &state->session->smb2->signing_key;
2699                         }
2700
2701                         /*
2702                          * If we do not have any session key yet, we skip the
2703                          * signing of SMB2_OP_SESSSETUP requests.
2704                          */
2705                         if (signing_key && signing_key->length == 0) {
2706                                 signing_key = NULL;
2707                         }
2708
2709                         if (state->smb2.should_encrypt) {
2710                                 encryption_key = &state->session->smb2->encryption_key;
2711                         }
2712                 }
2713
2714                 if (encryption_key) {
2715                         tf_iov = num_iov;
2716                         iov[num_iov].iov_base = state->smb2.transform;
2717                         iov[num_iov].iov_len  = sizeof(state->smb2.transform);
2718                         num_iov += 1;
2719                 }
2720
2721                 hdr_iov = num_iov;
2722                 iov[num_iov].iov_base = state->smb2.hdr;
2723                 iov[num_iov].iov_len  = sizeof(state->smb2.hdr);
2724                 num_iov += 1;
2725
2726                 iov[num_iov].iov_base = discard_const(state->smb2.fixed);
2727                 iov[num_iov].iov_len  = state->smb2.fixed_len;
2728                 num_iov += 1;
2729
2730                 if (state->smb2.dyn != NULL) {
2731                         iov[num_iov].iov_base = discard_const(state->smb2.dyn);
2732                         iov[num_iov].iov_len  = state->smb2.dyn_len;
2733                         num_iov += 1;
2734                 }
2735
2736                 reqlen  = sizeof(state->smb2.hdr);
2737                 reqlen += state->smb2.fixed_len;
2738                 reqlen += state->smb2.dyn_len;
2739
2740                 if (i < num_reqs-1) {
2741                         if ((reqlen % 8) > 0) {
2742                                 uint8_t pad = 8 - (reqlen % 8);
2743                                 iov[num_iov].iov_base = state->smb2.pad;
2744                                 iov[num_iov].iov_len = pad;
2745                                 num_iov += 1;
2746                                 reqlen += pad;
2747                         }
2748                         SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
2749                 }
2750
2751                 if (encryption_key) {
2752                         NTSTATUS status;
2753                         uint8_t *buf;
2754                         int vi;
2755
2756                         SBVAL(state->smb2.transform, SMB2_TF_NONCE,
2757                               state->session->smb2->nonce_low);
2758                         SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
2759                               state->session->smb2->nonce_high);
2760
2761                         state->session->smb2->nonce_low += 1;
2762                         if (state->session->smb2->nonce_low == 0) {
2763                                 state->session->smb2->nonce_high += 1;
2764                                 state->session->smb2->nonce_low += 1;
2765                         }
2766
2767                         SBVAL(state->smb2.transform, SMB2_TF_MSG_SIZE,
2768                               reqlen);
2769
2770                         buf = talloc_array(iov, uint8_t, reqlen);
2771                         if (buf == NULL) {
2772                                 return NT_STATUS_NO_MEMORY;
2773                         }
2774
2775                         reqlen += SMB2_TF_HDR_SIZE;
2776
2777                         /*
2778                          * We copy the buffers before encrypting them,
2779                          * this is at least currently needed for the
2780                          * to keep state->smb2.hdr.
2781                          *
2782                          * Also the callers may expect there buffers
2783                          * to be const.
2784                          */
2785                         for (vi = hdr_iov; vi < num_iov; vi++) {
2786                                 struct iovec *v = &iov[vi];
2787                                 const uint8_t *o = (const uint8_t *)v->iov_base;
2788
2789                                 memcpy(buf, o, v->iov_len);
2790                                 v->iov_base = (void *)buf;
2791                                 buf += v->iov_len;
2792                         }
2793
2794                         status = smb2_signing_encrypt_pdu(*encryption_key,
2795                                                 state->session->conn->protocol,
2796                                                 &iov[tf_iov], num_iov - tf_iov);
2797                         if (!NT_STATUS_IS_OK(status)) {
2798                                 return status;
2799                         }
2800                 } else if (signing_key) {
2801                         NTSTATUS status;
2802
2803                         status = smb2_signing_sign_pdu(*signing_key,
2804                                                        state->session->conn->protocol,
2805                                                        &iov[hdr_iov], num_iov - hdr_iov);
2806                         if (!NT_STATUS_IS_OK(status)) {
2807                                 return status;
2808                         }
2809                 }
2810
2811                 nbt_len += reqlen;
2812
2813                 ret = smbXcli_req_set_pending(reqs[i]);
2814                 if (!ret) {
2815                         return NT_STATUS_NO_MEMORY;
2816                 }
2817         }
2818
2819         state = tevent_req_data(reqs[0], struct smbXcli_req_state);
2820         _smb_setlen_tcp(state->length_hdr, nbt_len);
2821         iov[0].iov_base = state->length_hdr;
2822         iov[0].iov_len  = sizeof(state->length_hdr);
2823
2824         if (state->conn->dispatch_incoming == NULL) {
2825                 state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
2826         }
2827
2828         subreq = writev_send(state, state->ev, state->conn->outgoing,
2829                              state->conn->write_fd, false, iov, num_iov);
2830         if (subreq == NULL) {
2831                 return NT_STATUS_NO_MEMORY;
2832         }
2833         tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
2834         return NT_STATUS_OK;
2835 }
2836
2837 void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
2838 {
2839         struct smbXcli_req_state *state =
2840                 tevent_req_data(req,
2841                 struct smbXcli_req_state);
2842
2843         state->smb2.credit_charge = charge;
2844 }
2845
2846 struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
2847                                     struct tevent_context *ev,
2848                                     struct smbXcli_conn *conn,
2849                                     uint16_t cmd,
2850                                     uint32_t additional_flags,
2851                                     uint32_t clear_flags,
2852                                     uint32_t timeout_msec,
2853                                     struct smbXcli_tcon *tcon,
2854                                     struct smbXcli_session *session,
2855                                     const uint8_t *fixed,
2856                                     uint16_t fixed_len,
2857                                     const uint8_t *dyn,
2858                                     uint32_t dyn_len)
2859 {
2860         struct tevent_req *req;
2861         NTSTATUS status;
2862
2863         req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
2864                                  additional_flags, clear_flags,
2865                                  timeout_msec,
2866                                  tcon, session,
2867                                  fixed, fixed_len, dyn, dyn_len);
2868         if (req == NULL) {
2869                 return NULL;
2870         }
2871         if (!tevent_req_is_in_progress(req)) {
2872                 return tevent_req_post(req, ev);
2873         }
2874         status = smb2cli_req_compound_submit(&req, 1);
2875         if (tevent_req_nterror(req, status)) {
2876                 return tevent_req_post(req, ev);
2877         }
2878         return req;
2879 }
2880
2881 static void smb2cli_req_writev_done(struct tevent_req *subreq)
2882 {
2883         struct tevent_req *req =
2884                 tevent_req_callback_data(subreq,
2885                 struct tevent_req);
2886         struct smbXcli_req_state *state =
2887                 tevent_req_data(req,
2888                 struct smbXcli_req_state);
2889         ssize_t nwritten;
2890         int err;
2891
2892         nwritten = writev_recv(subreq, &err);
2893         TALLOC_FREE(subreq);
2894         if (nwritten == -1) {
2895                 /* here, we need to notify all pending requests */
2896                 NTSTATUS status = map_nt_error_from_unix_common(err);
2897                 smbXcli_conn_disconnect(state->conn, status);
2898                 return;
2899         }
2900 }
2901
2902 static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
2903                                              uint8_t *buf,
2904                                              size_t buflen,
2905                                              TALLOC_CTX *mem_ctx,
2906                                              struct iovec **piov, int *pnum_iov)
2907 {
2908         struct iovec *iov;
2909         int num_iov = 0;
2910         size_t taken = 0;
2911         uint8_t *first_hdr = buf;
2912
2913         iov = talloc_array(mem_ctx, struct iovec, num_iov);
2914         if (iov == NULL) {
2915                 return NT_STATUS_NO_MEMORY;
2916         }
2917
2918         while (taken < buflen) {
2919                 uint8_t *tf = NULL;
2920                 size_t tf_len = 0;
2921                 size_t len = buflen - taken;
2922                 uint8_t *hdr = first_hdr + taken;
2923                 struct iovec *cur;
2924                 size_t full_size;
2925                 size_t next_command_ofs;
2926                 uint16_t body_size;
2927                 struct iovec *iov_tmp;
2928
2929                 if (len < 4) {
2930                         DEBUG(10, ("%d bytes left, expected at least %d\n",
2931                                    (int)len, 4));
2932                         goto inval;
2933                 }
2934                 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
2935                         struct smbXcli_session *s;
2936                         uint64_t uid;
2937                         struct iovec tf_iov[2];
2938                         NTSTATUS status;
2939
2940                         if (len < SMB2_TF_HDR_SIZE) {
2941                                 DEBUG(10, ("%d bytes left, expected at least %d\n",
2942                                            (int)len, SMB2_TF_HDR_SIZE));
2943                                 goto inval;
2944                         }
2945                         tf = hdr;
2946                         tf_len = SMB2_TF_HDR_SIZE;
2947                         taken += tf_len;
2948
2949                         hdr = first_hdr + taken;
2950                         len = IVAL(tf, SMB2_TF_MSG_SIZE);
2951                         uid = BVAL(tf, SMB2_TF_SESSION_ID);
2952
2953                         s = conn->sessions;
2954                         for (; s; s = s->next) {
2955                                 if (s->smb2->session_id != uid) {
2956                                         continue;
2957                                 }
2958                                 break;
2959                         }
2960
2961                         if (s == NULL) {
2962                                 DEBUG(10, ("unknown session_id %llu\n",
2963                                            (unsigned long long)uid));
2964                                 goto inval;
2965                         }
2966
2967                         tf_iov[0].iov_base = (void *)tf;
2968                         tf_iov[0].iov_len = tf_len;
2969                         tf_iov[1].iov_base = (void *)hdr;
2970                         tf_iov[1].iov_len = len;
2971
2972                         status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
2973                                                           conn->protocol,
2974                                                           tf_iov, 2);
2975                         if (!NT_STATUS_IS_OK(status)) {
2976                                 TALLOC_FREE(iov);
2977                                 return status;
2978                         }
2979                 }
2980
2981                 /*
2982                  * We need the header plus the body length field
2983                  */
2984
2985                 if (len < SMB2_HDR_BODY + 2) {
2986                         DEBUG(10, ("%d bytes left, expected at least %d\n",
2987                                    (int)len, SMB2_HDR_BODY));
2988                         goto inval;
2989                 }
2990                 if (IVAL(hdr, 0) != SMB2_MAGIC) {
2991                         DEBUG(10, ("Got non-SMB2 PDU: %x\n",
2992                                    IVAL(hdr, 0)));
2993                         goto inval;
2994                 }
2995                 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
2996                         DEBUG(10, ("Got HDR len %d, expected %d\n",
2997                                    SVAL(hdr, 4), SMB2_HDR_BODY));
2998                         goto inval;
2999                 }
3000
3001                 full_size = len;
3002                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
3003                 body_size = SVAL(hdr, SMB2_HDR_BODY);
3004
3005                 if (next_command_ofs != 0) {
3006                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
3007                                 goto inval;
3008                         }
3009                         if (next_command_ofs > full_size) {
3010                                 goto inval;
3011                         }
3012                         if (tf && next_command_ofs < len) {
3013                                 goto inval;
3014                         }
3015                         full_size = next_command_ofs;
3016                 }
3017                 if (body_size < 2) {
3018                         goto inval;
3019                 }
3020                 body_size &= 0xfffe;
3021
3022                 if (body_size > (full_size - SMB2_HDR_BODY)) {
3023                         goto inval;
3024                 }
3025
3026                 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
3027                                          num_iov + 4);
3028                 if (iov_tmp == NULL) {
3029                         TALLOC_FREE(iov);
3030                         return NT_STATUS_NO_MEMORY;
3031                 }
3032                 iov = iov_tmp;
3033                 cur = &iov[num_iov];
3034                 num_iov += 4;
3035
3036                 cur[0].iov_base = tf;
3037                 cur[0].iov_len  = tf_len;
3038                 cur[1].iov_base = hdr;
3039                 cur[1].iov_len  = SMB2_HDR_BODY;
3040                 cur[2].iov_base = hdr + SMB2_HDR_BODY;
3041                 cur[2].iov_len  = body_size;
3042                 cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
3043                 cur[3].iov_len  = full_size - (SMB2_HDR_BODY + body_size);
3044
3045                 taken += full_size;
3046         }
3047
3048         *piov = iov;
3049         *pnum_iov = num_iov;
3050         return NT_STATUS_OK;
3051
3052 inval:
3053         TALLOC_FREE(iov);
3054         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3055 }
3056
3057 static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
3058                                                     uint64_t mid)
3059 {
3060         size_t num_pending = talloc_array_length(conn->pending);
3061         size_t i;
3062
3063         for (i=0; i<num_pending; i++) {
3064                 struct tevent_req *req = conn->pending[i];
3065                 struct smbXcli_req_state *state =
3066                         tevent_req_data(req,
3067                         struct smbXcli_req_state);
3068
3069                 if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
3070                         return req;
3071                 }
3072         }
3073         return NULL;
3074 }
3075
3076 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3077                                                TALLOC_CTX *tmp_mem,
3078                                                uint8_t *inbuf)
3079 {
3080         struct tevent_req *req;
3081         struct smbXcli_req_state *state = NULL;
3082         struct iovec *iov;
3083         int i, num_iov;
3084         NTSTATUS status;
3085         bool defer = true;
3086         struct smbXcli_session *last_session = NULL;
3087         size_t inbuf_len = smb_len_tcp(inbuf);
3088
3089         status = smb2cli_inbuf_parse_compound(conn,
3090                                               inbuf + NBT_HDR_SIZE,
3091                                               inbuf_len,
3092                                               tmp_mem,
3093                                               &iov, &num_iov);
3094         if (!NT_STATUS_IS_OK(status)) {
3095                 return status;
3096         }
3097
3098         for (i=0; i<num_iov; i+=4) {
3099                 uint8_t *inbuf_ref = NULL;
3100                 struct iovec *cur = &iov[i];
3101                 uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
3102                 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3103                 uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3104                 uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3105                 uint16_t req_opcode;
3106                 uint32_t req_flags;
3107                 uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
3108                 uint32_t new_credits;
3109                 struct smbXcli_session *session = NULL;
3110                 const DATA_BLOB *signing_key = NULL;
3111
3112                 new_credits = conn->smb2.cur_credits;
3113                 new_credits += credits;
3114                 if (new_credits > UINT16_MAX) {
3115                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3116                 }
3117                 conn->smb2.cur_credits += credits;
3118
3119                 req = smb2cli_conn_find_pending(conn, mid);
3120                 if (req == NULL) {
3121                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3122                 }
3123                 state = tevent_req_data(req, struct smbXcli_req_state);
3124
3125                 state->smb2.got_async = false;
3126
3127                 req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3128                 if (opcode != req_opcode) {
3129                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3130                 }
3131                 req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3132
3133                 if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
3134                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3135                 }
3136
3137                 status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
3138                 if ((flags & SMB2_HDR_FLAG_ASYNC) &&
3139                     NT_STATUS_EQUAL(status, STATUS_PENDING)) {
3140                         uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
3141
3142                         /*
3143                          * async interim responses are not signed,
3144                          * even if the SMB2_HDR_FLAG_SIGNED flag
3145                          * is set.
3146                          */
3147                         req_flags |= SMB2_HDR_FLAG_ASYNC;
3148                         SBVAL(state->smb2.hdr, SMB2_HDR_FLAGS, req_flags);
3149                         SBVAL(state->smb2.hdr, SMB2_HDR_ASYNC_ID, async_id);
3150
3151                         if (state->smb2.notify_async) {
3152                                 state->smb2.got_async = true;
3153                                 tevent_req_defer_callback(req, state->ev);
3154                                 tevent_req_notify_callback(req);
3155                         }
3156                         continue;
3157                 }
3158
3159                 session = state->session;
3160                 if (req_flags & SMB2_HDR_FLAG_CHAINED) {
3161                         session = last_session;
3162                 }
3163                 last_session = session;
3164
3165                 if (state->smb2.should_sign) {
3166                         if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
3167                                 return NT_STATUS_ACCESS_DENIED;
3168                         }
3169                 }
3170
3171                 if (flags & SMB2_HDR_FLAG_SIGNED) {
3172                         uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
3173
3174                         if (session == NULL) {
3175                                 struct smbXcli_session *s;
3176
3177                                 s = state->conn->sessions;
3178                                 for (; s; s = s->next) {
3179                                         if (s->smb2->session_id != uid) {
3180                                                 continue;
3181                                         }
3182
3183                                         session = s;
3184                                         break;
3185                                 }
3186                         }
3187
3188                         if (session == NULL) {
3189                                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3190                         }
3191
3192                         last_session = session;
3193                         signing_key = &session->smb2_channel.signing_key;
3194                 }
3195
3196                 if (opcode == SMB2_OP_SESSSETUP) {
3197                         /*
3198                          * We prefer the channel signing key, if it is
3199                          * already there.
3200                          *
3201                          * If we do not have a channel signing key yet,
3202                          * we try the main signing key, if it is not
3203                          * the final response.
3204                          */
3205                         if (signing_key && signing_key->length == 0 &&
3206                             !NT_STATUS_IS_OK(status)) {
3207                                 signing_key = &session->smb2->signing_key;
3208                         }
3209
3210                         if (signing_key && signing_key->length == 0) {
3211                                 /*
3212                                  * If we do not have a session key to
3213                                  * verify the signature, we defer the
3214                                  * signing check to the caller.
3215                                  *
3216                                  * The caller gets NT_STATUS_OK, it
3217                                  * has to call
3218                                  * smb2cli_session_set_session_key()
3219                                  * or
3220                                  * smb2cli_session_set_channel_key()
3221                                  * which will check the signature
3222                                  * with the channel signing key.
3223                                  */
3224                                 signing_key = NULL;
3225                         }
3226                 }
3227
3228                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
3229                         /*
3230                          * if the server returns NT_STATUS_USER_SESSION_DELETED
3231                          * the response is not signed and we should
3232                          * propagate the NT_STATUS_USER_SESSION_DELETED
3233                          * status to the caller.
3234                          */
3235                         signing_key = NULL;
3236                 } else if (state->smb2.should_encrypt) {
3237                         if (cur[0].iov_len != SMB2_TF_HDR_SIZE) {
3238                                 return NT_STATUS_ACCESS_DENIED;
3239                         }
3240                 }
3241
3242                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
3243                     NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
3244                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3245                         /*
3246                          * if the server returns
3247                          * NT_STATUS_NETWORK_NAME_DELETED
3248                          * NT_STATUS_FILE_CLOSED
3249                          * NT_STATUS_INVALID_PARAMETER
3250                          * the response might not be signed
3251                          * as this happens before the signing checks.
3252                          *
3253                          * If server echos the signature (or all zeros)
3254                          * we should report the status from the server
3255                          * to the caller.
3256                          */
3257                         if (signing_key) {
3258                                 int cmp;
3259
3260                                 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3261                                              state->smb2.hdr+SMB2_HDR_SIGNATURE,
3262                                              16);
3263                                 if (cmp == 0) {
3264                                         state->smb2.signing_skipped = true;
3265                                         signing_key = NULL;
3266                                 }
3267                         }
3268                         if (signing_key) {
3269                                 int cmp;
3270                                 static const uint8_t zeros[16];
3271
3272                                 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3273                                              zeros,
3274                                              16);
3275                                 if (cmp == 0) {
3276                                         state->smb2.signing_skipped = true;
3277                                         signing_key = NULL;
3278                                 }
3279                         }
3280                 }
3281
3282                 if (signing_key) {
3283                         status = smb2_signing_check_pdu(*signing_key,
3284                                                         state->conn->protocol,
3285                                                         &cur[1], 3);
3286                         if (!NT_STATUS_IS_OK(status)) {
3287                                 /*
3288                                  * If the signing check fails, we disconnect
3289                                  * the connection.
3290                                  */
3291                                 return status;
3292                         }
3293                 }
3294
3295                 smbXcli_req_unset_pending(req);
3296
3297                 /*
3298                  * There might be more than one response
3299                  * we need to defer the notifications
3300                  */
3301                 if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
3302                         defer = false;
3303                 }
3304
3305                 if (defer) {
3306                         tevent_req_defer_callback(req, state->ev);
3307                 }
3308
3309                 /*
3310                  * Note: here we use talloc_reference() in a way
3311                  *       that does not expose it to the caller.
3312                  */
3313                 inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
3314                 if (tevent_req_nomem(inbuf_ref, req)) {
3315                         continue;
3316                 }
3317
3318                 /* copy the related buffers */
3319                 state->smb2.recv_iov[0] = cur[1];
3320                 state->smb2.recv_iov[1] = cur[2];
3321                 state->smb2.recv_iov[2] = cur[3];
3322
3323                 tevent_req_done(req);
3324         }
3325
3326         if (defer) {
3327                 return NT_STATUS_RETRY;
3328         }
3329
3330         return NT_STATUS_OK;
3331 }
3332
3333 NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3334                           struct iovec **piov,
3335                           const struct smb2cli_req_expected_response *expected,
3336                           size_t num_expected)
3337 {
3338         struct smbXcli_req_state *state =
3339                 tevent_req_data(req,
3340                 struct smbXcli_req_state);
3341         NTSTATUS status;
3342         size_t body_size;
3343         bool found_status = false;
3344         bool found_size = false;
3345         size_t i;
3346
3347         if (piov != NULL) {
3348                 *piov = NULL;
3349         }
3350
3351         if (state->smb2.got_async) {
3352                 return STATUS_PENDING;
3353         }
3354
3355         if (tevent_req_is_nterror(req, &status)) {
3356                 for (i=0; i < num_expected; i++) {
3357                         if (NT_STATUS_EQUAL(status, expected[i].status)) {
3358                                 found_status = true;
3359                                 break;
3360                         }
3361                 }
3362
3363                 if (found_status) {
3364                         return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
3365                 }
3366
3367                 return status;
3368         }
3369
3370         if (num_expected == 0) {
3371                 found_status = true;
3372                 found_size = true;
3373         }
3374
3375         status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
3376         body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
3377
3378         for (i=0; i < num_expected; i++) {
3379                 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
3380                         continue;
3381                 }
3382
3383                 found_status = true;
3384                 if (expected[i].body_size == 0) {
3385                         found_size = true;
3386                         break;
3387                 }
3388
3389                 if (expected[i].body_size == body_size) {
3390                         found_size = true;
3391                         break;
3392                 }
3393         }
3394
3395         if (!found_status) {
3396                 return status;
3397         }
3398
3399         if (state->smb2.signing_skipped) {
3400                 if (num_expected > 0) {
3401                         return NT_STATUS_ACCESS_DENIED;
3402                 }
3403                 if (!NT_STATUS_IS_ERR(status)) {
3404                         return NT_STATUS_ACCESS_DENIED;
3405                 }
3406         }
3407
3408         if (!found_size) {
3409                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3410         }
3411
3412         if (piov != NULL) {
3413                 *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
3414         }
3415
3416         return status;
3417 }
3418
3419 static const struct {
3420         enum protocol_types proto;
3421         const char *smb1_name;
3422 } smb1cli_prots[] = {
3423         {PROTOCOL_CORE,         "PC NETWORK PROGRAM 1.0"},
3424         {PROTOCOL_COREPLUS,     "MICROSOFT NETWORKS 1.03"},
3425         {PROTOCOL_LANMAN1,      "MICROSOFT NETWORKS 3.0"},
3426         {PROTOCOL_LANMAN1,      "LANMAN1.0"},
3427         {PROTOCOL_LANMAN2,      "LM1.2X002"},
3428         {PROTOCOL_LANMAN2,      "DOS LANMAN2.1"},
3429         {PROTOCOL_LANMAN2,      "LANMAN2.1"},
3430         {PROTOCOL_LANMAN2,      "Samba"},
3431         {PROTOCOL_NT1,          "NT LANMAN 1.0"},
3432         {PROTOCOL_NT1,          "NT LM 0.12"},
3433         {PROTOCOL_SMB2_02,      "SMB 2.002"},
3434         {PROTOCOL_SMB2_10,      "SMB 2.???"},
3435 };
3436
3437 static const struct {
3438         enum protocol_types proto;
3439         uint16_t smb2_dialect;
3440 } smb2cli_prots[] = {
3441         {PROTOCOL_SMB2_02,      SMB2_DIALECT_REVISION_202},
3442         {PROTOCOL_SMB2_10,      SMB2_DIALECT_REVISION_210},
3443         {PROTOCOL_SMB2_22,      SMB2_DIALECT_REVISION_222},
3444         {PROTOCOL_SMB2_24,      SMB2_DIALECT_REVISION_224},
3445         {PROTOCOL_SMB3_00,      SMB3_DIALECT_REVISION_300},
3446 };
3447
3448 struct smbXcli_negprot_state {
3449         struct smbXcli_conn *conn;
3450         struct tevent_context *ev;
3451         uint32_t timeout_msec;
3452         enum protocol_types min_protocol;
3453         enum protocol_types max_protocol;
3454
3455         struct {
3456                 uint8_t fixed[36];
3457                 uint8_t dyn[ARRAY_SIZE(smb2cli_prots)*2];
3458         } smb2;
3459 };
3460
3461 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
3462 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
3463 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
3464 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
3465 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
3466 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
3467                                                   TALLOC_CTX *frame,
3468                                                   uint8_t *inbuf);
3469
3470 struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
3471                                         struct tevent_context *ev,
3472                                         struct smbXcli_conn *conn,
3473                                         uint32_t timeout_msec,
3474                                         enum protocol_types min_protocol,
3475                                         enum protocol_types max_protocol)
3476 {
3477         struct tevent_req *req, *subreq;
3478         struct smbXcli_negprot_state *state;
3479
3480         req = tevent_req_create(mem_ctx, &state,
3481                                 struct smbXcli_negprot_state);
3482         if (req == NULL) {
3483                 return NULL;
3484         }
3485         state->conn = conn;
3486         state->ev = ev;
3487         state->timeout_msec = timeout_msec;
3488         state->min_protocol = min_protocol;
3489         state->max_protocol = max_protocol;
3490
3491         if (min_protocol == PROTOCOL_NONE) {
3492                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3493                 return tevent_req_post(req, ev);
3494         }
3495
3496         if (max_protocol == PROTOCOL_NONE) {
3497                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3498                 return tevent_req_post(req, ev);
3499         }
3500
3501         if (min_protocol > max_protocol) {
3502                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3503                 return tevent_req_post(req, ev);
3504         }
3505
3506         if ((min_protocol < PROTOCOL_SMB2_02) &&
3507             (max_protocol < PROTOCOL_SMB2_02)) {
3508                 /*
3509                  * SMB1 only...
3510                  */
3511                 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
3512
3513                 subreq = smbXcli_negprot_smb1_subreq(state);
3514                 if (tevent_req_nomem(subreq, req)) {
3515                         return tevent_req_post(req, ev);
3516                 }
3517                 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
3518                 return req;
3519         }
3520
3521         if ((min_protocol >= PROTOCOL_SMB2_02) &&
3522             (max_protocol >= PROTOCOL_SMB2_02)) {
3523                 /*
3524                  * SMB2 only...
3525                  */
3526                 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3527
3528                 subreq = smbXcli_negprot_smb2_subreq(state);
3529                 if (tevent_req_nomem(subreq, req)) {
3530                         return tevent_req_post(req, ev);
3531                 }
3532                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
3533                 return req;
3534         }
3535
3536         /*
3537          * We send an SMB1 negprot with the SMB2 dialects
3538          * and expect a SMB1 or a SMB2 response.
3539          *
3540          * smbXcli_negprot_dispatch_incoming() will fix the
3541          * callback to match protocol of the response.
3542          */
3543         conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
3544
3545         subreq = smbXcli_negprot_smb1_subreq(state);
3546         if (tevent_req_nomem(subreq, req)) {
3547                 return tevent_req_post(req, ev);
3548         }
3549         tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
3550         return req;
3551 }
3552
3553 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
3554 {
3555         struct tevent_req *req =
3556                 tevent_req_callback_data(subreq,
3557                 struct tevent_req);
3558         NTSTATUS status;
3559
3560         /*
3561          * we just want the low level error
3562          */
3563         status = tevent_req_simple_recv_ntstatus(subreq);
3564         TALLOC_FREE(subreq);
3565         if (tevent_req_nterror(req, status)) {
3566                 return;
3567         }
3568
3569         /* this should never happen */
3570         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3571 }
3572
3573 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
3574 {
3575         size_t i;
3576         DATA_BLOB bytes = data_blob_null;
3577         uint8_t flags;
3578         uint16_t flags2;
3579
3580         /* setup the protocol strings */
3581         for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
3582                 uint8_t c = 2;
3583                 bool ok;
3584
3585                 if (smb1cli_prots[i].proto < state->min_protocol) {
3586                         continue;
3587                 }
3588
3589                 if (smb1cli_prots[i].proto > state->max_protocol) {
3590                         continue;
3591                 }
3592
3593                 ok = data_blob_append(state, &bytes, &c, sizeof(c));
3594                 if (!ok) {
3595                         return NULL;
3596                 }
3597
3598                 /*
3599                  * We now it is already ascii and
3600                  * we want NULL termination.
3601                  */
3602                 ok = data_blob_append(state, &bytes,
3603                                       smb1cli_prots[i].smb1_name,
3604                                       strlen(smb1cli_prots[i].smb1_name)+1);
3605                 if (!ok) {
3606                         return NULL;
3607                 }
3608         }
3609
3610         smb1cli_req_flags(state->max_protocol,
3611                           state->conn->smb1.client.capabilities,
3612                           SMBnegprot,
3613                           0, 0, &flags,
3614                           0, 0, &flags2);
3615
3616         return smb1cli_req_send(state, state->ev, state->conn,
3617                                 SMBnegprot,
3618                                 flags, ~flags,
3619                                 flags2, ~flags2,
3620                                 state->timeout_msec,
3621                                 0xFFFE, 0, NULL, /* pid, tid, session */
3622                                 0, NULL, /* wct, vwv */
3623                                 bytes.length, bytes.data);
3624 }
3625
3626 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
3627 {
3628         struct tevent_req *req =
3629                 tevent_req_callback_data(subreq,
3630                 struct tevent_req);
3631         struct smbXcli_negprot_state *state =
3632                 tevent_req_data(req,
3633                 struct smbXcli_negprot_state);
3634         struct smbXcli_conn *conn = state->conn;
3635         struct iovec *recv_iov = NULL;
3636         uint8_t *inhdr;
3637         uint8_t wct;
3638         uint16_t *vwv;
3639         uint32_t num_bytes;
3640         uint8_t *bytes;
3641         NTSTATUS status;
3642         uint16_t protnum;
3643         size_t i;
3644         size_t num_prots = 0;
3645         uint8_t flags;
3646         uint32_t client_capabilities = conn->smb1.client.capabilities;
3647         uint32_t both_capabilities;
3648         uint32_t server_capabilities = 0;
3649         uint32_t capabilities;
3650         uint32_t client_max_xmit = conn->smb1.client.max_xmit;
3651         uint32_t server_max_xmit = 0;
3652         uint32_t max_xmit;
3653         uint32_t server_max_mux = 0;
3654         uint16_t server_security_mode = 0;
3655         uint32_t server_session_key = 0;
3656         bool server_readbraw = false;
3657         bool server_writebraw = false;
3658         bool server_lockread = false;
3659         bool server_writeunlock = false;
3660         struct GUID server_guid = GUID_zero();
3661         DATA_BLOB server_gss_blob = data_blob_null;
3662         uint8_t server_challenge[8];
3663         char *server_workgroup = NULL;
3664         char *server_name = NULL;
3665         int server_time_zone = 0;
3666         NTTIME server_system_time = 0;
3667         static const struct smb1cli_req_expected_response expected[] = {
3668         {
3669                 .status = NT_STATUS_OK,
3670                 .wct = 0x11, /* NT1 */
3671         },
3672         {
3673                 .status = NT_STATUS_OK,
3674                 .wct = 0x0D, /* LM */
3675         },
3676         {
3677                 .status = NT_STATUS_OK,
3678                 .wct = 0x01, /* CORE */
3679         }
3680         };
3681
3682         ZERO_STRUCT(server_challenge);
3683
3684         status = smb1cli_req_recv(subreq, state,
3685                                   &recv_iov,
3686                                   &inhdr,
3687                                   &wct,
3688                                   &vwv,
3689                                   NULL, /* pvwv_offset */
3690                                   &num_bytes,
3691                                   &bytes,
3692                                   NULL, /* pbytes_offset */
3693                                   NULL, /* pinbuf */
3694                                   expected, ARRAY_SIZE(expected));
3695         TALLOC_FREE(subreq);
3696         if (tevent_req_nterror(req, status)) {
3697                 return;
3698         }
3699
3700         flags = CVAL(inhdr, HDR_FLG);
3701
3702         protnum = SVAL(vwv, 0);
3703
3704         for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
3705                 if (smb1cli_prots[i].proto < state->min_protocol) {
3706                         continue;
3707                 }
3708
3709                 if (smb1cli_prots[i].proto > state->max_protocol) {
3710                         continue;
3711                 }
3712
3713                 if (protnum != num_prots) {
3714                         num_prots++;
3715                         continue;
3716                 }
3717
3718                 conn->protocol = smb1cli_prots[i].proto;
3719                 break;
3720         }
3721
3722         if (conn->protocol == PROTOCOL_NONE) {
3723                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3724                 return;
3725         }
3726
3727         if ((conn->protocol < PROTOCOL_NT1) && conn->mandatory_signing) {
3728                 DEBUG(0,("smbXcli_negprot: SMB signing is mandatory "
3729                          "and the selected protocol level doesn't support it.\n"));
3730                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3731                 return;
3732         }
3733
3734         if (flags & FLAG_SUPPORT_LOCKREAD) {
3735                 server_lockread = true;
3736                 server_writeunlock = true;
3737         }
3738
3739         if (conn->protocol >= PROTOCOL_NT1) {
3740                 const char *client_signing = NULL;
3741                 bool server_mandatory = false;
3742                 bool server_allowed = false;
3743                 const char *server_signing = NULL;
3744                 bool ok;
3745                 uint8_t key_len;
3746
3747                 if (wct != 0x11) {
3748                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3749                         return;
3750                 }
3751
3752                 /* NT protocol */
3753                 server_security_mode = CVAL(vwv + 1, 0);
3754                 server_max_mux = SVAL(vwv + 1, 1);
3755                 server_max_xmit = IVAL(vwv + 3, 1);
3756                 server_session_key = IVAL(vwv + 7, 1);
3757                 server_time_zone = SVALS(vwv + 15, 1);
3758                 server_time_zone *= 60;
3759                 /* this time arrives in real GMT */
3760                 server_system_time = BVAL(vwv + 11, 1);
3761                 server_capabilities = IVAL(vwv + 9, 1);
3762
3763                 key_len = CVAL(vwv + 16, 1);
3764
3765                 if (server_capabilities & CAP_RAW_MODE) {
3766                         server_readbraw = true;
3767                         server_writebraw = true;
3768                 }
3769                 if (server_capabilities & CAP_LOCK_AND_READ) {
3770                         server_lockread = true;
3771                 }
3772
3773                 if (server_capabilities & CAP_EXTENDED_SECURITY) {
3774                         DATA_BLOB blob1, blob2;
3775
3776                         if (num_bytes < 16) {
3777                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3778                                 return;
3779                         }
3780
3781                         blob1 = data_blob_const(bytes, 16);
3782                         status = GUID_from_data_blob(&blob1, &server_guid);
3783                         if (tevent_req_nterror(req, status)) {
3784                                 return;
3785                         }
3786
3787                         blob1 = data_blob_const(bytes+16, num_bytes-16);
3788                         blob2 = data_blob_dup_talloc(state, blob1);
3789                         if (blob1.length > 0 &&
3790                             tevent_req_nomem(blob2.data, req)) {
3791                                 return;
3792                         }
3793                         server_gss_blob = blob2;
3794                 } else {
3795                         DATA_BLOB blob1, blob2;
3796
3797                         if (num_bytes < key_len) {
3798                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3799                                 return;
3800                         }
3801
3802                         if (key_len != 0 && key_len != 8) {
3803                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3804                                 return;
3805                         }
3806
3807                         if (key_len == 8) {
3808                                 memcpy(server_challenge, bytes, 8);
3809                         }
3810
3811                         blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
3812                         blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
3813                         if (blob1.length > 0) {
3814                                 size_t len;
3815
3816                                 len = utf16_len_n(blob1.data,
3817                                                   blob1.length);
3818                                 blob1.length = len;
3819
3820                                 ok = convert_string_talloc(state,
3821                                                            CH_UTF16LE,
3822                                                            CH_UNIX,
3823                                                            blob1.data,
3824                                                            blob1.length,
3825                                                            &server_workgroup,
3826                                                            &len);
3827                                 if (!ok) {
3828                                         status = map_nt_error_from_unix_common(errno);
3829                                         tevent_req_nterror(req, status);
3830                                         return;
3831                                 }
3832                         }
3833
3834                         blob2.data += blob1.length;
3835                         blob2.length -= blob1.length;
3836                         if (blob2.length > 0) {
3837                                 size_t len;
3838
3839                                 len = utf16_len_n(blob1.data,
3840                                                   blob1.length);
3841                                 blob1.length = len;
3842
3843                                 ok = convert_string_talloc(state,
3844                                                            CH_UTF16LE,
3845                                                            CH_UNIX,
3846                                                            blob2.data,
3847                                                            blob2.length,
3848                                                            &server_name,
3849                                                            &len);
3850                                 if (!ok) {
3851                                         status = map_nt_error_from_unix_common(errno);
3852                                         tevent_req_nterror(req, status);
3853                                         return;
3854                                 }
3855                         }
3856                 }
3857
3858                 client_signing = "disabled";
3859                 if (conn->allow_signing) {
3860                         client_signing = "allowed";
3861                 }
3862                 if (conn->mandatory_signing) {
3863                         client_signing = "required";
3864                 }
3865
3866                 server_signing = "not supported";
3867                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
3868                         server_signing = "supported";
3869                         server_allowed = true;
3870                 }
3871                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
3872                         server_signing = "required";
3873                         server_mandatory = true;
3874                 }
3875
3876                 ok = smb_signing_set_negotiated(conn->smb1.signing,
3877                                                 server_allowed,
3878                                                 server_mandatory);
3879                 if (!ok) {
3880                         DEBUG(1,("cli_negprot: SMB signing is required, "
3881                                  "but client[%s] and server[%s] mismatch\n",
3882                                  client_signing, server_signing));
3883                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3884                         return;
3885                 }
3886
3887         } else if (conn->protocol >= PROTOCOL_LANMAN1) {
3888                 DATA_BLOB blob1;
3889                 uint8_t key_len;
3890                 time_t t;
3891
3892                 if (wct != 0x0D) {
3893                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3894                         return;
3895                 }
3896
3897                 server_security_mode = SVAL(vwv + 1, 0);
3898                 server_max_xmit = SVAL(vwv + 2, 0);
3899                 server_max_mux = SVAL(vwv + 3, 0);
3900                 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
3901                 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
3902                 server_session_key = IVAL(vwv + 6, 0);
3903                 server_time_zone = SVALS(vwv + 10, 0);
3904                 server_time_zone *= 60;
3905                 /* this time is converted to GMT by make_unix_date */
3906                 t = pull_dos_date((const uint8_t *)(vwv + 8), server_time_zone);
3907                 unix_to_nt_time(&server_system_time, t);
3908                 key_len = SVAL(vwv + 11, 0);
3909
3910                 if (num_bytes < key_len) {
3911                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3912                         return;
3913                 }
3914
3915                 if (key_len != 0 && key_len != 8) {
3916                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3917                         return;
3918                 }
3919
3920                 if (key_len == 8) {
3921                         memcpy(server_challenge, bytes, 8);
3922                 }
3923
3924                 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
3925                 if (blob1.length > 0) {
3926                         size_t len;
3927                         bool ok;
3928
3929                         len = utf16_len_n(blob1.data,
3930                                           blob1.length);
3931                         blob1.length = len;
3932
3933                         ok = convert_string_talloc(state,
3934                                                    CH_DOS,
3935                                                    CH_UNIX,
3936                                                    blob1.data,
3937                                                    blob1.length,
3938                                                    &server_workgroup,
3939                                                    &len);
3940                         if (!ok) {
3941                                 status = map_nt_error_from_unix_common(errno);
3942                                 tevent_req_nterror(req, status);
3943                                 return;
3944                         }
3945                 }
3946
3947         } else {
3948                 /* the old core protocol */
3949                 server_time_zone = get_time_zone(time(NULL));
3950                 server_max_xmit = 1024;
3951                 server_max_mux = 1;
3952         }
3953
3954         if (server_max_xmit < 1024) {
3955                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3956                 return;
3957         }
3958
3959         if (server_max_mux < 1) {
3960                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3961                 return;
3962         }
3963
3964         /*
3965          * Now calculate the negotiated capabilities
3966          * based on the mask for:
3967          * - client only flags
3968          * - flags used in both directions
3969          * - server only flags
3970          */
3971         both_capabilities = client_capabilities & server_capabilities;
3972         capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
3973         capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
3974         capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
3975
3976         max_xmit = MIN(client_max_xmit, server_max_xmit);
3977
3978         conn->smb1.server.capabilities = server_capabilities;
3979         conn->smb1.capabilities = capabilities;
3980
3981         conn->smb1.server.max_xmit = server_max_xmit;
3982         conn->smb1.max_xmit = max_xmit;
3983
3984         conn->smb1.server.max_mux = server_max_mux;
3985
3986         conn->smb1.server.security_mode = server_security_mode;
3987
3988         conn->smb1.server.readbraw = server_readbraw;
3989         conn->smb1.server.writebraw = server_writebraw;
3990         conn->smb1.server.lockread = server_lockread;
3991         conn->smb1.server.writeunlock = server_writeunlock;
3992
3993         conn->smb1.server.session_key = server_session_key;
3994
3995         talloc_steal(conn, server_gss_blob.data);
3996         conn->smb1.server.gss_blob = server_gss_blob;
3997         conn->smb1.server.guid = server_guid;
3998         memcpy(conn->smb1.server.challenge, server_challenge, 8);
3999         conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
4000         conn->smb1.server.name = talloc_move(conn, &server_name);
4001
4002         conn->smb1.server.time_zone = server_time_zone;
4003         conn->smb1.server.system_time = server_system_time;
4004
4005         tevent_req_done(req);
4006 }
4007
4008 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state)
4009 {
4010         size_t i;
4011         uint8_t *buf;
4012         uint16_t dialect_count = 0;
4013
4014         buf = state->smb2.dyn;
4015         for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4016                 if (smb2cli_prots[i].proto < state->min_protocol) {
4017                         continue;
4018                 }
4019
4020                 if (smb2cli_prots[i].proto > state->max_protocol) {
4021                         continue;
4022                 }
4023
4024                 SSVAL(buf, dialect_count*2, smb2cli_prots[i].smb2_dialect);
4025                 dialect_count++;
4026         }
4027
4028         buf = state->smb2.fixed;
4029         SSVAL(buf, 0, 36);
4030         SSVAL(buf, 2, dialect_count);
4031         SSVAL(buf, 4, state->conn->smb2.client.security_mode);
4032         SSVAL(buf, 6, 0);       /* Reserved */
4033         if (state->max_protocol >= PROTOCOL_SMB2_22) {
4034                 SIVAL(buf, 8, state->conn->smb2.client.capabilities);
4035         } else {
4036                 SIVAL(buf, 8, 0);       /* Capabilities */
4037         }
4038         if (state->max_protocol >= PROTOCOL_SMB2_10) {
4039                 NTSTATUS status;
4040                 DATA_BLOB blob;
4041
4042                 status = GUID_to_ndr_blob(&state->conn->smb2.client.guid,
4043                                           state, &blob);
4044                 if (!NT_STATUS_IS_OK(status)) {
4045                         return NULL;
4046                 }
4047                 memcpy(buf+12, blob.data, 16); /* ClientGuid */
4048         } else {
4049                 memset(buf+12, 0, 16);  /* ClientGuid */
4050         }
4051         SBVAL(buf, 28, 0);      /* ClientStartTime */
4052
4053         return smb2cli_req_send(state, state->ev,
4054                                 state->conn, SMB2_OP_NEGPROT,
4055                                 0, 0, /* flags */
4056                                 state->timeout_msec,
4057                                 NULL, NULL, /* tcon, session */
4058                                 state->smb2.fixed, sizeof(state->smb2.fixed),
4059                                 state->smb2.dyn, dialect_count*2);
4060 }
4061
4062 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
4063 {
4064         struct tevent_req *req =
4065                 tevent_req_callback_data(subreq,
4066                 struct tevent_req);
4067         struct smbXcli_negprot_state *state =
4068                 tevent_req_data(req,
4069                 struct smbXcli_negprot_state);
4070         struct smbXcli_conn *conn = state->conn;
4071         size_t security_offset, security_length;
4072         DATA_BLOB blob;
4073         NTSTATUS status;
4074         struct iovec *iov;
4075         uint8_t *body;
4076         size_t i;
4077         uint16_t dialect_revision;
4078         static const struct smb2cli_req_expected_response expected[] = {
4079         {
4080                 .status = NT_STATUS_OK,
4081                 .body_size = 0x41
4082         }
4083         };
4084
4085         status = smb2cli_req_recv(subreq, state, &iov,
4086                                   expected, ARRAY_SIZE(expected));
4087         TALLOC_FREE(subreq);
4088         if (tevent_req_nterror(req, status)) {
4089                 return;
4090         }
4091
4092         body = (uint8_t *)iov[1].iov_base;
4093
4094         dialect_revision = SVAL(body, 4);
4095
4096         for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4097                 if (smb2cli_prots[i].proto < state->min_protocol) {
4098                         continue;
4099                 }
4100
4101                 if (smb2cli_prots[i].proto > state->max_protocol) {
4102                         continue;
4103                 }
4104
4105                 if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
4106                         continue;
4107                 }
4108
4109                 conn->protocol = smb2cli_prots[i].proto;
4110                 break;
4111         }
4112
4113         if (conn->protocol == PROTOCOL_NONE) {
4114                 if (state->min_protocol >= PROTOCOL_SMB2_02) {
4115                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4116                         return;
4117                 }
4118
4119                 if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
4120                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4121                         return;
4122                 }
4123
4124                 /* make sure we do not loop forever */
4125                 state->min_protocol = PROTOCOL_SMB2_02;
4126
4127                 /*
4128                  * send a SMB2 negprot, in order to negotiate
4129                  * the SMB2 dialect.
4130                  */
4131                 subreq = smbXcli_negprot_smb2_subreq(state);
4132                 if (tevent_req_nomem(subreq, req)) {
4133                         return;
4134                 }
4135                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4136                 return;
4137         }
4138
4139         conn->smb2.server.security_mode = SVAL(body, 2);
4140
4141         blob = data_blob_const(body + 8, 16);
4142         status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
4143         if (tevent_req_nterror(req, status)) {
4144                 return;
4145         }
4146
4147         conn->smb2.server.capabilities  = IVAL(body, 24);
4148         conn->smb2.server.max_trans_size= IVAL(body, 28);
4149         conn->smb2.server.max_read_size = IVAL(body, 32);
4150         conn->smb2.server.max_write_size= IVAL(body, 36);
4151         conn->smb2.server.system_time   = BVAL(body, 40);
4152         conn->smb2.server.start_time    = BVAL(body, 48);
4153
4154         security_offset = SVAL(body, 56);
4155         security_length = SVAL(body, 58);
4156
4157         if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
4158                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4159                 return;
4160         }
4161
4162         if (security_length > iov[2].iov_len) {
4163                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4164                 return;
4165         }
4166
4167         conn->smb2.server.gss_blob = data_blob_talloc(conn,
4168                                                 iov[2].iov_base,
4169                                                 security_length);
4170         if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
4171                 return;
4172         }
4173
4174         tevent_req_done(req);
4175 }
4176
4177 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
4178                                                   TALLOC_CTX *tmp_mem,
4179                                                   uint8_t *inbuf)
4180 {
4181         size_t num_pending = talloc_array_length(conn->pending);
4182         struct tevent_req *subreq;
4183         struct smbXcli_req_state *substate;
4184         struct tevent_req *req;
4185         uint32_t protocol_magic;
4186         size_t inbuf_len = smb_len_nbt(inbuf);
4187
4188         if (num_pending != 1) {
4189                 return NT_STATUS_INTERNAL_ERROR;
4190         }
4191
4192         if (inbuf_len < 4) {
4193                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4194         }
4195
4196         subreq = conn->pending[0];
4197         substate = tevent_req_data(subreq, struct smbXcli_req_state);
4198         req = tevent_req_callback_data(subreq, struct tevent_req);
4199
4200         protocol_magic = IVAL(inbuf, 4);
4201
4202         switch (protocol_magic) {
4203         case SMB_MAGIC:
4204                 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4205                 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4206                 return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
4207
4208         case SMB2_MAGIC:
4209                 if (substate->smb2.recv_iov == NULL) {
4210                         /*
4211                          * For the SMB1 negprot we have move it.
4212                          */
4213                         substate->smb2.recv_iov = substate->smb1.recv_iov;
4214                         substate->smb1.recv_iov = NULL;
4215                 }
4216
4217                 /*
4218                  * we got an SMB2 answer, which consumed sequence number 0
4219                  * so we need to use 1 as the next one
4220                  */
4221                 conn->smb2.mid = 1;
4222                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4223                 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4224                 return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
4225         }
4226
4227         DEBUG(10, ("Got non-SMB PDU\n"));
4228         return NT_STATUS_INVALID_NETWORK_RESPONSE;
4229 }
4230
4231 NTSTATUS smbXcli_negprot_recv(struct tevent_req *req)
4232 {
4233         return tevent_req_simple_recv_ntstatus(req);
4234 }
4235
4236 NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
4237                          uint32_t timeout_msec,
4238                          enum protocol_types min_protocol,
4239                          enum protocol_types max_protocol)
4240 {
4241         TALLOC_CTX *frame = talloc_stackframe();
4242         struct tevent_context *ev;
4243         struct tevent_req *req;
4244         NTSTATUS status = NT_STATUS_NO_MEMORY;
4245         bool ok;
4246
4247         if (smbXcli_conn_has_async_calls(conn)) {
4248                 /*
4249                  * Can't use sync call while an async call is in flight
4250                  */
4251                 status = NT_STATUS_INVALID_PARAMETER_MIX;
4252                 goto fail;
4253         }
4254         ev = tevent_context_init(frame);
4255         if (ev == NULL) {
4256                 goto fail;
4257         }
4258         req = smbXcli_negprot_send(frame, ev, conn, timeout_msec,
4259                                    min_protocol, max_protocol);
4260         if (req == NULL) {
4261                 goto fail;
4262         }
4263         ok = tevent_req_poll(req, ev);
4264         if (!ok) {
4265                 status = map_nt_error_from_unix_common(errno);
4266                 goto fail;
4267         }
4268         status = smbXcli_negprot_recv(req);
4269  fail:
4270         TALLOC_FREE(frame);
4271         return status;
4272 }
4273
4274 static int smbXcli_session_destructor(struct smbXcli_session *session)
4275 {
4276         if (session->conn == NULL) {
4277                 return 0;
4278         }
4279
4280         DLIST_REMOVE(session->conn->sessions, session);
4281         return 0;
4282 }
4283
4284 struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
4285                                                struct smbXcli_conn *conn)
4286 {
4287         struct smbXcli_session *session;
4288
4289         session = talloc_zero(mem_ctx, struct smbXcli_session);
4290         if (session == NULL) {
4291                 return NULL;
4292         }
4293         session->smb2 = talloc_zero(session, struct smb2cli_session);
4294         if (session->smb2 == NULL) {
4295                 talloc_free(session);
4296                 return NULL;
4297         }
4298         talloc_set_destructor(session, smbXcli_session_destructor);
4299
4300         DLIST_ADD_END(conn->sessions, session, struct smbXcli_session *);
4301         session->conn = conn;
4302
4303         return session;
4304 }
4305
4306 NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
4307                                          TALLOC_CTX *mem_ctx,
4308                                          DATA_BLOB *key)
4309 {
4310         const DATA_BLOB *application_key;
4311
4312         *key = data_blob_null;
4313
4314         if (session->conn == NULL) {
4315                 return NT_STATUS_NO_USER_SESSION_KEY;
4316         }
4317
4318         if (session->conn->protocol >= PROTOCOL_SMB2_02) {
4319                 application_key = &session->smb2->application_key;
4320         } else {
4321                 application_key = &session->smb1.application_key;
4322         }
4323
4324         if (application_key->length == 0) {
4325                 return NT_STATUS_NO_USER_SESSION_KEY;
4326         }
4327
4328         *key = data_blob_dup_talloc(mem_ctx, *application_key);
4329         if (key->data == NULL) {
4330                 return NT_STATUS_NO_MEMORY;
4331         }
4332
4333         return NT_STATUS_OK;
4334 }
4335
4336 uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
4337 {
4338         return session->smb1.session_id;
4339 }
4340
4341 void smb1cli_session_set_id(struct smbXcli_session *session,
4342                             uint16_t session_id)
4343 {
4344         session->smb1.session_id = session_id;
4345 }
4346
4347 NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
4348                                          const DATA_BLOB _session_key)
4349 {
4350         struct smbXcli_conn *conn = session->conn;
4351         uint8_t session_key[16];
4352
4353         if (conn == NULL) {
4354                 return NT_STATUS_INVALID_PARAMETER_MIX;
4355         }
4356
4357         if (session->smb1.application_key.length != 0) {
4358                 /*
4359                  * TODO: do not allow this...
4360                  *
4361                  * return NT_STATUS_INVALID_PARAMETER_MIX;
4362                  */
4363                 data_blob_clear_free(&session->smb1.application_key);
4364                 session->smb1.protected_key = false;
4365         }
4366
4367         if (_session_key.length == 0) {
4368                 return NT_STATUS_OK;
4369         }
4370
4371         ZERO_STRUCT(session_key);
4372         memcpy(session_key, _session_key.data,
4373                MIN(_session_key.length, sizeof(session_key)));
4374
4375         session->smb1.application_key = data_blob_talloc(session,
4376                                                          session_key,
4377                                                          sizeof(session_key));
4378         ZERO_STRUCT(session_key);
4379         if (session->smb1.application_key.data == NULL) {
4380                 return NT_STATUS_NO_MEMORY;
4381         }
4382
4383         session->smb1.protected_key = false;
4384
4385         return NT_STATUS_OK;
4386 }
4387
4388 NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
4389 {
4390         if (session->smb1.protected_key) {
4391                 /* already protected */
4392                 return NT_STATUS_OK;
4393         }
4394
4395         if (session->smb1.application_key.length != 16) {
4396                 return NT_STATUS_INVALID_PARAMETER_MIX;
4397         }
4398
4399         smb_key_derivation(session->smb1.application_key.data,
4400                            session->smb1.application_key.length,
4401                            session->smb1.application_key.data);
4402
4403         session->smb1.protected_key = true;
4404
4405         return NT_STATUS_OK;
4406 }
4407
4408 uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
4409 {
4410         struct smbXcli_conn *conn = session->conn;
4411         uint8_t security_mode = 0;
4412
4413         if (conn == NULL) {
4414                 return security_mode;
4415         }
4416
4417         security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
4418         if (conn->mandatory_signing) {
4419                 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
4420         }
4421
4422         return security_mode;
4423 }
4424
4425 uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
4426 {
4427         return session->smb2->session_id;
4428 }
4429
4430 uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
4431 {
4432         return session->smb2->session_flags;
4433 }
4434
4435 void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
4436                                       uint64_t session_id,
4437                                       uint16_t session_flags)
4438 {
4439         session->smb2->session_id = session_id;
4440         session->smb2->session_flags = session_flags;
4441 }
4442
4443 void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
4444 {
4445         session->smb2->channel_sequence += 1;
4446 }
4447
4448 NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
4449                                          const DATA_BLOB _session_key,
4450                                          const struct iovec *recv_iov)
4451 {
4452         struct smbXcli_conn *conn = session->conn;
4453         uint16_t no_sign_flags;
4454         uint8_t session_key[16];
4455         NTSTATUS status;
4456
4457         if (conn == NULL) {
4458                 return NT_STATUS_INVALID_PARAMETER_MIX;
4459         }
4460
4461         no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST | SMB2_SESSION_FLAG_IS_NULL;
4462
4463         if (session->smb2->session_flags & no_sign_flags) {
4464                 session->smb2->should_sign = false;
4465                 return NT_STATUS_OK;
4466         }
4467
4468         if (session->smb2->signing_key.length != 0) {
4469                 return NT_STATUS_INVALID_PARAMETER_MIX;
4470         }
4471
4472         ZERO_STRUCT(session_key);
4473         memcpy(session_key, _session_key.data,
4474                MIN(_session_key.length, sizeof(session_key)));
4475
4476         session->smb2->signing_key = data_blob_talloc(session,
4477                                                      session_key,
4478                                                      sizeof(session_key));
4479         if (session->smb2->signing_key.data == NULL) {
4480                 ZERO_STRUCT(session_key);
4481                 return NT_STATUS_NO_MEMORY;
4482         }
4483
4484         if (conn->protocol >= PROTOCOL_SMB2_24) {
4485                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCMAC");
4486                 const DATA_BLOB context = data_blob_string_const_null("SmbSign");
4487
4488                 smb2_key_derivation(session_key, sizeof(session_key),
4489                                     label.data, label.length,
4490                                     context.data, context.length,
4491                                     session->smb2->signing_key.data);
4492         }
4493
4494         session->smb2->encryption_key = data_blob_dup_talloc(session,
4495                                                 session->smb2->signing_key);
4496         if (session->smb2->encryption_key.data == NULL) {
4497                 ZERO_STRUCT(session_key);
4498                 return NT_STATUS_NO_MEMORY;
4499         }
4500
4501         if (conn->protocol >= PROTOCOL_SMB2_24) {
4502                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
4503                 const DATA_BLOB context = data_blob_string_const_null("ServerIn ");
4504
4505                 smb2_key_derivation(session_key, sizeof(session_key),
4506                                     label.data, label.length,
4507                                     context.data, context.length,
4508                                     session->smb2->encryption_key.data);
4509         }
4510
4511         session->smb2->decryption_key = data_blob_dup_talloc(session,
4512                                                 session->smb2->signing_key);
4513         if (session->smb2->decryption_key.data == NULL) {
4514                 ZERO_STRUCT(session_key);
4515                 return NT_STATUS_NO_MEMORY;
4516         }
4517
4518         if (conn->protocol >= PROTOCOL_SMB2_24) {
4519                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
4520                 const DATA_BLOB context = data_blob_string_const_null("ServerOut");
4521
4522                 smb2_key_derivation(session_key, sizeof(session_key),
4523                                     label.data, label.length,
4524                                     context.data, context.length,
4525                                     session->smb2->decryption_key.data);
4526         }
4527
4528         session->smb2->application_key = data_blob_dup_talloc(session,
4529                                                 session->smb2->signing_key);
4530         if (session->smb2->application_key.data == NULL) {
4531                 ZERO_STRUCT(session_key);
4532                 return NT_STATUS_NO_MEMORY;
4533         }
4534
4535         if (conn->protocol >= PROTOCOL_SMB2_24) {
4536                 const DATA_BLOB label = data_blob_string_const_null("SMB2APP");
4537                 const DATA_BLOB context = data_blob_string_const_null("SmbRpc");
4538
4539                 smb2_key_derivation(session_key, sizeof(session_key),
4540                                     label.data, label.length,
4541                                     context.data, context.length,
4542                                     session->smb2->application_key.data);
4543         }
4544         ZERO_STRUCT(session_key);
4545
4546         session->smb2_channel.signing_key = data_blob_dup_talloc(session,
4547                                                 session->smb2->signing_key);
4548         if (session->smb2_channel.signing_key.data == NULL) {
4549                 return NT_STATUS_NO_MEMORY;
4550         }
4551
4552         status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
4553                                         session->conn->protocol,
4554                                         recv_iov, 3);
4555         if (!NT_STATUS_IS_OK(status)) {
4556                 return status;
4557         }
4558
4559         session->smb2->should_sign = false;
4560         session->smb2->should_encrypt = false;
4561
4562         if (conn->desire_signing) {
4563                 session->smb2->should_sign = true;
4564         }
4565
4566         if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
4567                 session->smb2->should_sign = true;
4568         }
4569
4570         if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
4571                 session->smb2->should_encrypt = true;
4572         }
4573
4574         if (conn->protocol < PROTOCOL_SMB2_24) {
4575                 session->smb2->should_encrypt = false;
4576         }
4577
4578         if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
4579                 session->smb2->should_encrypt = false;
4580         }
4581
4582         generate_random_buffer((uint8_t *)&session->smb2->nonce_high,
4583                                sizeof(session->smb2->nonce_high));
4584         session->smb2->nonce_low = 1;
4585
4586         return NT_STATUS_OK;
4587 }
4588
4589 NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
4590                                         struct smbXcli_session *session1,
4591                                         struct smbXcli_conn *conn,
4592                                         struct smbXcli_session **_session2)
4593 {
4594         struct smbXcli_session *session2;
4595
4596         if (session1->smb2->signing_key.length == 0) {
4597                 return NT_STATUS_INVALID_PARAMETER_MIX;
4598         }
4599
4600         if (conn == NULL) {
4601                 return NT_STATUS_INVALID_PARAMETER_MIX;
4602         }
4603
4604         session2 = talloc_zero(mem_ctx, struct smbXcli_session);
4605         if (session2 == NULL) {
4606                 return NT_STATUS_NO_MEMORY;
4607         }
4608         session2->smb2 = talloc_reference(session2, session1->smb2);
4609         if (session2->smb2 == NULL) {
4610                 talloc_free(session2);
4611                 return NT_STATUS_NO_MEMORY;
4612         }
4613
4614         talloc_set_destructor(session2, smbXcli_session_destructor);
4615         DLIST_ADD_END(conn->sessions, session2, struct smbXcli_session *);
4616         session2->conn = conn;
4617
4618         *_session2 = session2;
4619         return NT_STATUS_OK;
4620 }
4621
4622 NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
4623                                          const DATA_BLOB _channel_key,
4624                                          const struct iovec *recv_iov)
4625 {
4626         struct smbXcli_conn *conn = session->conn;
4627         uint8_t channel_key[16];
4628         NTSTATUS status;
4629
4630         if (conn == NULL) {
4631                 return NT_STATUS_INVALID_PARAMETER_MIX;
4632         }
4633
4634         if (session->smb2_channel.signing_key.length != 0) {
4635                 return NT_STATUS_INVALID_PARAMETER_MIX;
4636         }
4637
4638         ZERO_STRUCT(channel_key);
4639         memcpy(channel_key, _channel_key.data,
4640                MIN(_channel_key.length, sizeof(channel_key)));
4641
4642         session->smb2_channel.signing_key = data_blob_talloc(session,
4643                                                 channel_key,
4644                                                 sizeof(channel_key));
4645         if (session->smb2_channel.signing_key.data == NULL) {
4646                 ZERO_STRUCT(channel_key);
4647                 return NT_STATUS_NO_MEMORY;
4648         }
4649
4650         if (conn->protocol >= PROTOCOL_SMB2_24) {
4651                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCMAC");
4652                 const DATA_BLOB context = data_blob_string_const_null("SmbSign");
4653
4654                 smb2_key_derivation(channel_key, sizeof(channel_key),
4655                                     label.data, label.length,
4656                                     context.data, context.length,
4657                                     session->smb2_channel.signing_key.data);
4658         }
4659         ZERO_STRUCT(channel_key);
4660
4661         status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
4662                                         session->conn->protocol,
4663                                         recv_iov, 3);
4664         if (!NT_STATUS_IS_OK(status)) {
4665                 return status;
4666         }
4667
4668         return NT_STATUS_OK;
4669 }
4670
4671 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
4672 {
4673         struct smbXcli_tcon *tcon;
4674
4675         tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
4676         if (tcon == NULL) {
4677                 return NULL;
4678         }
4679
4680         return tcon;
4681 }
4682
4683 uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
4684 {
4685         return tcon->smb1.tcon_id;
4686 }
4687
4688 void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
4689 {
4690         tcon->smb1.tcon_id = tcon_id;
4691 }
4692
4693 bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
4694                              uint16_t tcon_id,
4695                              uint16_t optional_support,
4696                              uint32_t maximal_access,
4697                              uint32_t guest_maximal_access,
4698                              const char *service,
4699                              const char *fs_type)
4700 {
4701         tcon->smb1.tcon_id = tcon_id;
4702         tcon->smb1.optional_support = optional_support;
4703         tcon->smb1.maximal_access = maximal_access;
4704         tcon->smb1.guest_maximal_access = guest_maximal_access;
4705
4706         TALLOC_FREE(tcon->smb1.service);
4707         tcon->smb1.service = talloc_strdup(tcon, service);
4708         if (service != NULL && tcon->smb1.service == NULL) {
4709                 return false;
4710         }
4711
4712         TALLOC_FREE(tcon->smb1.fs_type);
4713         tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
4714         if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
4715                 return false;
4716         }
4717
4718         return true;
4719 }
4720
4721 uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
4722 {
4723         return tcon->smb2.tcon_id;
4724 }
4725
4726 uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
4727 {
4728         return tcon->smb2.capabilities;
4729 }
4730
4731 void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
4732                              struct smbXcli_session *session,
4733                              uint32_t tcon_id,
4734                              uint8_t type,
4735                              uint32_t flags,
4736                              uint32_t capabilities,
4737                              uint32_t maximal_access)
4738 {
4739         tcon->smb2.tcon_id = tcon_id;
4740         tcon->smb2.type = type;
4741         tcon->smb2.flags = flags;
4742         tcon->smb2.capabilities = capabilities;
4743         tcon->smb2.maximal_access = maximal_access;
4744
4745         tcon->smb2.should_encrypt = false;
4746
4747         if (session == NULL) {
4748                 return;
4749         }
4750
4751         tcon->smb2.should_encrypt = session->smb2->should_encrypt;
4752
4753         if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
4754                 tcon->smb2.should_encrypt = true;
4755         }
4756 }