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