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