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