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