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