libcli/smb: all flags except SMB2_HDR_FLAG_ASYNC should be cleared in a cancel request.
[bbaumbach/samba-autobuild/.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         /*
2426          * clear everything but the SMB2_HDR_FLAG_ASYNC flag
2427          * e.g. if SMB2_HDR_FLAG_CHAINED is set we get INVALID_PARAMETER back
2428          */
2429         flags &= SMB2_HDR_FLAG_ASYNC;
2430
2431         if (flags & SMB2_HDR_FLAG_ASYNC) {
2432                 mid = 0;
2433         }
2434
2435         SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, flags);
2436         SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
2437         SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, aid);
2438
2439         status = smb2cli_req_compound_submit(&subreq, 1);
2440         if (!NT_STATUS_IS_OK(status)) {
2441                 TALLOC_FREE(subreq);
2442                 return false;
2443         }
2444
2445         tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2446
2447         return true;
2448 }
2449
2450 static void smb2cli_req_cancel_done(struct tevent_req *subreq)
2451 {
2452         /* we do not care about the result */
2453         TALLOC_FREE(subreq);
2454 }
2455
2456 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
2457                                       struct tevent_context *ev,
2458                                       struct smbXcli_conn *conn,
2459                                       uint16_t cmd,
2460                                       uint32_t additional_flags,
2461                                       uint32_t clear_flags,
2462                                       uint32_t timeout_msec,
2463                                       struct smbXcli_tcon *tcon,
2464                                       struct smbXcli_session *session,
2465                                       const uint8_t *fixed,
2466                                       uint16_t fixed_len,
2467                                       const uint8_t *dyn,
2468                                       uint32_t dyn_len)
2469 {
2470         struct tevent_req *req;
2471         struct smbXcli_req_state *state;
2472         uint32_t flags = 0;
2473         uint32_t tid = 0;
2474         uint64_t uid = 0;
2475         bool use_channel_sequence = false;
2476         uint16_t channel_sequence = 0;
2477
2478         req = tevent_req_create(mem_ctx, &state,
2479                                 struct smbXcli_req_state);
2480         if (req == NULL) {
2481                 return NULL;
2482         }
2483
2484         state->ev = ev;
2485         state->conn = conn;
2486         state->session = session;
2487         state->tcon = tcon;
2488
2489         if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
2490                 use_channel_sequence = true;
2491         } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
2492                 use_channel_sequence = true;
2493         }
2494
2495         if (session) {
2496                 uid = session->smb2->session_id;
2497
2498                 if (use_channel_sequence) {
2499                         channel_sequence = session->smb2->channel_sequence;
2500                 }
2501
2502                 state->smb2.should_sign = session->smb2->should_sign;
2503                 state->smb2.should_encrypt = session->smb2->should_encrypt;
2504
2505                 if (cmd == SMB2_OP_SESSSETUP &&
2506                     session->smb2->signing_key.length != 0) {
2507                         state->smb2.should_sign = true;
2508                 }
2509
2510                 if (cmd == SMB2_OP_SESSSETUP &&
2511                     session->smb2_channel.signing_key.length == 0) {
2512                         state->smb2.should_encrypt = false;
2513                 }
2514         }
2515
2516         if (tcon) {
2517                 tid = tcon->smb2.tcon_id;
2518
2519                 if (tcon->smb2.should_encrypt) {
2520                         state->smb2.should_encrypt = true;
2521                 }
2522         }
2523
2524         if (state->smb2.should_encrypt) {
2525                 state->smb2.should_sign = false;
2526         }
2527
2528         state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
2529         if (state->smb2.recv_iov == NULL) {
2530                 TALLOC_FREE(req);
2531                 return NULL;
2532         }
2533
2534         flags |= additional_flags;
2535         flags &= ~clear_flags;
2536
2537         state->smb2.fixed = fixed;
2538         state->smb2.fixed_len = fixed_len;
2539         state->smb2.dyn = dyn;
2540         state->smb2.dyn_len = dyn_len;
2541
2542         if (state->smb2.should_encrypt) {
2543                 SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2544                 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
2545         }
2546
2547         SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID,    SMB2_MAGIC);
2548         SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH,         SMB2_HDR_BODY);
2549         SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE,         cmd);
2550         SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
2551         SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS,          flags);
2552         SIVAL(state->smb2.hdr, SMB2_HDR_PID,            0); /* reserved */
2553         SIVAL(state->smb2.hdr, SMB2_HDR_TID,            tid);
2554         SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID,     uid);
2555
2556         switch (cmd) {
2557         case SMB2_OP_CANCEL:
2558                 state->one_way = true;
2559                 break;
2560         case SMB2_OP_BREAK:
2561                 /*
2562                  * If this is a dummy request, it will have
2563                  * UINT64_MAX as message id.
2564                  * If we send on break acknowledgement,
2565                  * this gets overwritten later.
2566                  */
2567                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
2568                 break;
2569         }
2570
2571         if (timeout_msec > 0) {
2572                 struct timeval endtime;
2573
2574                 endtime = timeval_current_ofs_msec(timeout_msec);
2575                 if (!tevent_req_set_endtime(req, ev, endtime)) {
2576                         return req;
2577                 }
2578         }
2579
2580         return req;
2581 }
2582
2583 void smb2cli_req_set_notify_async(struct tevent_req *req)
2584 {
2585         struct smbXcli_req_state *state =
2586                 tevent_req_data(req,
2587                 struct smbXcli_req_state);
2588
2589         state->smb2.notify_async = true;
2590 }
2591
2592 static void smb2cli_req_writev_done(struct tevent_req *subreq);
2593 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2594                                                TALLOC_CTX *tmp_mem,
2595                                                uint8_t *inbuf);
2596
2597 NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
2598                                      int num_reqs)
2599 {
2600         struct smbXcli_req_state *state;
2601         struct tevent_req *subreq;
2602         struct iovec *iov;
2603         int i, num_iov, nbt_len;
2604
2605         /*
2606          * 1 for the nbt length
2607          * per request: TRANSFORM, HDR, fixed, dyn, padding
2608          * -1 because the last one does not need padding
2609          */
2610
2611         iov = talloc_array(reqs[0], struct iovec, 1 + 5*num_reqs - 1);
2612         if (iov == NULL) {
2613                 return NT_STATUS_NO_MEMORY;
2614         }
2615
2616         num_iov = 1;
2617         nbt_len = 0;
2618
2619         for (i=0; i<num_reqs; i++) {
2620                 int tf_iov;
2621                 int hdr_iov;
2622                 size_t reqlen;
2623                 bool ret;
2624                 uint16_t opcode;
2625                 uint64_t avail;
2626                 uint16_t charge;
2627                 uint16_t credits;
2628                 uint64_t mid;
2629                 const DATA_BLOB *signing_key = NULL;
2630                 const DATA_BLOB *encryption_key = NULL;
2631
2632                 if (!tevent_req_is_in_progress(reqs[i])) {
2633                         return NT_STATUS_INTERNAL_ERROR;
2634                 }
2635
2636                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2637
2638                 if (!smbXcli_conn_is_connected(state->conn)) {
2639                         return NT_STATUS_CONNECTION_DISCONNECTED;
2640                 }
2641
2642                 if ((state->conn->protocol != PROTOCOL_NONE) &&
2643                     (state->conn->protocol < PROTOCOL_SMB2_02)) {
2644                         return NT_STATUS_REVISION_MISMATCH;
2645                 }
2646
2647                 opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
2648                 if (opcode == SMB2_OP_CANCEL) {
2649                         goto skip_credits;
2650                 }
2651
2652                 avail = UINT64_MAX - state->conn->smb2.mid;
2653                 if (avail < 1) {
2654                         return NT_STATUS_CONNECTION_ABORTED;
2655                 }
2656
2657                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2658                         charge = (MAX(state->smb2.dyn_len, 1) - 1)/ 65536 + 1;
2659                 } else {
2660                         charge = 1;
2661                 }
2662
2663                 charge = MAX(state->smb2.credit_charge, charge);
2664
2665                 avail = MIN(avail, state->conn->smb2.cur_credits);
2666                 if (avail < charge) {
2667                         return NT_STATUS_INTERNAL_ERROR;
2668                 }
2669
2670                 credits = 0;
2671                 if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
2672                         credits = state->conn->smb2.max_credits -
2673                                   state->conn->smb2.cur_credits;
2674                 }
2675                 if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
2676                         credits += 1;
2677                 }
2678
2679                 mid = state->conn->smb2.mid;
2680                 state->conn->smb2.mid += charge;
2681                 state->conn->smb2.cur_credits -= charge;
2682
2683                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2684                         SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
2685                 }
2686                 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
2687                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
2688
2689 skip_credits:
2690                 if (state->session) {
2691                         /*
2692                          * We prefer the channel signing key if it is
2693                          * already there.
2694                          */
2695                         if (state->smb2.should_sign) {
2696                                 signing_key = &state->session->smb2_channel.signing_key;
2697                         }
2698
2699                         /*
2700                          * If it is a channel binding, we already have the main
2701                          * signing key and try that one.
2702                          */
2703                         if (signing_key && signing_key->length == 0) {
2704                                 signing_key = &state->session->smb2->signing_key;
2705                         }
2706
2707                         /*
2708                          * If we do not have any session key yet, we skip the
2709                          * signing of SMB2_OP_SESSSETUP requests.
2710                          */
2711                         if (signing_key && signing_key->length == 0) {
2712                                 signing_key = NULL;
2713                         }
2714
2715                         if (state->smb2.should_encrypt) {
2716                                 encryption_key = &state->session->smb2->encryption_key;
2717                         }
2718                 }
2719
2720                 if (encryption_key) {
2721                         tf_iov = num_iov;
2722                         iov[num_iov].iov_base = state->smb2.transform;
2723                         iov[num_iov].iov_len  = sizeof(state->smb2.transform);
2724                         num_iov += 1;
2725                 }
2726
2727                 hdr_iov = num_iov;
2728                 iov[num_iov].iov_base = state->smb2.hdr;
2729                 iov[num_iov].iov_len  = sizeof(state->smb2.hdr);
2730                 num_iov += 1;
2731
2732                 iov[num_iov].iov_base = discard_const(state->smb2.fixed);
2733                 iov[num_iov].iov_len  = state->smb2.fixed_len;
2734                 num_iov += 1;
2735
2736                 if (state->smb2.dyn != NULL) {
2737                         iov[num_iov].iov_base = discard_const(state->smb2.dyn);
2738                         iov[num_iov].iov_len  = state->smb2.dyn_len;
2739                         num_iov += 1;
2740                 }
2741
2742                 reqlen  = sizeof(state->smb2.hdr);
2743                 reqlen += state->smb2.fixed_len;
2744                 reqlen += state->smb2.dyn_len;
2745
2746                 if (i < num_reqs-1) {
2747                         if ((reqlen % 8) > 0) {
2748                                 uint8_t pad = 8 - (reqlen % 8);
2749                                 iov[num_iov].iov_base = state->smb2.pad;
2750                                 iov[num_iov].iov_len = pad;
2751                                 num_iov += 1;
2752                                 reqlen += pad;
2753                         }
2754                         SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
2755                 }
2756
2757                 if (encryption_key) {
2758                         NTSTATUS status;
2759                         uint8_t *buf;
2760                         int vi;
2761
2762                         SBVAL(state->smb2.transform, SMB2_TF_NONCE,
2763                               state->session->smb2->nonce_low);
2764                         SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
2765                               state->session->smb2->nonce_high);
2766
2767                         state->session->smb2->nonce_low += 1;
2768                         if (state->session->smb2->nonce_low == 0) {
2769                                 state->session->smb2->nonce_high += 1;
2770                                 state->session->smb2->nonce_low += 1;
2771                         }
2772
2773                         buf = talloc_array(iov, uint8_t, reqlen);
2774                         if (buf == NULL) {
2775                                 return NT_STATUS_NO_MEMORY;
2776                         }
2777
2778                         reqlen += SMB2_TF_HDR_SIZE;
2779
2780                         /*
2781                          * We copy the buffers before encrypting them,
2782                          * this is at least currently needed for the
2783                          * to keep state->smb2.hdr.
2784                          *
2785                          * Also the callers may expect there buffers
2786                          * to be const.
2787                          */
2788                         for (vi = hdr_iov; vi < num_iov; vi++) {
2789                                 struct iovec *v = &iov[vi];
2790                                 const uint8_t *o = (const uint8_t *)v->iov_base;
2791
2792                                 memcpy(buf, o, v->iov_len);
2793                                 v->iov_base = (void *)buf;
2794                                 buf += v->iov_len;
2795                         }
2796
2797                         status = smb2_signing_encrypt_pdu(*encryption_key,
2798                                                 state->session->conn->protocol,
2799                                                 &iov[tf_iov], num_iov - tf_iov);
2800                         if (!NT_STATUS_IS_OK(status)) {
2801                                 return status;
2802                         }
2803                 } else if (signing_key) {
2804                         NTSTATUS status;
2805
2806                         status = smb2_signing_sign_pdu(*signing_key,
2807                                                        state->session->conn->protocol,
2808                                                        &iov[hdr_iov], num_iov - hdr_iov);
2809                         if (!NT_STATUS_IS_OK(status)) {
2810                                 return status;
2811                         }
2812                 }
2813
2814                 nbt_len += reqlen;
2815
2816                 ret = smbXcli_req_set_pending(reqs[i]);
2817                 if (!ret) {
2818                         return NT_STATUS_NO_MEMORY;
2819                 }
2820         }
2821
2822         state = tevent_req_data(reqs[0], struct smbXcli_req_state);
2823         _smb_setlen_tcp(state->length_hdr, nbt_len);
2824         iov[0].iov_base = state->length_hdr;
2825         iov[0].iov_len  = sizeof(state->length_hdr);
2826
2827         if (state->conn->dispatch_incoming == NULL) {
2828                 state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
2829         }
2830
2831         subreq = writev_send(state, state->ev, state->conn->outgoing,
2832                              state->conn->write_fd, false, iov, num_iov);
2833         if (subreq == NULL) {
2834                 return NT_STATUS_NO_MEMORY;
2835         }
2836         tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
2837         return NT_STATUS_OK;
2838 }
2839
2840 void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
2841 {
2842         struct smbXcli_req_state *state =
2843                 tevent_req_data(req,
2844                 struct smbXcli_req_state);
2845
2846         state->smb2.credit_charge = charge;
2847 }
2848
2849 struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
2850                                     struct tevent_context *ev,
2851                                     struct smbXcli_conn *conn,
2852                                     uint16_t cmd,
2853                                     uint32_t additional_flags,
2854                                     uint32_t clear_flags,
2855                                     uint32_t timeout_msec,
2856                                     struct smbXcli_tcon *tcon,
2857                                     struct smbXcli_session *session,
2858                                     const uint8_t *fixed,
2859                                     uint16_t fixed_len,
2860                                     const uint8_t *dyn,
2861                                     uint32_t dyn_len)
2862 {
2863         struct tevent_req *req;
2864         NTSTATUS status;
2865
2866         req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
2867                                  additional_flags, clear_flags,
2868                                  timeout_msec,
2869                                  tcon, session,
2870                                  fixed, fixed_len, dyn, dyn_len);
2871         if (req == NULL) {
2872                 return NULL;
2873         }
2874         if (!tevent_req_is_in_progress(req)) {
2875                 return tevent_req_post(req, ev);
2876         }
2877         status = smb2cli_req_compound_submit(&req, 1);
2878         if (tevent_req_nterror(req, status)) {
2879                 return tevent_req_post(req, ev);
2880         }
2881         return req;
2882 }
2883
2884 static void smb2cli_req_writev_done(struct tevent_req *subreq)
2885 {
2886         struct tevent_req *req =
2887                 tevent_req_callback_data(subreq,
2888                 struct tevent_req);
2889         struct smbXcli_req_state *state =
2890                 tevent_req_data(req,
2891                 struct smbXcli_req_state);
2892         ssize_t nwritten;
2893         int err;
2894
2895         nwritten = writev_recv(subreq, &err);
2896         TALLOC_FREE(subreq);
2897         if (nwritten == -1) {
2898                 /* here, we need to notify all pending requests */
2899                 NTSTATUS status = map_nt_error_from_unix_common(err);
2900                 smbXcli_conn_disconnect(state->conn, status);
2901                 return;
2902         }
2903 }
2904
2905 static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
2906                                              uint8_t *buf,
2907                                              size_t buflen,
2908                                              TALLOC_CTX *mem_ctx,
2909                                              struct iovec **piov, int *pnum_iov)
2910 {
2911         struct iovec *iov;
2912         int num_iov = 0;
2913         size_t taken = 0;
2914         uint8_t *first_hdr = buf;
2915
2916         iov = talloc_array(mem_ctx, struct iovec, num_iov);
2917         if (iov == NULL) {
2918                 return NT_STATUS_NO_MEMORY;
2919         }
2920
2921         while (taken < buflen) {
2922                 uint8_t *tf = NULL;
2923                 size_t tf_len = 0;
2924                 size_t len = buflen - taken;
2925                 uint8_t *hdr = first_hdr + taken;
2926                 struct iovec *cur;
2927                 size_t full_size;
2928                 size_t next_command_ofs;
2929                 uint16_t body_size;
2930                 struct iovec *iov_tmp;
2931
2932                 if (len < 4) {
2933                         DEBUG(10, ("%d bytes left, expected at least %d\n",
2934                                    (int)len, 4));
2935                         goto inval;
2936                 }
2937                 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
2938                         struct smbXcli_session *s;
2939                         uint64_t uid;
2940                         struct iovec tf_iov[2];
2941                         NTSTATUS status;
2942
2943                         if (len < SMB2_TF_HDR_SIZE) {
2944                                 DEBUG(10, ("%d bytes left, expected at least %d\n",
2945                                            (int)len, SMB2_TF_HDR_SIZE));
2946                                 goto inval;
2947                         }
2948                         tf = hdr;
2949                         tf_len = SMB2_TF_HDR_SIZE;
2950                         taken += tf_len;
2951
2952                         hdr = first_hdr + taken;
2953                         len = IVAL(tf, SMB2_TF_MSG_SIZE);
2954                         uid = BVAL(tf, SMB2_TF_SESSION_ID);
2955
2956                         s = conn->sessions;
2957                         for (; s; s = s->next) {
2958                                 if (s->smb2->session_id != uid) {
2959                                         continue;
2960                                 }
2961                                 break;
2962                         }
2963
2964                         if (s == NULL) {
2965                                 DEBUG(10, ("unknown session_id %llu\n",
2966                                            (unsigned long long)uid));
2967                                 goto inval;
2968                         }
2969
2970                         tf_iov[0].iov_base = (void *)tf;
2971                         tf_iov[0].iov_len = tf_len;
2972                         tf_iov[1].iov_base = (void *)hdr;
2973                         tf_iov[1].iov_len = len;
2974
2975                         status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
2976                                                           conn->protocol,
2977                                                           tf_iov, 2);
2978                         if (!NT_STATUS_IS_OK(status)) {
2979                                 TALLOC_FREE(iov);
2980                                 return status;
2981                         }
2982                 }
2983
2984                 /*
2985                  * We need the header plus the body length field
2986                  */
2987
2988                 if (len < SMB2_HDR_BODY + 2) {
2989                         DEBUG(10, ("%d bytes left, expected at least %d\n",
2990                                    (int)len, SMB2_HDR_BODY));
2991                         goto inval;
2992                 }
2993                 if (IVAL(hdr, 0) != SMB2_MAGIC) {
2994                         DEBUG(10, ("Got non-SMB2 PDU: %x\n",
2995                                    IVAL(hdr, 0)));
2996                         goto inval;
2997                 }
2998                 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
2999                         DEBUG(10, ("Got HDR len %d, expected %d\n",
3000                                    SVAL(hdr, 4), SMB2_HDR_BODY));
3001                         goto inval;
3002                 }
3003
3004                 full_size = len;
3005                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
3006                 body_size = SVAL(hdr, SMB2_HDR_BODY);
3007
3008                 if (next_command_ofs != 0) {
3009                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
3010                                 goto inval;
3011                         }
3012                         if (next_command_ofs > full_size) {
3013                                 goto inval;
3014                         }
3015                         if (tf && next_command_ofs < len) {
3016                                 goto inval;
3017                         }
3018                         full_size = next_command_ofs;
3019                 }
3020                 if (body_size < 2) {
3021                         goto inval;
3022                 }
3023                 body_size &= 0xfffe;
3024
3025                 if (body_size > (full_size - SMB2_HDR_BODY)) {
3026                         goto inval;
3027                 }
3028
3029                 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
3030                                          num_iov + 4);
3031                 if (iov_tmp == NULL) {
3032                         TALLOC_FREE(iov);
3033                         return NT_STATUS_NO_MEMORY;
3034                 }
3035                 iov = iov_tmp;
3036                 cur = &iov[num_iov];
3037                 num_iov += 4;
3038
3039                 cur[0].iov_base = tf;
3040                 cur[0].iov_len  = tf_len;
3041                 cur[1].iov_base = hdr;
3042                 cur[1].iov_len  = SMB2_HDR_BODY;
3043                 cur[2].iov_base = hdr + SMB2_HDR_BODY;
3044                 cur[2].iov_len  = body_size;
3045                 cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
3046                 cur[3].iov_len  = full_size - (SMB2_HDR_BODY + body_size);
3047
3048                 taken += full_size;
3049         }
3050
3051         *piov = iov;
3052         *pnum_iov = num_iov;
3053         return NT_STATUS_OK;
3054
3055 inval:
3056         TALLOC_FREE(iov);
3057         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3058 }
3059
3060 static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
3061                                                     uint64_t mid)
3062 {
3063         size_t num_pending = talloc_array_length(conn->pending);
3064         size_t i;
3065
3066         for (i=0; i<num_pending; i++) {
3067                 struct tevent_req *req = conn->pending[i];
3068                 struct smbXcli_req_state *state =
3069                         tevent_req_data(req,
3070                         struct smbXcli_req_state);
3071
3072                 if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
3073                         return req;
3074                 }
3075         }
3076         return NULL;
3077 }
3078
3079 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3080                                                TALLOC_CTX *tmp_mem,
3081                                                uint8_t *inbuf)
3082 {
3083         struct tevent_req *req;
3084         struct smbXcli_req_state *state = NULL;
3085         struct iovec *iov;
3086         int i, num_iov;
3087         NTSTATUS status;
3088         bool defer = true;
3089         struct smbXcli_session *last_session = NULL;
3090         size_t inbuf_len = smb_len_tcp(inbuf);
3091
3092         status = smb2cli_inbuf_parse_compound(conn,
3093                                               inbuf + NBT_HDR_SIZE,
3094                                               inbuf_len,
3095                                               tmp_mem,
3096                                               &iov, &num_iov);
3097         if (!NT_STATUS_IS_OK(status)) {
3098                 return status;
3099         }
3100
3101         for (i=0; i<num_iov; i+=4) {
3102                 uint8_t *inbuf_ref = NULL;
3103                 struct iovec *cur = &iov[i];
3104                 uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
3105                 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3106                 uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3107                 uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3108                 uint16_t req_opcode;
3109                 uint32_t req_flags;
3110                 uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
3111                 uint32_t new_credits;
3112                 struct smbXcli_session *session = NULL;
3113                 const DATA_BLOB *signing_key = NULL;
3114
3115                 new_credits = conn->smb2.cur_credits;
3116                 new_credits += credits;
3117                 if (new_credits > UINT16_MAX) {
3118                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3119                 }
3120                 conn->smb2.cur_credits += credits;
3121
3122                 req = smb2cli_conn_find_pending(conn, mid);
3123                 if (req == NULL) {
3124                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3125                 }
3126                 state = tevent_req_data(req, struct smbXcli_req_state);
3127
3128                 state->smb2.got_async = false;
3129
3130                 req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3131                 if (opcode != req_opcode) {
3132                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3133                 }
3134                 req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3135
3136                 if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
3137                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3138                 }
3139
3140                 status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
3141                 if ((flags & SMB2_HDR_FLAG_ASYNC) &&
3142                     NT_STATUS_EQUAL(status, STATUS_PENDING)) {
3143                         uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
3144
3145                         /*
3146                          * async interim responses are not signed,
3147                          * even if the SMB2_HDR_FLAG_SIGNED flag
3148                          * is set.
3149                          */
3150                         req_flags |= SMB2_HDR_FLAG_ASYNC;
3151                         SBVAL(state->smb2.hdr, SMB2_HDR_FLAGS, req_flags);
3152                         SBVAL(state->smb2.hdr, SMB2_HDR_ASYNC_ID, async_id);
3153
3154                         if (state->smb2.notify_async) {
3155                                 state->smb2.got_async = true;
3156                                 tevent_req_defer_callback(req, state->ev);
3157                                 tevent_req_notify_callback(req);
3158                         }
3159                         continue;
3160                 }
3161
3162                 session = state->session;
3163                 if (req_flags & SMB2_HDR_FLAG_CHAINED) {
3164                         session = last_session;
3165                 }
3166                 last_session = session;
3167
3168                 if (state->smb2.should_sign) {
3169                         if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
3170                                 return NT_STATUS_ACCESS_DENIED;
3171                         }
3172                 }
3173
3174                 if (flags & SMB2_HDR_FLAG_SIGNED) {
3175                         uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
3176
3177                         if (session == NULL) {
3178                                 struct smbXcli_session *s;
3179
3180                                 s = state->conn->sessions;
3181                                 for (; s; s = s->next) {
3182                                         if (s->smb2->session_id != uid) {
3183                                                 continue;
3184                                         }
3185
3186                                         session = s;
3187                                         break;
3188                                 }
3189                         }
3190
3191                         if (session == NULL) {
3192                                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3193                         }
3194
3195                         last_session = session;
3196                         signing_key = &session->smb2_channel.signing_key;
3197                 }
3198
3199                 if (opcode == SMB2_OP_SESSSETUP) {
3200                         /*
3201                          * We prefer the channel signing key, if it is
3202                          * already there.
3203                          *
3204                          * If we do not have a channel signing key yet,
3205                          * we try the main signing key, if it is not
3206                          * the final response.
3207                          */
3208                         if (signing_key && signing_key->length == 0 &&
3209                             !NT_STATUS_IS_OK(status)) {
3210                                 signing_key = &session->smb2->signing_key;
3211                         }
3212
3213                         if (signing_key && signing_key->length == 0) {
3214                                 /*
3215                                  * If we do not have a session key to
3216                                  * verify the signature, we defer the
3217                                  * signing check to the caller.
3218                                  *
3219                                  * The caller gets NT_STATUS_OK, it
3220                                  * has to call
3221                                  * smb2cli_session_set_session_key()
3222                                  * or
3223                                  * smb2cli_session_set_channel_key()
3224                                  * which will check the signature
3225                                  * with the channel signing key.
3226                                  */
3227                                 signing_key = NULL;
3228                         }
3229                 }
3230
3231                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
3232                         /*
3233                          * if the server returns NT_STATUS_USER_SESSION_DELETED
3234                          * the response is not signed and we should
3235                          * propagate the NT_STATUS_USER_SESSION_DELETED
3236                          * status to the caller.
3237                          */
3238                         signing_key = NULL;
3239                 } else if (state->smb2.should_encrypt) {
3240                         if (cur[0].iov_len != SMB2_TF_HDR_SIZE) {
3241                                 return NT_STATUS_ACCESS_DENIED;
3242                         }
3243                 }
3244
3245                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
3246                     NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
3247                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3248                         /*
3249                          * if the server returns
3250                          * NT_STATUS_NETWORK_NAME_DELETED
3251                          * NT_STATUS_FILE_CLOSED
3252                          * NT_STATUS_INVALID_PARAMETER
3253                          * the response might not be signed
3254                          * as this happens before the signing checks.
3255                          *
3256                          * If server echos the signature (or all zeros)
3257                          * we should report the status from the server
3258                          * to the caller.
3259                          */
3260                         if (signing_key) {
3261                                 int cmp;
3262
3263                                 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3264                                              state->smb2.hdr+SMB2_HDR_SIGNATURE,
3265                                              16);
3266                                 if (cmp == 0) {
3267                                         state->smb2.signing_skipped = true;
3268                                         signing_key = NULL;
3269                                 }
3270                         }
3271                         if (signing_key) {
3272                                 int cmp;
3273                                 static const uint8_t zeros[16];
3274
3275                                 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3276                                              zeros,
3277                                              16);
3278                                 if (cmp == 0) {
3279                                         state->smb2.signing_skipped = true;
3280                                         signing_key = NULL;
3281                                 }
3282                         }
3283                 }
3284
3285                 if (signing_key) {
3286                         status = smb2_signing_check_pdu(*signing_key,
3287                                                         state->conn->protocol,
3288                                                         &cur[1], 3);
3289                         if (!NT_STATUS_IS_OK(status)) {
3290                                 /*
3291                                  * If the signing check fails, we disconnect
3292                                  * the connection.
3293                                  */
3294                                 return status;
3295                         }
3296                 }
3297
3298                 smbXcli_req_unset_pending(req);
3299
3300                 /*
3301                  * There might be more than one response
3302                  * we need to defer the notifications
3303                  */
3304                 if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
3305                         defer = false;
3306                 }
3307
3308                 if (defer) {
3309                         tevent_req_defer_callback(req, state->ev);
3310                 }
3311
3312                 /*
3313                  * Note: here we use talloc_reference() in a way
3314                  *       that does not expose it to the caller.
3315                  */
3316                 inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
3317                 if (tevent_req_nomem(inbuf_ref, req)) {
3318                         continue;
3319                 }
3320
3321                 /* copy the related buffers */
3322                 state->smb2.recv_iov[0] = cur[1];
3323                 state->smb2.recv_iov[1] = cur[2];
3324                 state->smb2.recv_iov[2] = cur[3];
3325
3326                 tevent_req_done(req);
3327         }
3328
3329         if (defer) {
3330                 return NT_STATUS_RETRY;
3331         }
3332
3333         return NT_STATUS_OK;
3334 }
3335
3336 NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3337                           struct iovec **piov,
3338                           const struct smb2cli_req_expected_response *expected,
3339                           size_t num_expected)
3340 {
3341         struct smbXcli_req_state *state =
3342                 tevent_req_data(req,
3343                 struct smbXcli_req_state);
3344         NTSTATUS status;
3345         size_t body_size;
3346         bool found_status = false;
3347         bool found_size = false;
3348         size_t i;
3349
3350         if (piov != NULL) {
3351                 *piov = NULL;
3352         }
3353
3354         if (state->smb2.got_async) {
3355                 return STATUS_PENDING;
3356         }
3357
3358         if (tevent_req_is_nterror(req, &status)) {
3359                 for (i=0; i < num_expected; i++) {
3360                         if (NT_STATUS_EQUAL(status, expected[i].status)) {
3361                                 found_status = true;
3362                                 break;
3363                         }
3364                 }
3365
3366                 if (found_status) {
3367                         return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
3368                 }
3369
3370                 return status;
3371         }
3372
3373         if (num_expected == 0) {
3374                 found_status = true;
3375                 found_size = true;
3376         }
3377
3378         status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
3379         body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
3380
3381         for (i=0; i < num_expected; i++) {
3382                 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
3383                         continue;
3384                 }
3385
3386                 found_status = true;
3387                 if (expected[i].body_size == 0) {
3388                         found_size = true;
3389                         break;
3390                 }
3391
3392                 if (expected[i].body_size == body_size) {
3393                         found_size = true;
3394                         break;
3395                 }
3396         }
3397
3398         if (!found_status) {
3399                 return status;
3400         }
3401
3402         if (state->smb2.signing_skipped) {
3403                 if (num_expected > 0) {
3404                         return NT_STATUS_ACCESS_DENIED;
3405                 }
3406                 if (!NT_STATUS_IS_ERR(status)) {
3407                         return NT_STATUS_ACCESS_DENIED;
3408                 }
3409         }
3410
3411         if (!found_size) {
3412                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3413         }
3414
3415         if (piov != NULL) {
3416                 *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
3417         }
3418
3419         return status;
3420 }
3421
3422 static const struct {
3423         enum protocol_types proto;
3424         const char *smb1_name;
3425 } smb1cli_prots[] = {
3426         {PROTOCOL_CORE,         "PC NETWORK PROGRAM 1.0"},
3427         {PROTOCOL_COREPLUS,     "MICROSOFT NETWORKS 1.03"},
3428         {PROTOCOL_LANMAN1,      "MICROSOFT NETWORKS 3.0"},
3429         {PROTOCOL_LANMAN1,      "LANMAN1.0"},
3430         {PROTOCOL_LANMAN2,      "LM1.2X002"},
3431         {PROTOCOL_LANMAN2,      "DOS LANMAN2.1"},
3432         {PROTOCOL_LANMAN2,      "LANMAN2.1"},
3433         {PROTOCOL_LANMAN2,      "Samba"},
3434         {PROTOCOL_NT1,          "NT LANMAN 1.0"},
3435         {PROTOCOL_NT1,          "NT LM 0.12"},
3436         {PROTOCOL_SMB2_02,      "SMB 2.002"},
3437         {PROTOCOL_SMB2_10,      "SMB 2.???"},
3438 };
3439
3440 static const struct {
3441         enum protocol_types proto;
3442         uint16_t smb2_dialect;
3443 } smb2cli_prots[] = {
3444         {PROTOCOL_SMB2_02,      SMB2_DIALECT_REVISION_202},
3445         {PROTOCOL_SMB2_10,      SMB2_DIALECT_REVISION_210},
3446         {PROTOCOL_SMB2_22,      SMB2_DIALECT_REVISION_222},
3447         {PROTOCOL_SMB2_24,      SMB2_DIALECT_REVISION_224},
3448         {PROTOCOL_SMB3_00,      SMB3_DIALECT_REVISION_300},
3449 };
3450
3451 struct smbXcli_negprot_state {
3452         struct smbXcli_conn *conn;
3453         struct tevent_context *ev;
3454         uint32_t timeout_msec;
3455         enum protocol_types min_protocol;
3456         enum protocol_types max_protocol;
3457
3458         struct {
3459                 uint8_t fixed[36];
3460                 uint8_t dyn[ARRAY_SIZE(smb2cli_prots)*2];
3461         } smb2;
3462 };
3463
3464 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
3465 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
3466 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
3467 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
3468 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
3469 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
3470                                                   TALLOC_CTX *frame,
3471                                                   uint8_t *inbuf);
3472
3473 struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
3474                                         struct tevent_context *ev,
3475                                         struct smbXcli_conn *conn,
3476                                         uint32_t timeout_msec,
3477                                         enum protocol_types min_protocol,
3478                                         enum protocol_types max_protocol)
3479 {
3480         struct tevent_req *req, *subreq;
3481         struct smbXcli_negprot_state *state;
3482
3483         req = tevent_req_create(mem_ctx, &state,
3484                                 struct smbXcli_negprot_state);
3485         if (req == NULL) {
3486                 return NULL;
3487         }
3488         state->conn = conn;
3489         state->ev = ev;
3490         state->timeout_msec = timeout_msec;
3491         state->min_protocol = min_protocol;
3492         state->max_protocol = max_protocol;
3493
3494         if (min_protocol == PROTOCOL_NONE) {
3495                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3496                 return tevent_req_post(req, ev);
3497         }
3498
3499         if (max_protocol == PROTOCOL_NONE) {
3500                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3501                 return tevent_req_post(req, ev);
3502         }
3503
3504         if (min_protocol > max_protocol) {
3505                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3506                 return tevent_req_post(req, ev);
3507         }
3508
3509         if ((min_protocol < PROTOCOL_SMB2_02) &&
3510             (max_protocol < PROTOCOL_SMB2_02)) {
3511                 /*
3512                  * SMB1 only...
3513                  */
3514                 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
3515
3516                 subreq = smbXcli_negprot_smb1_subreq(state);
3517                 if (tevent_req_nomem(subreq, req)) {
3518                         return tevent_req_post(req, ev);
3519                 }
3520                 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
3521                 return req;
3522         }
3523
3524         if ((min_protocol >= PROTOCOL_SMB2_02) &&
3525             (max_protocol >= PROTOCOL_SMB2_02)) {
3526                 /*
3527                  * SMB2 only...
3528                  */
3529                 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3530
3531                 subreq = smbXcli_negprot_smb2_subreq(state);
3532                 if (tevent_req_nomem(subreq, req)) {
3533                         return tevent_req_post(req, ev);
3534                 }
3535                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
3536                 return req;
3537         }
3538
3539         /*
3540          * We send an SMB1 negprot with the SMB2 dialects
3541          * and expect a SMB1 or a SMB2 response.
3542          *
3543          * smbXcli_negprot_dispatch_incoming() will fix the
3544          * callback to match protocol of the response.
3545          */
3546         conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
3547
3548         subreq = smbXcli_negprot_smb1_subreq(state);
3549         if (tevent_req_nomem(subreq, req)) {
3550                 return tevent_req_post(req, ev);
3551         }
3552         tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
3553         return req;
3554 }
3555
3556 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
3557 {
3558         struct tevent_req *req =
3559                 tevent_req_callback_data(subreq,
3560                 struct tevent_req);
3561         NTSTATUS status;
3562
3563         /*
3564          * we just want the low level error
3565          */
3566         status = tevent_req_simple_recv_ntstatus(subreq);
3567         TALLOC_FREE(subreq);
3568         if (tevent_req_nterror(req, status)) {
3569                 return;
3570         }
3571
3572         /* this should never happen */
3573         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3574 }
3575
3576 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
3577 {
3578         size_t i;
3579         DATA_BLOB bytes = data_blob_null;
3580         uint8_t flags;
3581         uint16_t flags2;
3582
3583         /* setup the protocol strings */
3584         for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
3585                 uint8_t c = 2;
3586                 bool ok;
3587
3588                 if (smb1cli_prots[i].proto < state->min_protocol) {
3589                         continue;
3590                 }
3591
3592                 if (smb1cli_prots[i].proto > state->max_protocol) {
3593                         continue;
3594                 }
3595
3596                 ok = data_blob_append(state, &bytes, &c, sizeof(c));
3597                 if (!ok) {
3598                         return NULL;
3599                 }
3600
3601                 /*
3602                  * We now it is already ascii and
3603                  * we want NULL termination.
3604                  */
3605                 ok = data_blob_append(state, &bytes,
3606                                       smb1cli_prots[i].smb1_name,
3607                                       strlen(smb1cli_prots[i].smb1_name)+1);
3608                 if (!ok) {
3609                         return NULL;
3610                 }
3611         }
3612
3613         smb1cli_req_flags(state->max_protocol,
3614                           state->conn->smb1.client.capabilities,
3615                           SMBnegprot,
3616                           0, 0, &flags,
3617                           0, 0, &flags2);
3618
3619         return smb1cli_req_send(state, state->ev, state->conn,
3620                                 SMBnegprot,
3621                                 flags, ~flags,
3622                                 flags2, ~flags2,
3623                                 state->timeout_msec,
3624                                 0xFFFE, 0, NULL, /* pid, tid, session */
3625                                 0, NULL, /* wct, vwv */
3626                                 bytes.length, bytes.data);
3627 }
3628
3629 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
3630 {
3631         struct tevent_req *req =
3632                 tevent_req_callback_data(subreq,
3633                 struct tevent_req);
3634         struct smbXcli_negprot_state *state =
3635                 tevent_req_data(req,
3636                 struct smbXcli_negprot_state);
3637         struct smbXcli_conn *conn = state->conn;
3638         struct iovec *recv_iov = NULL;
3639         uint8_t *inhdr;
3640         uint8_t wct;
3641         uint16_t *vwv;
3642         uint32_t num_bytes;
3643         uint8_t *bytes;
3644         NTSTATUS status;
3645         uint16_t protnum;
3646         size_t i;
3647         size_t num_prots = 0;
3648         uint8_t flags;
3649         uint32_t client_capabilities = conn->smb1.client.capabilities;
3650         uint32_t both_capabilities;
3651         uint32_t server_capabilities = 0;
3652         uint32_t capabilities;
3653         uint32_t client_max_xmit = conn->smb1.client.max_xmit;
3654         uint32_t server_max_xmit = 0;
3655         uint32_t max_xmit;
3656         uint32_t server_max_mux = 0;
3657         uint16_t server_security_mode = 0;
3658         uint32_t server_session_key = 0;
3659         bool server_readbraw = false;
3660         bool server_writebraw = false;
3661         bool server_lockread = false;
3662         bool server_writeunlock = false;
3663         struct GUID server_guid = GUID_zero();
3664         DATA_BLOB server_gss_blob = data_blob_null;
3665         uint8_t server_challenge[8];
3666         char *server_workgroup = NULL;
3667         char *server_name = NULL;
3668         int server_time_zone = 0;
3669         NTTIME server_system_time = 0;
3670         static const struct smb1cli_req_expected_response expected[] = {
3671         {
3672                 .status = NT_STATUS_OK,
3673                 .wct = 0x11, /* NT1 */
3674         },
3675         {
3676                 .status = NT_STATUS_OK,
3677                 .wct = 0x0D, /* LM */
3678         },
3679         {
3680                 .status = NT_STATUS_OK,
3681                 .wct = 0x01, /* CORE */
3682         }
3683         };
3684
3685         ZERO_STRUCT(server_challenge);
3686
3687         status = smb1cli_req_recv(subreq, state,
3688                                   &recv_iov,
3689                                   &inhdr,
3690                                   &wct,
3691                                   &vwv,
3692                                   NULL, /* pvwv_offset */
3693                                   &num_bytes,
3694                                   &bytes,
3695                                   NULL, /* pbytes_offset */
3696                                   NULL, /* pinbuf */
3697                                   expected, ARRAY_SIZE(expected));
3698         TALLOC_FREE(subreq);
3699         if (tevent_req_nterror(req, status)) {
3700                 return;
3701         }
3702
3703         flags = CVAL(inhdr, HDR_FLG);
3704
3705         protnum = SVAL(vwv, 0);
3706
3707         for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
3708                 if (smb1cli_prots[i].proto < state->min_protocol) {
3709                         continue;
3710                 }
3711
3712                 if (smb1cli_prots[i].proto > state->max_protocol) {
3713                         continue;
3714                 }
3715
3716                 if (protnum != num_prots) {
3717                         num_prots++;
3718                         continue;
3719                 }
3720
3721                 conn->protocol = smb1cli_prots[i].proto;
3722                 break;
3723         }
3724
3725         if (conn->protocol == PROTOCOL_NONE) {
3726                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3727                 return;
3728         }
3729
3730         if ((conn->protocol < PROTOCOL_NT1) && conn->mandatory_signing) {
3731                 DEBUG(0,("smbXcli_negprot: SMB signing is mandatory "
3732                          "and the selected protocol level doesn't support it.\n"));
3733                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3734                 return;
3735         }
3736
3737         if (flags & FLAG_SUPPORT_LOCKREAD) {
3738                 server_lockread = true;
3739                 server_writeunlock = true;
3740         }
3741
3742         if (conn->protocol >= PROTOCOL_NT1) {
3743                 const char *client_signing = NULL;
3744                 bool server_mandatory = false;
3745                 bool server_allowed = false;
3746                 const char *server_signing = NULL;
3747                 bool ok;
3748                 uint8_t key_len;
3749
3750                 if (wct != 0x11) {
3751                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3752                         return;
3753                 }
3754
3755                 /* NT protocol */
3756                 server_security_mode = CVAL(vwv + 1, 0);
3757                 server_max_mux = SVAL(vwv + 1, 1);
3758                 server_max_xmit = IVAL(vwv + 3, 1);
3759                 server_session_key = IVAL(vwv + 7, 1);
3760                 server_time_zone = SVALS(vwv + 15, 1);
3761                 server_time_zone *= 60;
3762                 /* this time arrives in real GMT */
3763                 server_system_time = BVAL(vwv + 11, 1);
3764                 server_capabilities = IVAL(vwv + 9, 1);
3765
3766                 key_len = CVAL(vwv + 16, 1);
3767
3768                 if (server_capabilities & CAP_RAW_MODE) {
3769                         server_readbraw = true;
3770                         server_writebraw = true;
3771                 }
3772                 if (server_capabilities & CAP_LOCK_AND_READ) {
3773                         server_lockread = true;
3774                 }
3775
3776                 if (server_capabilities & CAP_EXTENDED_SECURITY) {
3777                         DATA_BLOB blob1, blob2;
3778
3779                         if (num_bytes < 16) {
3780                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3781                                 return;
3782                         }
3783
3784                         blob1 = data_blob_const(bytes, 16);
3785                         status = GUID_from_data_blob(&blob1, &server_guid);
3786                         if (tevent_req_nterror(req, status)) {
3787                                 return;
3788                         }
3789
3790                         blob1 = data_blob_const(bytes+16, num_bytes-16);
3791                         blob2 = data_blob_dup_talloc(state, blob1);
3792                         if (blob1.length > 0 &&
3793                             tevent_req_nomem(blob2.data, req)) {
3794                                 return;
3795                         }
3796                         server_gss_blob = blob2;
3797                 } else {
3798                         DATA_BLOB blob1, blob2;
3799
3800                         if (num_bytes < key_len) {
3801                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3802                                 return;
3803                         }
3804
3805                         if (key_len != 0 && key_len != 8) {
3806                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3807                                 return;
3808                         }
3809
3810                         if (key_len == 8) {
3811                                 memcpy(server_challenge, bytes, 8);
3812                         }
3813
3814                         blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
3815                         blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
3816                         if (blob1.length > 0) {
3817                                 size_t len;
3818
3819                                 len = utf16_len_n(blob1.data,
3820                                                   blob1.length);
3821                                 blob1.length = len;
3822
3823                                 ok = convert_string_talloc(state,
3824                                                            CH_UTF16LE,
3825                                                            CH_UNIX,
3826                                                            blob1.data,
3827                                                            blob1.length,
3828                                                            &server_workgroup,
3829                                                            &len);
3830                                 if (!ok) {
3831                                         status = map_nt_error_from_unix_common(errno);
3832                                         tevent_req_nterror(req, status);
3833                                         return;
3834                                 }
3835                         }
3836
3837                         blob2.data += blob1.length;
3838                         blob2.length -= blob1.length;
3839                         if (blob2.length > 0) {
3840                                 size_t len;
3841
3842                                 len = utf16_len_n(blob1.data,
3843                                                   blob1.length);
3844                                 blob1.length = len;
3845
3846                                 ok = convert_string_talloc(state,
3847                                                            CH_UTF16LE,
3848                                                            CH_UNIX,
3849                                                            blob2.data,
3850                                                            blob2.length,
3851                                                            &server_name,
3852                                                            &len);
3853                                 if (!ok) {
3854                                         status = map_nt_error_from_unix_common(errno);
3855                                         tevent_req_nterror(req, status);
3856                                         return;
3857                                 }
3858                         }
3859                 }
3860
3861                 client_signing = "disabled";
3862                 if (conn->allow_signing) {
3863                         client_signing = "allowed";
3864                 }
3865                 if (conn->mandatory_signing) {
3866                         client_signing = "required";
3867                 }
3868
3869                 server_signing = "not supported";
3870                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
3871                         server_signing = "supported";
3872                         server_allowed = true;
3873                 }
3874                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
3875                         server_signing = "required";
3876                         server_mandatory = true;
3877                 }
3878
3879                 ok = smb_signing_set_negotiated(conn->smb1.signing,
3880                                                 server_allowed,
3881                                                 server_mandatory);
3882                 if (!ok) {
3883                         DEBUG(1,("cli_negprot: SMB signing is required, "
3884                                  "but client[%s] and server[%s] mismatch\n",
3885                                  client_signing, server_signing));
3886                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3887                         return;
3888                 }
3889
3890         } else if (conn->protocol >= PROTOCOL_LANMAN1) {
3891                 DATA_BLOB blob1;
3892                 uint8_t key_len;
3893                 time_t t;
3894
3895                 if (wct != 0x0D) {
3896                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3897                         return;
3898                 }
3899
3900                 server_security_mode = SVAL(vwv + 1, 0);
3901                 server_max_xmit = SVAL(vwv + 2, 0);
3902                 server_max_mux = SVAL(vwv + 3, 0);
3903                 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
3904                 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
3905                 server_session_key = IVAL(vwv + 6, 0);
3906                 server_time_zone = SVALS(vwv + 10, 0);
3907                 server_time_zone *= 60;
3908                 /* this time is converted to GMT by make_unix_date */
3909                 t = pull_dos_date((const uint8_t *)(vwv + 8), server_time_zone);
3910                 unix_to_nt_time(&server_system_time, t);
3911                 key_len = SVAL(vwv + 11, 0);
3912
3913                 if (num_bytes < key_len) {
3914                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3915                         return;
3916                 }
3917
3918                 if (key_len != 0 && key_len != 8) {
3919                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3920                         return;
3921                 }
3922
3923                 if (key_len == 8) {
3924                         memcpy(server_challenge, bytes, 8);
3925                 }
3926
3927                 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
3928                 if (blob1.length > 0) {
3929                         size_t len;
3930                         bool ok;
3931
3932                         len = utf16_len_n(blob1.data,
3933                                           blob1.length);
3934                         blob1.length = len;
3935
3936                         ok = convert_string_talloc(state,
3937                                                    CH_DOS,
3938                                                    CH_UNIX,
3939                                                    blob1.data,
3940                                                    blob1.length,
3941                                                    &server_workgroup,
3942                                                    &len);
3943                         if (!ok) {
3944                                 status = map_nt_error_from_unix_common(errno);
3945                                 tevent_req_nterror(req, status);
3946                                 return;
3947                         }
3948                 }
3949
3950         } else {
3951                 /* the old core protocol */
3952                 server_time_zone = get_time_zone(time(NULL));
3953                 server_max_xmit = 1024;
3954                 server_max_mux = 1;
3955         }
3956
3957         if (server_max_xmit < 1024) {
3958                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3959                 return;
3960         }
3961
3962         if (server_max_mux < 1) {
3963                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3964                 return;
3965         }
3966
3967         /*
3968          * Now calculate the negotiated capabilities
3969          * based on the mask for:
3970          * - client only flags
3971          * - flags used in both directions
3972          * - server only flags
3973          */
3974         both_capabilities = client_capabilities & server_capabilities;
3975         capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
3976         capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
3977         capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
3978
3979         max_xmit = MIN(client_max_xmit, server_max_xmit);
3980
3981         conn->smb1.server.capabilities = server_capabilities;
3982         conn->smb1.capabilities = capabilities;
3983
3984         conn->smb1.server.max_xmit = server_max_xmit;
3985         conn->smb1.max_xmit = max_xmit;
3986
3987         conn->smb1.server.max_mux = server_max_mux;
3988
3989         conn->smb1.server.security_mode = server_security_mode;
3990
3991         conn->smb1.server.readbraw = server_readbraw;
3992         conn->smb1.server.writebraw = server_writebraw;
3993         conn->smb1.server.lockread = server_lockread;
3994         conn->smb1.server.writeunlock = server_writeunlock;
3995
3996         conn->smb1.server.session_key = server_session_key;
3997
3998         talloc_steal(conn, server_gss_blob.data);
3999         conn->smb1.server.gss_blob = server_gss_blob;
4000         conn->smb1.server.guid = server_guid;
4001         memcpy(conn->smb1.server.challenge, server_challenge, 8);
4002         conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
4003         conn->smb1.server.name = talloc_move(conn, &server_name);
4004
4005         conn->smb1.server.time_zone = server_time_zone;
4006         conn->smb1.server.system_time = server_system_time;
4007
4008         tevent_req_done(req);
4009 }
4010
4011 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state)
4012 {
4013         size_t i;
4014         uint8_t *buf;
4015         uint16_t dialect_count = 0;
4016
4017         buf = state->smb2.dyn;
4018         for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4019                 if (smb2cli_prots[i].proto < state->min_protocol) {
4020                         continue;
4021                 }
4022
4023                 if (smb2cli_prots[i].proto > state->max_protocol) {
4024                         continue;
4025                 }
4026
4027                 SSVAL(buf, dialect_count*2, smb2cli_prots[i].smb2_dialect);
4028                 dialect_count++;
4029         }
4030
4031         buf = state->smb2.fixed;
4032         SSVAL(buf, 0, 36);
4033         SSVAL(buf, 2, dialect_count);
4034         SSVAL(buf, 4, state->conn->smb2.client.security_mode);
4035         SSVAL(buf, 6, 0);       /* Reserved */
4036         if (state->max_protocol >= PROTOCOL_SMB2_22) {
4037                 SIVAL(buf, 8, state->conn->smb2.client.capabilities);
4038         } else {
4039                 SIVAL(buf, 8, 0);       /* Capabilities */
4040         }
4041         if (state->max_protocol >= PROTOCOL_SMB2_10) {
4042                 NTSTATUS status;
4043                 DATA_BLOB blob;
4044
4045                 status = GUID_to_ndr_blob(&state->conn->smb2.client.guid,
4046                                           state, &blob);
4047                 if (!NT_STATUS_IS_OK(status)) {
4048                         return NULL;
4049                 }
4050                 memcpy(buf+12, blob.data, 16); /* ClientGuid */
4051         } else {
4052                 memset(buf+12, 0, 16);  /* ClientGuid */
4053         }
4054         SBVAL(buf, 28, 0);      /* ClientStartTime */
4055
4056         return smb2cli_req_send(state, state->ev,
4057                                 state->conn, SMB2_OP_NEGPROT,
4058                                 0, 0, /* flags */
4059                                 state->timeout_msec,
4060                                 NULL, NULL, /* tcon, session */
4061                                 state->smb2.fixed, sizeof(state->smb2.fixed),
4062                                 state->smb2.dyn, dialect_count*2);
4063 }
4064
4065 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
4066 {
4067         struct tevent_req *req =
4068                 tevent_req_callback_data(subreq,
4069                 struct tevent_req);
4070         struct smbXcli_negprot_state *state =
4071                 tevent_req_data(req,
4072                 struct smbXcli_negprot_state);
4073         struct smbXcli_conn *conn = state->conn;
4074         size_t security_offset, security_length;
4075         DATA_BLOB blob;
4076         NTSTATUS status;
4077         struct iovec *iov;
4078         uint8_t *body;
4079         size_t i;
4080         uint16_t dialect_revision;
4081         static const struct smb2cli_req_expected_response expected[] = {
4082         {
4083                 .status = NT_STATUS_OK,
4084                 .body_size = 0x41
4085         }
4086         };
4087
4088         status = smb2cli_req_recv(subreq, state, &iov,
4089                                   expected, ARRAY_SIZE(expected));
4090         TALLOC_FREE(subreq);
4091         if (tevent_req_nterror(req, status)) {
4092                 return;
4093         }
4094
4095         body = (uint8_t *)iov[1].iov_base;
4096
4097         dialect_revision = SVAL(body, 4);
4098
4099         for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4100                 if (smb2cli_prots[i].proto < state->min_protocol) {
4101                         continue;
4102                 }
4103
4104                 if (smb2cli_prots[i].proto > state->max_protocol) {
4105                         continue;
4106                 }
4107
4108                 if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
4109                         continue;
4110                 }
4111
4112                 conn->protocol = smb2cli_prots[i].proto;
4113                 break;
4114         }
4115
4116         if (conn->protocol == PROTOCOL_NONE) {
4117                 if (state->min_protocol >= PROTOCOL_SMB2_02) {
4118                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4119                         return;
4120                 }
4121
4122                 if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
4123                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4124                         return;
4125                 }
4126
4127                 /* make sure we do not loop forever */
4128                 state->min_protocol = PROTOCOL_SMB2_02;
4129
4130                 /*
4131                  * send a SMB2 negprot, in order to negotiate
4132                  * the SMB2 dialect.
4133                  */
4134                 subreq = smbXcli_negprot_smb2_subreq(state);
4135                 if (tevent_req_nomem(subreq, req)) {
4136                         return;
4137                 }
4138                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4139                 return;
4140         }
4141
4142         conn->smb2.server.security_mode = SVAL(body, 2);
4143
4144         blob = data_blob_const(body + 8, 16);
4145         status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
4146         if (tevent_req_nterror(req, status)) {
4147                 return;
4148         }
4149
4150         conn->smb2.server.capabilities  = IVAL(body, 24);
4151         conn->smb2.server.max_trans_size= IVAL(body, 28);
4152         conn->smb2.server.max_read_size = IVAL(body, 32);
4153         conn->smb2.server.max_write_size= IVAL(body, 36);
4154         conn->smb2.server.system_time   = BVAL(body, 40);
4155         conn->smb2.server.start_time    = BVAL(body, 48);
4156
4157         security_offset = SVAL(body, 56);
4158         security_length = SVAL(body, 58);
4159
4160         if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
4161                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4162                 return;
4163         }
4164
4165         if (security_length > iov[2].iov_len) {
4166                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4167                 return;
4168         }
4169
4170         conn->smb2.server.gss_blob = data_blob_talloc(conn,
4171                                                 iov[2].iov_base,
4172                                                 security_length);
4173         if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
4174                 return;
4175         }
4176
4177         tevent_req_done(req);
4178 }
4179
4180 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
4181                                                   TALLOC_CTX *tmp_mem,
4182                                                   uint8_t *inbuf)
4183 {
4184         size_t num_pending = talloc_array_length(conn->pending);
4185         struct tevent_req *subreq;
4186         struct smbXcli_req_state *substate;
4187         struct tevent_req *req;
4188         uint32_t protocol_magic;
4189         size_t inbuf_len = smb_len_nbt(inbuf);
4190
4191         if (num_pending != 1) {
4192                 return NT_STATUS_INTERNAL_ERROR;
4193         }
4194
4195         if (inbuf_len < 4) {
4196                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4197         }
4198
4199         subreq = conn->pending[0];
4200         substate = tevent_req_data(subreq, struct smbXcli_req_state);
4201         req = tevent_req_callback_data(subreq, struct tevent_req);
4202
4203         protocol_magic = IVAL(inbuf, 4);
4204
4205         switch (protocol_magic) {
4206         case SMB_MAGIC:
4207                 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4208                 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4209                 return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
4210
4211         case SMB2_MAGIC:
4212                 if (substate->smb2.recv_iov == NULL) {
4213                         /*
4214                          * For the SMB1 negprot we have move it.
4215                          */
4216                         substate->smb2.recv_iov = substate->smb1.recv_iov;
4217                         substate->smb1.recv_iov = NULL;
4218                 }
4219
4220                 /*
4221                  * we got an SMB2 answer, which consumed sequence number 0
4222                  * so we need to use 1 as the next one
4223                  */
4224                 conn->smb2.mid = 1;
4225                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4226                 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4227                 return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
4228         }
4229
4230         DEBUG(10, ("Got non-SMB PDU\n"));
4231         return NT_STATUS_INVALID_NETWORK_RESPONSE;
4232 }
4233
4234 NTSTATUS smbXcli_negprot_recv(struct tevent_req *req)
4235 {
4236         return tevent_req_simple_recv_ntstatus(req);
4237 }
4238
4239 NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
4240                          uint32_t timeout_msec,
4241                          enum protocol_types min_protocol,
4242                          enum protocol_types max_protocol)
4243 {
4244         TALLOC_CTX *frame = talloc_stackframe();
4245         struct tevent_context *ev;
4246         struct tevent_req *req;
4247         NTSTATUS status = NT_STATUS_NO_MEMORY;
4248         bool ok;
4249
4250         if (smbXcli_conn_has_async_calls(conn)) {
4251                 /*
4252                  * Can't use sync call while an async call is in flight
4253                  */
4254                 status = NT_STATUS_INVALID_PARAMETER_MIX;
4255                 goto fail;
4256         }
4257         ev = tevent_context_init(frame);
4258         if (ev == NULL) {
4259                 goto fail;
4260         }
4261         req = smbXcli_negprot_send(frame, ev, conn, timeout_msec,
4262                                    min_protocol, max_protocol);
4263         if (req == NULL) {
4264                 goto fail;
4265         }
4266         ok = tevent_req_poll(req, ev);
4267         if (!ok) {
4268                 status = map_nt_error_from_unix_common(errno);
4269                 goto fail;
4270         }
4271         status = smbXcli_negprot_recv(req);
4272  fail:
4273         TALLOC_FREE(frame);
4274         return status;
4275 }
4276
4277 static int smbXcli_session_destructor(struct smbXcli_session *session)
4278 {
4279         if (session->conn == NULL) {
4280                 return 0;
4281         }
4282
4283         DLIST_REMOVE(session->conn->sessions, session);
4284         return 0;
4285 }
4286
4287 struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
4288                                                struct smbXcli_conn *conn)
4289 {
4290         struct smbXcli_session *session;
4291
4292         session = talloc_zero(mem_ctx, struct smbXcli_session);
4293         if (session == NULL) {
4294                 return NULL;
4295         }
4296         session->smb2 = talloc_zero(session, struct smb2cli_session);
4297         if (session->smb2 == NULL) {
4298                 talloc_free(session);
4299                 return NULL;
4300         }
4301         talloc_set_destructor(session, smbXcli_session_destructor);
4302
4303         DLIST_ADD_END(conn->sessions, session, struct smbXcli_session *);
4304         session->conn = conn;
4305
4306         return session;
4307 }
4308
4309 NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
4310                                          TALLOC_CTX *mem_ctx,
4311                                          DATA_BLOB *key)
4312 {
4313         const DATA_BLOB *application_key;
4314
4315         *key = data_blob_null;
4316
4317         if (session->conn == NULL) {
4318                 return NT_STATUS_NO_USER_SESSION_KEY;
4319         }
4320
4321         if (session->conn->protocol >= PROTOCOL_SMB2_02) {
4322                 application_key = &session->smb2->application_key;
4323         } else {
4324                 application_key = &session->smb1.application_key;
4325         }
4326
4327         if (application_key->length == 0) {
4328                 return NT_STATUS_NO_USER_SESSION_KEY;
4329         }
4330
4331         *key = data_blob_dup_talloc(mem_ctx, *application_key);
4332         if (key->data == NULL) {
4333                 return NT_STATUS_NO_MEMORY;
4334         }
4335
4336         return NT_STATUS_OK;
4337 }
4338
4339 uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
4340 {
4341         return session->smb1.session_id;
4342 }
4343
4344 void smb1cli_session_set_id(struct smbXcli_session *session,
4345                             uint16_t session_id)
4346 {
4347         session->smb1.session_id = session_id;
4348 }
4349
4350 NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
4351                                          const DATA_BLOB _session_key)
4352 {
4353         struct smbXcli_conn *conn = session->conn;
4354         uint8_t session_key[16];
4355
4356         if (conn == NULL) {
4357                 return NT_STATUS_INVALID_PARAMETER_MIX;
4358         }
4359
4360         if (session->smb1.application_key.length != 0) {
4361                 /*
4362                  * TODO: do not allow this...
4363                  *
4364                  * return NT_STATUS_INVALID_PARAMETER_MIX;
4365                  */
4366                 data_blob_clear_free(&session->smb1.application_key);
4367                 session->smb1.protected_key = false;
4368         }
4369
4370         if (_session_key.length == 0) {
4371                 return NT_STATUS_OK;
4372         }
4373
4374         ZERO_STRUCT(session_key);
4375         memcpy(session_key, _session_key.data,
4376                MIN(_session_key.length, sizeof(session_key)));
4377
4378         session->smb1.application_key = data_blob_talloc(session,
4379                                                          session_key,
4380                                                          sizeof(session_key));
4381         ZERO_STRUCT(session_key);
4382         if (session->smb1.application_key.data == NULL) {
4383                 return NT_STATUS_NO_MEMORY;
4384         }
4385
4386         session->smb1.protected_key = false;
4387
4388         return NT_STATUS_OK;
4389 }
4390
4391 NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
4392 {
4393         if (session->smb1.protected_key) {
4394                 /* already protected */
4395                 return NT_STATUS_OK;
4396         }
4397
4398         if (session->smb1.application_key.length != 16) {
4399                 return NT_STATUS_INVALID_PARAMETER_MIX;
4400         }
4401
4402         smb_key_derivation(session->smb1.application_key.data,
4403                            session->smb1.application_key.length,
4404                            session->smb1.application_key.data);
4405
4406         session->smb1.protected_key = true;
4407
4408         return NT_STATUS_OK;
4409 }
4410
4411 uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
4412 {
4413         struct smbXcli_conn *conn = session->conn;
4414         uint8_t security_mode = 0;
4415
4416         if (conn == NULL) {
4417                 return security_mode;
4418         }
4419
4420         security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
4421         if (conn->mandatory_signing) {
4422                 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
4423         }
4424
4425         return security_mode;
4426 }
4427
4428 uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
4429 {
4430         return session->smb2->session_id;
4431 }
4432
4433 uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
4434 {
4435         return session->smb2->session_flags;
4436 }
4437
4438 void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
4439                                       uint64_t session_id,
4440                                       uint16_t session_flags)
4441 {
4442         session->smb2->session_id = session_id;
4443         session->smb2->session_flags = session_flags;
4444 }
4445
4446 void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
4447 {
4448         session->smb2->channel_sequence += 1;
4449 }
4450
4451 NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
4452                                          const DATA_BLOB _session_key,
4453                                          const struct iovec *recv_iov)
4454 {
4455         struct smbXcli_conn *conn = session->conn;
4456         uint16_t no_sign_flags;
4457         uint8_t session_key[16];
4458         NTSTATUS status;
4459
4460         if (conn == NULL) {
4461                 return NT_STATUS_INVALID_PARAMETER_MIX;
4462         }
4463
4464         no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST | SMB2_SESSION_FLAG_IS_NULL;
4465
4466         if (session->smb2->session_flags & no_sign_flags) {
4467                 session->smb2->should_sign = false;
4468                 return NT_STATUS_OK;
4469         }
4470
4471         if (session->smb2->signing_key.length != 0) {
4472                 return NT_STATUS_INVALID_PARAMETER_MIX;
4473         }
4474
4475         ZERO_STRUCT(session_key);
4476         memcpy(session_key, _session_key.data,
4477                MIN(_session_key.length, sizeof(session_key)));
4478
4479         session->smb2->signing_key = data_blob_talloc(session,
4480                                                      session_key,
4481                                                      sizeof(session_key));
4482         if (session->smb2->signing_key.data == NULL) {
4483                 ZERO_STRUCT(session_key);
4484                 return NT_STATUS_NO_MEMORY;
4485         }
4486
4487         if (conn->protocol >= PROTOCOL_SMB2_24) {
4488                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCMAC");
4489                 const DATA_BLOB context = data_blob_string_const_null("SmbSign");
4490
4491                 smb2_key_derivation(session_key, sizeof(session_key),
4492                                     label.data, label.length,
4493                                     context.data, context.length,
4494                                     session->smb2->signing_key.data);
4495         }
4496
4497         session->smb2->encryption_key = data_blob_dup_talloc(session,
4498                                                 session->smb2->signing_key);
4499         if (session->smb2->encryption_key.data == NULL) {
4500                 ZERO_STRUCT(session_key);
4501                 return NT_STATUS_NO_MEMORY;
4502         }
4503
4504         if (conn->protocol >= PROTOCOL_SMB2_24) {
4505                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
4506                 const DATA_BLOB context = data_blob_string_const_null("ServerIn ");
4507
4508                 smb2_key_derivation(session_key, sizeof(session_key),
4509                                     label.data, label.length,
4510                                     context.data, context.length,
4511                                     session->smb2->encryption_key.data);
4512         }
4513
4514         session->smb2->decryption_key = data_blob_dup_talloc(session,
4515                                                 session->smb2->signing_key);
4516         if (session->smb2->decryption_key.data == NULL) {
4517                 ZERO_STRUCT(session_key);
4518                 return NT_STATUS_NO_MEMORY;
4519         }
4520
4521         if (conn->protocol >= PROTOCOL_SMB2_24) {
4522                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
4523                 const DATA_BLOB context = data_blob_string_const_null("ServerOut");
4524
4525                 smb2_key_derivation(session_key, sizeof(session_key),
4526                                     label.data, label.length,
4527                                     context.data, context.length,
4528                                     session->smb2->decryption_key.data);
4529         }
4530
4531         session->smb2->application_key = data_blob_dup_talloc(session,
4532                                                 session->smb2->signing_key);
4533         if (session->smb2->application_key.data == NULL) {
4534                 ZERO_STRUCT(session_key);
4535                 return NT_STATUS_NO_MEMORY;
4536         }
4537
4538         if (conn->protocol >= PROTOCOL_SMB2_24) {
4539                 const DATA_BLOB label = data_blob_string_const_null("SMB2APP");
4540                 const DATA_BLOB context = data_blob_string_const_null("SmbRpc");
4541
4542                 smb2_key_derivation(session_key, sizeof(session_key),
4543                                     label.data, label.length,
4544                                     context.data, context.length,
4545                                     session->smb2->application_key.data);
4546         }
4547         ZERO_STRUCT(session_key);
4548
4549         session->smb2_channel.signing_key = data_blob_dup_talloc(session,
4550                                                 session->smb2->signing_key);
4551         if (session->smb2_channel.signing_key.data == NULL) {
4552                 return NT_STATUS_NO_MEMORY;
4553         }
4554
4555         status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
4556                                         session->conn->protocol,
4557                                         recv_iov, 3);
4558         if (!NT_STATUS_IS_OK(status)) {
4559                 return status;
4560         }
4561
4562         session->smb2->should_sign = false;
4563         session->smb2->should_encrypt = false;
4564
4565         if (conn->desire_signing) {
4566                 session->smb2->should_sign = true;
4567         }
4568
4569         if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
4570                 session->smb2->should_sign = true;
4571         }
4572
4573         if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
4574                 session->smb2->should_encrypt = true;
4575         }
4576
4577         if (conn->protocol < PROTOCOL_SMB2_24) {
4578                 session->smb2->should_encrypt = false;
4579         }
4580
4581         if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
4582                 session->smb2->should_encrypt = false;
4583         }
4584
4585         generate_random_buffer((uint8_t *)&session->smb2->nonce_high,
4586                                sizeof(session->smb2->nonce_high));
4587         session->smb2->nonce_low = 1;
4588
4589         return NT_STATUS_OK;
4590 }
4591
4592 NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
4593                                         struct smbXcli_session *session1,
4594                                         struct smbXcli_conn *conn,
4595                                         struct smbXcli_session **_session2)
4596 {
4597         struct smbXcli_session *session2;
4598
4599         if (session1->smb2->signing_key.length == 0) {
4600                 return NT_STATUS_INVALID_PARAMETER_MIX;
4601         }
4602
4603         if (conn == NULL) {
4604                 return NT_STATUS_INVALID_PARAMETER_MIX;
4605         }
4606
4607         session2 = talloc_zero(mem_ctx, struct smbXcli_session);
4608         if (session2 == NULL) {
4609                 return NT_STATUS_NO_MEMORY;
4610         }
4611         session2->smb2 = talloc_reference(session2, session1->smb2);
4612         if (session2->smb2 == NULL) {
4613                 talloc_free(session2);
4614                 return NT_STATUS_NO_MEMORY;
4615         }
4616
4617         talloc_set_destructor(session2, smbXcli_session_destructor);
4618         DLIST_ADD_END(conn->sessions, session2, struct smbXcli_session *);
4619         session2->conn = conn;
4620
4621         *_session2 = session2;
4622         return NT_STATUS_OK;
4623 }
4624
4625 NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
4626                                          const DATA_BLOB _channel_key,
4627                                          const struct iovec *recv_iov)
4628 {
4629         struct smbXcli_conn *conn = session->conn;
4630         uint8_t channel_key[16];
4631         NTSTATUS status;
4632
4633         if (conn == NULL) {
4634                 return NT_STATUS_INVALID_PARAMETER_MIX;
4635         }
4636
4637         if (session->smb2_channel.signing_key.length != 0) {
4638                 return NT_STATUS_INVALID_PARAMETER_MIX;
4639         }
4640
4641         ZERO_STRUCT(channel_key);
4642         memcpy(channel_key, _channel_key.data,
4643                MIN(_channel_key.length, sizeof(channel_key)));
4644
4645         session->smb2_channel.signing_key = data_blob_talloc(session,
4646                                                 channel_key,
4647                                                 sizeof(channel_key));
4648         if (session->smb2_channel.signing_key.data == NULL) {
4649                 ZERO_STRUCT(channel_key);
4650                 return NT_STATUS_NO_MEMORY;
4651         }
4652
4653         if (conn->protocol >= PROTOCOL_SMB2_24) {
4654                 const DATA_BLOB label = data_blob_string_const_null("SMB2AESCMAC");
4655                 const DATA_BLOB context = data_blob_string_const_null("SmbSign");
4656
4657                 smb2_key_derivation(channel_key, sizeof(channel_key),
4658                                     label.data, label.length,
4659                                     context.data, context.length,
4660                                     session->smb2_channel.signing_key.data);
4661         }
4662         ZERO_STRUCT(channel_key);
4663
4664         status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
4665                                         session->conn->protocol,
4666                                         recv_iov, 3);
4667         if (!NT_STATUS_IS_OK(status)) {
4668                 return status;
4669         }
4670
4671         return NT_STATUS_OK;
4672 }
4673
4674 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
4675 {
4676         struct smbXcli_tcon *tcon;
4677
4678         tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
4679         if (tcon == NULL) {
4680                 return NULL;
4681         }
4682
4683         return tcon;
4684 }
4685
4686 uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
4687 {
4688         return tcon->smb1.tcon_id;
4689 }
4690
4691 void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
4692 {
4693         tcon->smb1.tcon_id = tcon_id;
4694 }
4695
4696 bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
4697                              uint16_t tcon_id,
4698                              uint16_t optional_support,
4699                              uint32_t maximal_access,
4700                              uint32_t guest_maximal_access,
4701                              const char *service,
4702                              const char *fs_type)
4703 {
4704         tcon->smb1.tcon_id = tcon_id;
4705         tcon->smb1.optional_support = optional_support;
4706         tcon->smb1.maximal_access = maximal_access;
4707         tcon->smb1.guest_maximal_access = guest_maximal_access;
4708
4709         TALLOC_FREE(tcon->smb1.service);
4710         tcon->smb1.service = talloc_strdup(tcon, service);
4711         if (service != NULL && tcon->smb1.service == NULL) {
4712                 return false;
4713         }
4714
4715         TALLOC_FREE(tcon->smb1.fs_type);
4716         tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
4717         if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
4718                 return false;
4719         }
4720
4721         return true;
4722 }
4723
4724 uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
4725 {
4726         return tcon->smb2.tcon_id;
4727 }
4728
4729 uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
4730 {
4731         return tcon->smb2.capabilities;
4732 }
4733
4734 void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
4735                              struct smbXcli_session *session,
4736                              uint32_t tcon_id,
4737                              uint8_t type,
4738                              uint32_t flags,
4739                              uint32_t capabilities,
4740                              uint32_t maximal_access)
4741 {
4742         tcon->smb2.tcon_id = tcon_id;
4743         tcon->smb2.type = type;
4744         tcon->smb2.flags = flags;
4745         tcon->smb2.capabilities = capabilities;
4746         tcon->smb2.maximal_access = maximal_access;
4747
4748         tcon->smb2.should_encrypt = false;
4749
4750         if (session == NULL) {
4751                 return;
4752         }
4753
4754         tcon->smb2.should_encrypt = session->smb2->should_encrypt;
4755
4756         if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
4757                 tcon->smb2.should_encrypt = true;
4758         }
4759 }