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