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