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