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