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