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