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