lib/util: add and use iov_concat
[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                 return NT_STATUS_REVISION_MISMATCH;
1665         }
1666
1667         if (iov_count < 4) {
1668                 return NT_STATUS_INVALID_PARAMETER_MIX;
1669         }
1670         if (iov[0].iov_len != NBT_HDR_SIZE) {
1671                 return NT_STATUS_INVALID_PARAMETER_MIX;
1672         }
1673         if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1674                 return NT_STATUS_INVALID_PARAMETER_MIX;
1675         }
1676         if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1677                 return NT_STATUS_INVALID_PARAMETER_MIX;
1678         }
1679         if (iov[3].iov_len != sizeof(uint16_t)) {
1680                 return NT_STATUS_INVALID_PARAMETER_MIX;
1681         }
1682
1683         cmd = CVAL(iov[1].iov_base, HDR_COM);
1684         if (cmd == SMBreadBraw) {
1685                 if (smbXcli_conn_has_async_calls(state->conn)) {
1686                         return NT_STATUS_INVALID_PARAMETER_MIX;
1687                 }
1688                 state->conn->smb1.read_braw_req = req;
1689         }
1690
1691         if (state->smb1.mid != 0) {
1692                 mid = state->smb1.mid;
1693         } else {
1694                 mid = smb1cli_alloc_mid(state->conn);
1695         }
1696         SSVAL(iov[1].iov_base, HDR_MID, mid);
1697
1698         nbtlen = iov_buflen(&iov[1], iov_count-1);
1699         if ((nbtlen == -1) || (nbtlen > 0x1FFFF)) {
1700                 return NT_STATUS_INVALID_PARAMETER_MIX;
1701         }
1702
1703         _smb_setlen_nbt(iov[0].iov_base, nbtlen);
1704
1705         status = smb1cli_conn_signv(state->conn, iov, iov_count,
1706                                     &state->smb1.seqnum,
1707                                     state->smb1.one_way_seqnum);
1708
1709         if (!NT_STATUS_IS_OK(status)) {
1710                 return status;
1711         }
1712
1713         /*
1714          * If we supported multiple encrytion contexts
1715          * here we'd look up based on tid.
1716          */
1717         if (common_encryption_on(state->conn->smb1.trans_enc)) {
1718                 char *buf, *enc_buf;
1719
1720                 buf = (char *)iov_concat(talloc_tos(), iov, iov_count);
1721                 if (buf == NULL) {
1722                         return NT_STATUS_NO_MEMORY;
1723                 }
1724                 status = common_encrypt_buffer(state->conn->smb1.trans_enc,
1725                                                (char *)buf, &enc_buf);
1726                 TALLOC_FREE(buf);
1727                 if (!NT_STATUS_IS_OK(status)) {
1728                         DEBUG(0, ("Error in encrypting client message: %s\n",
1729                                   nt_errstr(status)));
1730                         return status;
1731                 }
1732                 buf = (char *)talloc_memdup(state, enc_buf,
1733                                             smb_len_nbt(enc_buf)+4);
1734                 SAFE_FREE(enc_buf);
1735                 if (buf == NULL) {
1736                         return NT_STATUS_NO_MEMORY;
1737                 }
1738                 iov[0].iov_base = (void *)buf;
1739                 iov[0].iov_len = talloc_get_size(buf);
1740                 iov_count = 1;
1741         }
1742
1743         if (state->conn->dispatch_incoming == NULL) {
1744                 state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
1745         }
1746
1747         if (!smbXcli_req_set_pending(req)) {
1748                 return NT_STATUS_NO_MEMORY;
1749         }
1750
1751         tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1752
1753         subreq = writev_send(state, state->ev, state->conn->outgoing,
1754                              state->conn->sock_fd, false, iov, iov_count);
1755         if (subreq == NULL) {
1756                 return NT_STATUS_NO_MEMORY;
1757         }
1758         tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
1759         state->write_req = subreq;
1760
1761         return NT_STATUS_OK;
1762 }
1763
1764 struct tevent_req *smb1cli_req_send(TALLOC_CTX *mem_ctx,
1765                                     struct tevent_context *ev,
1766                                     struct smbXcli_conn *conn,
1767                                     uint8_t smb_command,
1768                                     uint8_t additional_flags,
1769                                     uint8_t clear_flags,
1770                                     uint16_t additional_flags2,
1771                                     uint16_t clear_flags2,
1772                                     uint32_t timeout_msec,
1773                                     uint32_t pid,
1774                                     struct smbXcli_tcon *tcon,
1775                                     struct smbXcli_session *session,
1776                                     uint8_t wct, uint16_t *vwv,
1777                                     uint32_t num_bytes,
1778                                     const uint8_t *bytes)
1779 {
1780         struct tevent_req *req;
1781         struct iovec iov;
1782         NTSTATUS status;
1783
1784         iov.iov_base = discard_const_p(void, bytes);
1785         iov.iov_len = num_bytes;
1786
1787         req = smb1cli_req_create(mem_ctx, ev, conn, smb_command,
1788                                  additional_flags, clear_flags,
1789                                  additional_flags2, clear_flags2,
1790                                  timeout_msec,
1791                                  pid, tcon, session,
1792                                  wct, vwv, 1, &iov);
1793         if (req == NULL) {
1794                 return NULL;
1795         }
1796         if (!tevent_req_is_in_progress(req)) {
1797                 return tevent_req_post(req, ev);
1798         }
1799         status = smb1cli_req_chain_submit(&req, 1);
1800         if (tevent_req_nterror(req, status)) {
1801                 return tevent_req_post(req, ev);
1802         }
1803         return req;
1804 }
1805
1806 static void smb1cli_req_writev_done(struct tevent_req *subreq)
1807 {
1808         struct tevent_req *req =
1809                 tevent_req_callback_data(subreq,
1810                 struct tevent_req);
1811         struct smbXcli_req_state *state =
1812                 tevent_req_data(req,
1813                 struct smbXcli_req_state);
1814         ssize_t nwritten;
1815         int err;
1816
1817         state->write_req = NULL;
1818
1819         nwritten = writev_recv(subreq, &err);
1820         TALLOC_FREE(subreq);
1821         if (nwritten == -1) {
1822                 /* here, we need to notify all pending requests */
1823                 NTSTATUS status = map_nt_error_from_unix_common(err);
1824                 smbXcli_conn_disconnect(state->conn, status);
1825                 return;
1826         }
1827
1828         if (state->one_way) {
1829                 state->inbuf = NULL;
1830                 tevent_req_done(req);
1831                 return;
1832         }
1833 }
1834
1835 static void smbXcli_conn_received(struct tevent_req *subreq)
1836 {
1837         struct smbXcli_conn *conn =
1838                 tevent_req_callback_data(subreq,
1839                 struct smbXcli_conn);
1840         TALLOC_CTX *frame = talloc_stackframe();
1841         NTSTATUS status;
1842         uint8_t *inbuf;
1843         ssize_t received;
1844         int err;
1845
1846         if (subreq != conn->read_smb_req) {
1847                 DEBUG(1, ("Internal error: cli_smb_received called with "
1848                           "unexpected subreq\n"));
1849                 smbXcli_conn_disconnect(conn, NT_STATUS_INTERNAL_ERROR);
1850                 TALLOC_FREE(frame);
1851                 return;
1852         }
1853         conn->read_smb_req = NULL;
1854
1855         received = read_smb_recv(subreq, frame, &inbuf, &err);
1856         TALLOC_FREE(subreq);
1857         if (received == -1) {
1858                 status = map_nt_error_from_unix_common(err);
1859                 smbXcli_conn_disconnect(conn, status);
1860                 TALLOC_FREE(frame);
1861                 return;
1862         }
1863
1864         status = conn->dispatch_incoming(conn, frame, inbuf);
1865         TALLOC_FREE(frame);
1866         if (NT_STATUS_IS_OK(status)) {
1867                 /*
1868                  * We should not do any more processing
1869                  * as the dispatch function called
1870                  * tevent_req_done().
1871                  */
1872                 return;
1873         }
1874
1875         if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1876                 /*
1877                  * We got an error, so notify all pending requests
1878                  */
1879                 smbXcli_conn_disconnect(conn, status);
1880                 return;
1881         }
1882
1883         /*
1884          * We got NT_STATUS_RETRY, so we may ask for a
1885          * next incoming pdu.
1886          */
1887         if (!smbXcli_conn_receive_next(conn)) {
1888                 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1889         }
1890 }
1891
1892 static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
1893                                           struct iovec **piov, int *pnum_iov)
1894 {
1895         struct iovec *iov;
1896         int num_iov;
1897         size_t buflen;
1898         size_t taken;
1899         size_t remaining;
1900         uint8_t *hdr;
1901         uint8_t cmd;
1902         uint32_t wct_ofs;
1903         NTSTATUS status;
1904         size_t min_size = MIN_SMB_SIZE;
1905
1906         buflen = smb_len_tcp(buf);
1907         taken = 0;
1908
1909         hdr = buf + NBT_HDR_SIZE;
1910
1911         status = smb1cli_pull_raw_error(hdr);
1912         if (NT_STATUS_IS_ERR(status)) {
1913                 /*
1914                  * This is an ugly hack to support OS/2
1915                  * which skips the byte_count in the DATA block
1916                  * on some error responses.
1917                  *
1918                  * See bug #9096
1919                  */
1920                 min_size -= sizeof(uint16_t);
1921         }
1922
1923         if (buflen < min_size) {
1924                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1925         }
1926
1927         /*
1928          * This returns iovec elements in the following order:
1929          *
1930          * - SMB header
1931          *
1932          * - Parameter Block
1933          * - Data Block
1934          *
1935          * - Parameter Block
1936          * - Data Block
1937          *
1938          * - Parameter Block
1939          * - Data Block
1940          */
1941         num_iov = 1;
1942
1943         iov = talloc_array(mem_ctx, struct iovec, num_iov);
1944         if (iov == NULL) {
1945                 return NT_STATUS_NO_MEMORY;
1946         }
1947         iov[0].iov_base = hdr;
1948         iov[0].iov_len = HDR_WCT;
1949         taken += HDR_WCT;
1950
1951         cmd = CVAL(hdr, HDR_COM);
1952         wct_ofs = HDR_WCT;
1953
1954         while (true) {
1955                 size_t len = buflen - taken;
1956                 struct iovec *cur;
1957                 struct iovec *iov_tmp;
1958                 uint8_t wct;
1959                 uint32_t bcc_ofs;
1960                 uint16_t bcc;
1961                 size_t needed;
1962
1963                 /*
1964                  * we need at least WCT
1965                  */
1966                 needed = sizeof(uint8_t);
1967                 if (len < needed) {
1968                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1969                                    __location__, (int)len, (int)needed));
1970                         goto inval;
1971                 }
1972
1973                 /*
1974                  * Now we check if the specified words are there
1975                  */
1976                 wct = CVAL(hdr, wct_ofs);
1977                 needed += wct * sizeof(uint16_t);
1978                 if (len < needed) {
1979                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1980                                    __location__, (int)len, (int)needed));
1981                         goto inval;
1982                 }
1983
1984                 if ((num_iov == 1) &&
1985                     (len == needed) &&
1986                     NT_STATUS_IS_ERR(status))
1987                 {
1988                         /*
1989                          * This is an ugly hack to support OS/2
1990                          * which skips the byte_count in the DATA block
1991                          * on some error responses.
1992                          *
1993                          * See bug #9096
1994                          */
1995                         iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
1996                                                  num_iov + 2);
1997                         if (iov_tmp == NULL) {
1998                                 TALLOC_FREE(iov);
1999                                 return NT_STATUS_NO_MEMORY;
2000                         }
2001                         iov = iov_tmp;
2002                         cur = &iov[num_iov];
2003                         num_iov += 2;
2004
2005                         cur[0].iov_len = 0;
2006                         cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2007                         cur[1].iov_len = 0;
2008                         cur[1].iov_base = cur[0].iov_base;
2009
2010                         taken += needed;
2011                         break;
2012                 }
2013
2014                 /*
2015                  * we need at least BCC
2016                  */
2017                 needed += sizeof(uint16_t);
2018                 if (len < needed) {
2019                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2020                                    __location__, (int)len, (int)needed));
2021                         goto inval;
2022                 }
2023
2024                 /*
2025                  * Now we check if the specified bytes are there
2026                  */
2027                 bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
2028                 bcc = SVAL(hdr, bcc_ofs);
2029                 needed += bcc * sizeof(uint8_t);
2030                 if (len < needed) {
2031                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2032                                    __location__, (int)len, (int)needed));
2033                         goto inval;
2034                 }
2035
2036                 /*
2037                  * we allocate 2 iovec structures for words and bytes
2038                  */
2039                 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2040                                          num_iov + 2);
2041                 if (iov_tmp == NULL) {
2042                         TALLOC_FREE(iov);
2043                         return NT_STATUS_NO_MEMORY;
2044                 }
2045                 iov = iov_tmp;
2046                 cur = &iov[num_iov];
2047                 num_iov += 2;
2048
2049                 cur[0].iov_len = wct * sizeof(uint16_t);
2050                 cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2051                 cur[1].iov_len = bcc * sizeof(uint8_t);
2052                 cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
2053
2054                 taken += needed;
2055
2056                 if (!smb1cli_is_andx_req(cmd)) {
2057                         /*
2058                          * If the current command does not have AndX chanining
2059                          * we are done.
2060                          */
2061                         break;
2062                 }
2063
2064                 if (wct == 0 && bcc == 0) {
2065                         /*
2066                          * An empty response also ends the chain,
2067                          * most likely with an error.
2068                          */
2069                         break;
2070                 }
2071
2072                 if (wct < 2) {
2073                         DEBUG(10, ("%s: wct[%d] < 2 for cmd[0x%02X]\n",
2074                                    __location__, (int)wct, (int)cmd));
2075                         goto inval;
2076                 }
2077                 cmd = CVAL(cur[0].iov_base, 0);
2078                 if (cmd == 0xFF) {
2079                         /*
2080                          * If it is the end of the chain we are also done.
2081                          */
2082                         break;
2083                 }
2084                 wct_ofs = SVAL(cur[0].iov_base, 2);
2085
2086                 if (wct_ofs < taken) {
2087                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2088                 }
2089                 if (wct_ofs > buflen) {
2090                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2091                 }
2092
2093                 /*
2094                  * we consumed everything up to the start of the next
2095                  * parameter block.
2096                  */
2097                 taken = wct_ofs;
2098         }
2099
2100         remaining = buflen - taken;
2101
2102         if (remaining > 0 && num_iov >= 3) {
2103                 /*
2104                  * The last DATA block gets the remaining
2105                  * bytes, this is needed to support
2106                  * CAP_LARGE_WRITEX and CAP_LARGE_READX.
2107                  */
2108                 iov[num_iov-1].iov_len += remaining;
2109         }
2110
2111         *piov = iov;
2112         *pnum_iov = num_iov;
2113         return NT_STATUS_OK;
2114
2115 inval:
2116         TALLOC_FREE(iov);
2117         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2118 }
2119
2120 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2121                                                TALLOC_CTX *tmp_mem,
2122                                                uint8_t *inbuf)
2123 {
2124         struct tevent_req *req;
2125         struct smbXcli_req_state *state;
2126         NTSTATUS status;
2127         size_t num_pending;
2128         size_t i;
2129         uint8_t cmd;
2130         uint16_t mid;
2131         bool oplock_break;
2132         uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
2133         size_t len = smb_len_tcp(inbuf);
2134         struct iovec *iov = NULL;
2135         int num_iov = 0;
2136         struct tevent_req **chain = NULL;
2137         size_t num_chained = 0;
2138         size_t num_responses = 0;
2139
2140         if (conn->smb1.read_braw_req != NULL) {
2141                 req = conn->smb1.read_braw_req;
2142                 conn->smb1.read_braw_req = NULL;
2143                 state = tevent_req_data(req, struct smbXcli_req_state);
2144
2145                 smbXcli_req_unset_pending(req);
2146
2147                 if (state->smb1.recv_iov == NULL) {
2148                         /*
2149                          * For requests with more than
2150                          * one response, we have to readd the
2151                          * recv_iov array.
2152                          */
2153                         state->smb1.recv_iov = talloc_zero_array(state,
2154                                                                  struct iovec,
2155                                                                  3);
2156                         if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2157                                 return NT_STATUS_OK;
2158                         }
2159                 }
2160
2161                 state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
2162                 state->smb1.recv_iov[0].iov_len = len;
2163                 ZERO_STRUCT(state->smb1.recv_iov[1]);
2164                 ZERO_STRUCT(state->smb1.recv_iov[2]);
2165
2166                 state->smb1.recv_cmd = SMBreadBraw;
2167                 state->smb1.recv_status = NT_STATUS_OK;
2168                 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2169
2170                 tevent_req_done(req);
2171                 return NT_STATUS_OK;
2172         }
2173
2174         if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
2175             && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
2176                 DEBUG(10, ("Got non-SMB PDU\n"));
2177                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2178         }
2179
2180         /*
2181          * If we supported multiple encrytion contexts
2182          * here we'd look up based on tid.
2183          */
2184         if (common_encryption_on(conn->smb1.trans_enc)
2185             && (CVAL(inbuf, 0) == 0)) {
2186                 uint16_t enc_ctx_num;
2187
2188                 status = get_enc_ctx_num(inbuf, &enc_ctx_num);
2189                 if (!NT_STATUS_IS_OK(status)) {
2190                         DEBUG(10, ("get_enc_ctx_num returned %s\n",
2191                                    nt_errstr(status)));
2192                         return status;
2193                 }
2194
2195                 if (enc_ctx_num != conn->smb1.trans_enc->enc_ctx_num) {
2196                         DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
2197                                    enc_ctx_num,
2198                                    conn->smb1.trans_enc->enc_ctx_num));
2199                         return NT_STATUS_INVALID_HANDLE;
2200                 }
2201
2202                 status = common_decrypt_buffer(conn->smb1.trans_enc,
2203                                                (char *)inbuf);
2204                 if (!NT_STATUS_IS_OK(status)) {
2205                         DEBUG(10, ("common_decrypt_buffer returned %s\n",
2206                                    nt_errstr(status)));
2207                         return status;
2208                 }
2209                 inhdr = inbuf + NBT_HDR_SIZE;
2210                 len = smb_len_nbt(inbuf);
2211         }
2212
2213         mid = SVAL(inhdr, HDR_MID);
2214         num_pending = talloc_array_length(conn->pending);
2215
2216         for (i=0; i<num_pending; i++) {
2217                 if (mid == smb1cli_req_mid(conn->pending[i])) {
2218                         break;
2219                 }
2220         }
2221         if (i == num_pending) {
2222                 /* Dump unexpected reply */
2223                 return NT_STATUS_RETRY;
2224         }
2225
2226         oplock_break = false;
2227
2228         if (mid == 0xffff) {
2229                 /*
2230                  * Paranoia checks that this is really an oplock break request.
2231                  */
2232                 oplock_break = (len == 51); /* hdr + 8 words */
2233                 oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
2234                 oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
2235                 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
2236                 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
2237
2238                 if (!oplock_break) {
2239                         /* Dump unexpected reply */
2240                         return NT_STATUS_RETRY;
2241                 }
2242         }
2243
2244         req = conn->pending[i];
2245         state = tevent_req_data(req, struct smbXcli_req_state);
2246
2247         if (!oplock_break /* oplock breaks are not signed */
2248             && !smb_signing_check_pdu(conn->smb1.signing,
2249                                       inhdr, len, state->smb1.seqnum+1)) {
2250                 DEBUG(10, ("cli_check_sign_mac failed\n"));
2251                 return NT_STATUS_ACCESS_DENIED;
2252         }
2253
2254         status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
2255                                            &iov, &num_iov);
2256         if (!NT_STATUS_IS_OK(status)) {
2257                 DEBUG(10,("smb1cli_inbuf_parse_chain - %s\n",
2258                           nt_errstr(status)));
2259                 return status;
2260         }
2261
2262         cmd = CVAL(inhdr, HDR_COM);
2263         status = smb1cli_pull_raw_error(inhdr);
2264
2265         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
2266             (state->session != NULL) && state->session->disconnect_expired)
2267         {
2268                 /*
2269                  * this should be a short term hack
2270                  * until the upper layers have implemented
2271                  * re-authentication.
2272                  */
2273                 return status;
2274         }
2275
2276         if (state->smb1.chained_requests == NULL) {
2277                 if (num_iov != 3) {
2278                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2279                 }
2280
2281                 smbXcli_req_unset_pending(req);
2282
2283                 if (state->smb1.recv_iov == NULL) {
2284                         /*
2285                          * For requests with more than
2286                          * one response, we have to readd the
2287                          * recv_iov array.
2288                          */
2289                         state->smb1.recv_iov = talloc_zero_array(state,
2290                                                                  struct iovec,
2291                                                                  3);
2292                         if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2293                                 return NT_STATUS_OK;
2294                         }
2295                 }
2296
2297                 state->smb1.recv_cmd = cmd;
2298                 state->smb1.recv_status = status;
2299                 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2300
2301                 state->smb1.recv_iov[0] = iov[0];
2302                 state->smb1.recv_iov[1] = iov[1];
2303                 state->smb1.recv_iov[2] = iov[2];
2304
2305                 if (talloc_array_length(conn->pending) == 0) {
2306                         tevent_req_done(req);
2307                         return NT_STATUS_OK;
2308                 }
2309
2310                 tevent_req_defer_callback(req, state->ev);
2311                 tevent_req_done(req);
2312                 return NT_STATUS_RETRY;
2313         }
2314
2315         chain = talloc_move(tmp_mem, &state->smb1.chained_requests);
2316         num_chained = talloc_array_length(chain);
2317         num_responses = (num_iov - 1)/2;
2318
2319         if (num_responses > num_chained) {
2320                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2321         }
2322
2323         for (i=0; i<num_chained; i++) {
2324                 size_t iov_idx = 1 + (i*2);
2325                 struct iovec *cur = &iov[iov_idx];
2326                 uint8_t *inbuf_ref;
2327
2328                 req = chain[i];
2329                 state = tevent_req_data(req, struct smbXcli_req_state);
2330
2331                 smbXcli_req_unset_pending(req);
2332
2333                 /*
2334                  * as we finish multiple requests here
2335                  * we need to defer the callbacks as
2336                  * they could destroy our current stack state.
2337                  */
2338                 tevent_req_defer_callback(req, state->ev);
2339
2340                 if (i >= num_responses) {
2341                         tevent_req_nterror(req, NT_STATUS_REQUEST_ABORTED);
2342                         continue;
2343                 }
2344
2345                 if (state->smb1.recv_iov == NULL) {
2346                         /*
2347                          * For requests with more than
2348                          * one response, we have to readd the
2349                          * recv_iov array.
2350                          */
2351                         state->smb1.recv_iov = talloc_zero_array(state,
2352                                                                  struct iovec,
2353                                                                  3);
2354                         if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2355                                 continue;
2356                         }
2357                 }
2358
2359                 state->smb1.recv_cmd = cmd;
2360
2361                 if (i == (num_responses - 1)) {
2362                         /*
2363                          * The last request in the chain gets the status
2364                          */
2365                         state->smb1.recv_status = status;
2366                 } else {
2367                         cmd = CVAL(cur[0].iov_base, 0);
2368                         state->smb1.recv_status = NT_STATUS_OK;
2369                 }
2370
2371                 state->inbuf = inbuf;
2372
2373                 /*
2374                  * Note: here we use talloc_reference() in a way
2375                  *       that does not expose it to the caller.
2376                  */
2377                 inbuf_ref = talloc_reference(state->smb1.recv_iov, inbuf);
2378                 if (tevent_req_nomem(inbuf_ref, req)) {
2379                         continue;
2380                 }
2381
2382                 /* copy the related buffers */
2383                 state->smb1.recv_iov[0] = iov[0];
2384                 state->smb1.recv_iov[1] = cur[0];
2385                 state->smb1.recv_iov[2] = cur[1];
2386
2387                 tevent_req_done(req);
2388         }
2389
2390         return NT_STATUS_RETRY;
2391 }
2392
2393 NTSTATUS smb1cli_req_recv(struct tevent_req *req,
2394                           TALLOC_CTX *mem_ctx,
2395                           struct iovec **piov,
2396                           uint8_t **phdr,
2397                           uint8_t *pwct,
2398                           uint16_t **pvwv,
2399                           uint32_t *pvwv_offset,
2400                           uint32_t *pnum_bytes,
2401                           uint8_t **pbytes,
2402                           uint32_t *pbytes_offset,
2403                           uint8_t **pinbuf,
2404                           const struct smb1cli_req_expected_response *expected,
2405                           size_t num_expected)
2406 {
2407         struct smbXcli_req_state *state =
2408                 tevent_req_data(req,
2409                 struct smbXcli_req_state);
2410         NTSTATUS status = NT_STATUS_OK;
2411         struct iovec *recv_iov = NULL;
2412         uint8_t *hdr = NULL;
2413         uint8_t wct = 0;
2414         uint32_t vwv_offset = 0;
2415         uint16_t *vwv = NULL;
2416         uint32_t num_bytes = 0;
2417         uint32_t bytes_offset = 0;
2418         uint8_t *bytes = NULL;
2419         size_t i;
2420         bool found_status = false;
2421         bool found_size = false;
2422
2423         if (piov != NULL) {
2424                 *piov = NULL;
2425         }
2426         if (phdr != NULL) {
2427                 *phdr = 0;
2428         }
2429         if (pwct != NULL) {
2430                 *pwct = 0;
2431         }
2432         if (pvwv != NULL) {
2433                 *pvwv = NULL;
2434         }
2435         if (pvwv_offset != NULL) {
2436                 *pvwv_offset = 0;
2437         }
2438         if (pnum_bytes != NULL) {
2439                 *pnum_bytes = 0;
2440         }
2441         if (pbytes != NULL) {
2442                 *pbytes = NULL;
2443         }
2444         if (pbytes_offset != NULL) {
2445                 *pbytes_offset = 0;
2446         }
2447         if (pinbuf != NULL) {
2448                 *pinbuf = NULL;
2449         }
2450
2451         if (state->inbuf != NULL) {
2452                 recv_iov = state->smb1.recv_iov;
2453                 state->smb1.recv_iov = NULL;
2454                 if (state->smb1.recv_cmd != SMBreadBraw) {
2455                         hdr = (uint8_t *)recv_iov[0].iov_base;
2456                         wct = recv_iov[1].iov_len/2;
2457                         vwv = (uint16_t *)recv_iov[1].iov_base;
2458                         vwv_offset = PTR_DIFF(vwv, hdr);
2459                         num_bytes = recv_iov[2].iov_len;
2460                         bytes = (uint8_t *)recv_iov[2].iov_base;
2461                         bytes_offset = PTR_DIFF(bytes, hdr);
2462                 }
2463         }
2464
2465         if (tevent_req_is_nterror(req, &status)) {
2466                 for (i=0; i < num_expected; i++) {
2467                         if (NT_STATUS_EQUAL(status, expected[i].status)) {
2468                                 found_status = true;
2469                                 break;
2470                         }
2471                 }
2472
2473                 if (found_status) {
2474                         return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2475                 }
2476
2477                 return status;
2478         }
2479
2480         if (num_expected == 0) {
2481                 found_status = true;
2482                 found_size = true;
2483         }
2484
2485         status = state->smb1.recv_status;
2486
2487         for (i=0; i < num_expected; i++) {
2488                 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
2489                         continue;
2490                 }
2491
2492                 found_status = true;
2493                 if (expected[i].wct == 0) {
2494                         found_size = true;
2495                         break;
2496                 }
2497
2498                 if (expected[i].wct == wct) {
2499                         found_size = true;
2500                         break;
2501                 }
2502         }
2503
2504         if (!found_status) {
2505                 return status;
2506         }
2507
2508         if (!found_size) {
2509                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2510         }
2511
2512         if (piov != NULL) {
2513                 *piov = talloc_move(mem_ctx, &recv_iov);
2514         }
2515
2516         if (phdr != NULL) {
2517                 *phdr = hdr;
2518         }
2519         if (pwct != NULL) {
2520                 *pwct = wct;
2521         }
2522         if (pvwv != NULL) {
2523                 *pvwv = vwv;
2524         }
2525         if (pvwv_offset != NULL) {
2526                 *pvwv_offset = vwv_offset;
2527         }
2528         if (pnum_bytes != NULL) {
2529                 *pnum_bytes = num_bytes;
2530         }
2531         if (pbytes != NULL) {
2532                 *pbytes = bytes;
2533         }
2534         if (pbytes_offset != NULL) {
2535                 *pbytes_offset = bytes_offset;
2536         }
2537         if (pinbuf != NULL) {
2538                 *pinbuf = state->inbuf;
2539         }
2540
2541         return status;
2542 }
2543
2544 size_t smb1cli_req_wct_ofs(struct tevent_req **reqs, int num_reqs)
2545 {
2546         size_t wct_ofs;
2547         int i;
2548
2549         wct_ofs = HDR_WCT;
2550
2551         for (i=0; i<num_reqs; i++) {
2552                 struct smbXcli_req_state *state;
2553                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2554                 wct_ofs += smbXcli_iov_len(state->smb1.iov+2,
2555                                            state->smb1.iov_count-2);
2556                 wct_ofs = (wct_ofs + 3) & ~3;
2557         }
2558         return wct_ofs;
2559 }
2560
2561 NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
2562 {
2563         struct smbXcli_req_state *first_state =
2564                 tevent_req_data(reqs[0],
2565                 struct smbXcli_req_state);
2566         struct smbXcli_req_state *state;
2567         size_t wct_offset;
2568         size_t chain_padding = 0;
2569         int i, iovlen;
2570         struct iovec *iov = NULL;
2571         struct iovec *this_iov;
2572         NTSTATUS status;
2573         ssize_t nbt_len;
2574
2575         if (num_reqs == 1) {
2576                 return smb1cli_req_writev_submit(reqs[0], first_state,
2577                                                  first_state->smb1.iov,
2578                                                  first_state->smb1.iov_count);
2579         }
2580
2581         iovlen = 0;
2582         for (i=0; i<num_reqs; i++) {
2583                 if (!tevent_req_is_in_progress(reqs[i])) {
2584                         return NT_STATUS_INTERNAL_ERROR;
2585                 }
2586
2587                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2588
2589                 if (state->smb1.iov_count < 4) {
2590                         return NT_STATUS_INVALID_PARAMETER_MIX;
2591                 }
2592
2593                 if (i == 0) {
2594                         /*
2595                          * The NBT and SMB header
2596                          */
2597                         iovlen += 2;
2598                 } else {
2599                         /*
2600                          * Chain padding
2601                          */
2602                         iovlen += 1;
2603                 }
2604
2605                 /*
2606                  * words and bytes
2607                  */
2608                 iovlen += state->smb1.iov_count - 2;
2609         }
2610
2611         iov = talloc_zero_array(first_state, struct iovec, iovlen);
2612         if (iov == NULL) {
2613                 return NT_STATUS_NO_MEMORY;
2614         }
2615
2616         first_state->smb1.chained_requests = (struct tevent_req **)talloc_memdup(
2617                 first_state, reqs, sizeof(*reqs) * num_reqs);
2618         if (first_state->smb1.chained_requests == NULL) {
2619                 TALLOC_FREE(iov);
2620                 return NT_STATUS_NO_MEMORY;
2621         }
2622
2623         wct_offset = HDR_WCT;
2624         this_iov = iov;
2625
2626         for (i=0; i<num_reqs; i++) {
2627                 size_t next_padding = 0;
2628                 uint16_t *vwv;
2629
2630                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2631
2632                 if (i < num_reqs-1) {
2633                         if (!smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))
2634                             || CVAL(state->smb1.hdr, HDR_WCT) < 2) {
2635                                 TALLOC_FREE(iov);
2636                                 TALLOC_FREE(first_state->smb1.chained_requests);
2637                                 return NT_STATUS_INVALID_PARAMETER_MIX;
2638                         }
2639                 }
2640
2641                 wct_offset += smbXcli_iov_len(state->smb1.iov+2,
2642                                               state->smb1.iov_count-2) + 1;
2643                 if ((wct_offset % 4) != 0) {
2644                         next_padding = 4 - (wct_offset % 4);
2645                 }
2646                 wct_offset += next_padding;
2647                 vwv = state->smb1.vwv;
2648
2649                 if (i < num_reqs-1) {
2650                         struct smbXcli_req_state *next_state =
2651                                 tevent_req_data(reqs[i+1],
2652                                 struct smbXcli_req_state);
2653                         SCVAL(vwv+0, 0, CVAL(next_state->smb1.hdr, HDR_COM));
2654                         SCVAL(vwv+0, 1, 0);
2655                         SSVAL(vwv+1, 0, wct_offset);
2656                 } else if (smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))) {
2657                         /* properly end the chain */
2658                         SCVAL(vwv+0, 0, 0xff);
2659                         SCVAL(vwv+0, 1, 0xff);
2660                         SSVAL(vwv+1, 0, 0);
2661                 }
2662
2663                 if (i == 0) {
2664                         /*
2665                          * The NBT and SMB header
2666                          */
2667                         this_iov[0] = state->smb1.iov[0];
2668                         this_iov[1] = state->smb1.iov[1];
2669                         this_iov += 2;
2670                 } else {
2671                         /*
2672                          * This one is a bit subtle. We have to add
2673                          * chain_padding bytes between the requests, and we
2674                          * have to also include the wct field of the
2675                          * subsequent requests. We use the subsequent header
2676                          * for the padding, it contains the wct field in its
2677                          * last byte.
2678                          */
2679                         this_iov[0].iov_len = chain_padding+1;
2680                         this_iov[0].iov_base = (void *)&state->smb1.hdr[
2681                                 sizeof(state->smb1.hdr) - this_iov[0].iov_len];
2682                         memset(this_iov[0].iov_base, 0, this_iov[0].iov_len-1);
2683                         this_iov += 1;
2684                 }
2685
2686                 /*
2687                  * copy the words and bytes
2688                  */
2689                 memcpy(this_iov, state->smb1.iov+2,
2690                        sizeof(struct iovec) * (state->smb1.iov_count-2));
2691                 this_iov += state->smb1.iov_count - 2;
2692                 chain_padding = next_padding;
2693         }
2694
2695         nbt_len = iov_buflen(&iov[1], iovlen-1);
2696         if ((nbt_len == -1) || (nbt_len > first_state->conn->smb1.max_xmit)) {
2697                 TALLOC_FREE(iov);
2698                 TALLOC_FREE(first_state->smb1.chained_requests);
2699                 return NT_STATUS_INVALID_PARAMETER_MIX;
2700         }
2701
2702         status = smb1cli_req_writev_submit(reqs[0], first_state, iov, iovlen);
2703         if (!NT_STATUS_IS_OK(status)) {
2704                 TALLOC_FREE(iov);
2705                 TALLOC_FREE(first_state->smb1.chained_requests);
2706                 return status;
2707         }
2708
2709         return NT_STATUS_OK;
2710 }
2711
2712 bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
2713 {
2714         return ((tevent_queue_length(conn->outgoing) != 0)
2715                 || (talloc_array_length(conn->pending) != 0));
2716 }
2717
2718 bool smbXcli_conn_dfs_supported(struct smbXcli_conn *conn)
2719 {
2720         if (conn->protocol >= PROTOCOL_SMB2_02) {
2721                 return (smb2cli_conn_server_capabilities(conn) & SMB2_CAP_DFS);
2722         }
2723
2724         return (smb1cli_conn_capabilities(conn) & CAP_DFS);
2725 }
2726
2727 bool smb2cli_conn_req_possible(struct smbXcli_conn *conn, uint32_t *max_dyn_len)
2728 {
2729         uint16_t credits = 1;
2730
2731         if (conn->smb2.cur_credits == 0) {
2732                 if (max_dyn_len != NULL) {
2733                         *max_dyn_len = 0;
2734                 }
2735                 return false;
2736         }
2737
2738         if (conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2739                 credits = conn->smb2.cur_credits;
2740         }
2741
2742         if (max_dyn_len != NULL) {
2743                 *max_dyn_len = credits * 65536;
2744         }
2745
2746         return true;
2747 }
2748
2749 uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
2750 {
2751         return conn->smb2.server.capabilities;
2752 }
2753
2754 uint16_t smb2cli_conn_server_security_mode(struct smbXcli_conn *conn)
2755 {
2756         return conn->smb2.server.security_mode;
2757 }
2758
2759 uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
2760 {
2761         return conn->smb2.server.max_trans_size;
2762 }
2763
2764 uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
2765 {
2766         return conn->smb2.server.max_read_size;
2767 }
2768
2769 uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
2770 {
2771         return conn->smb2.server.max_write_size;
2772 }
2773
2774 void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
2775                                   uint16_t max_credits)
2776 {
2777         conn->smb2.max_credits = max_credits;
2778 }
2779
2780 uint16_t smb2cli_conn_get_cur_credits(struct smbXcli_conn *conn)
2781 {
2782         return conn->smb2.cur_credits;
2783 }
2784
2785 uint8_t smb2cli_conn_get_io_priority(struct smbXcli_conn *conn)
2786 {
2787         if (conn->protocol < PROTOCOL_SMB3_11) {
2788                 return 0;
2789         }
2790
2791         return conn->smb2.io_priority;
2792 }
2793
2794 void smb2cli_conn_set_io_priority(struct smbXcli_conn *conn,
2795                                   uint8_t io_priority)
2796 {
2797         conn->smb2.io_priority = io_priority;
2798 }
2799
2800 uint32_t smb2cli_conn_cc_chunk_len(struct smbXcli_conn *conn)
2801 {
2802         return conn->smb2.cc_chunk_len;
2803 }
2804
2805 void smb2cli_conn_set_cc_chunk_len(struct smbXcli_conn *conn,
2806                                     uint32_t chunk_len)
2807 {
2808         conn->smb2.cc_chunk_len = chunk_len;
2809 }
2810
2811 uint32_t smb2cli_conn_cc_max_chunks(struct smbXcli_conn *conn)
2812 {
2813         return conn->smb2.cc_max_chunks;
2814 }
2815
2816 void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
2817                                     uint32_t max_chunks)
2818 {
2819         conn->smb2.cc_max_chunks = max_chunks;
2820 }
2821
2822 static void smb2cli_req_cancel_done(struct tevent_req *subreq);
2823
2824 static bool smb2cli_req_cancel(struct tevent_req *req)
2825 {
2826         struct smbXcli_req_state *state =
2827                 tevent_req_data(req,
2828                 struct smbXcli_req_state);
2829         struct smbXcli_tcon *tcon = state->tcon;
2830         struct smbXcli_session *session = state->session;
2831         uint8_t *fixed = state->smb2.pad;
2832         uint16_t fixed_len = 4;
2833         struct tevent_req *subreq;
2834         struct smbXcli_req_state *substate;
2835         NTSTATUS status;
2836
2837         SSVAL(fixed, 0, 0x04);
2838         SSVAL(fixed, 2, 0);
2839
2840         subreq = smb2cli_req_create(state, state->ev,
2841                                     state->conn,
2842                                     SMB2_OP_CANCEL,
2843                                     0, 0, /* flags */
2844                                     0, /* timeout */
2845                                     tcon, session,
2846                                     fixed, fixed_len,
2847                                     NULL, 0, 0);
2848         if (subreq == NULL) {
2849                 return false;
2850         }
2851         substate = tevent_req_data(subreq, struct smbXcli_req_state);
2852
2853         SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, state->smb2.cancel_flags);
2854         SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, state->smb2.cancel_mid);
2855         SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, state->smb2.cancel_aid);
2856
2857         status = smb2cli_req_compound_submit(&subreq, 1);
2858         if (!NT_STATUS_IS_OK(status)) {
2859                 TALLOC_FREE(subreq);
2860                 return false;
2861         }
2862
2863         tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2864
2865         return true;
2866 }
2867
2868 static void smb2cli_req_cancel_done(struct tevent_req *subreq)
2869 {
2870         /* we do not care about the result */
2871         TALLOC_FREE(subreq);
2872 }
2873
2874 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
2875                                       struct tevent_context *ev,
2876                                       struct smbXcli_conn *conn,
2877                                       uint16_t cmd,
2878                                       uint32_t additional_flags,
2879                                       uint32_t clear_flags,
2880                                       uint32_t timeout_msec,
2881                                       struct smbXcli_tcon *tcon,
2882                                       struct smbXcli_session *session,
2883                                       const uint8_t *fixed,
2884                                       uint16_t fixed_len,
2885                                       const uint8_t *dyn,
2886                                       uint32_t dyn_len,
2887                                       uint32_t max_dyn_len)
2888 {
2889         struct tevent_req *req;
2890         struct smbXcli_req_state *state;
2891         uint32_t flags = 0;
2892         uint32_t tid = 0;
2893         uint64_t uid = 0;
2894         bool use_channel_sequence = false;
2895         uint16_t channel_sequence = 0;
2896         bool use_replay_flag = false;
2897
2898         req = tevent_req_create(mem_ctx, &state,
2899                                 struct smbXcli_req_state);
2900         if (req == NULL) {
2901                 return NULL;
2902         }
2903
2904         state->ev = ev;
2905         state->conn = conn;
2906         state->session = session;
2907         state->tcon = tcon;
2908
2909         if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
2910                 use_channel_sequence = true;
2911         } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
2912                 use_channel_sequence = true;
2913         }
2914
2915         if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_00) {
2916                 use_replay_flag = true;
2917         }
2918
2919         if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
2920                 flags |= SMB2_PRIORITY_VALUE_TO_MASK(conn->smb2.io_priority);
2921         }
2922
2923         if (session) {
2924                 uid = session->smb2->session_id;
2925
2926                 if (use_channel_sequence) {
2927                         channel_sequence = session->smb2->channel_sequence;
2928                 }
2929
2930                 if (use_replay_flag && session->smb2->replay_active) {
2931                         additional_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
2932                 }
2933
2934                 state->smb2.should_sign = session->smb2->should_sign;
2935                 state->smb2.should_encrypt = session->smb2->should_encrypt;
2936
2937                 if (cmd == SMB2_OP_SESSSETUP &&
2938                     session->smb2_channel.signing_key.length == 0 &&
2939                     session->smb2->signing_key.length != 0)
2940                 {
2941                         /*
2942                          * a session bind needs to be signed
2943                          */
2944                         state->smb2.should_sign = true;
2945                 }
2946
2947                 if (cmd == SMB2_OP_SESSSETUP &&
2948                     session->smb2_channel.signing_key.length == 0) {
2949                         state->smb2.should_encrypt = false;
2950                 }
2951
2952                 if (additional_flags & SMB2_HDR_FLAG_SIGNED) {
2953                         if (session->smb2_channel.signing_key.length == 0) {
2954                                 tevent_req_nterror(req, NT_STATUS_NO_USER_SESSION_KEY);
2955                                 return req;
2956                         }
2957
2958                         additional_flags &= ~SMB2_HDR_FLAG_SIGNED;
2959                         state->smb2.should_sign = true;
2960                 }
2961         }
2962
2963         if (tcon) {
2964                 tid = tcon->smb2.tcon_id;
2965
2966                 if (tcon->smb2.should_sign) {
2967                         state->smb2.should_sign = true;
2968                 }
2969                 if (tcon->smb2.should_encrypt) {
2970                         state->smb2.should_encrypt = true;
2971                 }
2972         }
2973
2974         if (state->smb2.should_encrypt) {
2975                 state->smb2.should_sign = false;
2976         }
2977
2978         state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
2979         if (state->smb2.recv_iov == NULL) {
2980                 TALLOC_FREE(req);
2981                 return NULL;
2982         }
2983
2984         flags |= additional_flags;
2985         flags &= ~clear_flags;
2986
2987         state->smb2.fixed = fixed;
2988         state->smb2.fixed_len = fixed_len;
2989         state->smb2.dyn = dyn;
2990         state->smb2.dyn_len = dyn_len;
2991         state->smb2.max_dyn_len = max_dyn_len;
2992
2993         if (state->smb2.should_encrypt) {
2994                 SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2995                 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
2996         }
2997
2998         SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID,    SMB2_MAGIC);
2999         SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH,         SMB2_HDR_BODY);
3000         SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE,         cmd);
3001         SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
3002         SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS,          flags);
3003         SIVAL(state->smb2.hdr, SMB2_HDR_PID,            0); /* reserved */
3004         SIVAL(state->smb2.hdr, SMB2_HDR_TID,            tid);
3005         SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID,     uid);
3006
3007         switch (cmd) {
3008         case SMB2_OP_CANCEL:
3009                 state->one_way = true;
3010                 break;
3011         case SMB2_OP_BREAK:
3012                 /*
3013                  * If this is a dummy request, it will have
3014                  * UINT64_MAX as message id.
3015                  * If we send on break acknowledgement,
3016                  * this gets overwritten later.
3017                  */
3018                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
3019                 break;
3020         }
3021
3022         if (timeout_msec > 0) {
3023                 struct timeval endtime;
3024
3025                 endtime = timeval_current_ofs_msec(timeout_msec);
3026                 if (!tevent_req_set_endtime(req, ev, endtime)) {
3027                         return req;
3028                 }
3029         }
3030
3031         return req;
3032 }
3033
3034 void smb2cli_req_set_notify_async(struct tevent_req *req)
3035 {
3036         struct smbXcli_req_state *state =
3037                 tevent_req_data(req,
3038                 struct smbXcli_req_state);
3039
3040         state->smb2.notify_async = true;
3041 }
3042
3043 static void smb2cli_req_writev_done(struct tevent_req *subreq);
3044 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3045                                                TALLOC_CTX *tmp_mem,
3046                                                uint8_t *inbuf);
3047
3048 NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
3049                                      int num_reqs)
3050 {
3051         struct smbXcli_req_state *state;
3052         struct tevent_req *subreq;
3053         struct iovec *iov;
3054         int i, num_iov, nbt_len;
3055         int tf_iov = -1;
3056         const DATA_BLOB *encryption_key = NULL;
3057         uint64_t encryption_session_id = 0;
3058         uint64_t nonce_high = UINT64_MAX;
3059         uint64_t nonce_low = UINT64_MAX;
3060
3061         /*
3062          * 1 for the nbt length, optional TRANSFORM
3063          * per request: HDR, fixed, dyn, padding
3064          * -1 because the last one does not need padding
3065          */
3066
3067         iov = talloc_array(reqs[0], struct iovec, 1 + 1 + 4*num_reqs - 1);
3068         if (iov == NULL) {
3069                 return NT_STATUS_NO_MEMORY;
3070         }
3071
3072         num_iov = 1;
3073         nbt_len = 0;
3074
3075         /*
3076          * the session of the first request that requires encryption
3077          * specifies the encryption key.
3078          */
3079         for (i=0; i<num_reqs; i++) {
3080                 if (!tevent_req_is_in_progress(reqs[i])) {
3081                         return NT_STATUS_INTERNAL_ERROR;
3082                 }
3083
3084                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3085
3086                 if (!smbXcli_conn_is_connected(state->conn)) {
3087                         return NT_STATUS_CONNECTION_DISCONNECTED;
3088                 }
3089
3090                 if ((state->conn->protocol != PROTOCOL_NONE) &&
3091                     (state->conn->protocol < PROTOCOL_SMB2_02)) {
3092                         return NT_STATUS_REVISION_MISMATCH;
3093                 }
3094
3095                 if (state->session == NULL) {
3096                         continue;
3097                 }
3098
3099                 if (!state->smb2.should_encrypt) {
3100                         continue;
3101                 }
3102
3103                 encryption_key = &state->session->smb2->encryption_key;
3104                 if (encryption_key->length == 0) {
3105                         return NT_STATUS_INVALID_PARAMETER_MIX;
3106                 }
3107
3108                 encryption_session_id = state->session->smb2->session_id;
3109
3110                 state->session->smb2->nonce_low += 1;
3111                 if (state->session->smb2->nonce_low == 0) {
3112                         state->session->smb2->nonce_high += 1;
3113                         state->session->smb2->nonce_low += 1;
3114                 }
3115
3116                 /*
3117                  * CCM and GCM algorithms must never have their
3118                  * nonce wrap, or the security of the whole
3119                  * communication and the keys is destroyed.
3120                  * We must drop the connection once we have
3121                  * transfered too much data.
3122                  *
3123                  * NOTE: We assume nonces greater than 8 bytes.
3124                  */
3125                 if (state->session->smb2->nonce_high >=
3126                     state->session->smb2->nonce_high_max)
3127                 {
3128                         return NT_STATUS_ENCRYPTION_FAILED;
3129                 }
3130
3131                 nonce_high = state->session->smb2->nonce_high_random;
3132                 nonce_high += state->session->smb2->nonce_high;
3133                 nonce_low = state->session->smb2->nonce_low;
3134
3135                 tf_iov = num_iov;
3136                 iov[num_iov].iov_base = state->smb2.transform;
3137                 iov[num_iov].iov_len  = sizeof(state->smb2.transform);
3138                 num_iov += 1;
3139
3140                 SBVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3141                 SBVAL(state->smb2.transform, SMB2_TF_NONCE,
3142                       nonce_low);
3143                 SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
3144                       nonce_high);
3145                 SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID,
3146                       encryption_session_id);
3147
3148                 nbt_len += SMB2_TF_HDR_SIZE;
3149                 break;
3150         }
3151
3152         for (i=0; i<num_reqs; i++) {
3153                 int hdr_iov;
3154                 size_t reqlen;
3155                 bool ret;
3156                 uint16_t opcode;
3157                 uint64_t avail;
3158                 uint16_t charge;
3159                 uint16_t credits;
3160                 uint64_t mid;
3161                 const DATA_BLOB *signing_key = NULL;
3162
3163                 if (!tevent_req_is_in_progress(reqs[i])) {
3164                         return NT_STATUS_INTERNAL_ERROR;
3165                 }
3166
3167                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3168
3169                 if (!smbXcli_conn_is_connected(state->conn)) {
3170                         return NT_STATUS_CONNECTION_DISCONNECTED;
3171                 }
3172
3173                 if ((state->conn->protocol != PROTOCOL_NONE) &&
3174                     (state->conn->protocol < PROTOCOL_SMB2_02)) {
3175                         return NT_STATUS_REVISION_MISMATCH;
3176                 }
3177
3178                 opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3179                 if (opcode == SMB2_OP_CANCEL) {
3180                         goto skip_credits;
3181                 }
3182
3183                 avail = UINT64_MAX - state->conn->smb2.mid;
3184                 if (avail < 1) {
3185                         return NT_STATUS_CONNECTION_ABORTED;
3186                 }
3187
3188                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3189                         uint32_t max_dyn_len = 1;
3190
3191                         max_dyn_len = MAX(max_dyn_len, state->smb2.dyn_len);
3192                         max_dyn_len = MAX(max_dyn_len, state->smb2.max_dyn_len);
3193
3194                         charge = (max_dyn_len - 1)/ 65536 + 1;
3195                 } else {
3196                         charge = 1;
3197                 }
3198
3199                 charge = MAX(state->smb2.credit_charge, charge);
3200
3201                 avail = MIN(avail, state->conn->smb2.cur_credits);
3202                 if (avail < charge) {
3203                         return NT_STATUS_INTERNAL_ERROR;
3204                 }
3205
3206                 credits = 0;
3207                 if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
3208                         credits = state->conn->smb2.max_credits -
3209                                   state->conn->smb2.cur_credits;
3210                 }
3211                 if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
3212                         credits += 1;
3213                 }
3214
3215                 mid = state->conn->smb2.mid;
3216                 state->conn->smb2.mid += charge;
3217                 state->conn->smb2.cur_credits -= charge;
3218
3219                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3220                         SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
3221                 }
3222                 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
3223                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
3224
3225                 state->smb2.cancel_flags = 0;
3226                 state->smb2.cancel_mid = mid;
3227                 state->smb2.cancel_aid = 0;
3228
3229 skip_credits:
3230                 if (state->session && encryption_key == NULL) {
3231                         /*
3232                          * We prefer the channel signing key if it is
3233                          * already there.
3234                          */
3235                         if (state->smb2.should_sign) {
3236                                 signing_key = &state->session->smb2_channel.signing_key;
3237                         }
3238
3239                         /*
3240                          * If it is a channel binding, we already have the main
3241                          * signing key and try that one.
3242                          */
3243                         if (signing_key && signing_key->length == 0) {
3244                                 signing_key = &state->session->smb2->signing_key;
3245                         }
3246
3247                         /*
3248                          * If we do not have any session key yet, we skip the
3249                          * signing of SMB2_OP_SESSSETUP requests.
3250                          */
3251                         if (signing_key && signing_key->length == 0) {
3252                                 signing_key = NULL;
3253                         }
3254                 }
3255
3256                 hdr_iov = num_iov;
3257                 iov[num_iov].iov_base = state->smb2.hdr;
3258                 iov[num_iov].iov_len  = sizeof(state->smb2.hdr);
3259                 num_iov += 1;
3260
3261                 iov[num_iov].iov_base = discard_const(state->smb2.fixed);
3262                 iov[num_iov].iov_len  = state->smb2.fixed_len;
3263                 num_iov += 1;
3264
3265                 if (state->smb2.dyn != NULL) {
3266                         iov[num_iov].iov_base = discard_const(state->smb2.dyn);
3267                         iov[num_iov].iov_len  = state->smb2.dyn_len;
3268                         num_iov += 1;
3269                 }
3270
3271                 reqlen  = sizeof(state->smb2.hdr);
3272                 reqlen += state->smb2.fixed_len;
3273                 reqlen += state->smb2.dyn_len;
3274
3275                 if (i < num_reqs-1) {
3276                         if ((reqlen % 8) > 0) {
3277                                 uint8_t pad = 8 - (reqlen % 8);
3278                                 iov[num_iov].iov_base = state->smb2.pad;
3279                                 iov[num_iov].iov_len = pad;
3280                                 num_iov += 1;
3281                                 reqlen += pad;
3282                         }
3283                         SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
3284                 }
3285
3286                 state->smb2.encryption_session_id = encryption_session_id;
3287
3288                 if (signing_key != NULL) {
3289                         NTSTATUS status;
3290
3291                         status = smb2_signing_sign_pdu(*signing_key,
3292                                                        state->session->conn->protocol,
3293                                                        &iov[hdr_iov], num_iov - hdr_iov);
3294                         if (!NT_STATUS_IS_OK(status)) {
3295                                 return status;
3296                         }
3297                 }
3298
3299                 nbt_len += reqlen;
3300
3301                 ret = smbXcli_req_set_pending(reqs[i]);
3302                 if (!ret) {
3303                         return NT_STATUS_NO_MEMORY;
3304                 }
3305         }
3306
3307         state = tevent_req_data(reqs[0], struct smbXcli_req_state);
3308         _smb_setlen_tcp(state->length_hdr, nbt_len);
3309         iov[0].iov_base = state->length_hdr;
3310         iov[0].iov_len  = sizeof(state->length_hdr);
3311
3312         if (encryption_key != NULL) {
3313                 NTSTATUS status;
3314                 size_t buflen = nbt_len - SMB2_TF_HDR_SIZE;
3315                 uint8_t *buf;
3316                 int vi;
3317
3318                 buf = talloc_array(iov, uint8_t, buflen);
3319                 if (buf == NULL) {
3320                         return NT_STATUS_NO_MEMORY;
3321                 }
3322
3323                 /*
3324                  * We copy the buffers before encrypting them,
3325                  * this is at least currently needed for the
3326                  * to keep state->smb2.hdr.
3327                  *
3328                  * Also the callers may expect there buffers
3329                  * to be const.
3330                  */
3331                 for (vi = tf_iov + 1; vi < num_iov; vi++) {
3332                         struct iovec *v = &iov[vi];
3333                         const uint8_t *o = (const uint8_t *)v->iov_base;
3334
3335                         memcpy(buf, o, v->iov_len);
3336                         v->iov_base = (void *)buf;
3337                         buf += v->iov_len;
3338                 }
3339
3340                 status = smb2_signing_encrypt_pdu(*encryption_key,
3341                                         state->conn->smb2.server.cipher,
3342                                         &iov[tf_iov], num_iov - tf_iov);
3343                 if (!NT_STATUS_IS_OK(status)) {
3344                         return status;
3345                 }
3346         }
3347
3348         if (state->conn->dispatch_incoming == NULL) {
3349                 state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3350         }
3351
3352         subreq = writev_send(state, state->ev, state->conn->outgoing,
3353                              state->conn->sock_fd, false, iov, num_iov);
3354         if (subreq == NULL) {
3355                 return NT_STATUS_NO_MEMORY;
3356         }
3357         tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
3358         state->write_req = subreq;
3359
3360         return NT_STATUS_OK;
3361 }
3362
3363 void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
3364 {
3365         struct smbXcli_req_state *state =
3366                 tevent_req_data(req,
3367                 struct smbXcli_req_state);
3368
3369         state->smb2.credit_charge = charge;
3370 }
3371
3372 struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
3373                                     struct tevent_context *ev,
3374                                     struct smbXcli_conn *conn,
3375                                     uint16_t cmd,
3376                                     uint32_t additional_flags,
3377                                     uint32_t clear_flags,
3378                                     uint32_t timeout_msec,
3379                                     struct smbXcli_tcon *tcon,
3380                                     struct smbXcli_session *session,
3381                                     const uint8_t *fixed,
3382                                     uint16_t fixed_len,
3383                                     const uint8_t *dyn,
3384                                     uint32_t dyn_len,
3385                                     uint32_t max_dyn_len)
3386 {
3387         struct tevent_req *req;
3388         NTSTATUS status;
3389
3390         req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
3391                                  additional_flags, clear_flags,
3392                                  timeout_msec,
3393                                  tcon, session,
3394                                  fixed, fixed_len,
3395                                  dyn, dyn_len,
3396                                  max_dyn_len);
3397         if (req == NULL) {
3398                 return NULL;
3399         }
3400         if (!tevent_req_is_in_progress(req)) {
3401                 return tevent_req_post(req, ev);
3402         }
3403         status = smb2cli_req_compound_submit(&req, 1);
3404         if (tevent_req_nterror(req, status)) {
3405                 return tevent_req_post(req, ev);
3406         }
3407         return req;
3408 }
3409
3410 static void smb2cli_req_writev_done(struct tevent_req *subreq)
3411 {
3412         struct tevent_req *req =
3413                 tevent_req_callback_data(subreq,
3414                 struct tevent_req);
3415         struct smbXcli_req_state *state =
3416                 tevent_req_data(req,
3417                 struct smbXcli_req_state);
3418         ssize_t nwritten;
3419         int err;
3420
3421         state->write_req = NULL;
3422
3423         nwritten = writev_recv(subreq, &err);
3424         TALLOC_FREE(subreq);
3425         if (nwritten == -1) {
3426                 /* here, we need to notify all pending requests */
3427                 NTSTATUS status = map_nt_error_from_unix_common(err);
3428                 smbXcli_conn_disconnect(state->conn, status);
3429                 return;
3430         }
3431 }
3432
3433 static struct smbXcli_session* smbXcli_session_by_uid(struct smbXcli_conn *conn,
3434                                                      uint64_t uid)
3435 {
3436         struct smbXcli_session *s = conn->sessions;
3437
3438         for (; s; s = s->next) {
3439                 if (s->smb2->session_id != uid) {
3440                         continue;
3441                 }
3442                 break;
3443         }
3444
3445         return s;
3446 }
3447
3448 static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
3449                                              uint8_t *buf,
3450                                              size_t buflen,
3451                                              TALLOC_CTX *mem_ctx,
3452                                              struct iovec **piov, int *pnum_iov)
3453 {
3454         struct iovec *iov;
3455         int num_iov = 0;
3456         size_t taken = 0;
3457         uint8_t *first_hdr = buf;
3458         size_t verified_buflen = 0;
3459         uint8_t *tf = NULL;
3460         size_t tf_len = 0;
3461
3462         iov = talloc_array(mem_ctx, struct iovec, num_iov);
3463         if (iov == NULL) {
3464                 return NT_STATUS_NO_MEMORY;
3465         }
3466
3467         while (taken < buflen) {
3468                 size_t len = buflen - taken;
3469                 uint8_t *hdr = first_hdr + taken;
3470                 struct iovec *cur;
3471                 size_t full_size;
3472                 size_t next_command_ofs;
3473                 uint16_t body_size;
3474                 struct iovec *iov_tmp;
3475
3476                 if (verified_buflen > taken) {
3477                         len = verified_buflen - taken;
3478                 } else {
3479                         tf = NULL;
3480                         tf_len = 0;
3481                 }
3482
3483                 if (len < 4) {
3484                         DEBUG(10, ("%d bytes left, expected at least %d\n",
3485                                    (int)len, 4));
3486                         goto inval;
3487                 }
3488                 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
3489                         struct smbXcli_session *s;
3490                         uint64_t uid;
3491                         struct iovec tf_iov[2];
3492                         size_t enc_len;
3493                         NTSTATUS status;
3494
3495                         if (len < SMB2_TF_HDR_SIZE) {
3496                                 DEBUG(10, ("%d bytes left, expected at least %d\n",
3497                                            (int)len, SMB2_TF_HDR_SIZE));
3498                                 goto inval;
3499                         }
3500                         tf = hdr;
3501                         tf_len = SMB2_TF_HDR_SIZE;
3502                         taken += tf_len;
3503
3504                         hdr = first_hdr + taken;
3505                         enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
3506                         uid = BVAL(tf, SMB2_TF_SESSION_ID);
3507
3508                         if (len < SMB2_TF_HDR_SIZE + enc_len) {
3509                                 DEBUG(10, ("%d bytes left, expected at least %d\n",
3510                                            (int)len,
3511                                            (int)(SMB2_TF_HDR_SIZE + enc_len)));
3512                                 goto inval;
3513                         }
3514
3515                         s = smbXcli_session_by_uid(conn, uid);
3516                         if (s == NULL) {
3517                                 DEBUG(10, ("unknown session_id %llu\n",
3518                                            (unsigned long long)uid));
3519                                 goto inval;
3520                         }
3521
3522                         tf_iov[0].iov_base = (void *)tf;
3523                         tf_iov[0].iov_len = tf_len;
3524                         tf_iov[1].iov_base = (void *)hdr;
3525                         tf_iov[1].iov_len = enc_len;
3526
3527                         status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
3528                                                           conn->smb2.server.cipher,
3529                                                           tf_iov, 2);
3530                         if (!NT_STATUS_IS_OK(status)) {
3531                                 TALLOC_FREE(iov);
3532                                 return status;
3533                         }
3534
3535                         verified_buflen = taken + enc_len;
3536                         len = enc_len;
3537                 }
3538
3539                 /*
3540                  * We need the header plus the body length field
3541                  */
3542
3543                 if (len < SMB2_HDR_BODY + 2) {
3544                         DEBUG(10, ("%d bytes left, expected at least %d\n",
3545                                    (int)len, SMB2_HDR_BODY));
3546                         goto inval;
3547                 }
3548                 if (IVAL(hdr, 0) != SMB2_MAGIC) {
3549                         DEBUG(10, ("Got non-SMB2 PDU: %x\n",
3550                                    IVAL(hdr, 0)));
3551                         goto inval;
3552                 }
3553                 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
3554                         DEBUG(10, ("Got HDR len %d, expected %d\n",
3555                                    SVAL(hdr, 4), SMB2_HDR_BODY));
3556                         goto inval;
3557                 }
3558
3559                 full_size = len;
3560                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
3561                 body_size = SVAL(hdr, SMB2_HDR_BODY);
3562
3563                 if (next_command_ofs != 0) {
3564                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
3565                                 goto inval;
3566                         }
3567                         if (next_command_ofs > full_size) {
3568                                 goto inval;
3569                         }
3570                         full_size = next_command_ofs;
3571                 }
3572                 if (body_size < 2) {
3573                         goto inval;
3574                 }
3575                 body_size &= 0xfffe;
3576
3577                 if (body_size > (full_size - SMB2_HDR_BODY)) {
3578                         goto inval;
3579                 }
3580
3581                 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
3582                                          num_iov + 4);
3583                 if (iov_tmp == NULL) {
3584                         TALLOC_FREE(iov);
3585                         return NT_STATUS_NO_MEMORY;
3586                 }
3587                 iov = iov_tmp;
3588                 cur = &iov[num_iov];
3589                 num_iov += 4;
3590
3591                 cur[0].iov_base = tf;
3592                 cur[0].iov_len  = tf_len;
3593                 cur[1].iov_base = hdr;
3594                 cur[1].iov_len  = SMB2_HDR_BODY;
3595                 cur[2].iov_base = hdr + SMB2_HDR_BODY;
3596                 cur[2].iov_len  = body_size;
3597                 cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
3598                 cur[3].iov_len  = full_size - (SMB2_HDR_BODY + body_size);
3599
3600                 taken += full_size;
3601         }
3602
3603         *piov = iov;
3604         *pnum_iov = num_iov;
3605         return NT_STATUS_OK;
3606
3607 inval:
3608         TALLOC_FREE(iov);
3609         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3610 }
3611
3612 static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
3613                                                     uint64_t mid)
3614 {
3615         size_t num_pending = talloc_array_length(conn->pending);
3616         size_t i;
3617
3618         for (i=0; i<num_pending; i++) {
3619                 struct tevent_req *req = conn->pending[i];
3620                 struct smbXcli_req_state *state =
3621                         tevent_req_data(req,
3622                         struct smbXcli_req_state);
3623
3624                 if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
3625                         return req;
3626                 }
3627         }
3628         return NULL;
3629 }
3630
3631 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3632                                                TALLOC_CTX *tmp_mem,
3633                                                uint8_t *inbuf)
3634 {
3635         struct tevent_req *req;
3636         struct smbXcli_req_state *state = NULL;
3637         struct iovec *iov = NULL;
3638         int i, num_iov = 0;
3639         NTSTATUS status;
3640         bool defer = true;
3641         struct smbXcli_session *last_session = NULL;
3642         size_t inbuf_len = smb_len_tcp(inbuf);
3643
3644         status = smb2cli_inbuf_parse_compound(conn,
3645                                               inbuf + NBT_HDR_SIZE,
3646                                               inbuf_len,
3647                                               tmp_mem,
3648                                               &iov, &num_iov);
3649         if (!NT_STATUS_IS_OK(status)) {
3650                 return status;
3651         }
3652
3653         for (i=0; i<num_iov; i+=4) {
3654                 uint8_t *inbuf_ref = NULL;
3655                 struct iovec *cur = &iov[i];
3656                 uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
3657                 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3658                 uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3659                 uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3660                 uint16_t req_opcode;
3661                 uint32_t req_flags;
3662                 uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
3663                 uint32_t new_credits;
3664                 struct smbXcli_session *session = NULL;
3665                 const DATA_BLOB *signing_key = NULL;
3666                 bool was_encrypted = false;
3667
3668                 new_credits = conn->smb2.cur_credits;
3669                 new_credits += credits;
3670                 if (new_credits > UINT16_MAX) {
3671                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3672                 }
3673                 conn->smb2.cur_credits += credits;
3674
3675                 req = smb2cli_conn_find_pending(conn, mid);
3676                 if (req == NULL) {
3677                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3678                 }
3679                 state = tevent_req_data(req, struct smbXcli_req_state);
3680
3681                 req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3682                 if (opcode != req_opcode) {
3683                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3684                 }
3685                 req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3686
3687                 if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
3688                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
3689                 }
3690
3691                 status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
3692                 if ((flags & SMB2_HDR_FLAG_ASYNC) &&
3693                     NT_STATUS_EQUAL(status, STATUS_PENDING)) {
3694                         uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
3695
3696                         if (state->smb2.got_async) {
3697                                 /* We only expect one STATUS_PENDING response */
3698                                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3699                         }
3700                         state->smb2.got_async = true;
3701
3702                         /*
3703                          * async interim responses are not signed,
3704                          * even if the SMB2_HDR_FLAG_SIGNED flag
3705                          * is set.
3706                          */
3707                         state->smb2.cancel_flags = SMB2_HDR_FLAG_ASYNC;
3708                         state->smb2.cancel_mid = 0;
3709                         state->smb2.cancel_aid = async_id;
3710
3711                         if (state->smb2.notify_async) {
3712                                 tevent_req_defer_callback(req, state->ev);
3713                                 tevent_req_notify_callback(req);
3714                         }
3715                         continue;
3716                 }
3717
3718                 session = state->session;
3719                 if (req_flags & SMB2_HDR_FLAG_CHAINED) {
3720                         session = last_session;
3721                 }
3722                 last_session = session;
3723
3724                 if (state->smb2.should_sign) {
3725                         if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
3726                                 return NT_STATUS_ACCESS_DENIED;
3727                         }
3728                 }
3729
3730                 if (flags & SMB2_HDR_FLAG_SIGNED) {
3731                         uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
3732
3733                         if (session == NULL) {
3734                                 session = smbXcli_session_by_uid(state->conn,
3735                                                                  uid);
3736                         }
3737
3738                         if (session == NULL) {
3739                                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3740                         }
3741
3742                         last_session = session;
3743                         signing_key = &session->smb2_channel.signing_key;
3744                 }
3745
3746                 if (opcode == SMB2_OP_SESSSETUP) {
3747                         /*
3748                          * We prefer the channel signing key, if it is
3749                          * already there.
3750                          *
3751                          * If we do not have a channel signing key yet,
3752                          * we try the main signing key, if it is not
3753                          * the final response.
3754                          */
3755                         if (signing_key && signing_key->length == 0 &&
3756                             !NT_STATUS_IS_OK(status)) {
3757                                 signing_key = &session->smb2->signing_key;
3758                         }
3759
3760                         if (signing_key && signing_key->length == 0) {
3761                                 /*
3762                                  * If we do not have a session key to
3763                                  * verify the signature, we defer the
3764                                  * signing check to the caller.
3765                                  *
3766                                  * The caller gets NT_STATUS_OK, it
3767                                  * has to call
3768                                  * smb2cli_session_set_session_key()
3769                                  * or
3770                                  * smb2cli_session_set_channel_key()
3771                                  * which will check the signature
3772                                  * with the channel signing key.
3773                                  */
3774                                 signing_key = NULL;
3775                         }
3776                 }
3777
3778                 if (cur[0].iov_len == SMB2_TF_HDR_SIZE) {
3779                         const uint8_t *tf = (const uint8_t *)cur[0].iov_base;
3780                         uint64_t uid = BVAL(tf, SMB2_TF_SESSION_ID);
3781
3782                         /*
3783                          * If the response was encrypted in a SMB2_TRANSFORM
3784                          * pdu, which belongs to the correct session,
3785                          * we do not need to do signing checks
3786                          *
3787                          * It could be the session the response belongs to
3788                          * or the session that was used to encrypt the
3789                          * SMB2_TRANSFORM request.
3790                          */
3791                         if ((session && session->smb2->session_id == uid) ||
3792                             (state->smb2.encryption_session_id == uid)) {
3793                                 signing_key = NULL;
3794                                 was_encrypted = true;
3795                         }
3796                 }
3797
3798                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
3799                         /*
3800                          * if the server returns NT_STATUS_USER_SESSION_DELETED
3801                          * the response is not signed and we should
3802                          * propagate the NT_STATUS_USER_SESSION_DELETED
3803                          * status to the caller.
3804                          */
3805                         state->smb2.signing_skipped = true;
3806                         signing_key = NULL;
3807                 }
3808
3809                 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3810                         /*
3811                          * if the server returns
3812                          * NT_STATUS_INVALID_PARAMETER
3813                          * the response might not be encrypted.
3814                          */
3815                         if (state->smb2.should_encrypt && !was_encrypted) {
3816                                 state->smb2.signing_skipped = true;
3817                                 signing_key = NULL;
3818                         }
3819                 }
3820
3821                 if (state->smb2.should_encrypt && !was_encrypted) {
3822                         if (!state->smb2.signing_skipped) {
3823                                 return NT_STATUS_ACCESS_DENIED;
3824                         }
3825                 }
3826
3827                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
3828                     NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
3829                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3830                         /*
3831                          * if the server returns
3832                          * NT_STATUS_NETWORK_NAME_DELETED
3833                          * NT_STATUS_FILE_CLOSED
3834                          * NT_STATUS_INVALID_PARAMETER
3835                          * the response might not be signed
3836                          * as this happens before the signing checks.
3837                          *
3838                          * If server echos the signature (or all zeros)
3839                          * we should report the status from the server
3840                          * to the caller.
3841                          */
3842                         if (signing_key) {
3843                                 int cmp;
3844
3845                                 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
3846                                              state->smb2.hdr+SMB2_HDR_SIGNATURE,
3847                                              16);
3848                                 if (cmp == 0) {
3849                                         state->smb2.signing_skipped = true;
3850                                         signing_key = NULL;
3851                                 }
3852                         }
3853                         if (signing_key) {
3854                                 bool zero;
3855                                 zero = all_zero(inhdr+SMB2_HDR_SIGNATURE, 16);
3856                                 if (zero) {
3857                                         state->smb2.signing_skipped = true;
3858                                         signing_key = NULL;
3859                                 }
3860                         }
3861                 }
3862
3863                 if (signing_key) {
3864                         status = smb2_signing_check_pdu(*signing_key,
3865                                                         state->conn->protocol,
3866                                                         &cur[1], 3);
3867                         if (!NT_STATUS_IS_OK(status)) {
3868                                 /*
3869                                  * If the signing check fails, we disconnect
3870                                  * the connection.
3871                                  */
3872                                 return status;
3873                         }
3874                 }
3875
3876                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
3877                     (session != NULL) && session->disconnect_expired)
3878                 {
3879                         /*
3880                          * this should be a short term hack
3881                          * until the upper layers have implemented
3882                          * re-authentication.
3883                          */
3884                         return status;
3885                 }
3886
3887                 smbXcli_req_unset_pending(req);
3888
3889                 /*
3890                  * There might be more than one response
3891                  * we need to defer the notifications
3892                  */
3893                 if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
3894                         defer = false;
3895                 }
3896
3897                 if (defer) {
3898                         tevent_req_defer_callback(req, state->ev);
3899                 }
3900
3901                 /*
3902                  * Note: here we use talloc_reference() in a way
3903                  *       that does not expose it to the caller.
3904                  */
3905                 inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
3906                 if (tevent_req_nomem(inbuf_ref, req)) {
3907                         continue;
3908                 }
3909
3910                 /* copy the related buffers */
3911                 state->smb2.recv_iov[0] = cur[1];
3912                 state->smb2.recv_iov[1] = cur[2];
3913                 state->smb2.recv_iov[2] = cur[3];
3914
3915                 tevent_req_done(req);
3916         }
3917
3918         if (defer) {
3919                 return NT_STATUS_RETRY;
3920         }
3921
3922         return NT_STATUS_OK;
3923 }
3924
3925 NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3926                           struct iovec **piov,
3927                           const struct smb2cli_req_expected_response *expected,
3928                           size_t num_expected)
3929 {
3930         struct smbXcli_req_state *state =
3931                 tevent_req_data(req,
3932                 struct smbXcli_req_state);
3933         NTSTATUS status;
3934         size_t body_size;
3935         bool found_status = false;
3936         bool found_size = false;
3937         size_t i;
3938
3939         if (piov != NULL) {
3940                 *piov = NULL;
3941         }
3942
3943         if (tevent_req_is_in_progress(req) && state->smb2.got_async) {
3944                 return STATUS_PENDING;
3945         }
3946
3947         if (tevent_req_is_nterror(req, &status)) {
3948                 for (i=0; i < num_expected; i++) {
3949                         if (NT_STATUS_EQUAL(status, expected[i].status)) {
3950                                 found_status = true;
3951                                 break;
3952                         }
3953                 }
3954
3955                 if (found_status) {
3956                         return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
3957                 }
3958
3959                 return status;
3960         }
3961
3962         if (num_expected == 0) {
3963                 found_status = true;
3964                 found_size = true;
3965         }
3966
3967         status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
3968         body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
3969
3970         for (i=0; i < num_expected; i++) {
3971                 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
3972                         continue;
3973                 }
3974
3975                 found_status = true;
3976                 if (expected[i].body_size == 0) {
3977                         found_size = true;
3978                         break;
3979                 }
3980
3981                 if (expected[i].body_size == body_size) {
3982                         found_size = true;
3983                         break;
3984                 }
3985         }
3986
3987         if (!found_status) {
3988                 return status;
3989         }
3990
3991         if (state->smb2.signing_skipped) {
3992                 if (num_expected > 0) {
3993                         return NT_STATUS_ACCESS_DENIED;
3994                 }
3995                 if (!NT_STATUS_IS_ERR(status)) {
3996                         return NT_STATUS_ACCESS_DENIED;
3997                 }
3998         }
3999
4000         if (!found_size) {
4001                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4002         }
4003
4004         if (piov != NULL) {
4005                 *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
4006         }
4007
4008         return status;
4009 }
4010
4011 NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
4012                                   struct iovec *sent_iov)
4013 {
4014         struct smbXcli_req_state *state =
4015                 tevent_req_data(req,
4016                 struct smbXcli_req_state);
4017
4018         if (tevent_req_is_in_progress(req)) {
4019                 return STATUS_PENDING;
4020         }
4021
4022         sent_iov[0].iov_base = state->smb2.hdr;
4023         sent_iov[0].iov_len  = sizeof(state->smb2.hdr);
4024
4025         sent_iov[1].iov_base = discard_const(state->smb2.fixed);
4026         sent_iov[1].iov_len  = state->smb2.fixed_len;
4027
4028         if (state->smb2.dyn != NULL) {
4029                 sent_iov[2].iov_base = discard_const(state->smb2.dyn);
4030                 sent_iov[2].iov_len  = state->smb2.dyn_len;
4031         } else {
4032                 sent_iov[2].iov_base = NULL;
4033                 sent_iov[2].iov_len  = 0;
4034         }
4035
4036         return NT_STATUS_OK;
4037 }
4038
4039 static const struct {
4040         enum protocol_types proto;
4041         const char *smb1_name;
4042 } smb1cli_prots[] = {
4043         {PROTOCOL_CORE,         "PC NETWORK PROGRAM 1.0"},
4044         {PROTOCOL_COREPLUS,     "MICROSOFT NETWORKS 1.03"},
4045         {PROTOCOL_LANMAN1,      "MICROSOFT NETWORKS 3.0"},
4046         {PROTOCOL_LANMAN1,      "LANMAN1.0"},
4047         {PROTOCOL_LANMAN2,      "LM1.2X002"},
4048         {PROTOCOL_LANMAN2,      "DOS LANMAN2.1"},
4049         {PROTOCOL_LANMAN2,      "LANMAN2.1"},
4050         {PROTOCOL_LANMAN2,      "Samba"},
4051         {PROTOCOL_NT1,          "NT LANMAN 1.0"},
4052         {PROTOCOL_NT1,          "NT LM 0.12"},
4053         {PROTOCOL_SMB2_02,      "SMB 2.002"},
4054         {PROTOCOL_SMB2_10,      "SMB 2.???"},
4055 };
4056
4057 static const struct {
4058         enum protocol_types proto;
4059         uint16_t smb2_dialect;
4060 } smb2cli_prots[] = {
4061         {PROTOCOL_SMB2_02,      SMB2_DIALECT_REVISION_202},
4062         {PROTOCOL_SMB2_10,      SMB2_DIALECT_REVISION_210},
4063         {PROTOCOL_SMB2_22,      SMB2_DIALECT_REVISION_222},
4064         {PROTOCOL_SMB2_24,      SMB2_DIALECT_REVISION_224},
4065         {PROTOCOL_SMB3_00,      SMB3_DIALECT_REVISION_300},
4066         {PROTOCOL_SMB3_02,      SMB3_DIALECT_REVISION_302},
4067         {PROTOCOL_SMB3_10,      SMB3_DIALECT_REVISION_310},
4068         {PROTOCOL_SMB3_11,      SMB3_DIALECT_REVISION_311},
4069 };
4070
4071 struct smbXcli_negprot_state {
4072         struct smbXcli_conn *conn;
4073         struct tevent_context *ev;
4074         uint32_t timeout_msec;
4075
4076         struct {
4077                 uint8_t fixed[36];
4078         } smb2;
4079 };
4080
4081 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
4082 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
4083 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
4084 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
4085 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
4086 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
4087                                                   TALLOC_CTX *frame,
4088                                                   uint8_t *inbuf);
4089
4090 struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
4091                                         struct tevent_context *ev,
4092                                         struct smbXcli_conn *conn,
4093                                         uint32_t timeout_msec,
4094                                         enum protocol_types min_protocol,
4095                                         enum protocol_types max_protocol,
4096                                         uint16_t max_credits)
4097 {
4098         struct tevent_req *req, *subreq;
4099         struct smbXcli_negprot_state *state;
4100
4101         req = tevent_req_create(mem_ctx, &state,
4102                                 struct smbXcli_negprot_state);
4103         if (req == NULL) {
4104                 return NULL;
4105         }
4106         state->conn = conn;
4107         state->ev = ev;
4108         state->timeout_msec = timeout_msec;
4109
4110         if (min_protocol == PROTOCOL_NONE) {
4111                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4112                 return tevent_req_post(req, ev);
4113         }
4114
4115         if (max_protocol == PROTOCOL_NONE) {
4116                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4117                 return tevent_req_post(req, ev);
4118         }
4119
4120         if (min_protocol > max_protocol) {
4121                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4122                 return tevent_req_post(req, ev);
4123         }
4124
4125         conn->min_protocol = min_protocol;
4126         conn->max_protocol = max_protocol;
4127         conn->protocol = PROTOCOL_NONE;
4128
4129         if (max_protocol >= PROTOCOL_SMB2_02) {
4130                 conn->smb2.max_credits = max_credits;
4131         }
4132
4133         if ((min_protocol < PROTOCOL_SMB2_02) &&
4134             (max_protocol < PROTOCOL_SMB2_02)) {
4135                 /*
4136                  * SMB1 only...
4137                  */
4138                 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4139
4140                 subreq = smbXcli_negprot_smb1_subreq(state);
4141                 if (tevent_req_nomem(subreq, req)) {
4142                         return tevent_req_post(req, ev);
4143                 }
4144                 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4145                 return req;
4146         }
4147
4148         if ((min_protocol >= PROTOCOL_SMB2_02) &&
4149             (max_protocol >= PROTOCOL_SMB2_02)) {
4150                 /*
4151                  * SMB2 only...
4152                  */
4153                 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4154
4155                 subreq = smbXcli_negprot_smb2_subreq(state);
4156                 if (tevent_req_nomem(subreq, req)) {
4157                         return tevent_req_post(req, ev);
4158                 }
4159                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4160                 return req;
4161         }
4162
4163         /*
4164          * We send an SMB1 negprot with the SMB2 dialects
4165          * and expect a SMB1 or a SMB2 response.
4166          *
4167          * smbXcli_negprot_dispatch_incoming() will fix the
4168          * callback to match protocol of the response.
4169          */
4170         conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
4171
4172         subreq = smbXcli_negprot_smb1_subreq(state);
4173         if (tevent_req_nomem(subreq, req)) {
4174                 return tevent_req_post(req, ev);
4175         }
4176         tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
4177         return req;
4178 }
4179
4180 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
4181 {
4182         struct tevent_req *req =
4183                 tevent_req_callback_data(subreq,
4184                 struct tevent_req);
4185         NTSTATUS status;
4186
4187         /*
4188          * we just want the low level error
4189          */
4190         status = tevent_req_simple_recv_ntstatus(subreq);
4191         TALLOC_FREE(subreq);
4192         if (tevent_req_nterror(req, status)) {
4193                 return;
4194         }
4195
4196         /* this should never happen */
4197         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
4198 }
4199
4200 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
4201 {
4202         size_t i;
4203         DATA_BLOB bytes = data_blob_null;
4204         uint8_t flags;
4205         uint16_t flags2;
4206
4207         /* setup the protocol strings */
4208         for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4209                 uint8_t c = 2;
4210                 bool ok;
4211
4212                 if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4213                         continue;
4214                 }
4215
4216                 if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4217                         continue;
4218                 }
4219
4220                 ok = data_blob_append(state, &bytes, &c, sizeof(c));
4221                 if (!ok) {
4222                         return NULL;
4223                 }
4224
4225                 /*
4226                  * We now it is already ascii and
4227                  * we want NULL termination.
4228                  */
4229                 ok = data_blob_append(state, &bytes,
4230                                       smb1cli_prots[i].smb1_name,
4231                                       strlen(smb1cli_prots[i].smb1_name)+1);
4232                 if (!ok) {
4233                         return NULL;
4234                 }
4235         }
4236
4237         smb1cli_req_flags(state->conn->max_protocol,
4238                           state->conn->smb1.client.capabilities,
4239                           SMBnegprot,
4240                           0, 0, &flags,
4241                           0, 0, &flags2);
4242
4243         return smb1cli_req_send(state, state->ev, state->conn,
4244                                 SMBnegprot,
4245                                 flags, ~flags,
4246                                 flags2, ~flags2,
4247                                 state->timeout_msec,
4248                                 0xFFFE, 0, NULL, /* pid, tid, session */
4249                                 0, NULL, /* wct, vwv */
4250                                 bytes.length, bytes.data);
4251 }
4252
4253 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
4254 {
4255         struct tevent_req *req =
4256                 tevent_req_callback_data(subreq,
4257                 struct tevent_req);
4258         struct smbXcli_negprot_state *state =
4259                 tevent_req_data(req,
4260                 struct smbXcli_negprot_state);
4261         struct smbXcli_conn *conn = state->conn;
4262         struct iovec *recv_iov = NULL;
4263         uint8_t *inhdr;
4264         uint8_t wct;
4265         uint16_t *vwv;
4266         uint32_t num_bytes;
4267         uint8_t *bytes;
4268         NTSTATUS status;
4269         uint16_t protnum;
4270         size_t i;
4271         size_t num_prots = 0;
4272         uint8_t flags;
4273         uint32_t client_capabilities = conn->smb1.client.capabilities;
4274         uint32_t both_capabilities;
4275         uint32_t server_capabilities = 0;
4276         uint32_t capabilities;
4277         uint32_t client_max_xmit = conn->smb1.client.max_xmit;
4278         uint32_t server_max_xmit = 0;
4279         uint32_t max_xmit;
4280         uint32_t server_max_mux = 0;
4281         uint16_t server_security_mode = 0;
4282         uint32_t server_session_key = 0;
4283         bool server_readbraw = false;
4284         bool server_writebraw = false;
4285         bool server_lockread = false;
4286         bool server_writeunlock = false;
4287         struct GUID server_guid = GUID_zero();
4288         DATA_BLOB server_gss_blob = data_blob_null;
4289         uint8_t server_challenge[8];
4290         char *server_workgroup = NULL;
4291         char *server_name = NULL;
4292         int server_time_zone = 0;
4293         NTTIME server_system_time = 0;
4294         static const struct smb1cli_req_expected_response expected[] = {
4295         {
4296                 .status = NT_STATUS_OK,
4297                 .wct = 0x11, /* NT1 */
4298         },
4299         {
4300                 .status = NT_STATUS_OK,
4301                 .wct = 0x0D, /* LM */
4302         },
4303         {
4304                 .status = NT_STATUS_OK,
4305                 .wct = 0x01, /* CORE */
4306         }
4307         };
4308
4309         ZERO_STRUCT(server_challenge);
4310
4311         status = smb1cli_req_recv(subreq, state,
4312                                   &recv_iov,
4313                                   &inhdr,
4314                                   &wct,
4315                                   &vwv,
4316                                   NULL, /* pvwv_offset */
4317                                   &num_bytes,
4318                                   &bytes,
4319                                   NULL, /* pbytes_offset */
4320                                   NULL, /* pinbuf */
4321                                   expected, ARRAY_SIZE(expected));
4322         TALLOC_FREE(subreq);
4323         if (tevent_req_nterror(req, status)) {
4324                 return;
4325         }
4326
4327         flags = CVAL(inhdr, HDR_FLG);
4328
4329         protnum = SVAL(vwv, 0);
4330
4331         for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4332                 if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4333                         continue;
4334                 }
4335
4336                 if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4337                         continue;
4338                 }
4339
4340                 if (protnum != num_prots) {
4341                         num_prots++;
4342                         continue;
4343                 }
4344
4345                 conn->protocol = smb1cli_prots[i].proto;
4346                 break;
4347         }
4348
4349         if (conn->protocol == PROTOCOL_NONE) {
4350                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4351                 return;
4352         }
4353
4354         if ((conn->protocol < PROTOCOL_NT1) && conn->mandatory_signing) {
4355                 DEBUG(0,("smbXcli_negprot: SMB signing is mandatory "
4356                          "and the selected protocol level doesn't support it.\n"));
4357                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4358                 return;
4359         }
4360
4361         if (flags & FLAG_SUPPORT_LOCKREAD) {
4362                 server_lockread = true;
4363                 server_writeunlock = true;
4364         }
4365
4366         if (conn->protocol >= PROTOCOL_NT1) {
4367                 const char *client_signing = NULL;
4368                 bool server_mandatory = false;
4369                 bool server_allowed = false;
4370                 const char *server_signing = NULL;
4371                 bool ok;
4372                 uint8_t key_len;
4373
4374                 if (wct != 0x11) {
4375                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4376                         return;
4377                 }
4378
4379                 /* NT protocol */
4380                 server_security_mode = CVAL(vwv + 1, 0);
4381                 server_max_mux = SVAL(vwv + 1, 1);
4382                 server_max_xmit = IVAL(vwv + 3, 1);
4383                 server_session_key = IVAL(vwv + 7, 1);
4384                 server_time_zone = SVALS(vwv + 15, 1);
4385                 server_time_zone *= 60;
4386                 /* this time arrives in real GMT */
4387                 server_system_time = BVAL(vwv + 11, 1);
4388                 server_capabilities = IVAL(vwv + 9, 1);
4389
4390                 key_len = CVAL(vwv + 16, 1);
4391
4392                 if (server_capabilities & CAP_RAW_MODE) {
4393                         server_readbraw = true;
4394                         server_writebraw = true;
4395                 }
4396                 if (server_capabilities & CAP_LOCK_AND_READ) {
4397                         server_lockread = true;
4398                 }
4399
4400                 if (server_capabilities & CAP_EXTENDED_SECURITY) {
4401                         DATA_BLOB blob1, blob2;
4402
4403                         if (num_bytes < 16) {
4404                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4405                                 return;
4406                         }
4407
4408                         blob1 = data_blob_const(bytes, 16);
4409                         status = GUID_from_data_blob(&blob1, &server_guid);
4410                         if (tevent_req_nterror(req, status)) {
4411                                 return;
4412                         }
4413
4414                         blob1 = data_blob_const(bytes+16, num_bytes-16);
4415                         blob2 = data_blob_dup_talloc(state, blob1);
4416                         if (blob1.length > 0 &&
4417                             tevent_req_nomem(blob2.data, req)) {
4418                                 return;
4419                         }
4420                         server_gss_blob = blob2;
4421                 } else {
4422                         DATA_BLOB blob1, blob2;
4423
4424                         if (num_bytes < key_len) {
4425                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4426                                 return;
4427                         }
4428
4429                         if (key_len != 0 && key_len != 8) {
4430                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4431                                 return;
4432                         }
4433
4434                         if (key_len == 8) {
4435                                 memcpy(server_challenge, bytes, 8);
4436                         }
4437
4438                         blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4439                         blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
4440                         if (blob1.length > 0) {
4441                                 size_t len;
4442
4443                                 len = utf16_len_n(blob1.data,
4444                                                   blob1.length);
4445                                 blob1.length = len;
4446
4447                                 ok = convert_string_talloc(state,
4448                                                            CH_UTF16LE,
4449                                                            CH_UNIX,
4450                                                            blob1.data,
4451                                                            blob1.length,
4452                                                            &server_workgroup,
4453                                                            &len);
4454                                 if (!ok) {
4455                                         status = map_nt_error_from_unix_common(errno);
4456                                         tevent_req_nterror(req, status);
4457                                         return;
4458                                 }
4459                         }
4460
4461                         blob2.data += blob1.length;
4462                         blob2.length -= blob1.length;
4463                         if (blob2.length > 0) {
4464                                 size_t len;
4465
4466                                 len = utf16_len_n(blob1.data,
4467                                                   blob1.length);
4468                                 blob1.length = len;
4469
4470                                 ok = convert_string_talloc(state,
4471                                                            CH_UTF16LE,
4472                                                            CH_UNIX,
4473                                                            blob2.data,
4474                                                            blob2.length,
4475                                                            &server_name,
4476                                                            &len);
4477                                 if (!ok) {
4478                                         status = map_nt_error_from_unix_common(errno);
4479                                         tevent_req_nterror(req, status);
4480                                         return;
4481                                 }
4482                         }
4483                 }
4484
4485                 client_signing = "disabled";
4486                 if (conn->allow_signing) {
4487                         client_signing = "allowed";
4488                 }
4489                 if (conn->mandatory_signing) {
4490                         client_signing = "required";
4491                 }
4492
4493                 server_signing = "not supported";
4494                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
4495                         server_signing = "supported";
4496                         server_allowed = true;
4497                 } else if (conn->mandatory_signing) {
4498                         /*
4499                          * We have mandatory signing as client
4500                          * lets assume the server will look at our
4501                          * FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
4502                          * flag in the session setup
4503                          */
4504                         server_signing = "not announced";
4505                         server_allowed = true;
4506                 }
4507                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
4508                         server_signing = "required";
4509                         server_mandatory = true;
4510                 }
4511
4512                 ok = smb_signing_set_negotiated(conn->smb1.signing,
4513                                                 server_allowed,
4514                                                 server_mandatory);
4515                 if (!ok) {
4516                         DEBUG(1,("cli_negprot: SMB signing is required, "
4517                                  "but client[%s] and server[%s] mismatch\n",
4518                                  client_signing, server_signing));
4519                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
4520                         return;
4521                 }
4522
4523         } else if (conn->protocol >= PROTOCOL_LANMAN1) {
4524                 DATA_BLOB blob1;
4525                 uint8_t key_len;
4526                 time_t t;
4527
4528                 if (wct != 0x0D) {
4529                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4530                         return;
4531                 }
4532
4533                 server_security_mode = SVAL(vwv + 1, 0);
4534                 server_max_xmit = SVAL(vwv + 2, 0);
4535                 server_max_mux = SVAL(vwv + 3, 0);
4536                 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
4537                 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
4538                 server_session_key = IVAL(vwv + 6, 0);
4539                 server_time_zone = SVALS(vwv + 10, 0);
4540                 server_time_zone *= 60;
4541                 /* this time is converted to GMT by make_unix_date */
4542                 t = pull_dos_date((const uint8_t *)(vwv + 8), server_time_zone);
4543                 unix_to_nt_time(&server_system_time, t);
4544                 key_len = SVAL(vwv + 11, 0);
4545
4546                 if (num_bytes < key_len) {
4547                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4548                         return;
4549                 }
4550
4551                 if (key_len != 0 && key_len != 8) {
4552                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4553                         return;
4554                 }
4555
4556                 if (key_len == 8) {
4557                         memcpy(server_challenge, bytes, 8);
4558                 }
4559
4560                 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
4561                 if (blob1.length > 0) {
4562                         size_t len;
4563                         bool ok;
4564
4565                         len = utf16_len_n(blob1.data,
4566                                           blob1.length);
4567                         blob1.length = len;
4568
4569                         ok = convert_string_talloc(state,
4570                                                    CH_DOS,
4571                                                    CH_UNIX,
4572                                                    blob1.data,
4573                                                    blob1.length,
4574                                                    &server_workgroup,
4575                                                    &len);
4576                         if (!ok) {
4577                                 status = map_nt_error_from_unix_common(errno);
4578                                 tevent_req_nterror(req, status);
4579                                 return;
4580                         }
4581                 }
4582
4583         } else {
4584                 /* the old core protocol */
4585                 server_time_zone = get_time_zone(time(NULL));
4586                 server_max_xmit = 1024;
4587                 server_max_mux = 1;
4588         }
4589
4590         if (server_max_xmit < 1024) {
4591                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4592                 return;
4593         }
4594
4595         if (server_max_mux < 1) {
4596                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4597                 return;
4598         }
4599
4600         /*
4601          * Now calculate the negotiated capabilities
4602          * based on the mask for:
4603          * - client only flags
4604          * - flags used in both directions
4605          * - server only flags
4606          */
4607         both_capabilities = client_capabilities & server_capabilities;
4608         capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
4609         capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
4610         capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
4611
4612         max_xmit = MIN(client_max_xmit, server_max_xmit);
4613
4614         conn->smb1.server.capabilities = server_capabilities;
4615         conn->smb1.capabilities = capabilities;
4616
4617         conn->smb1.server.max_xmit = server_max_xmit;
4618         conn->smb1.max_xmit = max_xmit;
4619
4620         conn->smb1.server.max_mux = server_max_mux;
4621
4622         conn->smb1.server.security_mode = server_security_mode;
4623
4624         conn->smb1.server.readbraw = server_readbraw;
4625         conn->smb1.server.writebraw = server_writebraw;
4626         conn->smb1.server.lockread = server_lockread;
4627         conn->smb1.server.writeunlock = server_writeunlock;
4628
4629         conn->smb1.server.session_key = server_session_key;
4630
4631         talloc_steal(conn, server_gss_blob.data);
4632         conn->smb1.server.gss_blob = server_gss_blob;
4633         conn->smb1.server.guid = server_guid;
4634         memcpy(conn->smb1.server.challenge, server_challenge, 8);
4635         conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
4636         conn->smb1.server.name = talloc_move(conn, &server_name);
4637
4638         conn->smb1.server.time_zone = server_time_zone;
4639         conn->smb1.server.system_time = server_system_time;
4640
4641         tevent_req_done(req);
4642 }
4643
4644 static size_t smbXcli_padding_helper(uint32_t offset, size_t n)
4645 {
4646         if ((offset & (n-1)) == 0) return 0;
4647         return n - (offset & (n-1));
4648 }
4649
4650 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state)
4651 {
4652         size_t i;
4653         uint8_t *buf;
4654         uint16_t dialect_count = 0;
4655         DATA_BLOB dyn = data_blob_null;
4656
4657         for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4658                 bool ok;
4659                 uint8_t val[2];
4660
4661                 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4662                         continue;
4663                 }
4664
4665                 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4666                         continue;
4667                 }
4668
4669                 SSVAL(val, 0, smb2cli_prots[i].smb2_dialect);
4670
4671                 ok = data_blob_append(state, &dyn, val, sizeof(val));
4672                 if (!ok) {
4673                         return NULL;
4674                 }
4675
4676                 dialect_count++;
4677         }
4678
4679         buf = state->smb2.fixed;
4680         SSVAL(buf, 0, 36);
4681         SSVAL(buf, 2, dialect_count);
4682         SSVAL(buf, 4, state->conn->smb2.client.security_mode);
4683         SSVAL(buf, 6, 0);       /* Reserved */
4684         if (state->conn->max_protocol >= PROTOCOL_SMB2_22) {
4685                 SIVAL(buf, 8, state->conn->smb2.client.capabilities);
4686         } else {
4687                 SIVAL(buf, 8, 0);       /* Capabilities */
4688         }
4689         if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
4690                 NTSTATUS status;
4691                 DATA_BLOB blob;
4692
4693                 status = GUID_to_ndr_blob(&state->conn->smb2.client.guid,
4694                                           state, &blob);
4695                 if (!NT_STATUS_IS_OK(status)) {
4696                         return NULL;
4697                 }
4698                 memcpy(buf+12, blob.data, 16); /* ClientGuid */
4699         } else {
4700                 memset(buf+12, 0, 16);  /* ClientGuid */
4701         }
4702
4703         if (state->conn->max_protocol >= PROTOCOL_SMB3_10) {
4704                 NTSTATUS status;
4705                 struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4706                 uint32_t offset;
4707                 DATA_BLOB b;
4708                 uint8_t p[38];
4709                 const uint8_t zeros[8] = {0, };
4710                 size_t pad;
4711                 bool ok;
4712
4713                 SSVAL(p, 0,  1); /* HashAlgorithmCount */
4714                 SSVAL(p, 2, 32); /* SaltLength */
4715                 SSVAL(p, 4, SMB2_PREAUTH_INTEGRITY_SHA512);
4716                 generate_random_buffer(p + 6, 32);
4717
4718                 b = data_blob_const(p, 38);
4719                 status = smb2_negotiate_context_add(state, &c,
4720                                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES, b);
4721                 if (!NT_STATUS_IS_OK(status)) {
4722                         return NULL;
4723                 }
4724
4725                 SSVAL(p, 0, 2); /* ChiperCount */
4726                 /*
4727                  * For now we preferr CCM because our implementation
4728                  * is faster than GCM, see bug #11451.
4729                  */
4730                 SSVAL(p, 2, SMB2_ENCRYPTION_AES128_CCM);
4731                 SSVAL(p, 4, SMB2_ENCRYPTION_AES128_GCM);
4732
4733                 b = data_blob_const(p, 6);
4734                 status = smb2_negotiate_context_add(state, &c,
4735                                         SMB2_ENCRYPTION_CAPABILITIES, b);
4736                 if (!NT_STATUS_IS_OK(status)) {
4737                         return NULL;
4738                 }
4739
4740                 status = smb2_negotiate_context_push(state, &b, c);
4741                 if (!NT_STATUS_IS_OK(status)) {
4742                         return NULL;
4743                 }
4744
4745                 offset = SMB2_HDR_BODY + sizeof(state->smb2.fixed) + dyn.length;
4746                 pad = smbXcli_padding_helper(offset, 8);
4747
4748                 ok = data_blob_append(state, &dyn, zeros, pad);
4749                 if (!ok) {
4750                         return NULL;
4751                 }
4752                 offset += pad;
4753
4754                 ok = data_blob_append(state, &dyn, b.data, b.length);
4755                 if (!ok) {
4756                         return NULL;
4757                 }
4758
4759                 SIVAL(buf, 28, offset);   /* NegotiateContextOffset */
4760                 SSVAL(buf, 32, c.num_contexts); /* NegotiateContextCount */
4761                 SSVAL(buf, 34, 0);        /* Reserved */
4762         } else {
4763                 SBVAL(buf, 28, 0);      /* Reserved/ClientStartTime */
4764         }
4765
4766         return smb2cli_req_send(state, state->ev,
4767                                 state->conn, SMB2_OP_NEGPROT,
4768                                 0, 0, /* flags */
4769                                 state->timeout_msec,
4770                                 NULL, NULL, /* tcon, session */
4771                                 state->smb2.fixed, sizeof(state->smb2.fixed),
4772                                 dyn.data, dyn.length,
4773                                 UINT16_MAX); /* max_dyn_len */
4774 }
4775
4776 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
4777 {
4778         struct tevent_req *req =
4779                 tevent_req_callback_data(subreq,
4780                 struct tevent_req);
4781         struct smbXcli_negprot_state *state =
4782                 tevent_req_data(req,
4783                 struct smbXcli_negprot_state);
4784         struct smbXcli_conn *conn = state->conn;
4785         size_t security_offset, security_length;
4786         DATA_BLOB blob;
4787         NTSTATUS status;
4788         struct iovec *iov;
4789         uint8_t *body;
4790         size_t i;
4791         uint16_t dialect_revision;
4792         struct smb2_negotiate_contexts c = { .num_contexts = 0, };
4793         uint32_t negotiate_context_offset = 0;
4794         uint16_t negotiate_context_count = 0;
4795         DATA_BLOB negotiate_context_blob = data_blob_null;
4796         size_t avail;
4797         size_t ctx_ofs;
4798         size_t needed;
4799         struct smb2_negotiate_context *preauth = NULL;
4800         uint16_t hash_count;
4801         uint16_t salt_length;
4802         uint16_t hash_selected;
4803         struct hc_sha512state sctx;
4804         struct smb2_negotiate_context *cipher = NULL;
4805         struct iovec sent_iov[3];
4806         static const struct smb2cli_req_expected_response expected[] = {
4807         {
4808                 .status = NT_STATUS_OK,
4809                 .body_size = 0x41
4810         }
4811         };
4812
4813         status = smb2cli_req_recv(subreq, state, &iov,
4814                                   expected, ARRAY_SIZE(expected));
4815         if (tevent_req_nterror(req, status)) {
4816                 return;
4817         }
4818
4819         body = (uint8_t *)iov[1].iov_base;
4820
4821         dialect_revision = SVAL(body, 4);
4822
4823         for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
4824                 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
4825                         continue;
4826                 }
4827
4828                 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
4829                         continue;
4830                 }
4831
4832                 if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
4833                         continue;
4834                 }
4835
4836                 conn->protocol = smb2cli_prots[i].proto;
4837                 break;
4838         }
4839
4840         if (conn->protocol == PROTOCOL_NONE) {
4841                 TALLOC_FREE(subreq);
4842
4843                 if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
4844                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4845                         return;
4846                 }
4847
4848                 if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
4849                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4850                         return;
4851                 }
4852
4853                 /* make sure we do not loop forever */
4854                 state->conn->min_protocol = PROTOCOL_SMB2_02;
4855
4856                 /*
4857                  * send a SMB2 negprot, in order to negotiate
4858                  * the SMB2 dialect.
4859                  */
4860                 subreq = smbXcli_negprot_smb2_subreq(state);
4861                 if (tevent_req_nomem(subreq, req)) {
4862                         return;
4863                 }
4864                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4865                 return;
4866         }
4867
4868         conn->smb2.server.security_mode = SVAL(body, 2);
4869         if (conn->protocol >= PROTOCOL_SMB3_10) {
4870                 negotiate_context_count = SVAL(body, 6);
4871         }
4872
4873         blob = data_blob_const(body + 8, 16);
4874         status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
4875         if (tevent_req_nterror(req, status)) {
4876                 return;
4877         }
4878
4879         conn->smb2.server.capabilities  = IVAL(body, 24);
4880         conn->smb2.server.max_trans_size= IVAL(body, 28);
4881         conn->smb2.server.max_read_size = IVAL(body, 32);
4882         conn->smb2.server.max_write_size= IVAL(body, 36);
4883         conn->smb2.server.system_time   = BVAL(body, 40);
4884         conn->smb2.server.start_time    = BVAL(body, 48);
4885
4886         security_offset = SVAL(body, 56);
4887         security_length = SVAL(body, 58);
4888
4889         if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
4890                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4891                 return;
4892         }
4893
4894         if (security_length > iov[2].iov_len) {
4895                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4896                 return;
4897         }
4898
4899         conn->smb2.server.gss_blob = data_blob_talloc(conn,
4900                                                 iov[2].iov_base,
4901                                                 security_length);
4902         if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
4903                 return;
4904         }
4905
4906         if (conn->protocol < PROTOCOL_SMB3_10) {
4907                 TALLOC_FREE(subreq);
4908
4909                 if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
4910                         conn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
4911                 }
4912                 tevent_req_done(req);
4913                 return;
4914         }
4915
4916         if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
4917                 tevent_req_nterror(req,
4918                                 NT_STATUS_INVALID_NETWORK_RESPONSE);
4919                 return;
4920         }
4921
4922         negotiate_context_offset = IVAL(body, 60);
4923         if (negotiate_context_offset < security_offset) {
4924                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4925                 return;
4926         }
4927
4928         ctx_ofs = negotiate_context_offset - security_offset;
4929         if (ctx_ofs > iov[2].iov_len) {
4930                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4931                 return;
4932         }
4933         avail = iov[2].iov_len - security_length;
4934         needed = iov[2].iov_len - ctx_ofs;
4935         if (needed > avail) {
4936                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4937                 return;
4938         }
4939
4940         negotiate_context_blob.data = (uint8_t *)iov[2].iov_base;
4941         negotiate_context_blob.length = iov[2].iov_len;
4942
4943         negotiate_context_blob.data += ctx_ofs;
4944         negotiate_context_blob.length -= ctx_ofs;
4945
4946         status = smb2_negotiate_context_parse(state, negotiate_context_blob, &c);
4947         if (tevent_req_nterror(req, status)) {
4948                 return;
4949         }
4950
4951         if (negotiate_context_count != c.num_contexts) {
4952                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4953                 return;
4954         }
4955
4956         preauth = smb2_negotiate_context_find(&c,
4957                                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
4958         if (preauth == NULL) {
4959                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4960                 return;
4961         }
4962
4963         if (preauth->data.length < 6) {
4964                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4965                 return;
4966         }
4967
4968         hash_count = SVAL(preauth->data.data, 0);
4969         salt_length = SVAL(preauth->data.data, 2);
4970         hash_selected = SVAL(preauth->data.data, 4);
4971
4972         if (hash_count != 1) {
4973                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4974                 return;
4975         }
4976
4977         if (preauth->data.length != (6 + salt_length)) {
4978                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4979                 return;
4980         }
4981
4982         if (hash_selected != SMB2_PREAUTH_INTEGRITY_SHA512) {
4983                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
4984                 return;
4985         }
4986
4987         cipher = smb2_negotiate_context_find(&c, SMB2_ENCRYPTION_CAPABILITIES);
4988         if (cipher != NULL) {
4989                 uint16_t cipher_count;
4990
4991                 if (cipher->data.length < 2) {
4992                         tevent_req_nterror(req,
4993                                         NT_STATUS_INVALID_NETWORK_RESPONSE);
4994                         return;
4995                 }
4996
4997                 cipher_count = SVAL(cipher->data.data, 0);
4998
4999                 if (cipher_count > 1) {
5000                         tevent_req_nterror(req,
5001                                         NT_STATUS_INVALID_NETWORK_RESPONSE);
5002                         return;
5003                 }
5004
5005                 if (cipher->data.length != (2 + 2 * cipher_count)) {
5006                         tevent_req_nterror(req,
5007                                         NT_STATUS_INVALID_NETWORK_RESPONSE);
5008                         return;
5009                 }
5010
5011                 if (cipher_count == 1) {
5012                         uint16_t cipher_selected;
5013
5014                         cipher_selected = SVAL(cipher->data.data, 2);
5015
5016                         switch (cipher_selected) {
5017                         case SMB2_ENCRYPTION_AES128_GCM:
5018                         case SMB2_ENCRYPTION_AES128_CCM:
5019                                 conn->smb2.server.cipher = cipher_selected;
5020                                 break;
5021                         }
5022                 }
5023         }
5024
5025         /* First we hash the request */
5026         smb2cli_req_get_sent_iov(subreq, sent_iov);
5027         samba_SHA512_Init(&sctx);
5028         samba_SHA512_Update(&sctx, conn->smb2.preauth_sha512,
5029                       sizeof(conn->smb2.preauth_sha512));
5030         for (i = 0; i < 3; i++) {
5031                 samba_SHA512_Update(&sctx, sent_iov[i].iov_base, sent_iov[i].iov_len);
5032         }
5033         samba_SHA512_Final(conn->smb2.preauth_sha512, &sctx);
5034         TALLOC_FREE(subreq);
5035
5036         /* And now we hash the response */
5037         samba_SHA512_Init(&sctx);
5038         samba_SHA512_Update(&sctx, conn->smb2.preauth_sha512,
5039                       sizeof(conn->smb2.preauth_sha512));
5040         for (i = 0; i < 3; i++) {
5041                 samba_SHA512_Update(&sctx, iov[i].iov_base, iov[i].iov_len);
5042         }
5043         samba_SHA512_Final(conn->smb2.preauth_sha512, &sctx);
5044
5045         tevent_req_done(req);
5046 }
5047
5048 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
5049                                                   TALLOC_CTX *tmp_mem,
5050                                                   uint8_t *inbuf)
5051 {
5052         size_t num_pending = talloc_array_length(conn->pending);
5053         struct tevent_req *subreq;
5054         struct smbXcli_req_state *substate;
5055         struct tevent_req *req;
5056         uint32_t protocol_magic;
5057         size_t inbuf_len = smb_len_nbt(inbuf);
5058
5059         if (num_pending != 1) {
5060                 return NT_STATUS_INTERNAL_ERROR;
5061         }
5062
5063         if (inbuf_len < 4) {
5064                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
5065         }
5066
5067         subreq = conn->pending[0];
5068         substate = tevent_req_data(subreq, struct smbXcli_req_state);
5069         req = tevent_req_callback_data(subreq, struct tevent_req);
5070
5071         protocol_magic = IVAL(inbuf, 4);
5072
5073         switch (protocol_magic) {
5074         case SMB_MAGIC:
5075                 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
5076                 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
5077                 return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5078
5079         case SMB2_MAGIC:
5080                 if (substate->smb2.recv_iov == NULL) {
5081                         /*
5082                          * For the SMB1 negprot we have move it.
5083                          */
5084                         substate->smb2.recv_iov = substate->smb1.recv_iov;
5085                         substate->smb1.recv_iov = NULL;
5086                 }
5087
5088                 /*
5089                  * we got an SMB2 answer, which consumed sequence number 0
5090                  * so we need to use 1 as the next one.
5091                  *
5092                  * we also need to set the current credits to 0
5093                  * as we consumed the initial one. The SMB2 answer
5094                  * hopefully grant us a new credit.
5095                  */
5096                 conn->smb2.mid = 1;
5097                 conn->smb2.cur_credits = 0;
5098                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
5099                 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
5100                 return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
5101         }
5102
5103         DEBUG(10, ("Got non-SMB PDU\n"));
5104         return NT_STATUS_INVALID_NETWORK_RESPONSE;
5105 }
5106
5107 NTSTATUS smbXcli_negprot_recv(struct tevent_req *req)
5108 {
5109         return tevent_req_simple_recv_ntstatus(req);
5110 }
5111
5112 NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
5113                          uint32_t timeout_msec,
5114                          enum protocol_types min_protocol,
5115                          enum protocol_types max_protocol)
5116 {
5117         TALLOC_CTX *frame = talloc_stackframe();
5118         struct tevent_context *ev;
5119         struct tevent_req *req;
5120         NTSTATUS status = NT_STATUS_NO_MEMORY;
5121         bool ok;
5122
5123         if (smbXcli_conn_has_async_calls(conn)) {
5124                 /*
5125                  * Can't use sync call while an async call is in flight
5126                  */
5127                 status = NT_STATUS_INVALID_PARAMETER_MIX;
5128                 goto fail;
5129         }
5130         ev = samba_tevent_context_init(frame);
5131         if (ev == NULL) {
5132                 goto fail;
5133         }
5134         req = smbXcli_negprot_send(frame, ev, conn, timeout_msec,
5135                                    min_protocol, max_protocol,
5136                                    WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
5137         if (req == NULL) {
5138                 goto fail;
5139         }
5140         ok = tevent_req_poll_ntstatus(req, ev, &status);
5141         if (!ok) {
5142                 goto fail;
5143         }
5144         status = smbXcli_negprot_recv(req);
5145  fail:
5146         TALLOC_FREE(frame);
5147         return status;
5148 }
5149
5150 struct smb2cli_validate_negotiate_info_state {
5151         struct smbXcli_conn *conn;
5152         DATA_BLOB in_input_buffer;
5153         DATA_BLOB in_output_buffer;
5154         DATA_BLOB out_input_buffer;
5155         DATA_BLOB out_output_buffer;
5156         uint16_t dialect;
5157 };
5158
5159 static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq);
5160
5161 struct tevent_req *smb2cli_validate_negotiate_info_send(TALLOC_CTX *mem_ctx,
5162                                                 struct tevent_context *ev,
5163                                                 struct smbXcli_conn *conn,
5164                                                 uint32_t timeout_msec,
5165                                                 struct smbXcli_session *session,
5166                                                 struct smbXcli_tcon *tcon)
5167 {
5168         struct tevent_req *req;
5169         struct smb2cli_validate_negotiate_info_state *state;
5170         uint8_t *buf;
5171         uint16_t dialect_count = 0;
5172         struct tevent_req *subreq;
5173         bool _save_should_sign;
5174         size_t i;
5175
5176         req = tevent_req_create(mem_ctx, &state,
5177                                 struct smb2cli_validate_negotiate_info_state);
5178         if (req == NULL) {
5179                 return NULL;
5180         }
5181         state->conn = conn;
5182
5183         state->in_input_buffer = data_blob_talloc_zero(state,
5184                                         4 + 16 + 1 + 1 + 2);
5185         if (tevent_req_nomem(state->in_input_buffer.data, req)) {
5186                 return tevent_req_post(req, ev);
5187         }
5188         buf = state->in_input_buffer.data;
5189
5190         if (state->conn->max_protocol >= PROTOCOL_SMB2_22) {
5191                 SIVAL(buf, 0, conn->smb2.client.capabilities);
5192         } else {
5193                 SIVAL(buf, 0, 0); /* Capabilities */
5194         }
5195         if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
5196                 NTSTATUS status;
5197                 DATA_BLOB blob;
5198
5199                 status = GUID_to_ndr_blob(&conn->smb2.client.guid,
5200                                           state, &blob);
5201                 if (!NT_STATUS_IS_OK(status)) {
5202                         return NULL;
5203                 }
5204                 memcpy(buf+4, blob.data, 16); /* ClientGuid */
5205         } else {
5206                 memset(buf+4, 0, 16);   /* ClientGuid */
5207         }
5208         if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5209                 SCVAL(buf, 20, conn->smb2.client.security_mode);
5210         } else {
5211                 SCVAL(buf, 20, 0);
5212         }
5213         SCVAL(buf, 21, 0); /* reserved */
5214
5215         for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5216                 bool ok;
5217                 size_t ofs;
5218
5219                 if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5220                         continue;
5221                 }
5222
5223                 if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5224                         continue;
5225                 }
5226
5227                 if (smb2cli_prots[i].proto == state->conn->protocol) {
5228                         state->dialect = smb2cli_prots[i].smb2_dialect;
5229                 }
5230
5231                 ofs = state->in_input_buffer.length;
5232                 ok = data_blob_realloc(state, &state->in_input_buffer,
5233                                        ofs + 2);
5234                 if (!ok) {
5235                         tevent_req_oom(req);
5236                         return tevent_req_post(req, ev);
5237                 }
5238
5239                 buf = state->in_input_buffer.data;
5240                 SSVAL(buf, ofs, smb2cli_prots[i].smb2_dialect);
5241
5242                 dialect_count++;
5243         }
5244         buf = state->in_input_buffer.data;
5245         SSVAL(buf, 22, dialect_count);
5246
5247         _save_should_sign = smb2cli_tcon_is_signing_on(tcon);
5248         smb2cli_tcon_should_sign(tcon, true);
5249         subreq = smb2cli_ioctl_send(state, ev, conn,
5250                                     timeout_msec, session, tcon,
5251                                     UINT64_MAX, /* in_fid_persistent */
5252                                     UINT64_MAX, /* in_fid_volatile */
5253                                     FSCTL_VALIDATE_NEGOTIATE_INFO,
5254                                     0, /* in_max_input_length */
5255                                     &state->in_input_buffer,
5256                                     24, /* in_max_output_length */
5257                                     &state->in_output_buffer,
5258                                     SMB2_IOCTL_FLAG_IS_FSCTL);
5259         smb2cli_tcon_should_sign(tcon, _save_should_sign);
5260         if (tevent_req_nomem(subreq, req)) {
5261                 return tevent_req_post(req, ev);
5262         }
5263         tevent_req_set_callback(subreq,
5264                                 smb2cli_validate_negotiate_info_done,
5265                                 req);
5266
5267         return req;
5268 }
5269
5270 static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
5271 {
5272         struct tevent_req *req =
5273                 tevent_req_callback_data(subreq,
5274                 struct tevent_req);
5275         struct smb2cli_validate_negotiate_info_state *state =
5276                 tevent_req_data(req,
5277                 struct smb2cli_validate_negotiate_info_state);
5278         NTSTATUS status;
5279         const uint8_t *buf;
5280         uint32_t capabilities;
5281         DATA_BLOB guid_blob;
5282         struct GUID server_guid;
5283         uint16_t security_mode;
5284         uint16_t dialect;
5285
5286         status = smb2cli_ioctl_recv(subreq, state,
5287                                     &state->out_input_buffer,
5288                                     &state->out_output_buffer);
5289         TALLOC_FREE(subreq);
5290         if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
5291                 /*
5292                  * The response was signed, but not supported
5293                  *
5294                  * Older Windows and Samba releases return
5295                  * NT_STATUS_FILE_CLOSED.
5296                  */
5297                 tevent_req_done(req);
5298                 return;
5299         }
5300         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
5301                 /*
5302                  * The response was signed, but not supported
5303                  *
5304                  * This is returned by the NTVFS based Samba 4.x file server
5305                  * for file shares.
5306                  */
5307                 tevent_req_done(req);
5308                 return;
5309         }
5310         if (NT_STATUS_EQUAL(status, NT_STATUS_FS_DRIVER_REQUIRED)) {
5311                 /*
5312                  * The response was signed, but not supported
5313                  *
5314                  * This is returned by the NTVFS based Samba 4.x file server
5315                  * for ipc shares.
5316                  */
5317                 tevent_req_done(req);
5318                 return;
5319         }
5320         if (tevent_req_nterror(req, status)) {
5321                 return;
5322         }
5323
5324         if (state->out_output_buffer.length != 24) {
5325                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5326                 return;
5327         }
5328
5329         buf = state->out_output_buffer.data;
5330
5331         capabilities = IVAL(buf, 0);
5332         guid_blob = data_blob_const(buf + 4, 16);
5333         status = GUID_from_data_blob(&guid_blob, &server_guid);
5334         if (tevent_req_nterror(req, status)) {
5335                 return;
5336         }
5337         security_mode = CVAL(buf, 20);
5338         dialect = SVAL(buf, 22);
5339
5340         if (capabilities != state->conn->smb2.server.capabilities) {
5341                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5342                 return;
5343         }
5344
5345         if (!GUID_equal(&server_guid, &state->conn->smb2.server.guid)) {
5346                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5347                 return;
5348         }
5349
5350         if (security_mode != state->conn->smb2.server.security_mode) {
5351                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5352                 return;
5353         }
5354
5355         if (dialect != state->dialect) {
5356                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5357                 return;
5358         }
5359
5360         tevent_req_done(req);
5361 }
5362
5363 NTSTATUS smb2cli_validate_negotiate_info_recv(struct tevent_req *req)
5364 {
5365         return tevent_req_simple_recv_ntstatus(req);
5366 }
5367
5368 static int smbXcli_session_destructor(struct smbXcli_session *session)
5369 {
5370         if (session->conn == NULL) {
5371                 return 0;
5372         }
5373
5374         DLIST_REMOVE(session->conn->sessions, session);
5375         return 0;
5376 }
5377
5378 struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
5379                                                struct smbXcli_conn *conn)
5380 {
5381         struct smbXcli_session *session;
5382
5383         session = talloc_zero(mem_ctx, struct smbXcli_session);
5384         if (session == NULL) {
5385                 return NULL;
5386         }
5387         session->smb2 = talloc_zero(session, struct smb2cli_session);
5388         if (session->smb2 == NULL) {
5389                 talloc_free(session);
5390                 return NULL;
5391         }
5392         talloc_set_destructor(session, smbXcli_session_destructor);
5393
5394         DLIST_ADD_END(conn->sessions, session);
5395         session->conn = conn;
5396
5397         memcpy(session->smb2_channel.preauth_sha512,
5398                conn->smb2.preauth_sha512,
5399                sizeof(session->smb2_channel.preauth_sha512));
5400
5401         return session;
5402 }
5403
5404 struct smbXcli_session *smbXcli_session_copy(TALLOC_CTX *mem_ctx,
5405                                                 struct smbXcli_session *src)
5406 {
5407         struct smbXcli_session *session;
5408
5409         session = talloc_zero(mem_ctx, struct smbXcli_session);
5410         if (session == NULL) {
5411                 return NULL;
5412         }
5413         session->smb2 = talloc_zero(session, struct smb2cli_session);
5414         if (session->smb2 == NULL) {
5415                 talloc_free(session);
5416                 return NULL;
5417         }
5418
5419         session->conn = src->conn;
5420         *session->smb2 = *src->smb2;
5421         session->smb2_channel = src->smb2_channel;
5422         session->disconnect_expired = src->disconnect_expired;
5423
5424         DLIST_ADD_END(src->conn->sessions, session);
5425         talloc_set_destructor(session, smbXcli_session_destructor);
5426
5427         return session;
5428 }
5429
5430 bool smbXcli_session_is_guest(struct smbXcli_session *session)
5431 {
5432         if (session == NULL) {
5433                 return false;
5434         }
5435
5436         if (session->conn == NULL) {
5437                 return false;
5438         }
5439
5440         if (session->conn->mandatory_signing) {
5441                 return false;
5442         }
5443
5444         if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5445                 if (session->smb2->session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
5446                         return true;
5447                 }
5448                 return false;
5449         }
5450
5451         if (session->smb1.action & SMB_SETUP_GUEST) {
5452                 return true;
5453         }
5454
5455         return false;
5456 }
5457
5458 bool smbXcli_session_is_authenticated(struct smbXcli_session *session)
5459 {
5460         const DATA_BLOB *application_key;
5461
5462         if (session == NULL) {
5463                 return false;
5464         }
5465
5466         if (session->conn == NULL) {
5467                 return false;
5468         }
5469
5470         /*
5471          * If we have an application key we had a session key negotiated
5472          * at auth time.
5473          */
5474         if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5475                 application_key = &session->smb2->application_key;
5476         } else {
5477                 application_key = &session->smb1.application_key;
5478         }
5479
5480         if (application_key->length == 0) {
5481                 return false;
5482         }
5483
5484         return true;
5485 }
5486
5487 NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
5488                                          TALLOC_CTX *mem_ctx,
5489                                          DATA_BLOB *key)
5490 {
5491         const DATA_BLOB *application_key;
5492
5493         *key = data_blob_null;
5494
5495         if (session->conn == NULL) {
5496                 return NT_STATUS_NO_USER_SESSION_KEY;
5497         }
5498
5499         if (session->conn->protocol >= PROTOCOL_SMB2_02) {
5500                 application_key = &session->smb2->application_key;
5501         } else {
5502                 application_key = &session->smb1.application_key;
5503         }
5504
5505         if (application_key->length == 0) {
5506                 return NT_STATUS_NO_USER_SESSION_KEY;
5507         }
5508
5509         *key = data_blob_dup_talloc(mem_ctx, *application_key);
5510         if (key->data == NULL) {
5511                 return NT_STATUS_NO_MEMORY;
5512         }
5513
5514         return NT_STATUS_OK;
5515 }
5516
5517 void smbXcli_session_set_disconnect_expired(struct smbXcli_session *session)
5518 {
5519         session->disconnect_expired = true;
5520 }
5521
5522 uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
5523 {
5524         return session->smb1.session_id;
5525 }
5526
5527 void smb1cli_session_set_id(struct smbXcli_session *session,
5528                             uint16_t session_id)
5529 {
5530         session->smb1.session_id = session_id;
5531 }
5532
5533 void smb1cli_session_set_action(struct smbXcli_session *session,
5534                                 uint16_t action)
5535 {
5536         session->smb1.action = action;
5537 }
5538
5539 NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
5540                                          const DATA_BLOB _session_key)
5541 {
5542         struct smbXcli_conn *conn = session->conn;
5543         uint8_t session_key[16];
5544
5545         if (conn == NULL) {
5546                 return NT_STATUS_INVALID_PARAMETER_MIX;
5547         }
5548
5549         if (session->smb1.application_key.length != 0) {
5550                 /*
5551                  * TODO: do not allow this...
5552                  *
5553                  * return NT_STATUS_INVALID_PARAMETER_MIX;
5554                  */
5555                 data_blob_clear_free(&session->smb1.application_key);
5556                 session->smb1.protected_key = false;
5557         }
5558
5559         if (_session_key.length == 0) {
5560                 return NT_STATUS_OK;
5561         }
5562
5563         ZERO_STRUCT(session_key);
5564         memcpy(session_key, _session_key.data,
5565                MIN(_session_key.length, sizeof(session_key)));
5566
5567         session->smb1.application_key = data_blob_talloc(session,
5568                                                          session_key,
5569                                                          sizeof(session_key));
5570         ZERO_STRUCT(session_key);
5571         if (session->smb1.application_key.data == NULL) {
5572                 return NT_STATUS_NO_MEMORY;
5573         }
5574
5575         session->smb1.protected_key = false;
5576
5577         return NT_STATUS_OK;
5578 }
5579
5580 NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
5581 {
5582         if (session->smb1.protected_key) {
5583                 /* already protected */
5584                 return NT_STATUS_OK;
5585         }
5586
5587         if (session->smb1.application_key.length != 16) {
5588                 return NT_STATUS_INVALID_PARAMETER_MIX;
5589         }
5590
5591         smb_key_derivation(session->smb1.application_key.data,
5592                            session->smb1.application_key.length,
5593                            session->smb1.application_key.data);
5594
5595         session->smb1.protected_key = true;
5596
5597         return NT_STATUS_OK;
5598 }
5599
5600 uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
5601 {
5602         struct smbXcli_conn *conn = session->conn;
5603         uint8_t security_mode = 0;
5604
5605         if (conn == NULL) {
5606                 return security_mode;
5607         }
5608
5609         security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
5610         if (conn->mandatory_signing) {
5611                 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
5612         }
5613         if (session->smb2->should_sign) {
5614                 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
5615         }
5616
5617         return security_mode;
5618 }
5619
5620 uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
5621 {
5622         return session->smb2->session_id;
5623 }
5624
5625 uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
5626 {
5627         return session->smb2->session_flags;
5628 }
5629
5630 void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
5631                                       uint64_t session_id,
5632                                       uint16_t session_flags)
5633 {
5634         session->smb2->session_id = session_id;
5635         session->smb2->session_flags = session_flags;
5636 }
5637
5638 void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
5639 {
5640         session->smb2->channel_sequence += 1;
5641 }
5642
5643 uint16_t smb2cli_session_reset_channel_sequence(struct smbXcli_session *session,
5644                                                 uint16_t channel_sequence)
5645 {
5646         uint16_t prev_cs;
5647
5648         prev_cs = session->smb2->channel_sequence;
5649         session->smb2->channel_sequence = channel_sequence;
5650
5651         return prev_cs;
5652 }
5653
5654 uint16_t smb2cli_session_current_channel_sequence(struct smbXcli_session *session)
5655 {
5656         return session->smb2->channel_sequence;
5657 }
5658
5659 void smb2cli_session_start_replay(struct smbXcli_session *session)
5660 {
5661         session->smb2->replay_active = true;
5662 }
5663
5664 void smb2cli_session_stop_replay(struct smbXcli_session *session)
5665 {
5666         session->smb2->replay_active = false;
5667 }
5668
5669 NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
5670                                         const struct iovec *iov)
5671 {
5672         struct hc_sha512state sctx;
5673         size_t i;
5674
5675         if (session->conn == NULL) {
5676                 return NT_STATUS_INTERNAL_ERROR;
5677         }
5678
5679         if (session->conn->protocol < PROTOCOL_SMB3_10) {
5680                 return NT_STATUS_OK;
5681         }
5682
5683         if (session->smb2_channel.signing_key.length != 0) {
5684                 return NT_STATUS_OK;
5685         }
5686
5687         samba_SHA512_Init(&sctx);
5688         samba_SHA512_Update(&sctx, session->smb2_channel.preauth_sha512,
5689                       sizeof(session->smb2_channel.preauth_sha512));
5690         for (i = 0; i < 3; i++) {
5691                 samba_SHA512_Update(&sctx, iov[i].iov_base, iov[i].iov_len);
5692         }
5693         samba_SHA512_Final(session->smb2_channel.preauth_sha512, &sctx);
5694
5695         return NT_STATUS_OK;
5696 }
5697
5698 NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
5699                                          const DATA_BLOB _session_key,
5700                                          const struct iovec *recv_iov)
5701 {
5702         struct smbXcli_conn *conn = session->conn;
5703         uint16_t no_sign_flags = 0;
5704         uint8_t session_key[16];
5705         bool check_signature = true;
5706         uint32_t hdr_flags;
5707         NTSTATUS status;
5708         struct _derivation {
5709                 DATA_BLOB label;
5710                 DATA_BLOB context;
5711         };
5712         struct {
5713                 struct _derivation signing;
5714                 struct _derivation encryption;
5715                 struct _derivation decryption;
5716                 struct _derivation application;
5717         } derivation = { };
5718         size_t nonce_size = 0;
5719
5720         if (conn == NULL) {
5721                 return NT_STATUS_INVALID_PARAMETER_MIX;
5722         }
5723
5724         if (recv_iov[0].iov_len != SMB2_HDR_BODY) {
5725                 return NT_STATUS_INVALID_PARAMETER_MIX;
5726         }
5727
5728         if (!conn->mandatory_signing) {
5729                 /*
5730                  * only allow guest sessions without
5731                  * mandatory signing.
5732                  *
5733                  * If we try an authentication with username != ""
5734                  * and the server let us in without verifying the
5735                  * password we don't have a negotiated session key
5736                  * for signing.
5737                  */
5738                 no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST;
5739         }
5740
5741         if (session->smb2->session_flags & no_sign_flags) {
5742                 session->smb2->should_sign = false;
5743                 return NT_STATUS_OK;
5744         }
5745
5746         if (session->smb2->signing_key.length != 0) {
5747                 return NT_STATUS_INVALID_PARAMETER_MIX;
5748         }
5749
5750         if (conn->protocol >= PROTOCOL_SMB3_10) {
5751                 struct _derivation *d;
5752                 DATA_BLOB p;
5753
5754                 p = data_blob_const(session->smb2_channel.preauth_sha512,
5755                                 sizeof(session->smb2_channel.preauth_sha512));
5756
5757                 d = &derivation.signing;
5758                 d->label = data_blob_string_const_null("SMBSigningKey");
5759                 d->context = p;
5760
5761                 d = &derivation.encryption;
5762                 d->label = data_blob_string_const_null("SMBC2SCipherKey");
5763                 d->context = p;
5764
5765                 d = &derivation.decryption;
5766                 d->label = data_blob_string_const_null("SMBS2CCipherKey");
5767                 d->context = p;
5768
5769                 d = &derivation.application;
5770                 d->label = data_blob_string_const_null("SMBAppKey");
5771                 d->context = p;
5772
5773         } else if (conn->protocol >= PROTOCOL_SMB2_24) {
5774                 struct _derivation *d;
5775
5776                 d = &derivation.signing;
5777                 d->label = data_blob_string_const_null("SMB2AESCMAC");
5778                 d->context = data_blob_string_const_null("SmbSign");
5779
5780                 d = &derivation.encryption;
5781                 d->label = data_blob_string_const_null("SMB2AESCCM");
5782                 d->context = data_blob_string_const_null("ServerIn ");
5783
5784                 d = &derivation.decryption;
5785                 d->label = data_blob_string_const_null("SMB2AESCCM");
5786                 d->context = data_blob_string_const_null("ServerOut");
5787
5788                 d = &derivation.application;
5789                 d->label = data_blob_string_const_null("SMB2APP");
5790                 d->context = data_blob_string_const_null("SmbRpc");
5791         }
5792
5793         ZERO_STRUCT(session_key);
5794         memcpy(session_key, _session_key.data,
5795                MIN(_session_key.length, sizeof(session_key)));
5796
5797         session->smb2->signing_key = data_blob_talloc(session,
5798                                                      session_key,
5799                                                      sizeof(session_key));
5800         if (session->smb2->signing_key.data == NULL) {
5801                 ZERO_STRUCT(session_key);
5802                 return NT_STATUS_NO_MEMORY;
5803         }
5804
5805         if (conn->protocol >= PROTOCOL_SMB2_24) {
5806                 struct _derivation *d = &derivation.signing;
5807
5808                 smb2_key_derivation(session_key, sizeof(session_key),
5809                                     d->label.data, d->label.length,
5810                                     d->context.data, d->context.length,
5811                                     session->smb2->signing_key.data);
5812         }
5813
5814         session->smb2->encryption_key = data_blob_dup_talloc(session,
5815                                                 session->smb2->signing_key);
5816         if (session->smb2->encryption_key.data == NULL) {
5817                 ZERO_STRUCT(session_key);
5818                 return NT_STATUS_NO_MEMORY;
5819         }
5820
5821         if (conn->protocol >= PROTOCOL_SMB2_24) {
5822                 struct _derivation *d = &derivation.encryption;
5823
5824                 smb2_key_derivation(session_key, sizeof(session_key),
5825                                     d->label.data, d->label.length,
5826                                     d->context.data, d->context.length,
5827                                     session->smb2->encryption_key.data);
5828         }
5829
5830         session->smb2->decryption_key = data_blob_dup_talloc(session,
5831                                                 session->smb2->signing_key);
5832         if (session->smb2->decryption_key.data == NULL) {
5833                 ZERO_STRUCT(session_key);
5834                 return NT_STATUS_NO_MEMORY;
5835         }
5836
5837         if (conn->protocol >= PROTOCOL_SMB2_24) {
5838                 struct _derivation *d = &derivation.decryption;
5839
5840                 smb2_key_derivation(session_key, sizeof(session_key),
5841                                     d->label.data, d->label.length,
5842                                     d->context.data, d->context.length,
5843                                     session->smb2->decryption_key.data);
5844         }
5845
5846         session->smb2->application_key = data_blob_dup_talloc(session,
5847                                                 session->smb2->signing_key);
5848         if (session->smb2->application_key.data == NULL) {
5849                 ZERO_STRUCT(session_key);
5850                 return NT_STATUS_NO_MEMORY;
5851         }
5852
5853         if (conn->protocol >= PROTOCOL_SMB2_24) {
5854                 struct _derivation *d = &derivation.application;
5855
5856                 smb2_key_derivation(session_key, sizeof(session_key),
5857                                     d->label.data, d->label.length,
5858                                     d->context.data, d->context.length,
5859                                     session->smb2->application_key.data);
5860         }
5861         ZERO_STRUCT(session_key);
5862
5863         session->smb2_channel.signing_key = data_blob_dup_talloc(session,
5864                                                 session->smb2->signing_key);
5865         if (session->smb2_channel.signing_key.data == NULL) {
5866                 return NT_STATUS_NO_MEMORY;
5867         }
5868
5869         check_signature = conn->mandatory_signing;
5870
5871         hdr_flags = IVAL(recv_iov[0].iov_base, SMB2_HDR_FLAGS);
5872         if (hdr_flags & SMB2_HDR_FLAG_SIGNED) {
5873                 /*
5874                  * Sadly some vendors don't sign the
5875                  * final SMB2 session setup response
5876                  *
5877                  * At least Windows and Samba are always doing this
5878                  * if there's a session key available.
5879                  *
5880                  * We only check the signature if it's mandatory
5881                  * or SMB2_HDR_FLAG_SIGNED is provided.
5882                  */
5883                 check_signature = true;
5884         }
5885
5886         if (conn->protocol >= PROTOCOL_SMB3_10) {
5887                 check_signature = true;
5888         }
5889
5890         if (check_signature) {
5891                 status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
5892                                                 session->conn->protocol,
5893                                                 recv_iov, 3);
5894                 if (!NT_STATUS_IS_OK(status)) {
5895                         return status;
5896                 }
5897         }
5898
5899         session->smb2->should_sign = false;
5900         session->smb2->should_encrypt = false;
5901
5902         if (conn->desire_signing) {
5903                 session->smb2->should_sign = true;
5904         }
5905
5906         if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
5907                 session->smb2->should_sign = true;
5908         }
5909
5910         if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
5911                 session->smb2->should_encrypt = true;
5912         }
5913
5914         if (conn->protocol < PROTOCOL_SMB2_24) {
5915                 session->smb2->should_encrypt = false;
5916         }
5917
5918         if (conn->smb2.server.cipher == 0) {
5919                 session->smb2->should_encrypt = false;
5920         }
5921
5922         /*
5923          * CCM and GCM algorithms must never have their
5924          * nonce wrap, or the security of the whole
5925          * communication and the keys is destroyed.
5926          * We must drop the connection once we have
5927          * transfered too much data.
5928          *
5929          * NOTE: We assume nonces greater than 8 bytes.
5930          */
5931         generate_random_buffer((uint8_t *)&session->smb2->nonce_high_random,
5932                                sizeof(session->smb2->nonce_high_random));
5933         switch (conn->smb2.server.cipher) {
5934         case SMB2_ENCRYPTION_AES128_CCM:
5935                 nonce_size = AES_CCM_128_NONCE_SIZE;
5936                 break;
5937         case SMB2_ENCRYPTION_AES128_GCM:
5938                 nonce_size = AES_GCM_128_IV_SIZE;
5939                 break;
5940         default:
5941                 nonce_size = 0;
5942                 break;
5943         }
5944         session->smb2->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
5945         session->smb2->nonce_high = 0;
5946         session->smb2->nonce_low = 0;
5947
5948         return NT_STATUS_OK;
5949 }
5950
5951 NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
5952                                         struct smbXcli_session *session1,
5953                                         struct smbXcli_conn *conn,
5954                                         struct smbXcli_session **_session2)
5955 {
5956         struct smbXcli_session *session2;
5957
5958         if (session1->smb2->signing_key.length == 0) {
5959                 return NT_STATUS_INVALID_PARAMETER_MIX;
5960         }
5961
5962         if (conn == NULL) {
5963                 return NT_STATUS_INVALID_PARAMETER_MIX;
5964         }
5965
5966         session2 = talloc_zero(mem_ctx, struct smbXcli_session);
5967         if (session2 == NULL) {
5968                 return NT_STATUS_NO_MEMORY;
5969         }
5970         session2->smb2 = talloc_reference(session2, session1->smb2);
5971         if (session2->smb2 == NULL) {
5972                 talloc_free(session2);
5973                 return NT_STATUS_NO_MEMORY;
5974         }
5975
5976         talloc_set_destructor(session2, smbXcli_session_destructor);
5977         DLIST_ADD_END(conn->sessions, session2);
5978         session2->conn = conn;
5979
5980         memcpy(session2->smb2_channel.preauth_sha512,
5981                conn->smb2.preauth_sha512,
5982                sizeof(session2->smb2_channel.preauth_sha512));
5983
5984         *_session2 = session2;
5985         return NT_STATUS_OK;
5986 }
5987
5988 NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
5989                                          const DATA_BLOB _channel_key,
5990                                          const struct iovec *recv_iov)
5991 {
5992         struct smbXcli_conn *conn = session->conn;
5993         uint8_t channel_key[16];
5994         NTSTATUS status;
5995         struct _derivation {
5996                 DATA_BLOB label;
5997                 DATA_BLOB context;
5998         };
5999         struct {
6000                 struct _derivation signing;
6001         } derivation = { };
6002
6003         if (conn == NULL) {
6004                 return NT_STATUS_INVALID_PARAMETER_MIX;
6005         }
6006
6007         if (session->smb2_channel.signing_key.length != 0) {
6008                 return NT_STATUS_INVALID_PARAMETER_MIX;
6009         }
6010
6011         if (conn->protocol >= PROTOCOL_SMB3_10) {
6012                 struct _derivation *d;
6013                 DATA_BLOB p;
6014
6015                 p = data_blob_const(session->smb2_channel.preauth_sha512,
6016                                 sizeof(session->smb2_channel.preauth_sha512));
6017
6018                 d = &derivation.signing;
6019                 d->label = data_blob_string_const_null("SMBSigningKey");
6020                 d->context = p;
6021         } else if (conn->protocol >= PROTOCOL_SMB2_24) {
6022                 struct _derivation *d;
6023
6024                 d = &derivation.signing;
6025                 d->label = data_blob_string_const_null("SMB2AESCMAC");
6026                 d->context = data_blob_string_const_null("SmbSign");
6027         }
6028
6029         ZERO_STRUCT(channel_key);
6030         memcpy(channel_key, _channel_key.data,
6031                MIN(_channel_key.length, sizeof(channel_key)));
6032
6033         session->smb2_channel.signing_key = data_blob_talloc(session,
6034                                                 channel_key,
6035                                                 sizeof(channel_key));
6036         if (session->smb2_channel.signing_key.data == NULL) {
6037                 ZERO_STRUCT(channel_key);
6038                 return NT_STATUS_NO_MEMORY;
6039         }
6040
6041         if (conn->protocol >= PROTOCOL_SMB2_24) {
6042                 struct _derivation *d = &derivation.signing;
6043
6044                 smb2_key_derivation(channel_key, sizeof(channel_key),
6045                                     d->label.data, d->label.length,
6046                                     d->context.data, d->context.length,
6047                                     session->smb2_channel.signing_key.data);
6048         }
6049         ZERO_STRUCT(channel_key);
6050
6051         status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
6052                                         session->conn->protocol,
6053                                         recv_iov, 3);
6054         if (!NT_STATUS_IS_OK(status)) {
6055                 return status;
6056         }
6057
6058         return NT_STATUS_OK;
6059 }
6060
6061 NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
6062 {
6063         if (!session->smb2->should_sign) {
6064                 /*
6065                  * We need required signing on the session
6066                  * in order to prevent man in the middle attacks.
6067                  */
6068                 return NT_STATUS_INVALID_PARAMETER_MIX;
6069         }
6070
6071         if (session->smb2->should_encrypt) {
6072                 return NT_STATUS_OK;
6073         }
6074
6075         if (session->conn->protocol < PROTOCOL_SMB2_24) {
6076                 return NT_STATUS_NOT_SUPPORTED;
6077         }
6078
6079         if (session->conn->smb2.server.cipher == 0) {
6080                 return NT_STATUS_NOT_SUPPORTED;
6081         }
6082
6083         if (session->smb2->signing_key.data == NULL) {
6084                 return NT_STATUS_NOT_SUPPORTED;
6085         }
6086         session->smb2->should_encrypt = true;
6087         return NT_STATUS_OK;
6088 }
6089
6090 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
6091 {
6092         struct smbXcli_tcon *tcon;
6093
6094         tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
6095         if (tcon == NULL) {
6096                 return NULL;
6097         }
6098
6099         return tcon;
6100 }
6101
6102 void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
6103                                     uint32_t fs_attributes)
6104 {
6105         tcon->fs_attributes = fs_attributes;
6106 }
6107
6108 uint32_t smbXcli_tcon_get_fs_attributes(struct smbXcli_tcon *tcon)
6109 {
6110         return tcon->fs_attributes;
6111 }
6112
6113 bool smbXcli_tcon_is_dfs_share(struct smbXcli_tcon *tcon)
6114 {
6115         if (tcon == NULL) {
6116                 return false;
6117         }
6118
6119         if (tcon->is_smb1) {
6120                 if (tcon->smb1.optional_support & SMB_SHARE_IN_DFS) {
6121                         return true;
6122                 }
6123
6124                 return false;
6125         }
6126
6127         if (tcon->smb2.capabilities & SMB2_SHARE_CAP_DFS) {
6128                 return true;
6129         }
6130
6131         return false;
6132 }
6133
6134 uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
6135 {
6136         return tcon->smb1.tcon_id;
6137 }
6138
6139 void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
6140 {
6141         tcon->is_smb1 = true;
6142         tcon->smb1.tcon_id = tcon_id;
6143 }
6144
6145 bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
6146                              uint16_t tcon_id,
6147                              uint16_t optional_support,
6148                              uint32_t maximal_access,
6149                              uint32_t guest_maximal_access,
6150                              const char *service,
6151                              const char *fs_type)
6152 {
6153         tcon->is_smb1 = true;
6154         tcon->fs_attributes = 0;
6155         tcon->smb1.tcon_id = tcon_id;
6156         tcon->smb1.optional_support = optional_support;
6157         tcon->smb1.maximal_access = maximal_access;
6158         tcon->smb1.guest_maximal_access = guest_maximal_access;
6159
6160         TALLOC_FREE(tcon->smb1.service);
6161         tcon->smb1.service = talloc_strdup(tcon, service);
6162         if (service != NULL && tcon->smb1.service == NULL) {
6163                 return false;
6164         }
6165
6166         TALLOC_FREE(tcon->smb1.fs_type);
6167         tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
6168         if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
6169                 return false;
6170         }
6171
6172         return true;
6173 }
6174
6175 uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
6176 {
6177         return tcon->smb2.tcon_id;
6178 }
6179
6180 uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
6181 {
6182         return tcon->smb2.capabilities;
6183 }
6184
6185 uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon)
6186 {
6187         return tcon->smb2.flags;
6188 }
6189
6190 void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
6191                              struct smbXcli_session *session,
6192                              uint32_t tcon_id,
6193                              uint8_t type,
6194                              uint32_t flags,
6195                              uint32_t capabilities,
6196                              uint32_t maximal_access)
6197 {
6198         tcon->is_smb1 = false;
6199         tcon->fs_attributes = 0;
6200         tcon->smb2.tcon_id = tcon_id;
6201         tcon->smb2.type = type;
6202         tcon->smb2.flags = flags;
6203         tcon->smb2.capabilities = capabilities;
6204         tcon->smb2.maximal_access = maximal_access;
6205
6206         tcon->smb2.should_sign = false;
6207         tcon->smb2.should_encrypt = false;
6208
6209         if (session == NULL) {
6210                 return;
6211         }
6212
6213         tcon->smb2.should_sign = session->smb2->should_sign;
6214         tcon->smb2.should_encrypt = session->smb2->should_encrypt;
6215
6216         if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
6217                 tcon->smb2.should_encrypt = true;
6218         }
6219 }
6220
6221 void smb2cli_tcon_should_sign(struct smbXcli_tcon *tcon,
6222                               bool should_sign)
6223 {
6224         tcon->smb2.should_sign = should_sign;
6225 }
6226
6227 bool smb2cli_tcon_is_signing_on(struct smbXcli_tcon *tcon)
6228 {
6229         if (tcon->smb2.should_encrypt) {
6230                 return true;
6231         }
6232
6233         return tcon->smb2.should_sign;
6234 }
6235
6236 void smb2cli_tcon_should_encrypt(struct smbXcli_tcon *tcon,
6237                                  bool should_encrypt)
6238 {
6239         tcon->smb2.should_encrypt = should_encrypt;
6240 }
6241
6242 bool smb2cli_tcon_is_encryption_on(struct smbXcli_tcon *tcon)
6243 {
6244         return tcon->smb2.should_encrypt;
6245 }
6246
6247 void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid)
6248 {
6249         conn->smb2.mid = mid;
6250 }
6251
6252 uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
6253 {
6254         return conn->smb2.mid;
6255 }