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