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