smbXcli: call tevent_queue_stop() for the outgoing queue on disconnect
[gd/samba-autobuild/.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         tevent_queue_stop(conn->outgoing);
747
748         if (conn->read_fd != -1) {
749                 close(conn->read_fd);
750         }
751         if (conn->write_fd != -1) {
752                 close(conn->write_fd);
753         }
754         conn->read_fd = -1;
755         conn->write_fd = -1;
756
757         /*
758          * Cancel all pending requests. We do not do a for-loop walking
759          * conn->pending because that array changes in
760          * smbXcli_req_unset_pending.
761          */
762         while (talloc_array_length(conn->pending) > 0) {
763                 struct tevent_req *req;
764                 struct smbXcli_req_state *state;
765                 struct tevent_req **chain;
766                 size_t num_chained;
767                 size_t i;
768
769                 req = conn->pending[0];
770                 state = tevent_req_data(req, struct smbXcli_req_state);
771
772                 if (state->smb1.chained_requests == NULL) {
773                         /*
774                          * We're dead. No point waiting for trans2
775                          * replies.
776                          */
777                         state->smb1.mid = 0;
778
779                         smbXcli_req_unset_pending(req);
780
781                         if (NT_STATUS_IS_OK(status)) {
782                                 /* do not notify the callers */
783                                 continue;
784                         }
785
786                         /*
787                          * we need to defer the callback, because we may notify
788                          * more then one caller.
789                          */
790                         tevent_req_defer_callback(req, state->ev);
791                         tevent_req_nterror(req, status);
792                         continue;
793                 }
794
795                 chain = talloc_move(conn, &state->smb1.chained_requests);
796                 num_chained = talloc_array_length(chain);
797
798                 for (i=0; i<num_chained; i++) {
799                         req = chain[i];
800                         state = tevent_req_data(req, struct smbXcli_req_state);
801
802                         /*
803                          * We're dead. No point waiting for trans2
804                          * replies.
805                          */
806                         state->smb1.mid = 0;
807
808                         smbXcli_req_unset_pending(req);
809
810                         if (NT_STATUS_IS_OK(status)) {
811                                 /* do not notify the callers */
812                                 continue;
813                         }
814
815                         /*
816                          * we need to defer the callback, because we may notify
817                          * more than one caller.
818                          */
819                         tevent_req_defer_callback(req, state->ev);
820                         tevent_req_nterror(req, status);
821                 }
822                 TALLOC_FREE(chain);
823         }
824 }
825
826 /*
827  * Fetch a smb request's mid. Only valid after the request has been sent by
828  * smb1cli_req_send().
829  */
830 uint16_t smb1cli_req_mid(struct tevent_req *req)
831 {
832         struct smbXcli_req_state *state =
833                 tevent_req_data(req,
834                 struct smbXcli_req_state);
835
836         if (state->smb1.mid != 0) {
837                 return state->smb1.mid;
838         }
839
840         return SVAL(state->smb1.hdr, HDR_MID);
841 }
842
843 void smb1cli_req_set_mid(struct tevent_req *req, uint16_t mid)
844 {
845         struct smbXcli_req_state *state =
846                 tevent_req_data(req,
847                 struct smbXcli_req_state);
848
849         state->smb1.mid = mid;
850 }
851
852 uint32_t smb1cli_req_seqnum(struct tevent_req *req)
853 {
854         struct smbXcli_req_state *state =
855                 tevent_req_data(req,
856                 struct smbXcli_req_state);
857
858         return state->smb1.seqnum;
859 }
860
861 void smb1cli_req_set_seqnum(struct tevent_req *req, uint32_t seqnum)
862 {
863         struct smbXcli_req_state *state =
864                 tevent_req_data(req,
865                 struct smbXcli_req_state);
866
867         state->smb1.seqnum = seqnum;
868 }
869
870 static size_t smbXcli_iov_len(const struct iovec *iov, int count)
871 {
872         size_t result = 0;
873         int i;
874         for (i=0; i<count; i++) {
875                 result += iov[i].iov_len;
876         }
877         return result;
878 }
879
880 static uint8_t *smbXcli_iov_concat(TALLOC_CTX *mem_ctx,
881                                    const struct iovec *iov,
882                                    int count)
883 {
884         size_t len = smbXcli_iov_len(iov, count);
885         size_t copied;
886         uint8_t *buf;
887         int i;
888
889         buf = talloc_array(mem_ctx, uint8_t, len);
890         if (buf == NULL) {
891                 return NULL;
892         }
893         copied = 0;
894         for (i=0; i<count; i++) {
895                 memcpy(buf+copied, iov[i].iov_base, iov[i].iov_len);
896                 copied += iov[i].iov_len;
897         }
898         return buf;
899 }
900
901 static void smb1cli_req_flags(enum protocol_types protocol,
902                               uint32_t smb1_capabilities,
903                               uint8_t smb_command,
904                               uint8_t additional_flags,
905                               uint8_t clear_flags,
906                               uint8_t *_flags,
907                               uint16_t additional_flags2,
908                               uint16_t clear_flags2,
909                               uint16_t *_flags2)
910 {
911         uint8_t flags = 0;
912         uint16_t flags2 = 0;
913
914         if (protocol >= PROTOCOL_LANMAN1) {
915                 flags |= FLAG_CASELESS_PATHNAMES;
916                 flags |= FLAG_CANONICAL_PATHNAMES;
917         }
918
919         if (protocol >= PROTOCOL_LANMAN2) {
920                 flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
921                 flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
922         }
923
924         if (protocol >= PROTOCOL_NT1) {
925                 flags2 |= FLAGS2_IS_LONG_NAME;
926
927                 if (smb1_capabilities & CAP_UNICODE) {
928                         flags2 |= FLAGS2_UNICODE_STRINGS;
929                 }
930                 if (smb1_capabilities & CAP_STATUS32) {
931                         flags2 |= FLAGS2_32_BIT_ERROR_CODES;
932                 }
933                 if (smb1_capabilities & CAP_EXTENDED_SECURITY) {
934                         flags2 |= FLAGS2_EXTENDED_SECURITY;
935                 }
936         }
937
938         flags |= additional_flags;
939         flags &= ~clear_flags;
940         flags2 |= additional_flags2;
941         flags2 &= ~clear_flags2;
942
943         *_flags = flags;
944         *_flags2 = flags2;
945 }
946
947 static void smb1cli_req_cancel_done(struct tevent_req *subreq);
948
949 static bool smb1cli_req_cancel(struct tevent_req *req)
950 {
951         struct smbXcli_req_state *state =
952                 tevent_req_data(req,
953                 struct smbXcli_req_state);
954         uint8_t flags;
955         uint16_t flags2;
956         uint32_t pid;
957         uint16_t tid;
958         uint16_t uid;
959         uint16_t mid;
960         struct tevent_req *subreq;
961         NTSTATUS status;
962
963         flags = CVAL(state->smb1.hdr, HDR_FLG);
964         flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
965         pid  = SVAL(state->smb1.hdr, HDR_PID);
966         pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
967         tid = SVAL(state->smb1.hdr, HDR_TID);
968         uid = SVAL(state->smb1.hdr, HDR_UID);
969         mid = SVAL(state->smb1.hdr, HDR_MID);
970
971         subreq = smb1cli_req_create(state, state->ev,
972                                     state->conn,
973                                     SMBntcancel,
974                                     flags, 0,
975                                     flags2, 0,
976                                     0, /* timeout */
977                                     pid, tid, uid,
978                                     0, NULL, /* vwv */
979                                     0, NULL); /* bytes */
980         if (subreq == NULL) {
981                 return false;
982         }
983         smb1cli_req_set_mid(subreq, mid);
984
985         status = smb1cli_req_chain_submit(&subreq, 1);
986         if (!NT_STATUS_IS_OK(status)) {
987                 TALLOC_FREE(subreq);
988                 return false;
989         }
990         smb1cli_req_set_mid(subreq, 0);
991
992         tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
993
994         return true;
995 }
996
997 static void smb1cli_req_cancel_done(struct tevent_req *subreq)
998 {
999         /* we do not care about the result */
1000         TALLOC_FREE(subreq);
1001 }
1002
1003 struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
1004                                       struct tevent_context *ev,
1005                                       struct smbXcli_conn *conn,
1006                                       uint8_t smb_command,
1007                                       uint8_t additional_flags,
1008                                       uint8_t clear_flags,
1009                                       uint16_t additional_flags2,
1010                                       uint16_t clear_flags2,
1011                                       uint32_t timeout_msec,
1012                                       uint32_t pid,
1013                                       uint16_t tid,
1014                                       uint16_t uid,
1015                                       uint8_t wct, uint16_t *vwv,
1016                                       int iov_count,
1017                                       struct iovec *bytes_iov)
1018 {
1019         struct tevent_req *req;
1020         struct smbXcli_req_state *state;
1021         uint8_t flags = 0;
1022         uint16_t flags2 = 0;
1023
1024         if (iov_count > MAX_SMB_IOV) {
1025                 /*
1026                  * Should not happen :-)
1027                  */
1028                 return NULL;
1029         }
1030
1031         req = tevent_req_create(mem_ctx, &state,
1032                                 struct smbXcli_req_state);
1033         if (req == NULL) {
1034                 return NULL;
1035         }
1036         state->ev = ev;
1037         state->conn = conn;
1038
1039         state->smb1.recv_cmd = 0xFF;
1040         state->smb1.recv_status = NT_STATUS_INTERNAL_ERROR;
1041         state->smb1.recv_iov = talloc_zero_array(state, struct iovec, 3);
1042         if (state->smb1.recv_iov == NULL) {
1043                 TALLOC_FREE(req);
1044                 return NULL;
1045         }
1046
1047         smb1cli_req_flags(conn->protocol,
1048                           conn->smb1.capabilities,
1049                           smb_command,
1050                           additional_flags,
1051                           clear_flags,
1052                           &flags,
1053                           additional_flags2,
1054                           clear_flags2,
1055                           &flags2);
1056
1057         SIVAL(state->smb1.hdr, 0,           SMB_MAGIC);
1058         SCVAL(state->smb1.hdr, HDR_COM,     smb_command);
1059         SIVAL(state->smb1.hdr, HDR_RCLS,    NT_STATUS_V(NT_STATUS_OK));
1060         SCVAL(state->smb1.hdr, HDR_FLG,     flags);
1061         SSVAL(state->smb1.hdr, HDR_FLG2,    flags2);
1062         SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);
1063         SSVAL(state->smb1.hdr, HDR_TID,     tid);
1064         SSVAL(state->smb1.hdr, HDR_PID,     pid);
1065         SSVAL(state->smb1.hdr, HDR_UID,     uid);
1066         SSVAL(state->smb1.hdr, HDR_MID,     0); /* this comes later */
1067         SCVAL(state->smb1.hdr, HDR_WCT,     wct);
1068
1069         state->smb1.vwv = vwv;
1070
1071         SSVAL(state->smb1.bytecount_buf, 0, smbXcli_iov_len(bytes_iov, iov_count));
1072
1073         state->smb1.iov[0].iov_base = (void *)state->length_hdr;
1074         state->smb1.iov[0].iov_len  = sizeof(state->length_hdr);
1075         state->smb1.iov[1].iov_base = (void *)state->smb1.hdr;
1076         state->smb1.iov[1].iov_len  = sizeof(state->smb1.hdr);
1077         state->smb1.iov[2].iov_base = (void *)state->smb1.vwv;
1078         state->smb1.iov[2].iov_len  = wct * sizeof(uint16_t);
1079         state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;
1080         state->smb1.iov[3].iov_len  = sizeof(uint16_t);
1081
1082         if (iov_count != 0) {
1083                 memcpy(&state->smb1.iov[4], bytes_iov,
1084                        iov_count * sizeof(*bytes_iov));
1085         }
1086         state->smb1.iov_count = iov_count + 4;
1087
1088         if (timeout_msec > 0) {
1089                 struct timeval endtime;
1090
1091                 endtime = timeval_current_ofs_msec(timeout_msec);
1092                 if (!tevent_req_set_endtime(req, ev, endtime)) {
1093                         return req;
1094                 }
1095         }
1096
1097         switch (smb_command) {
1098         case SMBtranss:
1099         case SMBtranss2:
1100         case SMBnttranss:
1101                 state->one_way = true;
1102                 break;
1103         case SMBntcancel:
1104                 state->one_way = true;
1105                 state->smb1.one_way_seqnum = true;
1106                 break;
1107         case SMBlockingX:
1108                 if ((wct == 8) &&
1109                     (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
1110                         state->one_way = true;
1111                 }
1112                 break;
1113         }
1114
1115         return req;
1116 }
1117
1118 static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
1119                                    struct iovec *iov, int iov_count,
1120                                    uint32_t *seqnum,
1121                                    bool one_way_seqnum)
1122 {
1123         TALLOC_CTX *frame = NULL;
1124         uint8_t *buf;
1125
1126         /*
1127          * Obvious optimization: Make cli_calculate_sign_mac work with struct
1128          * iovec directly. MD5Update would do that just fine.
1129          */
1130
1131         if (iov_count < 4) {
1132                 return NT_STATUS_INVALID_PARAMETER_MIX;
1133         }
1134         if (iov[0].iov_len != NBT_HDR_SIZE) {
1135                 return NT_STATUS_INVALID_PARAMETER_MIX;
1136         }
1137         if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1138                 return NT_STATUS_INVALID_PARAMETER_MIX;
1139         }
1140         if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1141                 return NT_STATUS_INVALID_PARAMETER_MIX;
1142         }
1143         if (iov[3].iov_len != sizeof(uint16_t)) {
1144                 return NT_STATUS_INVALID_PARAMETER_MIX;
1145         }
1146
1147         frame = talloc_stackframe();
1148
1149         buf = smbXcli_iov_concat(frame, iov, iov_count);
1150         if (buf == NULL) {
1151                 return NT_STATUS_NO_MEMORY;
1152         }
1153
1154         *seqnum = smb_signing_next_seqnum(conn->smb1.signing,
1155                                           one_way_seqnum);
1156         smb_signing_sign_pdu(conn->smb1.signing, buf, *seqnum);
1157         memcpy(iov[1].iov_base, buf+4, iov[1].iov_len);
1158
1159         TALLOC_FREE(frame);
1160         return NT_STATUS_OK;
1161 }
1162
1163 static void smb1cli_req_writev_done(struct tevent_req *subreq);
1164 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1165                                                TALLOC_CTX *tmp_mem,
1166                                                uint8_t *inbuf);
1167
1168 static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
1169                                           struct smbXcli_req_state *state,
1170                                           struct iovec *iov, int iov_count)
1171 {
1172         struct tevent_req *subreq;
1173         NTSTATUS status;
1174         uint16_t mid;
1175
1176         if (!smbXcli_conn_is_connected(state->conn)) {
1177                 return NT_STATUS_CONNECTION_DISCONNECTED;
1178         }
1179
1180         if (state->conn->protocol > PROTOCOL_NT1) {
1181                 return NT_STATUS_REVISION_MISMATCH;
1182         }
1183
1184         if (iov_count < 4) {
1185                 return NT_STATUS_INVALID_PARAMETER_MIX;
1186         }
1187         if (iov[0].iov_len != NBT_HDR_SIZE) {
1188                 return NT_STATUS_INVALID_PARAMETER_MIX;
1189         }
1190         if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
1191                 return NT_STATUS_INVALID_PARAMETER_MIX;
1192         }
1193         if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
1194                 return NT_STATUS_INVALID_PARAMETER_MIX;
1195         }
1196         if (iov[3].iov_len != sizeof(uint16_t)) {
1197                 return NT_STATUS_INVALID_PARAMETER_MIX;
1198         }
1199
1200         if (state->smb1.mid != 0) {
1201                 mid = state->smb1.mid;
1202         } else {
1203                 mid = smb1cli_alloc_mid(state->conn);
1204         }
1205         SSVAL(iov[1].iov_base, HDR_MID, mid);
1206
1207         _smb_setlen_nbt(iov[0].iov_base, smbXcli_iov_len(&iov[1], iov_count-1));
1208
1209         status = smb1cli_conn_signv(state->conn, iov, iov_count,
1210                                     &state->smb1.seqnum,
1211                                     state->smb1.one_way_seqnum);
1212
1213         if (!NT_STATUS_IS_OK(status)) {
1214                 return status;
1215         }
1216
1217         /*
1218          * If we supported multiple encrytion contexts
1219          * here we'd look up based on tid.
1220          */
1221         if (common_encryption_on(state->conn->smb1.trans_enc)) {
1222                 char *buf, *enc_buf;
1223
1224                 buf = (char *)smbXcli_iov_concat(talloc_tos(), iov, iov_count);
1225                 if (buf == NULL) {
1226                         return NT_STATUS_NO_MEMORY;
1227                 }
1228                 status = common_encrypt_buffer(state->conn->smb1.trans_enc,
1229                                                (char *)buf, &enc_buf);
1230                 TALLOC_FREE(buf);
1231                 if (!NT_STATUS_IS_OK(status)) {
1232                         DEBUG(0, ("Error in encrypting client message: %s\n",
1233                                   nt_errstr(status)));
1234                         return status;
1235                 }
1236                 buf = (char *)talloc_memdup(state, enc_buf,
1237                                             smb_len_nbt(enc_buf)+4);
1238                 SAFE_FREE(enc_buf);
1239                 if (buf == NULL) {
1240                         return NT_STATUS_NO_MEMORY;
1241                 }
1242                 iov[0].iov_base = (void *)buf;
1243                 iov[0].iov_len = talloc_get_size(buf);
1244                 iov_count = 1;
1245         }
1246
1247         if (state->conn->dispatch_incoming == NULL) {
1248                 state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
1249         }
1250
1251         tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1252
1253         subreq = writev_send(state, state->ev, state->conn->outgoing,
1254                              state->conn->write_fd, false, iov, iov_count);
1255         if (subreq == NULL) {
1256                 return NT_STATUS_NO_MEMORY;
1257         }
1258         tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
1259         return NT_STATUS_OK;
1260 }
1261
1262 struct tevent_req *smb1cli_req_send(TALLOC_CTX *mem_ctx,
1263                                     struct tevent_context *ev,
1264                                     struct smbXcli_conn *conn,
1265                                     uint8_t smb_command,
1266                                     uint8_t additional_flags,
1267                                     uint8_t clear_flags,
1268                                     uint16_t additional_flags2,
1269                                     uint16_t clear_flags2,
1270                                     uint32_t timeout_msec,
1271                                     uint32_t pid,
1272                                     uint16_t tid,
1273                                     uint16_t uid,
1274                                     uint8_t wct, uint16_t *vwv,
1275                                     uint32_t num_bytes,
1276                                     const uint8_t *bytes)
1277 {
1278         struct tevent_req *req;
1279         struct iovec iov;
1280         NTSTATUS status;
1281
1282         iov.iov_base = discard_const_p(void, bytes);
1283         iov.iov_len = num_bytes;
1284
1285         req = smb1cli_req_create(mem_ctx, ev, conn, smb_command,
1286                                  additional_flags, clear_flags,
1287                                  additional_flags2, clear_flags2,
1288                                  timeout_msec,
1289                                  pid, tid, uid,
1290                                  wct, vwv, 1, &iov);
1291         if (req == NULL) {
1292                 return NULL;
1293         }
1294         if (!tevent_req_is_in_progress(req)) {
1295                 return tevent_req_post(req, ev);
1296         }
1297         status = smb1cli_req_chain_submit(&req, 1);
1298         if (tevent_req_nterror(req, status)) {
1299                 return tevent_req_post(req, ev);
1300         }
1301         return req;
1302 }
1303
1304 static void smb1cli_req_writev_done(struct tevent_req *subreq)
1305 {
1306         struct tevent_req *req =
1307                 tevent_req_callback_data(subreq,
1308                 struct tevent_req);
1309         struct smbXcli_req_state *state =
1310                 tevent_req_data(req,
1311                 struct smbXcli_req_state);
1312         ssize_t nwritten;
1313         int err;
1314
1315         nwritten = writev_recv(subreq, &err);
1316         TALLOC_FREE(subreq);
1317         if (nwritten == -1) {
1318                 NTSTATUS status = map_nt_error_from_unix_common(err);
1319                 smbXcli_conn_disconnect(state->conn, status);
1320                 return;
1321         }
1322
1323         if (state->one_way) {
1324                 state->inbuf = NULL;
1325                 tevent_req_done(req);
1326                 return;
1327         }
1328
1329         if (!smbXcli_req_set_pending(req)) {
1330                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1331                 return;
1332         }
1333 }
1334
1335 static void smbXcli_conn_received(struct tevent_req *subreq)
1336 {
1337         struct smbXcli_conn *conn =
1338                 tevent_req_callback_data(subreq,
1339                 struct smbXcli_conn);
1340         TALLOC_CTX *frame = talloc_stackframe();
1341         NTSTATUS status;
1342         uint8_t *inbuf;
1343         ssize_t received;
1344         int err;
1345
1346         if (subreq != conn->read_smb_req) {
1347                 DEBUG(1, ("Internal error: cli_smb_received called with "
1348                           "unexpected subreq\n"));
1349                 status = NT_STATUS_INTERNAL_ERROR;
1350                 smbXcli_conn_disconnect(conn, status);
1351                 TALLOC_FREE(frame);
1352                 return;
1353         }
1354         conn->read_smb_req = NULL;
1355
1356         received = read_smb_recv(subreq, frame, &inbuf, &err);
1357         TALLOC_FREE(subreq);
1358         if (received == -1) {
1359                 status = map_nt_error_from_unix_common(err);
1360                 smbXcli_conn_disconnect(conn, status);
1361                 TALLOC_FREE(frame);
1362                 return;
1363         }
1364
1365         status = conn->dispatch_incoming(conn, frame, inbuf);
1366         TALLOC_FREE(frame);
1367         if (NT_STATUS_IS_OK(status)) {
1368                 /*
1369                  * We should not do any more processing
1370                  * as the dispatch function called
1371                  * tevent_req_done().
1372                  */
1373                 return;
1374         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1375                 /*
1376                  * We got an error, so notify all pending requests
1377                  */
1378                 smbXcli_conn_disconnect(conn, status);
1379                 return;
1380         }
1381
1382         /*
1383          * We got NT_STATUS_RETRY, so we may ask for a
1384          * next incoming pdu.
1385          */
1386         if (!smbXcli_conn_receive_next(conn)) {
1387                 smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1388         }
1389 }
1390
1391 static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
1392                                           struct iovec **piov, int *pnum_iov)
1393 {
1394         struct iovec *iov;
1395         int num_iov;
1396         size_t buflen;
1397         size_t taken;
1398         size_t remaining;
1399         uint8_t *hdr;
1400         uint8_t cmd;
1401         uint32_t wct_ofs;
1402
1403         buflen = smb_len_nbt(buf);
1404         taken = 0;
1405
1406         hdr = buf + NBT_HDR_SIZE;
1407
1408         if (buflen < MIN_SMB_SIZE) {
1409                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1410         }
1411
1412         /*
1413          * This returns iovec elements in the following order:
1414          *
1415          * - SMB header
1416          *
1417          * - Parameter Block
1418          * - Data Block
1419          *
1420          * - Parameter Block
1421          * - Data Block
1422          *
1423          * - Parameter Block
1424          * - Data Block
1425          */
1426         num_iov = 1;
1427
1428         iov = talloc_array(mem_ctx, struct iovec, num_iov);
1429         if (iov == NULL) {
1430                 return NT_STATUS_NO_MEMORY;
1431         }
1432         iov[0].iov_base = hdr;
1433         iov[0].iov_len = HDR_WCT;
1434         taken += HDR_WCT;
1435
1436         cmd = CVAL(hdr, HDR_COM);
1437         wct_ofs = HDR_WCT;
1438
1439         while (true) {
1440                 size_t len = buflen - taken;
1441                 struct iovec *cur;
1442                 struct iovec *iov_tmp;
1443                 uint8_t wct;
1444                 uint32_t bcc_ofs;
1445                 uint16_t bcc;
1446                 size_t needed;
1447
1448                 /*
1449                  * we need at least WCT and BCC
1450                  */
1451                 needed = sizeof(uint8_t) + sizeof(uint16_t);
1452                 if (len < needed) {
1453                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1454                                    __location__, (int)len, (int)needed));
1455                         goto inval;
1456                 }
1457
1458                 /*
1459                  * Now we check if the specified words are there
1460                  */
1461                 wct = CVAL(hdr, wct_ofs);
1462                 needed += wct * sizeof(uint16_t);
1463                 if (len < needed) {
1464                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1465                                    __location__, (int)len, (int)needed));
1466                         goto inval;
1467                 }
1468
1469                 /*
1470                  * Now we check if the specified bytes are there
1471                  */
1472                 bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
1473                 bcc = SVAL(hdr, bcc_ofs);
1474                 needed += bcc * sizeof(uint8_t);
1475                 if (len < needed) {
1476                         DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
1477                                    __location__, (int)len, (int)needed));
1478                         goto inval;
1479                 }
1480
1481                 /*
1482                  * we allocate 2 iovec structures for words and bytes
1483                  */
1484                 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
1485                                          num_iov + 2);
1486                 if (iov_tmp == NULL) {
1487                         TALLOC_FREE(iov);
1488                         return NT_STATUS_NO_MEMORY;
1489                 }
1490                 iov = iov_tmp;
1491                 cur = &iov[num_iov];
1492                 num_iov += 2;
1493
1494                 cur[0].iov_len = wct * sizeof(uint16_t);
1495                 cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
1496                 cur[1].iov_len = bcc * sizeof(uint8_t);
1497                 cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
1498
1499                 taken += needed;
1500
1501                 if (!smb1cli_is_andx_req(cmd)) {
1502                         /*
1503                          * If the current command does not have AndX chanining
1504                          * we are done.
1505                          */
1506                         break;
1507                 }
1508
1509                 if (wct == 0 && bcc == 0) {
1510                         /*
1511                          * An empty response also ends the chain,
1512                          * most likely with an error.
1513                          */
1514                         break;
1515                 }
1516
1517                 if (wct < 2) {
1518                         DEBUG(10, ("%s: wct[%d] < 2 for cmd[0x%02X]\n",
1519                                    __location__, (int)wct, (int)cmd));
1520                         goto inval;
1521                 }
1522                 cmd = CVAL(cur[0].iov_base, 0);
1523                 if (cmd == 0xFF) {
1524                         /*
1525                          * If it is the end of the chain we are also done.
1526                          */
1527                         break;
1528                 }
1529                 wct_ofs = SVAL(cur[0].iov_base, 2);
1530
1531                 if (wct_ofs < taken) {
1532                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1533                 }
1534                 if (wct_ofs > buflen) {
1535                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1536                 }
1537
1538                 /*
1539                  * we consumed everything up to the start of the next
1540                  * parameter block.
1541                  */
1542                 taken = wct_ofs;
1543         }
1544
1545         remaining = buflen - taken;
1546
1547         if (remaining > 0 && num_iov >= 3) {
1548                 /*
1549                  * The last DATA block gets the remaining
1550                  * bytes, this is needed to support
1551                  * CAP_LARGE_WRITEX and CAP_LARGE_READX.
1552                  */
1553                 iov[num_iov-1].iov_len += remaining;
1554         }
1555
1556         *piov = iov;
1557         *pnum_iov = num_iov;
1558         return NT_STATUS_OK;
1559
1560 inval:
1561         TALLOC_FREE(iov);
1562         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1563 }
1564
1565 static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
1566                                                TALLOC_CTX *tmp_mem,
1567                                                uint8_t *inbuf)
1568 {
1569         struct tevent_req *req;
1570         struct smbXcli_req_state *state;
1571         NTSTATUS status;
1572         size_t num_pending;
1573         size_t i;
1574         uint8_t cmd;
1575         uint16_t mid;
1576         bool oplock_break;
1577         const uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
1578         struct iovec *iov = NULL;
1579         int num_iov = 0;
1580         struct tevent_req **chain = NULL;
1581         size_t num_chained = 0;
1582         size_t num_responses = 0;
1583
1584         if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
1585             && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
1586                 DEBUG(10, ("Got non-SMB PDU\n"));
1587                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1588         }
1589
1590         /*
1591          * If we supported multiple encrytion contexts
1592          * here we'd look up based on tid.
1593          */
1594         if (common_encryption_on(conn->smb1.trans_enc)
1595             && (CVAL(inbuf, 0) == 0)) {
1596                 uint16_t enc_ctx_num;
1597
1598                 status = get_enc_ctx_num(inbuf, &enc_ctx_num);
1599                 if (!NT_STATUS_IS_OK(status)) {
1600                         DEBUG(10, ("get_enc_ctx_num returned %s\n",
1601                                    nt_errstr(status)));
1602                         return status;
1603                 }
1604
1605                 if (enc_ctx_num != conn->smb1.trans_enc->enc_ctx_num) {
1606                         DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
1607                                    enc_ctx_num,
1608                                    conn->smb1.trans_enc->enc_ctx_num));
1609                         return NT_STATUS_INVALID_HANDLE;
1610                 }
1611
1612                 status = common_decrypt_buffer(conn->smb1.trans_enc,
1613                                                (char *)inbuf);
1614                 if (!NT_STATUS_IS_OK(status)) {
1615                         DEBUG(10, ("common_decrypt_buffer returned %s\n",
1616                                    nt_errstr(status)));
1617                         return status;
1618                 }
1619         }
1620
1621         mid = SVAL(inhdr, HDR_MID);
1622         num_pending = talloc_array_length(conn->pending);
1623
1624         for (i=0; i<num_pending; i++) {
1625                 if (mid == smb1cli_req_mid(conn->pending[i])) {
1626                         break;
1627                 }
1628         }
1629         if (i == num_pending) {
1630                 /* Dump unexpected reply */
1631                 return NT_STATUS_RETRY;
1632         }
1633
1634         oplock_break = false;
1635
1636         if (mid == 0xffff) {
1637                 /*
1638                  * Paranoia checks that this is really an oplock break request.
1639                  */
1640                 oplock_break = (smb_len_nbt(inbuf) == 51); /* hdr + 8 words */
1641                 oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
1642                 oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
1643                 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
1644                 oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
1645
1646                 if (!oplock_break) {
1647                         /* Dump unexpected reply */
1648                         return NT_STATUS_RETRY;
1649                 }
1650         }
1651
1652         req = conn->pending[i];
1653         state = tevent_req_data(req, struct smbXcli_req_state);
1654
1655         if (!oplock_break /* oplock breaks are not signed */
1656             && !smb_signing_check_pdu(conn->smb1.signing,
1657                                       inbuf, state->smb1.seqnum+1)) {
1658                 DEBUG(10, ("cli_check_sign_mac failed\n"));
1659                 return NT_STATUS_ACCESS_DENIED;
1660         }
1661
1662         status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
1663                                            &iov, &num_iov);
1664         if (!NT_STATUS_IS_OK(status)) {
1665                 DEBUG(10,("smb1cli_inbuf_parse_chain - %s\n",
1666                           nt_errstr(status)));
1667                 return status;
1668         }
1669
1670         cmd = CVAL(inhdr, HDR_COM);
1671         status = smb1cli_pull_raw_error(inhdr);
1672
1673         if (state->smb1.chained_requests == NULL) {
1674                 if (num_iov != 3) {
1675                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
1676                 }
1677
1678                 smbXcli_req_unset_pending(req);
1679
1680                 state->smb1.recv_cmd = cmd;
1681                 state->smb1.recv_status = status;
1682                 state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
1683
1684                 state->smb1.recv_iov[0] = iov[0];
1685                 state->smb1.recv_iov[1] = iov[1];
1686                 state->smb1.recv_iov[2] = iov[2];
1687
1688                 if (talloc_array_length(conn->pending) == 0) {
1689                         tevent_req_done(req);
1690                         return NT_STATUS_OK;
1691                 }
1692
1693                 tevent_req_defer_callback(req, state->ev);
1694                 tevent_req_done(req);
1695                 return NT_STATUS_RETRY;
1696         }
1697
1698         chain = talloc_move(tmp_mem, &state->smb1.chained_requests);
1699         num_chained = talloc_array_length(chain);
1700         num_responses = (num_iov - 1)/2;
1701
1702         if (num_responses > num_chained) {
1703                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1704         }
1705
1706         for (i=0; i<num_chained; i++) {
1707                 size_t iov_idx = 1 + (i*2);
1708                 struct iovec *cur = &iov[iov_idx];
1709                 uint8_t *inbuf_ref;
1710
1711                 req = chain[i];
1712                 state = tevent_req_data(req, struct smbXcli_req_state);
1713
1714                 smbXcli_req_unset_pending(req);
1715
1716                 /*
1717                  * as we finish multiple requests here
1718                  * we need to defer the callbacks as
1719                  * they could destroy our current stack state.
1720                  */
1721                 tevent_req_defer_callback(req, state->ev);
1722
1723                 if (i >= num_responses) {
1724                         tevent_req_nterror(req, NT_STATUS_REQUEST_ABORTED);
1725                         continue;
1726                 }
1727
1728                 state->smb1.recv_cmd = cmd;
1729
1730                 if (i == (num_responses - 1)) {
1731                         /*
1732                          * The last request in the chain gets the status
1733                          */
1734                         state->smb1.recv_status = status;
1735                 } else {
1736                         cmd = CVAL(cur[0].iov_base, 0);
1737                         state->smb1.recv_status = NT_STATUS_OK;
1738                 }
1739
1740                 state->inbuf = inbuf;
1741
1742                 /*
1743                  * Note: here we use talloc_reference() in a way
1744                  *       that does not expose it to the caller.
1745                  */
1746                 inbuf_ref = talloc_reference(state->smb1.recv_iov, inbuf);
1747                 if (tevent_req_nomem(inbuf_ref, req)) {
1748                         continue;
1749                 }
1750
1751                 /* copy the related buffers */
1752                 state->smb1.recv_iov[0] = iov[0];
1753                 state->smb1.recv_iov[1] = cur[0];
1754                 state->smb1.recv_iov[2] = cur[1];
1755
1756                 tevent_req_done(req);
1757         }
1758
1759         return NT_STATUS_RETRY;
1760 }
1761
1762 NTSTATUS smb1cli_req_recv(struct tevent_req *req,
1763                           TALLOC_CTX *mem_ctx,
1764                           struct iovec **piov,
1765                           uint8_t **phdr,
1766                           uint8_t *pwct,
1767                           uint16_t **pvwv,
1768                           uint32_t *pvwv_offset,
1769                           uint32_t *pnum_bytes,
1770                           uint8_t **pbytes,
1771                           uint32_t *pbytes_offset,
1772                           uint8_t **pinbuf,
1773                           const struct smb1cli_req_expected_response *expected,
1774                           size_t num_expected)
1775 {
1776         struct smbXcli_req_state *state =
1777                 tevent_req_data(req,
1778                 struct smbXcli_req_state);
1779         NTSTATUS status = NT_STATUS_OK;
1780         struct iovec *recv_iov = NULL;
1781         uint8_t *hdr = NULL;
1782         uint8_t wct = 0;
1783         uint32_t vwv_offset = 0;
1784         uint16_t *vwv = NULL;
1785         uint32_t num_bytes = 0;
1786         uint32_t bytes_offset = 0;
1787         uint8_t *bytes = NULL;
1788         size_t i;
1789         bool found_status = false;
1790         bool found_size = false;
1791
1792         if (piov != NULL) {
1793                 *piov = NULL;
1794         }
1795         if (phdr != NULL) {
1796                 *phdr = 0;
1797         }
1798         if (pwct != NULL) {
1799                 *pwct = 0;
1800         }
1801         if (pvwv != NULL) {
1802                 *pvwv = NULL;
1803         }
1804         if (pvwv_offset != NULL) {
1805                 *pvwv_offset = 0;
1806         }
1807         if (pnum_bytes != NULL) {
1808                 *pnum_bytes = 0;
1809         }
1810         if (pbytes != NULL) {
1811                 *pbytes = NULL;
1812         }
1813         if (pbytes_offset != NULL) {
1814                 *pbytes_offset = 0;
1815         }
1816         if (pinbuf != NULL) {
1817                 *pinbuf = NULL;
1818         }
1819
1820         if (state->inbuf != NULL) {
1821                 recv_iov = state->smb1.recv_iov;
1822                 hdr = (uint8_t *)recv_iov[0].iov_base;
1823                 wct = recv_iov[1].iov_len/2;
1824                 vwv = (uint16_t *)recv_iov[1].iov_base;
1825                 vwv_offset = PTR_DIFF(vwv, hdr);
1826                 num_bytes = recv_iov[2].iov_len;
1827                 bytes = (uint8_t *)recv_iov[2].iov_base;
1828                 bytes_offset = PTR_DIFF(bytes, hdr);
1829         }
1830
1831         if (tevent_req_is_nterror(req, &status)) {
1832                 for (i=0; i < num_expected; i++) {
1833                         if (NT_STATUS_EQUAL(status, expected[i].status)) {
1834                                 found_status = true;
1835                                 break;
1836                         }
1837                 }
1838
1839                 if (found_status) {
1840                         return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
1841                 }
1842
1843                 return status;
1844         }
1845
1846         if (num_expected == 0) {
1847                 found_status = true;
1848                 found_size = true;
1849         }
1850
1851         status = state->smb1.recv_status;
1852
1853         for (i=0; i < num_expected; i++) {
1854                 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
1855                         continue;
1856                 }
1857
1858                 found_status = true;
1859                 if (expected[i].wct == 0) {
1860                         found_size = true;
1861                         break;
1862                 }
1863
1864                 if (expected[i].wct == wct) {
1865                         found_size = true;
1866                         break;
1867                 }
1868         }
1869
1870         if (!found_status) {
1871                 return status;
1872         }
1873
1874         if (!found_size) {
1875                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1876         }
1877
1878         if (piov != NULL) {
1879                 *piov = talloc_move(mem_ctx, &recv_iov);
1880         }
1881
1882         if (phdr != NULL) {
1883                 *phdr = hdr;
1884         }
1885         if (pwct != NULL) {
1886                 *pwct = wct;
1887         }
1888         if (pvwv != NULL) {
1889                 *pvwv = vwv;
1890         }
1891         if (pvwv_offset != NULL) {
1892                 *pvwv_offset = vwv_offset;
1893         }
1894         if (pnum_bytes != NULL) {
1895                 *pnum_bytes = num_bytes;
1896         }
1897         if (pbytes != NULL) {
1898                 *pbytes = bytes;
1899         }
1900         if (pbytes_offset != NULL) {
1901                 *pbytes_offset = bytes_offset;
1902         }
1903         if (pinbuf != NULL) {
1904                 *pinbuf = state->inbuf;
1905         }
1906
1907         return status;
1908 }
1909
1910 size_t smb1cli_req_wct_ofs(struct tevent_req **reqs, int num_reqs)
1911 {
1912         size_t wct_ofs;
1913         int i;
1914
1915         wct_ofs = HDR_WCT;
1916
1917         for (i=0; i<num_reqs; i++) {
1918                 struct smbXcli_req_state *state;
1919                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
1920                 wct_ofs += smbXcli_iov_len(state->smb1.iov+2,
1921                                            state->smb1.iov_count-2);
1922                 wct_ofs = (wct_ofs + 3) & ~3;
1923         }
1924         return wct_ofs;
1925 }
1926
1927 NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
1928 {
1929         struct smbXcli_req_state *first_state =
1930                 tevent_req_data(reqs[0],
1931                 struct smbXcli_req_state);
1932         struct smbXcli_req_state *state;
1933         size_t wct_offset;
1934         size_t chain_padding = 0;
1935         int i, iovlen;
1936         struct iovec *iov = NULL;
1937         struct iovec *this_iov;
1938         NTSTATUS status;
1939         size_t nbt_len;
1940
1941         if (num_reqs == 1) {
1942                 return smb1cli_req_writev_submit(reqs[0], first_state,
1943                                                  first_state->smb1.iov,
1944                                                  first_state->smb1.iov_count);
1945         }
1946
1947         iovlen = 0;
1948         for (i=0; i<num_reqs; i++) {
1949                 if (!tevent_req_is_in_progress(reqs[i])) {
1950                         return NT_STATUS_INTERNAL_ERROR;
1951                 }
1952
1953                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
1954
1955                 if (state->smb1.iov_count < 4) {
1956                         return NT_STATUS_INVALID_PARAMETER_MIX;
1957                 }
1958
1959                 if (i == 0) {
1960                         /*
1961                          * The NBT and SMB header
1962                          */
1963                         iovlen += 2;
1964                 } else {
1965                         /*
1966                          * Chain padding
1967                          */
1968                         iovlen += 1;
1969                 }
1970
1971                 /*
1972                  * words and bytes
1973                  */
1974                 iovlen += state->smb1.iov_count - 2;
1975         }
1976
1977         iov = talloc_zero_array(first_state, struct iovec, iovlen);
1978         if (iov == NULL) {
1979                 return NT_STATUS_NO_MEMORY;
1980         }
1981
1982         first_state->smb1.chained_requests = (struct tevent_req **)talloc_memdup(
1983                 first_state, reqs, sizeof(*reqs) * num_reqs);
1984         if (first_state->smb1.chained_requests == NULL) {
1985                 TALLOC_FREE(iov);
1986                 return NT_STATUS_NO_MEMORY;
1987         }
1988
1989         wct_offset = HDR_WCT;
1990         this_iov = iov;
1991
1992         for (i=0; i<num_reqs; i++) {
1993                 size_t next_padding = 0;
1994                 uint16_t *vwv;
1995
1996                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
1997
1998                 if (i < num_reqs-1) {
1999                         if (!smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))
2000                             || CVAL(state->smb1.hdr, HDR_WCT) < 2) {
2001                                 TALLOC_FREE(iov);
2002                                 TALLOC_FREE(first_state->smb1.chained_requests);
2003                                 return NT_STATUS_INVALID_PARAMETER_MIX;
2004                         }
2005                 }
2006
2007                 wct_offset += smbXcli_iov_len(state->smb1.iov+2,
2008                                               state->smb1.iov_count-2) + 1;
2009                 if ((wct_offset % 4) != 0) {
2010                         next_padding = 4 - (wct_offset % 4);
2011                 }
2012                 wct_offset += next_padding;
2013                 vwv = state->smb1.vwv;
2014
2015                 if (i < num_reqs-1) {
2016                         struct smbXcli_req_state *next_state =
2017                                 tevent_req_data(reqs[i+1],
2018                                 struct smbXcli_req_state);
2019                         SCVAL(vwv+0, 0, CVAL(next_state->smb1.hdr, HDR_COM));
2020                         SCVAL(vwv+0, 1, 0);
2021                         SSVAL(vwv+1, 0, wct_offset);
2022                 } else if (smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))) {
2023                         /* properly end the chain */
2024                         SCVAL(vwv+0, 0, 0xff);
2025                         SCVAL(vwv+0, 1, 0xff);
2026                         SSVAL(vwv+1, 0, 0);
2027                 }
2028
2029                 if (i == 0) {
2030                         /*
2031                          * The NBT and SMB header
2032                          */
2033                         this_iov[0] = state->smb1.iov[0];
2034                         this_iov[1] = state->smb1.iov[1];
2035                         this_iov += 2;
2036                 } else {
2037                         /*
2038                          * This one is a bit subtle. We have to add
2039                          * chain_padding bytes between the requests, and we
2040                          * have to also include the wct field of the
2041                          * subsequent requests. We use the subsequent header
2042                          * for the padding, it contains the wct field in its
2043                          * last byte.
2044                          */
2045                         this_iov[0].iov_len = chain_padding+1;
2046                         this_iov[0].iov_base = (void *)&state->smb1.hdr[
2047                                 sizeof(state->smb1.hdr) - this_iov[0].iov_len];
2048                         memset(this_iov[0].iov_base, 0, this_iov[0].iov_len-1);
2049                         this_iov += 1;
2050                 }
2051
2052                 /*
2053                  * copy the words and bytes
2054                  */
2055                 memcpy(this_iov, state->smb1.iov+2,
2056                        sizeof(struct iovec) * (state->smb1.iov_count-2));
2057                 this_iov += state->smb1.iov_count - 2;
2058                 chain_padding = next_padding;
2059         }
2060
2061         nbt_len = smbXcli_iov_len(&iov[1], iovlen-1);
2062         if (nbt_len > first_state->conn->smb1.max_xmit) {
2063                 TALLOC_FREE(iov);
2064                 TALLOC_FREE(first_state->smb1.chained_requests);
2065                 return NT_STATUS_INVALID_PARAMETER_MIX;
2066         }
2067
2068         status = smb1cli_req_writev_submit(reqs[0], first_state, iov, iovlen);
2069         if (!NT_STATUS_IS_OK(status)) {
2070                 TALLOC_FREE(iov);
2071                 TALLOC_FREE(first_state->smb1.chained_requests);
2072                 return status;
2073         }
2074
2075         return NT_STATUS_OK;
2076 }
2077
2078 bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
2079 {
2080         return ((tevent_queue_length(conn->outgoing) != 0)
2081                 || (talloc_array_length(conn->pending) != 0));
2082 }
2083
2084 uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
2085 {
2086         return conn->smb2.server.capabilities;
2087 }
2088
2089 uint16_t smb2cli_conn_server_security_mode(struct smbXcli_conn *conn)
2090 {
2091         return conn->smb2.server.security_mode;
2092 }
2093
2094 uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
2095 {
2096         return conn->smb2.server.max_trans_size;
2097 }
2098
2099 uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
2100 {
2101         return conn->smb2.server.max_read_size;
2102 }
2103
2104 uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
2105 {
2106         return conn->smb2.server.max_write_size;
2107 }
2108
2109 void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
2110                                   uint16_t max_credits)
2111 {
2112         conn->smb2.max_credits = max_credits;
2113 }
2114
2115 static void smb2cli_req_cancel_done(struct tevent_req *subreq);
2116
2117 static bool smb2cli_req_cancel(struct tevent_req *req)
2118 {
2119         struct smbXcli_req_state *state =
2120                 tevent_req_data(req,
2121                 struct smbXcli_req_state);
2122         uint32_t flags = IVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
2123         uint32_t pid = IVAL(state->smb2.hdr, SMB2_HDR_PID);
2124         uint32_t tid = IVAL(state->smb2.hdr, SMB2_HDR_TID);
2125         uint64_t mid = BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID);
2126         uint64_t aid = BVAL(state->smb2.hdr, SMB2_HDR_ASYNC_ID);
2127         struct smbXcli_session *session = state->session;
2128         uint8_t *fixed = state->smb2.pad;
2129         uint16_t fixed_len = 4;
2130         struct tevent_req *subreq;
2131         struct smbXcli_req_state *substate;
2132         NTSTATUS status;
2133
2134         SSVAL(fixed, 0, 0x04);
2135         SSVAL(fixed, 2, 0);
2136
2137         subreq = smb2cli_req_create(state, state->ev,
2138                                     state->conn,
2139                                     SMB2_OP_CANCEL,
2140                                     flags, 0,
2141                                     0, /* timeout */
2142                                     pid, tid, session,
2143                                     fixed, fixed_len,
2144                                     NULL, 0);
2145         if (subreq == NULL) {
2146                 return false;
2147         }
2148         substate = tevent_req_data(subreq, struct smbXcli_req_state);
2149
2150         if (flags & SMB2_HDR_FLAG_ASYNC) {
2151                 mid = 0;
2152         }
2153
2154         SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, flags);
2155         SIVAL(substate->smb2.hdr, SMB2_HDR_PID, pid);
2156         SIVAL(substate->smb2.hdr, SMB2_HDR_TID, tid);
2157         SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
2158         SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, aid);
2159
2160         status = smb2cli_req_compound_submit(&subreq, 1);
2161         if (!NT_STATUS_IS_OK(status)) {
2162                 TALLOC_FREE(subreq);
2163                 return false;
2164         }
2165
2166         tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
2167
2168         return true;
2169 }
2170
2171 static void smb2cli_req_cancel_done(struct tevent_req *subreq)
2172 {
2173         /* we do not care about the result */
2174         TALLOC_FREE(subreq);
2175 }
2176
2177 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
2178                                       struct tevent_context *ev,
2179                                       struct smbXcli_conn *conn,
2180                                       uint16_t cmd,
2181                                       uint32_t additional_flags,
2182                                       uint32_t clear_flags,
2183                                       uint32_t timeout_msec,
2184                                       uint32_t pid,
2185                                       uint32_t tid,
2186                                       struct smbXcli_session *session,
2187                                       const uint8_t *fixed,
2188                                       uint16_t fixed_len,
2189                                       const uint8_t *dyn,
2190                                       uint32_t dyn_len)
2191 {
2192         struct tevent_req *req;
2193         struct smbXcli_req_state *state;
2194         uint32_t flags = 0;
2195         uint64_t uid = 0;
2196
2197         req = tevent_req_create(mem_ctx, &state,
2198                                 struct smbXcli_req_state);
2199         if (req == NULL) {
2200                 return NULL;
2201         }
2202
2203         state->ev = ev;
2204         state->conn = conn;
2205         state->session = session;
2206
2207         if (session) {
2208                 uid = session->smb2.session_id;
2209         }
2210
2211         state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
2212         if (state->smb2.recv_iov == NULL) {
2213                 TALLOC_FREE(req);
2214                 return NULL;
2215         }
2216
2217         flags |= additional_flags;
2218         flags &= ~clear_flags;
2219
2220         state->smb2.fixed = fixed;
2221         state->smb2.fixed_len = fixed_len;
2222         state->smb2.dyn = dyn;
2223         state->smb2.dyn_len = dyn_len;
2224
2225         SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID,    SMB2_MAGIC);
2226         SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH,         SMB2_HDR_BODY);
2227         SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE,         cmd);
2228         SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS,          flags);
2229         SIVAL(state->smb2.hdr, SMB2_HDR_PID,            pid);
2230         SIVAL(state->smb2.hdr, SMB2_HDR_TID,            tid);
2231         SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID,     uid);
2232
2233         switch (cmd) {
2234         case SMB2_OP_CANCEL:
2235                 state->one_way = true;
2236                 break;
2237         case SMB2_OP_BREAK:
2238                 /*
2239                  * If this is a dummy request, it will have
2240                  * UINT64_MAX as message id.
2241                  * If we send on break acknowledgement,
2242                  * this gets overwritten later.
2243                  */
2244                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
2245                 break;
2246         }
2247
2248         if (timeout_msec > 0) {
2249                 struct timeval endtime;
2250
2251                 endtime = timeval_current_ofs_msec(timeout_msec);
2252                 if (!tevent_req_set_endtime(req, ev, endtime)) {
2253                         return req;
2254                 }
2255         }
2256
2257         return req;
2258 }
2259
2260 void smb2cli_req_set_notify_async(struct tevent_req *req)
2261 {
2262         struct smbXcli_req_state *state =
2263                 tevent_req_data(req,
2264                 struct smbXcli_req_state);
2265
2266         state->smb2.notify_async = true;
2267 }
2268
2269 static void smb2cli_writev_done(struct tevent_req *subreq);
2270 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2271                                                TALLOC_CTX *tmp_mem,
2272                                                uint8_t *inbuf);
2273
2274 NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
2275                                      int num_reqs)
2276 {
2277         struct smbXcli_req_state *state;
2278         struct tevent_req *subreq;
2279         struct iovec *iov;
2280         int i, num_iov, nbt_len;
2281
2282         /*
2283          * 1 for the nbt length
2284          * per request: HDR, fixed, dyn, padding
2285          * -1 because the last one does not need padding
2286          */
2287
2288         iov = talloc_array(reqs[0], struct iovec, 1 + 4*num_reqs - 1);
2289         if (iov == NULL) {
2290                 return NT_STATUS_NO_MEMORY;
2291         }
2292
2293         num_iov = 1;
2294         nbt_len = 0;
2295
2296         for (i=0; i<num_reqs; i++) {
2297                 int hdr_iov;
2298                 size_t reqlen;
2299                 bool ret;
2300                 uint16_t opcode;
2301                 uint64_t avail;
2302                 uint16_t charge;
2303                 uint16_t credits;
2304                 uint64_t mid;
2305                 bool should_sign = false;
2306
2307                 if (!tevent_req_is_in_progress(reqs[i])) {
2308                         return NT_STATUS_INTERNAL_ERROR;
2309                 }
2310
2311                 state = tevent_req_data(reqs[i], struct smbXcli_req_state);
2312
2313                 if (!smbXcli_conn_is_connected(state->conn)) {
2314                         return NT_STATUS_CONNECTION_DISCONNECTED;
2315                 }
2316
2317                 if ((state->conn->protocol != PROTOCOL_NONE) &&
2318                     (state->conn->protocol < PROTOCOL_SMB2_02)) {
2319                         return NT_STATUS_REVISION_MISMATCH;
2320                 }
2321
2322                 opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
2323                 if (opcode == SMB2_OP_CANCEL) {
2324                         goto skip_credits;
2325                 }
2326
2327                 avail = UINT64_MAX - state->conn->smb2.mid;
2328                 if (avail < 1) {
2329                         return NT_STATUS_CONNECTION_ABORTED;
2330                 }
2331
2332                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2333                         charge = (MAX(state->smb2.dyn_len, 1) - 1)/ 65536 + 1;
2334                 } else {
2335                         charge = 1;
2336                 }
2337
2338                 charge = MAX(state->smb2.credit_charge, charge);
2339
2340                 avail = MIN(avail, state->conn->smb2.cur_credits);
2341                 if (avail < charge) {
2342                         return NT_STATUS_INTERNAL_ERROR;
2343                 }
2344
2345                 credits = 0;
2346                 if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
2347                         credits = state->conn->smb2.max_credits -
2348                                   state->conn->smb2.cur_credits;
2349                 }
2350                 if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
2351                         credits += 1;
2352                 }
2353
2354                 mid = state->conn->smb2.mid;
2355                 state->conn->smb2.mid += charge;
2356                 state->conn->smb2.cur_credits -= charge;
2357
2358                 if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
2359                         SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
2360                 }
2361                 SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
2362                 SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
2363
2364 skip_credits:
2365                 hdr_iov = num_iov;
2366                 iov[num_iov].iov_base = state->smb2.hdr;
2367                 iov[num_iov].iov_len  = sizeof(state->smb2.hdr);
2368                 num_iov += 1;
2369
2370                 iov[num_iov].iov_base = discard_const(state->smb2.fixed);
2371                 iov[num_iov].iov_len  = state->smb2.fixed_len;
2372                 num_iov += 1;
2373
2374                 if (state->smb2.dyn != NULL) {
2375                         iov[num_iov].iov_base = discard_const(state->smb2.dyn);
2376                         iov[num_iov].iov_len  = state->smb2.dyn_len;
2377                         num_iov += 1;
2378                 }
2379
2380                 reqlen  = sizeof(state->smb2.hdr);
2381                 reqlen += state->smb2.fixed_len;
2382                 reqlen += state->smb2.dyn_len;
2383
2384                 if (i < num_reqs-1) {
2385                         if ((reqlen % 8) > 0) {
2386                                 uint8_t pad = 8 - (reqlen % 8);
2387                                 iov[num_iov].iov_base = state->smb2.pad;
2388                                 iov[num_iov].iov_len = pad;
2389                                 num_iov += 1;
2390                                 reqlen += pad;
2391                         }
2392                         SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
2393                 }
2394                 nbt_len += reqlen;
2395
2396                 if (state->session) {
2397                         should_sign = state->session->smb2.should_sign;
2398                         if (state->session->smb2.channel_setup) {
2399                                 should_sign = true;
2400                         }
2401                 }
2402
2403                 if (should_sign) {
2404                         NTSTATUS status;
2405
2406                         status = smb2_signing_sign_pdu(state->session->smb2.signing_key,
2407                                                        &iov[hdr_iov], num_iov - hdr_iov);
2408                         if (!NT_STATUS_IS_OK(status)) {
2409                                 return status;
2410                         }
2411                 }
2412
2413                 ret = smbXcli_req_set_pending(reqs[i]);
2414                 if (!ret) {
2415                         return NT_STATUS_NO_MEMORY;
2416                 }
2417         }
2418
2419         state = tevent_req_data(reqs[0], struct smbXcli_req_state);
2420         _smb_setlen_tcp(state->length_hdr, nbt_len);
2421         iov[0].iov_base = state->length_hdr;
2422         iov[0].iov_len  = sizeof(state->length_hdr);
2423
2424         if (state->conn->dispatch_incoming == NULL) {
2425                 state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
2426         }
2427
2428         subreq = writev_send(state, state->ev, state->conn->outgoing,
2429                              state->conn->write_fd, false, iov, num_iov);
2430         if (subreq == NULL) {
2431                 return NT_STATUS_NO_MEMORY;
2432         }
2433         tevent_req_set_callback(subreq, smb2cli_writev_done, reqs[0]);
2434         return NT_STATUS_OK;
2435 }
2436
2437 void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
2438 {
2439         struct smbXcli_req_state *state =
2440                 tevent_req_data(req,
2441                 struct smbXcli_req_state);
2442
2443         state->smb2.credit_charge = charge;
2444 }
2445
2446 struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
2447                                     struct tevent_context *ev,
2448                                     struct smbXcli_conn *conn,
2449                                     uint16_t cmd,
2450                                     uint32_t additional_flags,
2451                                     uint32_t clear_flags,
2452                                     uint32_t timeout_msec,
2453                                     uint32_t pid,
2454                                     uint32_t tid,
2455                                     struct smbXcli_session *session,
2456                                     const uint8_t *fixed,
2457                                     uint16_t fixed_len,
2458                                     const uint8_t *dyn,
2459                                     uint32_t dyn_len)
2460 {
2461         struct tevent_req *req;
2462         NTSTATUS status;
2463
2464         req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
2465                                  additional_flags, clear_flags,
2466                                  timeout_msec,
2467                                  pid, tid, session,
2468                                  fixed, fixed_len, dyn, dyn_len);
2469         if (req == NULL) {
2470                 return NULL;
2471         }
2472         if (!tevent_req_is_in_progress(req)) {
2473                 return tevent_req_post(req, ev);
2474         }
2475         status = smb2cli_req_compound_submit(&req, 1);
2476         if (tevent_req_nterror(req, status)) {
2477                 return tevent_req_post(req, ev);
2478         }
2479         return req;
2480 }
2481
2482 static void smb2cli_writev_done(struct tevent_req *subreq)
2483 {
2484         struct tevent_req *req =
2485                 tevent_req_callback_data(subreq,
2486                 struct tevent_req);
2487         struct smbXcli_req_state *state =
2488                 tevent_req_data(req,
2489                 struct smbXcli_req_state);
2490         ssize_t nwritten;
2491         int err;
2492
2493         nwritten = writev_recv(subreq, &err);
2494         TALLOC_FREE(subreq);
2495         if (nwritten == -1) {
2496                 /* here, we need to notify all pending requests */
2497                 NTSTATUS status = map_nt_error_from_unix_common(err);
2498                 smbXcli_conn_disconnect(state->conn, status);
2499                 return;
2500         }
2501 }
2502
2503 static NTSTATUS smb2cli_inbuf_parse_compound(uint8_t *buf, TALLOC_CTX *mem_ctx,
2504                                              struct iovec **piov, int *pnum_iov)
2505 {
2506         struct iovec *iov;
2507         int num_iov;
2508         size_t buflen;
2509         size_t taken;
2510         uint8_t *first_hdr;
2511
2512         num_iov = 0;
2513
2514         iov = talloc_array(mem_ctx, struct iovec, num_iov);
2515         if (iov == NULL) {
2516                 return NT_STATUS_NO_MEMORY;
2517         }
2518
2519         buflen = smb_len_tcp(buf);
2520         taken = 0;
2521         first_hdr = buf + NBT_HDR_SIZE;
2522
2523         while (taken < buflen) {
2524                 size_t len = buflen - taken;
2525                 uint8_t *hdr = first_hdr + taken;
2526                 struct iovec *cur;
2527                 size_t full_size;
2528                 size_t next_command_ofs;
2529                 uint16_t body_size;
2530                 struct iovec *iov_tmp;
2531
2532                 /*
2533                  * We need the header plus the body length field
2534                  */
2535
2536                 if (len < SMB2_HDR_BODY + 2) {
2537                         DEBUG(10, ("%d bytes left, expected at least %d\n",
2538                                    (int)len, SMB2_HDR_BODY));
2539                         goto inval;
2540                 }
2541                 if (IVAL(hdr, 0) != SMB2_MAGIC) {
2542                         DEBUG(10, ("Got non-SMB2 PDU: %x\n",
2543                                    IVAL(hdr, 0)));
2544                         goto inval;
2545                 }
2546                 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
2547                         DEBUG(10, ("Got HDR len %d, expected %d\n",
2548                                    SVAL(hdr, 4), SMB2_HDR_BODY));
2549                         goto inval;
2550                 }
2551
2552                 full_size = len;
2553                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
2554                 body_size = SVAL(hdr, SMB2_HDR_BODY);
2555
2556                 if (next_command_ofs != 0) {
2557                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
2558                                 goto inval;
2559                         }
2560                         if (next_command_ofs > full_size) {
2561                                 goto inval;
2562                         }
2563                         full_size = next_command_ofs;
2564                 }
2565                 if (body_size < 2) {
2566                         goto inval;
2567                 }
2568                 body_size &= 0xfffe;
2569
2570                 if (body_size > (full_size - SMB2_HDR_BODY)) {
2571                         goto inval;
2572                 }
2573
2574                 iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2575                                          num_iov + 3);
2576                 if (iov_tmp == NULL) {
2577                         TALLOC_FREE(iov);
2578                         return NT_STATUS_NO_MEMORY;
2579                 }
2580                 iov = iov_tmp;
2581                 cur = &iov[num_iov];
2582                 num_iov += 3;
2583
2584                 cur[0].iov_base = hdr;
2585                 cur[0].iov_len  = SMB2_HDR_BODY;
2586                 cur[1].iov_base = hdr + SMB2_HDR_BODY;
2587                 cur[1].iov_len  = body_size;
2588                 cur[2].iov_base = hdr + SMB2_HDR_BODY + body_size;
2589                 cur[2].iov_len  = full_size - (SMB2_HDR_BODY + body_size);
2590
2591                 taken += full_size;
2592         }
2593
2594         *piov = iov;
2595         *pnum_iov = num_iov;
2596         return NT_STATUS_OK;
2597
2598 inval:
2599         TALLOC_FREE(iov);
2600         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2601 }
2602
2603 static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
2604                                                     uint64_t mid)
2605 {
2606         size_t num_pending = talloc_array_length(conn->pending);
2607         size_t i;
2608
2609         for (i=0; i<num_pending; i++) {
2610                 struct tevent_req *req = conn->pending[i];
2611                 struct smbXcli_req_state *state =
2612                         tevent_req_data(req,
2613                         struct smbXcli_req_state);
2614
2615                 if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
2616                         return req;
2617                 }
2618         }
2619         return NULL;
2620 }
2621
2622 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2623                                                TALLOC_CTX *tmp_mem,
2624                                                uint8_t *inbuf)
2625 {
2626         struct tevent_req *req;
2627         struct smbXcli_req_state *state = NULL;
2628         struct iovec *iov;
2629         int i, num_iov;
2630         NTSTATUS status;
2631         bool defer = true;
2632         struct smbXcli_session *last_session = NULL;
2633
2634         status = smb2cli_inbuf_parse_compound(inbuf, tmp_mem,
2635                                               &iov, &num_iov);
2636         if (!NT_STATUS_IS_OK(status)) {
2637                 return status;
2638         }
2639
2640         for (i=0; i<num_iov; i+=3) {
2641                 uint8_t *inbuf_ref = NULL;
2642                 struct iovec *cur = &iov[i];
2643                 uint8_t *inhdr = (uint8_t *)cur[0].iov_base;
2644                 uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2645                 uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2646                 uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2647                 uint16_t req_opcode;
2648                 uint32_t req_flags;
2649                 uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
2650                 uint32_t new_credits;
2651                 struct smbXcli_session *session = NULL;
2652                 const DATA_BLOB *signing_key = NULL;
2653                 bool should_sign = false;
2654
2655                 new_credits = conn->smb2.cur_credits;
2656                 new_credits += credits;
2657                 if (new_credits > UINT16_MAX) {
2658                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2659                 }
2660                 conn->smb2.cur_credits += credits;
2661
2662                 req = smb2cli_conn_find_pending(conn, mid);
2663                 if (req == NULL) {
2664                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2665                 }
2666                 state = tevent_req_data(req, struct smbXcli_req_state);
2667
2668                 state->smb2.got_async = false;
2669
2670                 req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
2671                 if (opcode != req_opcode) {
2672                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2673                 }
2674                 req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
2675
2676                 if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
2677                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
2678                 }
2679
2680                 status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
2681                 if ((flags & SMB2_HDR_FLAG_ASYNC) &&
2682                     NT_STATUS_EQUAL(status, STATUS_PENDING)) {
2683                         uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
2684
2685                         /*
2686                          * async interim responses are not signed,
2687                          * even if the SMB2_HDR_FLAG_SIGNED flag
2688                          * is set.
2689                          */
2690                         req_flags |= SMB2_HDR_FLAG_ASYNC;
2691                         SBVAL(state->smb2.hdr, SMB2_HDR_FLAGS, req_flags);
2692                         SBVAL(state->smb2.hdr, SMB2_HDR_ASYNC_ID, async_id);
2693
2694                         if (state->smb2.notify_async) {
2695                                 state->smb2.got_async = true;
2696                                 tevent_req_defer_callback(req, state->ev);
2697                                 tevent_req_notify_callback(req);
2698                         }
2699                         continue;
2700                 }
2701
2702                 session = state->session;
2703                 if (req_flags & SMB2_HDR_FLAG_CHAINED) {
2704                         session = last_session;
2705                 }
2706                 last_session = session;
2707
2708                 if (session) {
2709                         should_sign = session->smb2.should_sign;
2710                         if (session->smb2.channel_setup) {
2711                                 should_sign = true;
2712                         }
2713                 }
2714
2715                 if (should_sign) {
2716                         if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
2717                                 return NT_STATUS_ACCESS_DENIED;
2718                         }
2719                 }
2720
2721                 if (flags & SMB2_HDR_FLAG_SIGNED) {
2722                         uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
2723
2724                         if (session == NULL) {
2725                                 struct smbXcli_session *s;
2726
2727                                 s = state->conn->sessions;
2728                                 for (; s; s = s->next) {
2729                                         if (s->smb2.session_id != uid) {
2730                                                 continue;
2731                                         }
2732
2733                                         session = s;
2734                                         break;
2735                                 }
2736                         }
2737
2738                         if (session == NULL) {
2739                                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2740                         }
2741
2742                         last_session = session;
2743                         signing_key = &session->smb2.signing_key;
2744                 }
2745
2746                 if ((opcode == SMB2_OP_SESSSETUP) &&
2747                      NT_STATUS_IS_OK(status)) {
2748                         /*
2749                          * the caller has to check the signing
2750                          * as only the caller knows the correct
2751                          * session key
2752                          */
2753                         signing_key = NULL;
2754                 }
2755
2756                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
2757                         /*
2758                          * if the server returns NT_STATUS_USER_SESSION_DELETED
2759                          * the response is not signed and we should
2760                          * propagate the NT_STATUS_USER_SESSION_DELETED
2761                          * status to the caller.
2762                          */
2763                         if (signing_key) {
2764                                 signing_key = NULL;
2765                         }
2766                 }
2767
2768                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
2769                     NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
2770                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2771                         /*
2772                          * if the server returns
2773                          * NT_STATUS_NETWORK_NAME_DELETED
2774                          * NT_STATUS_FILE_CLOSED
2775                          * NT_STATUS_INVALID_PARAMETER
2776                          * the response might not be signed
2777                          * as this happens before the signing checks.
2778                          *
2779                          * If server echos the signature (or all zeros)
2780                          * we should report the status from the server
2781                          * to the caller.
2782                          */
2783                         if (signing_key) {
2784                                 int cmp;
2785
2786                                 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
2787                                              state->smb2.hdr+SMB2_HDR_SIGNATURE,
2788                                              16);
2789                                 if (cmp == 0) {
2790                                         state->smb2.signing_skipped = true;
2791                                         signing_key = NULL;
2792                                 }
2793                         }
2794                         if (signing_key) {
2795                                 int cmp;
2796                                 static const uint8_t zeros[16];
2797
2798                                 cmp = memcmp(inhdr+SMB2_HDR_SIGNATURE,
2799                                              zeros,
2800                                              16);
2801                                 if (cmp == 0) {
2802                                         state->smb2.signing_skipped = true;
2803                                         signing_key = NULL;
2804                                 }
2805                         }
2806                 }
2807
2808                 if (signing_key) {
2809                         status = smb2_signing_check_pdu(*signing_key, cur, 3);
2810                         if (!NT_STATUS_IS_OK(status)) {
2811                                 /*
2812                                  * If the signing check fails, we disconnect
2813                                  * the connection.
2814                                  */
2815                                 return status;
2816                         }
2817                 }
2818
2819                 smbXcli_req_unset_pending(req);
2820
2821                 /*
2822                  * There might be more than one response
2823                  * we need to defer the notifications
2824                  */
2825                 if ((num_iov == 4) && (talloc_array_length(conn->pending) == 0)) {
2826                         defer = false;
2827                 }
2828
2829                 if (defer) {
2830                         tevent_req_defer_callback(req, state->ev);
2831                 }
2832
2833                 /*
2834                  * Note: here we use talloc_reference() in a way
2835                  *       that does not expose it to the caller.
2836                  */
2837                 inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
2838                 if (tevent_req_nomem(inbuf_ref, req)) {
2839                         continue;
2840                 }
2841
2842                 /* copy the related buffers */
2843                 state->smb2.recv_iov[0] = cur[0];
2844                 state->smb2.recv_iov[1] = cur[1];
2845                 state->smb2.recv_iov[2] = cur[2];
2846
2847                 tevent_req_done(req);
2848         }
2849
2850         if (defer) {
2851                 return NT_STATUS_RETRY;
2852         }
2853
2854         return NT_STATUS_OK;
2855 }
2856
2857 NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2858                           struct iovec **piov,
2859                           const struct smb2cli_req_expected_response *expected,
2860                           size_t num_expected)
2861 {
2862         struct smbXcli_req_state *state =
2863                 tevent_req_data(req,
2864                 struct smbXcli_req_state);
2865         NTSTATUS status;
2866         size_t body_size;
2867         bool found_status = false;
2868         bool found_size = false;
2869         size_t i;
2870
2871         if (piov != NULL) {
2872                 *piov = NULL;
2873         }
2874
2875         if (state->smb2.got_async) {
2876                 return STATUS_PENDING;
2877         }
2878
2879         if (tevent_req_is_nterror(req, &status)) {
2880                 for (i=0; i < num_expected; i++) {
2881                         if (NT_STATUS_EQUAL(status, expected[i].status)) {
2882                                 found_status = true;
2883                                 break;
2884                         }
2885                 }
2886
2887                 if (found_status) {
2888                         return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2889                 }
2890
2891                 return status;
2892         }
2893
2894         if (num_expected == 0) {
2895                 found_status = true;
2896                 found_size = true;
2897         }
2898
2899         status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
2900         body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
2901
2902         for (i=0; i < num_expected; i++) {
2903                 if (!NT_STATUS_EQUAL(status, expected[i].status)) {
2904                         continue;
2905                 }
2906
2907                 found_status = true;
2908                 if (expected[i].body_size == 0) {
2909                         found_size = true;
2910                         break;
2911                 }
2912
2913                 if (expected[i].body_size == body_size) {
2914                         found_size = true;
2915                         break;
2916                 }
2917         }
2918
2919         if (!found_status) {
2920                 return status;
2921         }
2922
2923         if (state->smb2.signing_skipped) {
2924                 if (num_expected > 0) {
2925                         return NT_STATUS_ACCESS_DENIED;
2926                 }
2927                 if (!NT_STATUS_IS_ERR(status)) {
2928                         return NT_STATUS_ACCESS_DENIED;
2929                 }
2930         }
2931
2932         if (!found_size) {
2933                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
2934         }
2935
2936         if (piov != NULL) {
2937                 *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
2938         }
2939
2940         return status;
2941 }
2942
2943 static const struct {
2944         enum protocol_types proto;
2945         const char *smb1_name;
2946 } smb1cli_prots[] = {
2947         {PROTOCOL_CORE,         "PC NETWORK PROGRAM 1.0"},
2948         {PROTOCOL_COREPLUS,     "MICROSOFT NETWORKS 1.03"},
2949         {PROTOCOL_LANMAN1,      "MICROSOFT NETWORKS 3.0"},
2950         {PROTOCOL_LANMAN1,      "LANMAN1.0"},
2951         {PROTOCOL_LANMAN2,      "LM1.2X002"},
2952         {PROTOCOL_LANMAN2,      "DOS LANMAN2.1"},
2953         {PROTOCOL_LANMAN2,      "LANMAN2.1"},
2954         {PROTOCOL_LANMAN2,      "Samba"},
2955         {PROTOCOL_NT1,          "NT LANMAN 1.0"},
2956         {PROTOCOL_NT1,          "NT LM 0.12"},
2957         {PROTOCOL_SMB2_02,      "SMB 2.002"},
2958         {PROTOCOL_SMB2_10,      "SMB 2.???"},
2959 };
2960
2961 static const struct {
2962         enum protocol_types proto;
2963         uint16_t smb2_dialect;
2964 } smb2cli_prots[] = {
2965         {PROTOCOL_SMB2_02,      SMB2_DIALECT_REVISION_202},
2966         {PROTOCOL_SMB2_10,      SMB2_DIALECT_REVISION_210},
2967         {PROTOCOL_SMB2_22,      SMB2_DIALECT_REVISION_222},
2968 };
2969
2970 struct smbXcli_negprot_state {
2971         struct smbXcli_conn *conn;
2972         struct tevent_context *ev;
2973         uint32_t timeout_msec;
2974         enum protocol_types min_protocol;
2975         enum protocol_types max_protocol;
2976
2977         struct {
2978                 uint8_t fixed[36];
2979                 uint8_t dyn[ARRAY_SIZE(smb2cli_prots)*2];
2980         } smb2;
2981 };
2982
2983 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
2984 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
2985 static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
2986 static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
2987 static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
2988 static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
2989                                                   TALLOC_CTX *frame,
2990                                                   uint8_t *inbuf);
2991
2992 struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
2993                                         struct tevent_context *ev,
2994                                         struct smbXcli_conn *conn,
2995                                         uint32_t timeout_msec,
2996                                         enum protocol_types min_protocol,
2997                                         enum protocol_types max_protocol)
2998 {
2999         struct tevent_req *req, *subreq;
3000         struct smbXcli_negprot_state *state;
3001
3002         req = tevent_req_create(mem_ctx, &state,
3003                                 struct smbXcli_negprot_state);
3004         if (req == NULL) {
3005                 return NULL;
3006         }
3007         state->conn = conn;
3008         state->ev = ev;
3009         state->timeout_msec = timeout_msec;
3010         state->min_protocol = min_protocol;
3011         state->max_protocol = max_protocol;
3012
3013         if (min_protocol == PROTOCOL_NONE) {
3014                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3015                 return tevent_req_post(req, ev);
3016         }
3017
3018         if (max_protocol == PROTOCOL_NONE) {
3019                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3020                 return tevent_req_post(req, ev);
3021         }
3022
3023         if (min_protocol > max_protocol) {
3024                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3025                 return tevent_req_post(req, ev);
3026         }
3027
3028         if ((min_protocol < PROTOCOL_SMB2_02) &&
3029             (max_protocol < PROTOCOL_SMB2_02)) {
3030                 /*
3031                  * SMB1 only...
3032                  */
3033                 conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
3034
3035                 subreq = smbXcli_negprot_smb1_subreq(state);
3036                 if (tevent_req_nomem(subreq, req)) {
3037                         return tevent_req_post(req, ev);
3038                 }
3039                 tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
3040                 return req;
3041         }
3042
3043         if ((min_protocol >= PROTOCOL_SMB2_02) &&
3044             (max_protocol >= PROTOCOL_SMB2_02)) {
3045                 /*
3046                  * SMB2 only...
3047                  */
3048                 conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3049
3050                 subreq = smbXcli_negprot_smb2_subreq(state);
3051                 if (tevent_req_nomem(subreq, req)) {
3052                         return tevent_req_post(req, ev);
3053                 }
3054                 tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
3055                 return req;
3056         }
3057
3058         /*
3059          * We send an SMB1 negprot with the SMB2 dialects
3060          * and expect a SMB1 or a SMB2 response.
3061          *
3062          * smbXcli_negprot_dispatch_incoming() will fix the
3063          * callback to match protocol of the response.
3064          */
3065         conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
3066
3067         subreq = smbXcli_negprot_smb1_subreq(state);
3068         if (tevent_req_nomem(subreq, req)) {
3069                 return tevent_req_post(req, ev);
3070         }
3071         tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
3072         return req;
3073 }
3074
3075 static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
3076 {
3077         struct tevent_req *req =
3078                 tevent_req_callback_data(subreq,
3079                 struct tevent_req);
3080         NTSTATUS status;
3081
3082         /*
3083          * we just want the low level error
3084          */
3085         status = tevent_req_simple_recv_ntstatus(subreq);
3086         TALLOC_FREE(subreq);
3087         if (tevent_req_nterror(req, status)) {
3088                 return;
3089         }
3090
3091         /* this should never happen */
3092         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3093 }
3094
3095 static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
3096 {
3097         size_t i;
3098         DATA_BLOB bytes = data_blob_null;
3099         uint8_t flags;
3100         uint16_t flags2;
3101