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