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