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