smbd: Use NT_STATUS_PENDING instead of STATUS_PENDING
[gd/samba-autobuild/.git] / source3 / smbd / smb2_server.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30 #include "../librpc/gen_ndr/krb5pac.h"
31 #include "lib/util/iov_buf.h"
32 #include "auth.h"
33 #include "libcli/smb/smbXcli_base.h"
34
35 #include "lib/crypto/gnutls_helpers.h"
36 #include <gnutls/gnutls.h>
37 #include <gnutls/crypto.h>
38
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_SMB2
41
42 static void smbd_smb2_connection_handler(struct tevent_context *ev,
43                                          struct tevent_fd *fde,
44                                          uint16_t flags,
45                                          void *private_data);
46 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
47
48 static const struct smbd_smb2_dispatch_table {
49         uint16_t opcode;
50         const char *name;
51         bool need_session;
52         bool need_tcon;
53         bool as_root;
54         uint16_t fileid_ofs;
55         bool allow_invalid_fileid;
56         bool modify;
57 } smbd_smb2_table[] = {
58 #define _OP(o) .opcode = o, .name = #o
59         {
60                 _OP(SMB2_OP_NEGPROT),
61                 .as_root = true,
62         },{
63                 _OP(SMB2_OP_SESSSETUP),
64                 .as_root = true,
65         },{
66                 _OP(SMB2_OP_LOGOFF),
67                 .need_session = true,
68                 .as_root = true,
69         },{
70                 _OP(SMB2_OP_TCON),
71                 .need_session = true,
72                 /*
73                  * This call needs to be run as root.
74                  *
75                  * smbd_smb2_request_process_tcon()
76                  * calls make_connection_snum(), which will call
77                  * change_to_user(), when needed.
78                  */
79                 .as_root = true,
80         },{
81                 _OP(SMB2_OP_TDIS),
82                 .need_session = true,
83                 .need_tcon = true,
84                 .as_root = true,
85         },{
86                 _OP(SMB2_OP_CREATE),
87                 .need_session = true,
88                 .need_tcon = true,
89         },{
90                 _OP(SMB2_OP_CLOSE),
91                 .need_session = true,
92                 .need_tcon = true,
93                 .fileid_ofs = 0x08,
94         },{
95                 _OP(SMB2_OP_FLUSH),
96                 .need_session = true,
97                 .need_tcon = true,
98                 .fileid_ofs = 0x08,
99         },{
100                 _OP(SMB2_OP_READ),
101                 .need_session = true,
102                 .need_tcon = true,
103                 .fileid_ofs = 0x10,
104         },{
105                 _OP(SMB2_OP_WRITE),
106                 .need_session = true,
107                 .need_tcon = true,
108                 .fileid_ofs = 0x10,
109                 .modify = true,
110         },{
111                 _OP(SMB2_OP_LOCK),
112                 .need_session = true,
113                 .need_tcon = true,
114                 .fileid_ofs = 0x08,
115         },{
116                 _OP(SMB2_OP_IOCTL),
117                 .need_session = true,
118                 .need_tcon = true,
119                 .fileid_ofs = 0x08,
120                 .allow_invalid_fileid = true,
121                 .modify = true,
122         },{
123                 _OP(SMB2_OP_CANCEL),
124                 .as_root = true,
125         },{
126                 _OP(SMB2_OP_KEEPALIVE),
127                 .as_root = true,
128         },{
129                 _OP(SMB2_OP_QUERY_DIRECTORY),
130                 .need_session = true,
131                 .need_tcon = true,
132                 .fileid_ofs = 0x08,
133         },{
134                 _OP(SMB2_OP_NOTIFY),
135                 .need_session = true,
136                 .need_tcon = true,
137                 .fileid_ofs = 0x08,
138         },{
139                 _OP(SMB2_OP_GETINFO),
140                 .need_session = true,
141                 .need_tcon = true,
142                 .fileid_ofs = 0x18,
143         },{
144                 _OP(SMB2_OP_SETINFO),
145                 .need_session = true,
146                 .need_tcon = true,
147                 .fileid_ofs = 0x10,
148                 .modify = true,
149         },{
150                 _OP(SMB2_OP_BREAK),
151                 .need_session = true,
152                 .need_tcon = true,
153                 /*
154                  * we do not set
155                  * .fileid_ofs here
156                  * as LEASE breaks does not
157                  * have a file id
158                  */
159         }
160 };
161
162 const char *smb2_opcode_name(uint16_t opcode)
163 {
164         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
165                 return "Bad SMB2 opcode";
166         }
167         return smbd_smb2_table[opcode].name;
168 }
169
170 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
171 {
172         const struct smbd_smb2_dispatch_table *ret = NULL;
173
174         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
175                 return NULL;
176         }
177
178         ret = &smbd_smb2_table[opcode];
179
180         SMB_ASSERT(ret->opcode == opcode);
181
182         return ret;
183 }
184
185 static void print_req_vectors(const struct smbd_smb2_request *req)
186 {
187         int i;
188
189         for (i = 0; i < req->in.vector_count; i++) {
190                 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
191                         (unsigned int)i,
192                         (unsigned int)req->in.vector[i].iov_len);
193         }
194         for (i = 0; i < req->out.vector_count; i++) {
195                 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
196                         (unsigned int)i,
197                         (unsigned int)req->out.vector[i].iov_len);
198         }
199 }
200
201 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
202 {
203         if (size < (4 + SMB2_HDR_BODY)) {
204                 return false;
205         }
206
207         if (IVAL(inbuf, 4) != SMB2_MAGIC) {
208                 return false;
209         }
210
211         return true;
212 }
213
214 bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
215 {
216         return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
217 }
218
219 static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
220                                      uint64_t expected_seq_low)
221 {
222         TALLOC_FREE(xconn->transport.fde);
223
224         xconn->smb2.credits.seq_low = expected_seq_low;
225         xconn->smb2.credits.seq_range = 1;
226         xconn->smb2.credits.granted = 1;
227         xconn->smb2.credits.max = lp_smb2_max_credits();
228         xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
229                                                    xconn->smb2.credits.max);
230         if (xconn->smb2.credits.bitmap == NULL) {
231                 return NT_STATUS_NO_MEMORY;
232         }
233
234         xconn->transport.fde = tevent_add_fd(
235                                         xconn->client->raw_ev_ctx,
236                                         xconn,
237                                         xconn->transport.sock,
238                                         TEVENT_FD_READ,
239                                         smbd_smb2_connection_handler,
240                                         xconn);
241         if (xconn->transport.fde == NULL) {
242                 return NT_STATUS_NO_MEMORY;
243         }
244
245         /* Ensure child is set to non-blocking mode */
246         set_blocking(xconn->transport.sock, false);
247         return NT_STATUS_OK;
248 }
249
250 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
251 #define _smb2_setlen(_buf,len) do { \
252         uint8_t *buf = (uint8_t *)_buf; \
253         buf[0] = 0; \
254         buf[1] = ((len)&0xFF0000)>>16; \
255         buf[2] = ((len)&0xFF00)>>8; \
256         buf[3] = (len)&0xFF; \
257 } while (0)
258
259 static bool smb2_setup_nbt_length(struct iovec *vector, int count)
260 {
261         ssize_t len;
262
263         if (count == 0) {
264                 return false;
265         }
266
267         len = iov_buflen(vector+1, count-1);
268
269         if ((len == -1) || (len > 0xFFFFFF)) {
270                 return false;
271         }
272
273         _smb2_setlen(vector[0].iov_base, len);
274         return true;
275 }
276
277 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
278 {
279         if (req->first_key.length > 0) {
280                 data_blob_clear_free(&req->first_key);
281         }
282         if (req->last_key.length > 0) {
283                 data_blob_clear_free(&req->last_key);
284         }
285         return 0;
286 }
287
288 void smb2_request_set_async_internal(struct smbd_smb2_request *req,
289                                      bool async_internal)
290 {
291         req->async_internal = async_internal;
292 }
293
294 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
295 {
296         TALLOC_CTX *mem_pool;
297         struct smbd_smb2_request *req;
298
299 #if 0
300         /* Enable this to find subtle valgrind errors. */
301         mem_pool = talloc_init("smbd_smb2_request_allocate");
302 #else
303         mem_pool = talloc_tos();
304 #endif
305         if (mem_pool == NULL) {
306                 return NULL;
307         }
308
309         req = talloc_zero(mem_pool, struct smbd_smb2_request);
310         if (req == NULL) {
311                 talloc_free(mem_pool);
312                 return NULL;
313         }
314         talloc_reparent(mem_pool, mem_ctx, req);
315 #if 0
316         TALLOC_FREE(mem_pool);
317 #endif
318
319         req->last_session_id = UINT64_MAX;
320         req->last_tid = UINT32_MAX;
321
322         talloc_set_destructor(req, smbd_smb2_request_destructor);
323
324         return req;
325 }
326
327 static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
328                                                NTTIME now,
329                                                uint8_t *buf,
330                                                size_t buflen,
331                                                struct smbd_smb2_request *req,
332                                                struct iovec **piov,
333                                                int *pnum_iov)
334 {
335         TALLOC_CTX *mem_ctx = req;
336         struct iovec *iov;
337         int num_iov = 1;
338         size_t taken = 0;
339         uint8_t *first_hdr = buf;
340         size_t verified_buflen = 0;
341         uint8_t *tf = NULL;
342         size_t tf_len = 0;
343
344         /*
345          * Note: index '0' is reserved for the transport protocol
346          */
347         iov = req->in._vector;
348
349         while (taken < buflen) {
350                 size_t len = buflen - taken;
351                 uint8_t *hdr = first_hdr + taken;
352                 struct iovec *cur;
353                 size_t full_size;
354                 size_t next_command_ofs;
355                 uint16_t body_size;
356                 uint8_t *body = NULL;
357                 uint32_t dyn_size;
358                 uint8_t *dyn = NULL;
359                 struct iovec *iov_alloc = NULL;
360
361                 if (iov != req->in._vector) {
362                         iov_alloc = iov;
363                 }
364
365                 if (verified_buflen > taken) {
366                         len = verified_buflen - taken;
367                 } else {
368                         tf = NULL;
369                         tf_len = 0;
370                 }
371
372                 if (len < 4) {
373                         DEBUG(10, ("%d bytes left, expected at least %d\n",
374                                    (int)len, 4));
375                         goto inval;
376                 }
377                 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
378                         struct smbXsrv_session *s = NULL;
379                         uint64_t uid;
380                         struct iovec tf_iov[2];
381                         NTSTATUS status;
382                         size_t enc_len;
383
384                         if (xconn->protocol < PROTOCOL_SMB2_24) {
385                                 DEBUG(10, ("Got SMB2_TRANSFORM header, "
386                                            "but dialect[0x%04X] is used\n",
387                                            xconn->smb2.server.dialect));
388                                 goto inval;
389                         }
390
391                         if (xconn->smb2.server.cipher == 0) {
392                                 DEBUG(10, ("Got SMB2_TRANSFORM header, "
393                                            "but not negotiated "
394                                            "client[0x%08X] server[0x%08X]\n",
395                                            xconn->smb2.client.capabilities,
396                                            xconn->smb2.server.capabilities));
397                                 goto inval;
398                         }
399
400                         if (len < SMB2_TF_HDR_SIZE) {
401                                 DEBUG(1, ("%d bytes left, expected at least %d\n",
402                                            (int)len, SMB2_TF_HDR_SIZE));
403                                 goto inval;
404                         }
405                         tf = hdr;
406                         tf_len = SMB2_TF_HDR_SIZE;
407                         taken += tf_len;
408
409                         hdr = first_hdr + taken;
410                         enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
411                         uid = BVAL(tf, SMB2_TF_SESSION_ID);
412
413                         if (len < SMB2_TF_HDR_SIZE + enc_len) {
414                                 DEBUG(1, ("%d bytes left, expected at least %d\n",
415                                            (int)len,
416                                            (int)(SMB2_TF_HDR_SIZE + enc_len)));
417                                 goto inval;
418                         }
419
420                         status = smb2srv_session_lookup_conn(xconn, uid, now,
421                                                              &s);
422                         if (s == NULL) {
423                                 DEBUG(1, ("invalid session[%llu] in "
424                                           "SMB2_TRANSFORM header\n",
425                                            (unsigned long long)uid));
426                                 TALLOC_FREE(iov_alloc);
427                                 return NT_STATUS_USER_SESSION_DELETED;
428                         }
429
430                         tf_iov[0].iov_base = (void *)tf;
431                         tf_iov[0].iov_len = tf_len;
432                         tf_iov[1].iov_base = (void *)hdr;
433                         tf_iov[1].iov_len = enc_len;
434
435                         status = smb2_signing_decrypt_pdu(s->global->decryption_key,
436                                                           xconn->smb2.server.cipher,
437                                                           tf_iov, 2);
438                         if (!NT_STATUS_IS_OK(status)) {
439                                 TALLOC_FREE(iov_alloc);
440                                 return status;
441                         }
442
443                         verified_buflen = taken + enc_len;
444                         len = enc_len;
445                 }
446
447                 /*
448                  * We need the header plus the body length field
449                  */
450
451                 if (len < SMB2_HDR_BODY + 2) {
452
453                         if ((len == 5) &&
454                             (IVAL(hdr, 0) == SMB_SUICIDE_PACKET) &&
455                             lp_parm_bool(-1, "smbd", "suicide mode", false)) {
456                                 uint8_t exitcode = CVAL(hdr, 4);
457                                 DBG_WARNING("SUICIDE: Exiting immediately "
458                                             "with code %"PRIu8"\n",
459                                             exitcode);
460                                 exit(exitcode);
461                         }
462
463                         DEBUG(10, ("%d bytes left, expected at least %d\n",
464                                    (int)len, SMB2_HDR_BODY));
465                         goto inval;
466                 }
467                 if (IVAL(hdr, 0) != SMB2_MAGIC) {
468                         DEBUG(10, ("Got non-SMB2 PDU: %x\n",
469                                    IVAL(hdr, 0)));
470                         goto inval;
471                 }
472                 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
473                         DEBUG(10, ("Got HDR len %d, expected %d\n",
474                                    SVAL(hdr, 4), SMB2_HDR_BODY));
475                         goto inval;
476                 }
477
478                 full_size = len;
479                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
480                 body_size = SVAL(hdr, SMB2_HDR_BODY);
481
482                 if (next_command_ofs != 0) {
483                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
484                                 goto inval;
485                         }
486                         if (next_command_ofs > full_size) {
487                                 goto inval;
488                         }
489                         full_size = next_command_ofs;
490                 }
491                 if (body_size < 2) {
492                         goto inval;
493                 }
494                 body_size &= 0xfffe;
495
496                 if (body_size > (full_size - SMB2_HDR_BODY)) {
497                         /*
498                          * let the caller handle the error
499                          */
500                         body_size = full_size - SMB2_HDR_BODY;
501                 }
502                 body = hdr + SMB2_HDR_BODY;
503                 dyn = body + body_size;
504                 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
505
506                 if (num_iov >= ARRAY_SIZE(req->in._vector)) {
507                         struct iovec *iov_tmp = NULL;
508
509                         iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
510                                                  struct iovec,
511                                                  num_iov +
512                                                  SMBD_SMB2_NUM_IOV_PER_REQ);
513                         if (iov_tmp == NULL) {
514                                 TALLOC_FREE(iov_alloc);
515                                 return NT_STATUS_NO_MEMORY;
516                         }
517
518                         if (iov_alloc == NULL) {
519                                 memcpy(iov_tmp,
520                                        req->in._vector,
521                                        sizeof(req->in._vector));
522                         }
523
524                         iov = iov_tmp;
525                 }
526                 cur = &iov[num_iov];
527                 num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
528
529                 cur[SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
530                 cur[SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
531                 cur[SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
532                 cur[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
533                 cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
534                 cur[SMBD_SMB2_BODY_IOV_OFS].iov_len  = body_size;
535                 cur[SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
536                 cur[SMBD_SMB2_DYN_IOV_OFS].iov_len   = dyn_size;
537
538                 taken += full_size;
539         }
540
541         *piov = iov;
542         *pnum_iov = num_iov;
543         return NT_STATUS_OK;
544
545 inval:
546         if (iov != req->in._vector) {
547                 TALLOC_FREE(iov);
548         }
549         return NT_STATUS_INVALID_PARAMETER;
550 }
551
552 static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
553                                          const uint8_t *_inpdu, size_t size,
554                                          struct smbd_smb2_request **_req)
555 {
556         struct smbd_server_connection *sconn = xconn->client->sconn;
557         struct smbd_smb2_request *req;
558         uint32_t protocol_version;
559         uint8_t *inpdu = NULL;
560         const uint8_t *inhdr = NULL;
561         uint16_t cmd;
562         uint32_t next_command_ofs;
563         NTSTATUS status;
564         NTTIME now;
565
566         if (size < (SMB2_HDR_BODY + 2)) {
567                 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
568                 return NT_STATUS_INVALID_PARAMETER;
569         }
570
571         inhdr = _inpdu;
572
573         protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
574         if (protocol_version != SMB2_MAGIC) {
575                 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
576                          protocol_version));
577                 return NT_STATUS_INVALID_PARAMETER;
578         }
579
580         cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
581         if (cmd != SMB2_OP_NEGPROT) {
582                 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
583                          cmd));
584                 return NT_STATUS_INVALID_PARAMETER;
585         }
586
587         next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
588         if (next_command_ofs != 0) {
589                 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
590                          next_command_ofs));
591                 return NT_STATUS_INVALID_PARAMETER;
592         }
593
594         req = smbd_smb2_request_allocate(xconn);
595         if (req == NULL) {
596                 return NT_STATUS_NO_MEMORY;
597         }
598         req->sconn = sconn;
599         req->xconn = xconn;
600
601         inpdu = talloc_memdup(req, _inpdu, size);
602         if (inpdu == NULL) {
603                 return NT_STATUS_NO_MEMORY;
604         }
605
606         req->request_time = timeval_current();
607         now = timeval_to_nttime(&req->request_time);
608
609         status = smbd_smb2_inbuf_parse_compound(xconn,
610                                                 now,
611                                                 inpdu,
612                                                 size,
613                                                 req, &req->in.vector,
614                                                 &req->in.vector_count);
615         if (!NT_STATUS_IS_OK(status)) {
616                 TALLOC_FREE(req);
617                 return status;
618         }
619
620         req->current_idx = 1;
621
622         *_req = req;
623         return NT_STATUS_OK;
624 }
625
626 static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
627                                           uint64_t message_id, uint64_t seq_id)
628 {
629         struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
630         unsigned int offset;
631         uint64_t seq_tmp;
632
633         seq_tmp = xconn->smb2.credits.seq_low;
634         if (seq_id < seq_tmp) {
635                 DBGC_ERR(DBGC_SMB2_CREDITS,
636                         "smb2_validate_sequence_number: bad message_id "
637                         "%llu (sequence id %llu) "
638                         "(granted = %u, low = %llu, range = %u)\n",
639                         (unsigned long long)message_id,
640                         (unsigned long long)seq_id,
641                         (unsigned int)xconn->smb2.credits.granted,
642                         (unsigned long long)xconn->smb2.credits.seq_low,
643                         (unsigned int)xconn->smb2.credits.seq_range);
644                 return false;
645         }
646
647         seq_tmp += xconn->smb2.credits.seq_range;
648         if (seq_id >= seq_tmp) {
649                 DBGC_ERR(DBGC_SMB2_CREDITS,
650                         "smb2_validate_sequence_number: bad message_id "
651                         "%llu (sequence id %llu) "
652                         "(granted = %u, low = %llu, range = %u)\n",
653                         (unsigned long long)message_id,
654                         (unsigned long long)seq_id,
655                         (unsigned int)xconn->smb2.credits.granted,
656                         (unsigned long long)xconn->smb2.credits.seq_low,
657                         (unsigned int)xconn->smb2.credits.seq_range);
658                 return false;
659         }
660
661         offset = seq_id % xconn->smb2.credits.max;
662
663         if (bitmap_query(credits_bm, offset)) {
664                 DBGC_ERR(DBGC_SMB2_CREDITS,
665                         "smb2_validate_sequence_number: duplicate message_id "
666                         "%llu (sequence id %llu) "
667                         "(granted = %u, low = %llu, range = %u) "
668                         "(bm offset %u)\n",
669                         (unsigned long long)message_id,
670                         (unsigned long long)seq_id,
671                         (unsigned int)xconn->smb2.credits.granted,
672                         (unsigned long long)xconn->smb2.credits.seq_low,
673                         (unsigned int)xconn->smb2.credits.seq_range,
674                         offset);
675                 return false;
676         }
677
678         /* Mark the message_ids as seen in the bitmap. */
679         bitmap_set(credits_bm, offset);
680
681         if (seq_id != xconn->smb2.credits.seq_low) {
682                 return true;
683         }
684
685         /*
686          * Move the window forward by all the message_id's
687          * already seen.
688          */
689         while (bitmap_query(credits_bm, offset)) {
690                 DBGC_DEBUG(DBGC_SMB2_CREDITS,
691                           "smb2_validate_sequence_number: clearing "
692                           "id %llu (position %u) from bitmap\n",
693                           (unsigned long long)(xconn->smb2.credits.seq_low),
694                           offset);
695                 bitmap_clear(credits_bm, offset);
696
697                 xconn->smb2.credits.seq_low += 1;
698                 xconn->smb2.credits.seq_range -= 1;
699                 offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
700         }
701
702         return true;
703 }
704
705 static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
706                                      const uint8_t *inhdr)
707 {
708         uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
709         uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
710         uint16_t credit_charge = 1;
711         uint64_t i;
712
713         if (opcode == SMB2_OP_CANCEL) {
714                 /* SMB2_CANCEL requests by definition resend messageids. */
715                 return true;
716         }
717
718         if (xconn->smb2.credits.multicredit) {
719                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
720                 credit_charge = MAX(credit_charge, 1);
721         }
722
723         DEBUGC(11,
724                    DBGC_SMB2_CREDITS,
725                    ("smb2_validate_message_id: mid %llu (charge %llu), "
726                    "credits_granted %llu, "
727                    "seqnum low/range: %llu/%llu\n",
728                    (unsigned long long) message_id,
729                    (unsigned long long) credit_charge,
730                    (unsigned long long) xconn->smb2.credits.granted,
731                    (unsigned long long) xconn->smb2.credits.seq_low,
732                    (unsigned long long) xconn->smb2.credits.seq_range));
733
734         if (xconn->smb2.credits.granted < credit_charge) {
735                 DBGC_ERR(DBGC_SMB2_CREDITS,
736                           "smb2_validate_message_id: client used more "
737                           "credits than granted, mid %llu, charge %llu, "
738                           "credits_granted %llu, "
739                           "seqnum low/range: %llu/%llu\n",
740                           (unsigned long long) message_id,
741                           (unsigned long long) credit_charge,
742                           (unsigned long long) xconn->smb2.credits.granted,
743                           (unsigned long long) xconn->smb2.credits.seq_low,
744                           (unsigned long long) xconn->smb2.credits.seq_range);
745                 return false;
746         }
747
748         /*
749          * now check the message ids
750          *
751          * for multi-credit requests we need to check all current mid plus
752          * the implicit mids caused by the credit charge
753          * e.g. current mid = 15, charge 5 => mark 15-19 as used
754          */
755
756         for (i = 0; i <= (credit_charge-1); i++) {
757                 uint64_t id = message_id + i;
758                 bool ok;
759
760                 DEBUGC(11,
761                            DBGC_SMB2_CREDITS,
762                            ("Iterating mid %llu charge %u (sequence %llu)\n",
763                            (unsigned long long)message_id,
764                            credit_charge,
765                            (unsigned long long)id));
766
767                 ok = smb2_validate_sequence_number(xconn, message_id, id);
768                 if (!ok) {
769                         return false;
770                 }
771         }
772
773         /* substract used credits */
774         xconn->smb2.credits.granted -= credit_charge;
775
776         return true;
777 }
778
779 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
780 {
781         int count;
782         int idx;
783
784         count = req->in.vector_count;
785
786         if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
787                 /* It's not a SMB2 request */
788                 return NT_STATUS_INVALID_PARAMETER;
789         }
790
791         for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
792                 struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
793                 struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
794                 const uint8_t *inhdr = NULL;
795
796                 if (hdr->iov_len != SMB2_HDR_BODY) {
797                         return NT_STATUS_INVALID_PARAMETER;
798                 }
799
800                 if (body->iov_len < 2) {
801                         return NT_STATUS_INVALID_PARAMETER;
802                 }
803
804                 inhdr = (const uint8_t *)hdr->iov_base;
805
806                 /* Check the SMB2 header */
807                 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
808                         return NT_STATUS_INVALID_PARAMETER;
809                 }
810
811                 if (!smb2_validate_message_id(req->xconn, inhdr)) {
812                         return NT_STATUS_INVALID_PARAMETER;
813                 }
814         }
815
816         return NT_STATUS_OK;
817 }
818
819 static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
820                                       const struct iovec *in_vector,
821                                       struct iovec *out_vector)
822 {
823         const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
824         uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
825         uint16_t credit_charge = 1;
826         uint16_t credits_requested;
827         uint32_t out_flags;
828         uint16_t cmd;
829         NTSTATUS out_status;
830         uint16_t credits_granted = 0;
831         uint64_t credits_possible;
832         uint16_t current_max_credits;
833
834         /*
835          * first we grant only 1/16th of the max range.
836          *
837          * Windows also starts with the 1/16th and then grants
838          * more later. I was only able to trigger higher
839          * values, when using a very high credit charge.
840          *
841          * TODO: scale up depending on load, free memory
842          *       or other stuff.
843          *       Maybe also on the relationship between number
844          *       of requests and the used sequence number.
845          *       Which means we would grant more credits
846          *       for client which use multi credit requests.
847          *
848          * The above is what Windows Server < 2016 is doing,
849          * but new servers use all credits (8192 by default).
850          */
851         current_max_credits = xconn->smb2.credits.max;
852         current_max_credits = MAX(current_max_credits, 1);
853
854         if (xconn->smb2.credits.multicredit) {
855                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
856                 credit_charge = MAX(credit_charge, 1);
857         }
858
859         cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
860         credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
861         credits_requested = MAX(credits_requested, 1);
862         out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
863         out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
864
865         SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
866
867         if (xconn->smb2.credits.max < credit_charge) {
868                 smbd_server_connection_terminate(xconn,
869                         "client error: credit charge > max credits\n");
870                 return;
871         }
872
873         if (out_flags & SMB2_HDR_FLAG_ASYNC) {
874                 /*
875                  * In case we already send an async interim
876                  * response, we should not grant
877                  * credits on the final response.
878                  */
879                 credits_granted = 0;
880         } else {
881                 uint16_t additional_possible =
882                         xconn->smb2.credits.max - credit_charge;
883                 uint16_t additional_max = 0;
884                 uint16_t additional_credits = credits_requested - 1;
885
886                 switch (cmd) {
887                 case SMB2_OP_NEGPROT:
888                         break;
889                 case SMB2_OP_SESSSETUP:
890                         /*
891                          * Windows 2012 RC1 starts to grant
892                          * additional credits
893                          * with a successful session setup
894                          */
895                         if (NT_STATUS_IS_OK(out_status)) {
896                                 additional_max = xconn->smb2.credits.max;
897                         }
898                         break;
899                 default:
900                         /*
901                          * Windows Server < 2016 and older Samba versions
902                          * used to only grant additional credits in
903                          * chunks of 32 credits.
904                          *
905                          * But we match Windows Server 2016 and grant
906                          * all credits as requested.
907                          */
908                         additional_max = xconn->smb2.credits.max;
909                         break;
910                 }
911
912                 additional_max = MIN(additional_max, additional_possible);
913                 additional_credits = MIN(additional_credits, additional_max);
914
915                 credits_granted = credit_charge + additional_credits;
916         }
917
918         /*
919          * sequence numbers should not wrap
920          *
921          * 1. calculate the possible credits until
922          *    the sequence numbers start to wrap on 64-bit.
923          *
924          * 2. UINT64_MAX is used for Break Notifications.
925          *
926          * 2. truncate the possible credits to the maximum
927          *    credits we want to grant to the client in total.
928          *
929          * 3. remove the range we'll already granted to the client
930          *    this makes sure the client consumes the lowest sequence
931          *    number, before we can grant additional credits.
932          */
933         credits_possible = UINT64_MAX - xconn->smb2.credits.seq_low;
934         if (credits_possible > 0) {
935                 /* remove UINT64_MAX */
936                 credits_possible -= 1;
937         }
938         credits_possible = MIN(credits_possible, current_max_credits);
939         credits_possible -= xconn->smb2.credits.seq_range;
940
941         credits_granted = MIN(credits_granted, credits_possible);
942
943         SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
944         xconn->smb2.credits.granted += credits_granted;
945         xconn->smb2.credits.seq_range += credits_granted;
946
947         DBGC_DEBUG(DBGC_SMB2_CREDITS,
948                 "smb2_set_operation_credit: requested %u, charge %u, "
949                 "granted %u, current possible/max %u/%u, "
950                 "total granted/max/low/range %u/%u/%llu/%u\n",
951                 (unsigned int)credits_requested,
952                 (unsigned int)credit_charge,
953                 (unsigned int)credits_granted,
954                 (unsigned int)credits_possible,
955                 (unsigned int)current_max_credits,
956                 (unsigned int)xconn->smb2.credits.granted,
957                 (unsigned int)xconn->smb2.credits.max,
958                 (unsigned long long)xconn->smb2.credits.seq_low,
959                 (unsigned int)xconn->smb2.credits.seq_range);
960 }
961
962 static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
963                                 struct smbd_smb2_request *outreq)
964 {
965         int count, idx;
966         uint16_t total_credits = 0;
967
968         count = outreq->out.vector_count;
969
970         for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
971                 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
972                 struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
973                 uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
974
975                 smb2_set_operation_credit(outreq->xconn, inhdr_v, outhdr_v);
976
977                 /* To match Windows, count up what we
978                    just granted. */
979                 total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
980                 /* Set to zero in all but the last reply. */
981                 if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
982                         SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
983                 } else {
984                         SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
985                 }
986         }
987 }
988
989 DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size)
990 {
991         if (req->current_idx <= 1) {
992                 if (size <= sizeof(req->out._body)) {
993                         return data_blob_const(req->out._body, size);
994                 }
995         }
996
997         return data_blob_talloc(req, NULL, size);
998 }
999
1000 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
1001 {
1002         struct smbXsrv_connection *xconn = req->xconn;
1003         TALLOC_CTX *mem_ctx;
1004         struct iovec *vector;
1005         int count;
1006         int idx;
1007         bool ok;
1008
1009         count = req->in.vector_count;
1010         if (count <= ARRAY_SIZE(req->out._vector)) {
1011                 mem_ctx = req;
1012                 vector = req->out._vector;
1013         } else {
1014                 vector = talloc_zero_array(req, struct iovec, count);
1015                 if (vector == NULL) {
1016                         return NT_STATUS_NO_MEMORY;
1017                 }
1018                 mem_ctx = vector;
1019         }
1020
1021         vector[0].iov_base      = req->out.nbt_hdr;
1022         vector[0].iov_len       = 4;
1023         SIVAL(req->out.nbt_hdr, 0, 0);
1024
1025         for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
1026                 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
1027                 const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
1028                 uint8_t *outhdr = NULL;
1029                 uint8_t *outbody = NULL;
1030                 uint32_t next_command_ofs = 0;
1031                 struct iovec *current = &vector[idx];
1032
1033                 if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
1034                         /* we have a next command -
1035                          * setup for the error case. */
1036                         next_command_ofs = SMB2_HDR_BODY + 9;
1037                 }
1038
1039                 if (idx == 1) {
1040                         outhdr = req->out._hdr;
1041                 } else {
1042                         outhdr = talloc_zero_array(mem_ctx, uint8_t,
1043                                                    OUTVEC_ALLOC_SIZE);
1044                         if (outhdr == NULL) {
1045                                 return NT_STATUS_NO_MEMORY;
1046                         }
1047                 }
1048
1049                 outbody = outhdr + SMB2_HDR_BODY;
1050
1051                 /*
1052                  * SMBD_SMB2_TF_IOV_OFS might be used later
1053                  */
1054                 current[SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
1055                 current[SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
1056
1057                 current[SMBD_SMB2_HDR_IOV_OFS].iov_base  = (void *)outhdr;
1058                 current[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
1059
1060                 current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
1061                 current[SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
1062
1063                 current[SMBD_SMB2_DYN_IOV_OFS].iov_base  = NULL;
1064                 current[SMBD_SMB2_DYN_IOV_OFS].iov_len   = 0;
1065
1066                 /* setup the SMB2 header */
1067                 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID,     SMB2_MAGIC);
1068                 SSVAL(outhdr, SMB2_HDR_LENGTH,          SMB2_HDR_BODY);
1069                 SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1070                       SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1071                 SIVAL(outhdr, SMB2_HDR_STATUS,
1072                       NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1073                 SSVAL(outhdr, SMB2_HDR_OPCODE,
1074                       SVAL(inhdr, SMB2_HDR_OPCODE));
1075                 SIVAL(outhdr, SMB2_HDR_FLAGS,
1076                       IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1077                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND,    next_command_ofs);
1078                 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1079                       BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1080                 SIVAL(outhdr, SMB2_HDR_PID,
1081                       IVAL(inhdr, SMB2_HDR_PID));
1082                 SIVAL(outhdr, SMB2_HDR_TID,
1083                       IVAL(inhdr, SMB2_HDR_TID));
1084                 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1085                       BVAL(inhdr, SMB2_HDR_SESSION_ID));
1086                 memcpy(outhdr + SMB2_HDR_SIGNATURE,
1087                        inhdr + SMB2_HDR_SIGNATURE, 16);
1088
1089                 /* setup error body header */
1090                 SSVAL(outbody, 0x00, 0x08 + 1);
1091                 SSVAL(outbody, 0x02, 0);
1092                 SIVAL(outbody, 0x04, 0);
1093         }
1094
1095         req->out.vector = vector;
1096         req->out.vector_count = count;
1097
1098         /* setup the length of the NBT packet */
1099         ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1100         if (!ok) {
1101                 return NT_STATUS_INVALID_PARAMETER_MIX;
1102         }
1103
1104         DLIST_ADD_END(xconn->smb2.requests, req);
1105
1106         return NT_STATUS_OK;
1107 }
1108
1109 void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
1110                                              NTSTATUS status)
1111 {
1112         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
1113                 return;
1114         }
1115
1116         xconn->transport.status = status;
1117         TALLOC_FREE(xconn->transport.fde);
1118         if (xconn->transport.sock != -1) {
1119                 xconn->transport.sock = -1;
1120         }
1121         DO_PROFILE_INC(disconnect);
1122 }
1123
1124 static size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
1125 {
1126         struct smbXsrv_connection *xconn = NULL;
1127         size_t num_ok = 0;
1128
1129         for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1130                 if (NT_STATUS_IS_OK(xconn->transport.status)) {
1131                         num_ok++;
1132                 }
1133         }
1134
1135         return num_ok;
1136 }
1137
1138 struct smbXsrv_connection_shutdown_state {
1139         struct tevent_queue *wait_queue;
1140 };
1141
1142 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
1143
1144 static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
1145                                         struct tevent_context *ev,
1146                                         struct smbXsrv_connection *xconn)
1147 {
1148         struct tevent_req *req = NULL;
1149         struct smbXsrv_connection_shutdown_state *state = NULL;
1150         struct tevent_req *subreq = NULL;
1151         size_t len = 0;
1152         struct smbd_smb2_request *preq = NULL;
1153         NTSTATUS status;
1154
1155         /*
1156          * The caller should have called
1157          * smbXsrv_connection_disconnect_transport() before.
1158          */
1159         SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
1160
1161         req = tevent_req_create(mem_ctx, &state,
1162                                 struct smbXsrv_connection_shutdown_state);
1163         if (req == NULL) {
1164                 return NULL;
1165         }
1166
1167         status = smbXsrv_session_disconnect_xconn(xconn);
1168         if (tevent_req_nterror(req, status)) {
1169                 return tevent_req_post(req, ev);
1170         }
1171
1172         state->wait_queue = tevent_queue_create(state, "smbXsrv_connection_shutdown_queue");
1173         if (tevent_req_nomem(state->wait_queue, req)) {
1174                 return tevent_req_post(req, ev);
1175         }
1176
1177         for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next) {
1178                 /*
1179                  * The connection is gone so we
1180                  * don't need to take care of
1181                  * any crypto
1182                  */
1183                 preq->session = NULL;
1184                 preq->do_signing = false;
1185                 preq->do_encryption = false;
1186                 preq->preauth = NULL;
1187
1188                 if (preq->subreq != NULL) {
1189                         tevent_req_cancel(preq->subreq);
1190                 }
1191
1192                 /*
1193                  * Now wait until the request is finished.
1194                  *
1195                  * We don't set a callback, as we just want to block the
1196                  * wait queue and the talloc_free() of the request will
1197                  * remove the item from the wait queue.
1198                  */
1199                 subreq = tevent_queue_wait_send(preq, ev, state->wait_queue);
1200                 if (tevent_req_nomem(subreq, req)) {
1201                         return tevent_req_post(req, ev);
1202                 }
1203         }
1204
1205         len = tevent_queue_length(state->wait_queue);
1206         if (len == 0) {
1207                 tevent_req_done(req);
1208                 return tevent_req_post(req, ev);
1209         }
1210
1211         /*
1212          * Now we add our own waiter to the end of the queue,
1213          * this way we get notified when all pending requests are finished
1214          * and send to the socket.
1215          */
1216         subreq = tevent_queue_wait_send(state, ev, state->wait_queue);
1217         if (tevent_req_nomem(subreq, req)) {
1218                 return tevent_req_post(req, ev);
1219         }
1220         tevent_req_set_callback(subreq, smbXsrv_connection_shutdown_wait_done, req);
1221
1222         return req;
1223 }
1224
1225 static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
1226 {
1227         struct tevent_req *req =
1228                 tevent_req_callback_data(subreq,
1229                 struct tevent_req);
1230
1231         tevent_queue_wait_recv(subreq);
1232         TALLOC_FREE(subreq);
1233
1234         tevent_req_done(req);
1235 }
1236
1237 static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
1238 {
1239         return tevent_req_simple_recv_ntstatus(req);
1240 }
1241
1242 static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
1243 {
1244         struct smbXsrv_connection *xconn =
1245                 tevent_req_callback_data(subreq,
1246                 struct smbXsrv_connection);
1247         struct smbXsrv_client *client = xconn->client;
1248         NTSTATUS status;
1249
1250         status = smbXsrv_connection_shutdown_recv(subreq);
1251         if (!NT_STATUS_IS_OK(status)) {
1252                 exit_server("smbXsrv_connection_shutdown_recv failed");
1253         }
1254
1255         DLIST_REMOVE(client->connections, xconn);
1256         TALLOC_FREE(xconn);
1257 }
1258
1259 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
1260                                          const char *reason,
1261                                          const char *location)
1262 {
1263         struct smbXsrv_client *client = xconn->client;
1264         size_t num_ok = 0;
1265
1266         /*
1267          * Make sure that no new request will be able to use this session.
1268          *
1269          * smbXsrv_connection_disconnect_transport() might be called already,
1270          * but calling it again is a no-op.
1271          */
1272         smbXsrv_connection_disconnect_transport(xconn,
1273                                         NT_STATUS_CONNECTION_DISCONNECTED);
1274
1275         num_ok = smbXsrv_client_valid_connections(client);
1276
1277         DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1278                   smbXsrv_connection_dbg(xconn), num_ok,
1279                   reason, location);
1280
1281         if (num_ok != 0) {
1282                 struct tevent_req *subreq = NULL;
1283
1284                 subreq = smbXsrv_connection_shutdown_send(client,
1285                                                           client->raw_ev_ctx,
1286                                                           xconn);
1287                 if (subreq == NULL) {
1288                         exit_server("smbXsrv_connection_shutdown_send failed");
1289                 }
1290                 tevent_req_set_callback(subreq,
1291                                         smbd_server_connection_terminate_done,
1292                                         xconn);
1293                 return;
1294         }
1295
1296         /*
1297          * The last connection was disconnected
1298          */
1299         exit_server_cleanly(reason);
1300 }
1301
1302 static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1303                         struct iovec *outvec,
1304                         const struct iovec *srcvec)
1305 {
1306         const uint8_t *srctf;
1307         size_t srctf_len;
1308         const uint8_t *srchdr;
1309         size_t srchdr_len;
1310         const uint8_t *srcbody;
1311         size_t srcbody_len;
1312         const uint8_t *expected_srcbody;
1313         const uint8_t *srcdyn;
1314         size_t srcdyn_len;
1315         const uint8_t *expected_srcdyn;
1316         uint8_t *dsttf;
1317         uint8_t *dsthdr;
1318         uint8_t *dstbody;
1319         uint8_t *dstdyn;
1320
1321         srctf  = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1322         srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1323         srchdr  = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1324         srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1325         srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1326         srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1327         expected_srcbody = srchdr + SMB2_HDR_BODY;
1328         srcdyn  = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1329         srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1330         expected_srcdyn = srcbody + 8;
1331
1332         if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1333                 return false;
1334         }
1335
1336         if (srchdr_len != SMB2_HDR_BODY) {
1337                 return false;
1338         }
1339
1340         if (srctf_len == SMB2_TF_HDR_SIZE) {
1341                 dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1342                 if (dsttf == NULL) {
1343                         return false;
1344                 }
1345         } else {
1346                 dsttf = NULL;
1347         }
1348         outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1349         outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1350
1351         /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1352          * be allocated with size OUTVEC_ALLOC_SIZE. */
1353
1354         dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1355         if (dsthdr == NULL) {
1356                 return false;
1357         }
1358         outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1359         outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1360
1361         /*
1362          * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1363          * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1364          * then duplicate this. Else use talloc_memdup().
1365          */
1366
1367         if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1368                 dstbody = dsthdr + SMB2_HDR_BODY;
1369         } else {
1370                 dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1371                 if (dstbody == NULL) {
1372                         return false;
1373                 }
1374         }
1375         outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1376         outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1377
1378         /*
1379          * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1380          * pointing to
1381          * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1382          * then duplicate this. Else use talloc_memdup().
1383          */
1384
1385         if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1386                 dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1387         } else if (srcdyn == NULL) {
1388                 dstdyn = NULL;
1389         } else {
1390                 dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1391                 if (dstdyn == NULL) {
1392                         return false;
1393                 }
1394         }
1395         outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1396         outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1397
1398         return true;
1399 }
1400
1401 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1402 {
1403         struct smbd_smb2_request *newreq = NULL;
1404         struct iovec *outvec = NULL;
1405         int count = req->out.vector_count;
1406         int i;
1407         bool ok;
1408
1409         newreq = smbd_smb2_request_allocate(req->xconn);
1410         if (!newreq) {
1411                 return NULL;
1412         }
1413
1414         newreq->sconn = req->sconn;
1415         newreq->xconn = req->xconn;
1416         newreq->session = req->session;
1417         newreq->do_encryption = req->do_encryption;
1418         newreq->do_signing = req->do_signing;
1419         newreq->current_idx = req->current_idx;
1420
1421         outvec = talloc_zero_array(newreq, struct iovec, count);
1422         if (!outvec) {
1423                 TALLOC_FREE(newreq);
1424                 return NULL;
1425         }
1426         newreq->out.vector = outvec;
1427         newreq->out.vector_count = count;
1428
1429         /* Setup the outvec's identically to req. */
1430         outvec[0].iov_base = newreq->out.nbt_hdr;
1431         outvec[0].iov_len = 4;
1432         memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1433
1434         /* Setup the vectors identically to the ones in req. */
1435         for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1436                 if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1437                         break;
1438                 }
1439         }
1440
1441         if (i < count) {
1442                 /* Alloc failed. */
1443                 TALLOC_FREE(newreq);
1444                 return NULL;
1445         }
1446
1447         ok = smb2_setup_nbt_length(newreq->out.vector,
1448                                    newreq->out.vector_count);
1449         if (!ok) {
1450                 TALLOC_FREE(newreq);
1451                 return NULL;
1452         }
1453
1454         return newreq;
1455 }
1456
1457 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
1458 {
1459         struct smbXsrv_connection *xconn = req->xconn;
1460         int first_idx = 1;
1461         struct iovec *firsttf = NULL;
1462         struct iovec *outhdr_v = NULL;
1463         uint8_t *outhdr = NULL;
1464         struct smbd_smb2_request *nreq = NULL;
1465         NTSTATUS status;
1466         bool ok;
1467
1468         /* Create a new smb2 request we'll use
1469            for the interim return. */
1470         nreq = dup_smb2_req(req);
1471         if (!nreq) {
1472                 return NT_STATUS_NO_MEMORY;
1473         }
1474
1475         /* Lose the last X out vectors. They're the
1476            ones we'll be using for the async reply. */
1477         nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
1478
1479         ok = smb2_setup_nbt_length(nreq->out.vector,
1480                                    nreq->out.vector_count);
1481         if (!ok) {
1482                 return NT_STATUS_INVALID_PARAMETER_MIX;
1483         }
1484
1485         /* Step back to the previous reply. */
1486         nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
1487         firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
1488         outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
1489         outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
1490         /* And end the chain. */
1491         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
1492
1493         /* Calculate outgoing credits */
1494         smb2_calculate_credits(req, nreq);
1495
1496         if (DEBUGLEVEL >= 10) {
1497                 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1498                         (unsigned int)nreq->current_idx );
1499                 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1500                         (unsigned int)nreq->out.vector_count );
1501                 print_req_vectors(nreq);
1502         }
1503
1504         /*
1505          * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1506          * we need to sign/encrypt here with the last/first key we remembered
1507          */
1508         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
1509                 struct smb2_signing_key key = {
1510                         .blob = req->first_key,
1511                 };
1512                 status = smb2_signing_encrypt_pdu(&key,
1513                                         xconn->smb2.server.cipher,
1514                                         firsttf,
1515                                         nreq->out.vector_count - first_idx);
1516                 smb2_signing_key_destructor(&key);
1517                 if (!NT_STATUS_IS_OK(status)) {
1518                         return status;
1519                 }
1520         } else if (req->last_key.length > 0) {
1521                 struct smb2_signing_key key = {
1522                         .blob = req->last_key,
1523                 };
1524
1525                 status = smb2_signing_sign_pdu(&key,
1526                                                xconn->protocol,
1527                                                outhdr_v,
1528                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1529                 smb2_signing_key_destructor(&key);
1530                 if (!NT_STATUS_IS_OK(status)) {
1531                         return status;
1532                 }
1533         }
1534
1535         nreq->queue_entry.mem_ctx = nreq;
1536         nreq->queue_entry.vector = nreq->out.vector;
1537         nreq->queue_entry.count = nreq->out.vector_count;
1538         DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
1539         xconn->smb2.send_queue_len++;
1540
1541         status = smbd_smb2_flush_send_queue(xconn);
1542         if (!NT_STATUS_IS_OK(status)) {
1543                 return status;
1544         }
1545
1546         return NT_STATUS_OK;
1547 }
1548
1549 struct smbd_smb2_request_pending_state {
1550         struct smbd_smb2_send_queue queue_entry;
1551         uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1552         struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1553 };
1554
1555 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1556                                             struct tevent_timer *te,
1557                                             struct timeval current_time,
1558                                             void *private_data);
1559
1560 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1561                                          struct tevent_req *subreq,
1562                                          uint32_t defer_time)
1563 {
1564         NTSTATUS status;
1565         struct timeval defer_endtime;
1566         uint8_t *outhdr = NULL;
1567         uint32_t flags;
1568
1569         if (!tevent_req_is_in_progress(subreq)) {
1570                 /*
1571                  * This is a performance optimization,
1572                  * it avoids one tevent_loop iteration,
1573                  * which means we avoid one
1574                  * talloc_stackframe_pool/talloc_free pair.
1575                  */
1576                 tevent_req_notify_callback(subreq);
1577                 return NT_STATUS_OK;
1578         }
1579
1580         req->subreq = subreq;
1581         subreq = NULL;
1582
1583         if (req->async_te) {
1584                 /* We're already async. */
1585                 return NT_STATUS_OK;
1586         }
1587
1588         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1589         flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1590         if (flags & SMB2_HDR_FLAG_ASYNC) {
1591                 /* We're already async. */
1592                 return NT_STATUS_OK;
1593         }
1594
1595         if (req->async_internal || defer_time == 0) {
1596                 /*
1597                  * An SMB2 request implementation wants to handle the request
1598                  * asynchronously "internally" while keeping synchronous
1599                  * behaviour for the SMB2 request. This means we don't send an
1600                  * interim response and we can allow processing of compound SMB2
1601                  * requests (cf the subsequent check) for all cases.
1602                  */
1603                 return NT_STATUS_OK;
1604         }
1605
1606         if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
1607                 /*
1608                  * We're trying to go async in a compound request
1609                  * chain. This is only allowed for opens that cause an
1610                  * oplock break or for the last operation in the
1611                  * chain, otherwise it is not allowed. See
1612                  * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
1613                  */
1614                 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1615
1616                 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
1617                         /*
1618                          * Cancel the outstanding request.
1619                          */
1620                         bool ok = tevent_req_cancel(req->subreq);
1621                         if (ok) {
1622                                 return NT_STATUS_OK;
1623                         }
1624                         TALLOC_FREE(req->subreq);
1625                         return smbd_smb2_request_error(req,
1626                                 NT_STATUS_INTERNAL_ERROR);
1627                 }
1628         }
1629
1630         if (DEBUGLEVEL >= 10) {
1631                 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1632                         (unsigned int)req->current_idx );
1633                 print_req_vectors(req);
1634         }
1635
1636         if (req->current_idx > 1) {
1637                 /*
1638                  * We're going async in a compound
1639                  * chain after the first request has
1640                  * already been processed. Send an
1641                  * interim response containing the
1642                  * set of replies already generated.
1643                  */
1644                 int idx = req->current_idx;
1645
1646                 status = smb2_send_async_interim_response(req);
1647                 if (!NT_STATUS_IS_OK(status)) {
1648                         return status;
1649                 }
1650                 if (req->first_key.length > 0) {
1651                         data_blob_clear_free(&req->first_key);
1652                 }
1653
1654                 req->current_idx = 1;
1655
1656                 /*
1657                  * Re-arrange the in.vectors to remove what
1658                  * we just sent.
1659                  */
1660                 memmove(&req->in.vector[1],
1661                         &req->in.vector[idx],
1662                         sizeof(req->in.vector[0])*(req->in.vector_count - idx));
1663                 req->in.vector_count = 1 + (req->in.vector_count - idx);
1664
1665                 /* Re-arrange the out.vectors to match. */
1666                 memmove(&req->out.vector[1],
1667                         &req->out.vector[idx],
1668                         sizeof(req->out.vector[0])*(req->out.vector_count - idx));
1669                 req->out.vector_count = 1 + (req->out.vector_count - idx);
1670
1671                 if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
1672                         /*
1673                          * We only have one remaining request as
1674                          * we've processed everything else.
1675                          * This is no longer a compound request.
1676                          */
1677                         req->compound_related = false;
1678                         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1679                         flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
1680                         SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
1681                 }
1682         }
1683         if (req->last_key.length > 0) {
1684                 data_blob_clear_free(&req->last_key);
1685         }
1686
1687         /*
1688          * smbd_smb2_request_pending_timer() just send a packet
1689          * to the client and doesn't need any impersonation.
1690          * So we use req->xconn->client->raw_ev_ctx instead
1691          * of req->ev_ctx here.
1692          */
1693         defer_endtime = timeval_current_ofs_usec(defer_time);
1694         req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
1695                                          req, defer_endtime,
1696                                          smbd_smb2_request_pending_timer,
1697                                          req);
1698         if (req->async_te == NULL) {
1699                 return NT_STATUS_NO_MEMORY;
1700         }
1701
1702         return NT_STATUS_OK;
1703 }
1704
1705 static
1706 struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
1707                                                struct smbXsrv_connection *xconn)
1708 {
1709         struct smbXsrv_channel_global0 *c = NULL;
1710         NTSTATUS status;
1711         struct smb2_signing_key *key = NULL;
1712
1713         status = smbXsrv_session_find_channel(session, xconn, &c);
1714         if (NT_STATUS_IS_OK(status)) {
1715                 key = c->signing_key;
1716         }
1717
1718         if (!smb2_signing_key_valid(key)) {
1719                 key = session->global->signing_key;
1720         }
1721
1722         return key;
1723 }
1724
1725 static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
1726                                    uint64_t *new_nonce_high,
1727                                    uint64_t *new_nonce_low)
1728 {
1729         uint64_t nonce_high;
1730         uint64_t nonce_low;
1731
1732         session->nonce_low += 1;
1733         if (session->nonce_low == 0) {
1734                 session->nonce_low += 1;
1735                 session->nonce_high += 1;
1736         }
1737
1738         /*
1739          * CCM and GCM algorithms must never have their
1740          * nonce wrap, or the security of the whole
1741          * communication and the keys is destroyed.
1742          * We must drop the connection once we have
1743          * transfered too much data.
1744          *
1745          * NOTE: We assume nonces greater than 8 bytes.
1746          */
1747         if (session->nonce_high >= session->nonce_high_max) {
1748                 return NT_STATUS_ENCRYPTION_FAILED;
1749         }
1750
1751         nonce_high = session->nonce_high_random;
1752         nonce_high += session->nonce_high;
1753         nonce_low = session->nonce_low;
1754
1755         *new_nonce_high = nonce_high;
1756         *new_nonce_low = nonce_low;
1757         return NT_STATUS_OK;
1758 }
1759
1760 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1761                                             struct tevent_timer *te,
1762                                             struct timeval current_time,
1763                                             void *private_data)
1764 {
1765         struct smbd_smb2_request *req =
1766                 talloc_get_type_abort(private_data,
1767                 struct smbd_smb2_request);
1768         struct smbXsrv_connection *xconn = req->xconn;
1769         struct smbd_smb2_request_pending_state *state = NULL;
1770         uint8_t *outhdr = NULL;
1771         const uint8_t *inhdr = NULL;
1772         uint8_t *tf = NULL;
1773         uint8_t *hdr = NULL;
1774         uint8_t *body = NULL;
1775         uint8_t *dyn = NULL;
1776         uint32_t flags = 0;
1777         uint64_t message_id = 0;
1778         uint64_t async_id = 0;
1779         NTSTATUS status;
1780         bool ok;
1781
1782         TALLOC_FREE(req->async_te);
1783
1784         /* Ensure our final reply matches the interim one. */
1785         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1786         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1787         flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1788         message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1789
1790         async_id = message_id; /* keep it simple for now... */
1791
1792         SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1793         SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
1794
1795         DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1796                 "going async\n",
1797                 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
1798                 (unsigned long long)async_id ));
1799
1800         /*
1801          * What we send is identical to a smbd_smb2_request_error
1802          * packet with an error status of STATUS_PENDING. Make use
1803          * of this fact sometime when refactoring. JRA.
1804          */
1805
1806         state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
1807         if (state == NULL) {
1808                 smbd_server_connection_terminate(xconn,
1809                                                  nt_errstr(NT_STATUS_NO_MEMORY));
1810                 return;
1811         }
1812
1813         tf = state->buf + NBT_HDR_SIZE;
1814
1815         hdr = tf + SMB2_TF_HDR_SIZE;
1816         body = hdr + SMB2_HDR_BODY;
1817         dyn = body + 8;
1818
1819         if (req->do_encryption) {
1820                 uint64_t nonce_high = 0;
1821                 uint64_t nonce_low = 0;
1822                 uint64_t session_id = req->session->global->session_wire_id;
1823
1824                 status = smb2_get_new_nonce(req->session,
1825                                             &nonce_high,
1826                                             &nonce_low);
1827                 if (!NT_STATUS_IS_OK(status)) {
1828                         smbd_server_connection_terminate(xconn,
1829                                                          nt_errstr(status));
1830                         return;
1831                 }
1832
1833                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
1834                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
1835                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
1836                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
1837         }
1838
1839         SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1840         SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1841         SSVAL(hdr, SMB2_HDR_EPOCH, 0);
1842         SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_PENDING));
1843         SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
1844
1845         SIVAL(hdr, SMB2_HDR_FLAGS, flags);
1846         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
1847         SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
1848         SBVAL(hdr, SMB2_HDR_PID, async_id);
1849         SBVAL(hdr, SMB2_HDR_SESSION_ID,
1850                 BVAL(outhdr, SMB2_HDR_SESSION_ID));
1851         memcpy(hdr+SMB2_HDR_SIGNATURE,
1852                outhdr+SMB2_HDR_SIGNATURE, 16);
1853
1854         SSVAL(body, 0x00, 0x08 + 1);
1855
1856         SCVAL(body, 0x02, 0);
1857         SCVAL(body, 0x03, 0);
1858         SIVAL(body, 0x04, 0);
1859         /* Match W2K8R2... */
1860         SCVAL(dyn,  0x00, 0x21);
1861
1862         state->vector[0].iov_base = (void *)state->buf;
1863         state->vector[0].iov_len = NBT_HDR_SIZE;
1864
1865         if (req->do_encryption) {
1866                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
1867                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    =
1868                                                         SMB2_TF_HDR_SIZE;
1869         } else {
1870                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
1871                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
1872         }
1873
1874         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
1875         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
1876
1877         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
1878         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
1879
1880         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
1881         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = 1;
1882
1883         ok = smb2_setup_nbt_length(state->vector,
1884                                    1 + SMBD_SMB2_NUM_IOV_PER_REQ);
1885         if (!ok) {
1886                 smbd_server_connection_terminate(
1887                         xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
1888                 return;
1889         }
1890
1891         /* Ensure we correctly go through crediting. Grant
1892            the credits now, and zero credits on the final
1893            response. */
1894         smb2_set_operation_credit(req->xconn,
1895                         SMBD_SMB2_IN_HDR_IOV(req),
1896                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
1897
1898         SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1899
1900         if (DEBUGLVL(10)) {
1901                 int i;
1902
1903                 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
1904                         dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1905                                 (unsigned int)i,
1906                                 (unsigned int)ARRAY_SIZE(state->vector),
1907                                 (unsigned int)state->vector[i].iov_len);
1908                 }
1909         }
1910
1911         if (req->do_encryption) {
1912                 struct smbXsrv_session *x = req->session;
1913                 struct smb2_signing_key *encryption_key = x->global->encryption_key;
1914
1915                 status = smb2_signing_encrypt_pdu(encryption_key,
1916                                         xconn->smb2.server.cipher,
1917                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
1918                                         SMBD_SMB2_NUM_IOV_PER_REQ);
1919                 if (!NT_STATUS_IS_OK(status)) {
1920                         smbd_server_connection_terminate(xconn,
1921                                                 nt_errstr(status));
1922                         return;
1923                 }
1924         } else if (req->do_signing) {
1925                 struct smbXsrv_session *x = req->session;
1926                 struct smb2_signing_key *signing_key =
1927                         smbd_smb2_signing_key(x, xconn);
1928
1929                 status = smb2_signing_sign_pdu(signing_key,
1930                                         xconn->protocol,
1931                                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS],
1932                                         SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1933                 if (!NT_STATUS_IS_OK(status)) {
1934                         smbd_server_connection_terminate(xconn,
1935                                                 nt_errstr(status));
1936                         return;
1937                 }
1938         }
1939
1940         state->queue_entry.mem_ctx = state;
1941         state->queue_entry.vector = state->vector;
1942         state->queue_entry.count = ARRAY_SIZE(state->vector);
1943         DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
1944         xconn->smb2.send_queue_len++;
1945
1946         status = smbd_smb2_flush_send_queue(xconn);
1947         if (!NT_STATUS_IS_OK(status)) {
1948                 smbd_server_connection_terminate(xconn,
1949                                                  nt_errstr(status));
1950                 return;
1951         }
1952 }
1953
1954 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
1955 {
1956         struct smbXsrv_connection *xconn = req->xconn;
1957         struct smbd_smb2_request *cur;
1958         const uint8_t *inhdr;
1959         uint32_t flags;
1960         uint64_t search_message_id;
1961         uint64_t search_async_id;
1962         uint64_t found_id;
1963
1964         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1965
1966         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1967         search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1968         search_async_id = BVAL(inhdr, SMB2_HDR_PID);
1969
1970         /*
1971          * We don't need the request anymore cancel requests never
1972          * have a response.
1973          *
1974          * We defer the TALLOC_FREE(req) to the caller.
1975          */
1976         DLIST_REMOVE(xconn->smb2.requests, req);
1977
1978         for (cur = xconn->smb2.requests; cur; cur = cur->next) {
1979                 const uint8_t *outhdr;
1980                 uint64_t message_id;
1981                 uint64_t async_id;
1982
1983                 if (cur->compound_related) {
1984                         /*
1985                          * Never cancel anything in a compound request.
1986                          * Way too hard to deal with the result.
1987                          */
1988                         continue;
1989                 }
1990
1991                 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
1992
1993                 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1994                 async_id = BVAL(outhdr, SMB2_HDR_PID);
1995
1996                 if (flags & SMB2_HDR_FLAG_ASYNC) {
1997                         if (search_async_id == async_id) {
1998                                 found_id = async_id;
1999                                 break;
2000                         }
2001                 } else {
2002                         if (search_message_id == message_id) {
2003                                 found_id = message_id;
2004                                 break;
2005                         }
2006                 }
2007         }
2008
2009         if (cur && cur->subreq) {
2010                 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
2011                 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2012                         "cancel opcode[%s] mid %llu\n",
2013                         smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2014                         (unsigned long long)found_id ));
2015                 tevent_req_cancel(cur->subreq);
2016         }
2017
2018         return NT_STATUS_OK;
2019 }
2020
2021 /*************************************************************
2022  Ensure an incoming tid is a valid one for us to access.
2023  Change to the associated uid credentials and chdir to the
2024  valid tid directory.
2025 *************************************************************/
2026
2027 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
2028 {
2029         const uint8_t *inhdr;
2030         uint32_t in_flags;
2031         uint32_t in_tid;
2032         struct smbXsrv_tcon *tcon;
2033         NTSTATUS status;
2034         NTTIME now = timeval_to_nttime(&req->request_time);
2035
2036         req->tcon = NULL;
2037
2038         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2039
2040         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2041         in_tid = IVAL(inhdr, SMB2_HDR_TID);
2042
2043         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2044                 in_tid = req->last_tid;
2045         }
2046
2047         req->last_tid = 0;
2048
2049         status = smb2srv_tcon_lookup(req->session,
2050                                      in_tid, now, &tcon);
2051         if (!NT_STATUS_IS_OK(status)) {
2052                 return status;
2053         }
2054
2055         if (!change_to_user_and_service(
2056                     tcon->compat,
2057                     req->session->global->session_wire_id))
2058         {
2059                 return NT_STATUS_ACCESS_DENIED;
2060         }
2061
2062         req->tcon = tcon;
2063         req->last_tid = in_tid;
2064
2065         return NT_STATUS_OK;
2066 }
2067
2068 /*************************************************************
2069  Ensure an incoming session_id is a valid one for us to access.
2070 *************************************************************/
2071
2072 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
2073 {
2074         const uint8_t *inhdr;
2075         uint32_t in_flags;
2076         uint16_t in_opcode;
2077         uint64_t in_session_id;
2078         struct smbXsrv_session *session = NULL;
2079         struct auth_session_info *session_info;
2080         NTSTATUS status;
2081         NTTIME now = timeval_to_nttime(&req->request_time);
2082
2083         req->session = NULL;
2084         req->tcon = NULL;
2085
2086         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2087
2088         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2089         in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2090         in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
2091
2092         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2093                 in_session_id = req->last_session_id;
2094         }
2095
2096         req->last_session_id = 0;
2097
2098         /* look an existing session up */
2099         switch (in_opcode) {
2100         case SMB2_OP_SESSSETUP:
2101                 /*
2102                  * For a session bind request, we don't have the
2103                  * channel set up at this point yet, so we defer
2104                  * the verification that the connection belongs
2105                  * to the session to the session setup code, which
2106                  * can look at the session binding flags.
2107                  */
2108                 status = smb2srv_session_lookup_client(req->xconn->client,
2109                                                        in_session_id, now,
2110                                                        &session);
2111                 break;
2112         default:
2113                 status = smb2srv_session_lookup_conn(req->xconn,
2114                                                      in_session_id, now,
2115                                                      &session);
2116                 break;
2117         }
2118         if (session) {
2119                 req->session = session;
2120                 req->last_session_id = in_session_id;
2121         }
2122         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
2123                 switch (in_opcode) {
2124                 case SMB2_OP_SESSSETUP:
2125                         status = NT_STATUS_OK;
2126                         break;
2127                 case SMB2_OP_LOGOFF:
2128                 case SMB2_OP_CLOSE:
2129                 case SMB2_OP_LOCK:
2130                 case SMB2_OP_CANCEL:
2131                 case SMB2_OP_KEEPALIVE:
2132                         /*
2133                          * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2134                          * specifies that LOGOFF, CLOSE and (UN)LOCK
2135                          * should always be processed even on expired sessions.
2136                          *
2137                          * Also see the logic in
2138                          * smbd_smb2_request_process_lock().
2139                          *
2140                          * The smb2.session.expire2 test shows that
2141                          * CANCEL and KEEPALIVE/ECHO should also
2142                          * be processed.
2143                          */
2144                         status = NT_STATUS_OK;
2145                         break;
2146                 default:
2147                         break;
2148                 }
2149         }
2150         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2151                 switch (in_opcode) {
2152                 case SMB2_OP_TCON:
2153                 case SMB2_OP_CREATE:
2154                 case SMB2_OP_GETINFO:
2155                 case SMB2_OP_SETINFO:
2156                         return NT_STATUS_INVALID_HANDLE;
2157                 default:
2158                         /*
2159                          * Notice the check for
2160                          * (session_info == NULL)
2161                          * below.
2162                          */
2163                         status = NT_STATUS_OK;
2164                         break;
2165                 }
2166         }
2167         if (!NT_STATUS_IS_OK(status)) {
2168                 return status;
2169         }
2170
2171         session_info = session->global->auth_session_info;
2172         if (session_info == NULL) {
2173                 return NT_STATUS_INVALID_HANDLE;
2174         }
2175
2176         return NT_STATUS_OK;
2177 }
2178
2179 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
2180                                                 uint32_t data_length)
2181 {
2182         struct smbXsrv_connection *xconn = req->xconn;
2183         uint16_t needed_charge;
2184         uint16_t credit_charge = 1;
2185         const uint8_t *inhdr;
2186
2187         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2188
2189         if (xconn->smb2.credits.multicredit) {
2190                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
2191                 credit_charge = MAX(credit_charge, 1);
2192         }
2193
2194         needed_charge = (data_length - 1)/ 65536 + 1;
2195
2196         DBGC_DEBUG(DBGC_SMB2_CREDITS,
2197                    "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2198                    (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
2199                    credit_charge, needed_charge);
2200
2201         if (needed_charge > credit_charge) {
2202                 DBGC_WARNING(DBGC_SMB2_CREDITS,
2203                           "CreditCharge too low, given %d, needed %d\n",
2204                           credit_charge, needed_charge);
2205                 return NT_STATUS_INVALID_PARAMETER;
2206         }
2207
2208         return NT_STATUS_OK;
2209 }
2210
2211 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
2212                                         size_t expected_body_size)
2213 {
2214         struct iovec *inhdr_v;
2215         const uint8_t *inhdr;
2216         uint16_t opcode;
2217         const uint8_t *inbody;
2218         size_t body_size;
2219         size_t min_dyn_size = expected_body_size & 0x00000001;
2220         int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2221
2222         /*
2223          * The following should be checked already.
2224          */
2225         if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2226                 return NT_STATUS_INTERNAL_ERROR;
2227         }
2228         if (req->current_idx > max_idx) {
2229                 return NT_STATUS_INTERNAL_ERROR;
2230         }
2231
2232         inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2233         if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2234                 return NT_STATUS_INTERNAL_ERROR;
2235         }
2236         if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2237                 return NT_STATUS_INTERNAL_ERROR;
2238         }
2239
2240         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2241         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2242
2243         switch (opcode) {
2244         case SMB2_OP_IOCTL:
2245         case SMB2_OP_GETINFO:
2246         case SMB2_OP_WRITE:
2247                 min_dyn_size = 0;
2248                 break;
2249         }
2250
2251         /*
2252          * Now check the expected body size,
2253          * where the last byte might be in the
2254          * dynamic section..
2255          */
2256         if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2257                 return NT_STATUS_INVALID_PARAMETER;
2258         }
2259         if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2260                 return NT_STATUS_INVALID_PARAMETER;
2261         }
2262
2263         inbody = SMBD_SMB2_IN_BODY_PTR(req);
2264
2265         body_size = SVAL(inbody, 0x00);
2266         if (body_size != expected_body_size) {
2267                 return NT_STATUS_INVALID_PARAMETER;
2268         }
2269
2270         return NT_STATUS_OK;
2271 }
2272
2273 bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2274 {
2275         return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2276                 &&
2277                 (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2278                                      SMBXSRV_ENCRYPTION_DESIRED |
2279                                      SMBXSRV_ENCRYPTION_REQUIRED)));
2280 }
2281
2282 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2283 {
2284         return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2285                 (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2286 }
2287
2288 /* Set a flag if not already set, return true if set */
2289 bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2290 {
2291         if ((flag == 0) || (*flags & flag)) {
2292                 return false;
2293         }
2294
2295         *flags |= flag;
2296         return true;
2297 }
2298
2299 /*
2300  * Update encryption state tracking flags, this can be used to
2301  * determine whether whether the session or tcon is "encrypted".
2302  */
2303 static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2304                                         uint16_t opcode,
2305                                         bool *update_session_globalp,
2306                                         bool *update_tcon_globalp)
2307 {
2308         /* Default: assume unecrypted and unsigned */
2309         struct smbXsrv_session *session = req->session;
2310         struct smbXsrv_tcon *tcon = req->tcon;
2311         uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2312         uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2313         bool update_session = false;
2314         bool update_tcon = false;
2315
2316         if (req->was_encrypted && req->do_encryption) {
2317                 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2318                 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2319         } else {
2320                 /* Unencrypted packet, can be signed */
2321                 if (req->do_signing) {
2322                         sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2323                 } else if (opcode == SMB2_OP_CANCEL) {
2324                         /* Cancel requests are allowed to skip signing */
2325                         sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2326                 }
2327         }
2328
2329         update_session |= smbXsrv_set_crypto_flag(
2330                 &session->global->encryption_flags, encrypt_flag);
2331         update_session |= smbXsrv_set_crypto_flag(
2332                 &session->global->signing_flags, sign_flag);
2333
2334         if (tcon) {
2335                 update_tcon |= smbXsrv_set_crypto_flag(
2336                         &tcon->global->encryption_flags, encrypt_flag);
2337                 update_tcon |= smbXsrv_set_crypto_flag(
2338                         &tcon->global->signing_flags, sign_flag);
2339         }
2340
2341         *update_session_globalp = update_session;
2342         *update_tcon_globalp = update_tcon;
2343         return;
2344 }
2345
2346 bool smbXsrv_is_signed(uint8_t signing_flags)
2347 {
2348         /*
2349          * Signing is always enabled, so unless we got an unsigned
2350          * packet and at least one signed packet that was not
2351          * encrypted, the session or tcon is "signed".
2352          */
2353         return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2354                 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2355 }
2356
2357 bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2358 {
2359         return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2360                 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2361 }
2362
2363 static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2364                                 struct smbd_smb2_request *req,
2365                                 bool modify_call)
2366 {
2367         struct smbXsrv_connection *xconn = req->xconn;
2368         const uint8_t *inhdr;
2369         uint16_t channel_sequence;
2370         uint8_t generation_wrap = 0;
2371         uint32_t flags;
2372         int cmp;
2373         struct smbXsrv_open *op;
2374         bool update_open = false;
2375         NTSTATUS status = NT_STATUS_OK;
2376
2377         SMB_ASSERT(!req->request_counters_updated);
2378
2379         if (xconn->protocol < PROTOCOL_SMB2_22) {
2380                 return NT_STATUS_OK;
2381         }
2382
2383         if (req->compat_chain_fsp == NULL) {
2384                 return NT_STATUS_OK;
2385         }
2386
2387         op = req->compat_chain_fsp->op;
2388         if (op == NULL) {
2389                 return NT_STATUS_OK;
2390         }
2391
2392         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2393         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2394         channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2395
2396         cmp = channel_sequence - op->global->channel_sequence;
2397         if (cmp < 0) {
2398                 /*
2399                  * csn wrap. We need to watch out for long-running
2400                  * requests that are still sitting on a previously
2401                  * used csn. SMB2_OP_NOTIFY can take VERY long.
2402                  */
2403                 generation_wrap += 1;
2404         }
2405
2406         if (abs(cmp) > INT16_MAX) {
2407                 /*
2408                  * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2409                  *
2410                  * If the channel sequence number of the request and the one
2411                  * known to the server are not equal, the channel sequence
2412                  * number and outstanding request counts are only updated
2413                  * "... if the unsigned difference using 16-bit arithmetic
2414                  * between ChannelSequence and Open.ChannelSequence is less than
2415                  * or equal to 0x7FFF ...".
2416                  * Otherwise, an error is returned for the modifying
2417                  * calls write, set_info, and ioctl.
2418                  *
2419                  * There are currently two issues with the description:
2420                  *
2421                  * * For the other calls, the document seems to imply
2422                  *   that processing continues without adapting the
2423                  *   counters (if the sequence numbers are not equal).
2424                  *
2425                  *   TODO: This needs clarification!
2426                  *
2427                  * * Also, the behaviour if the difference is larger
2428                  *   than 0x7FFF is not clear. The document seems to
2429                  *   imply that if such a difference is reached,
2430                  *   the server starts to ignore the counters or
2431                  *   in the case of the modifying calls, return errors.
2432                  *
2433                  *   TODO: This needs clarification!
2434                  *
2435                  * At this point Samba tries to be a little more
2436                  * clever than the description in the MS-SMB2 document
2437                  * by heuristically detecting and properly treating
2438                  * a 16 bit overflow of the client-submitted sequence
2439                  * number:
2440                  *
2441                  * If the stored channel sequence number is more than
2442                  * 0x7FFF larger than the one from the request, then
2443                  * the client-provided sequence number has likely
2444                  * overflown. We treat this case as valid instead
2445                  * of as failure.
2446                  *
2447                  * The MS-SMB2 behaviour would be setting cmp = -1.
2448                  */
2449                 cmp *= -1;
2450         }
2451
2452         if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2453                 if (cmp == 0 && op->pre_request_count == 0) {
2454                         op->request_count += 1;
2455                         req->request_counters_updated = true;
2456                 } else if (cmp > 0 && op->pre_request_count == 0) {
2457                         op->pre_request_count += op->request_count;
2458                         op->request_count = 1;
2459                         op->global->channel_sequence = channel_sequence;
2460                         op->global->channel_generation += generation_wrap;
2461                         update_open = true;
2462                         req->request_counters_updated = true;
2463                 } else if (modify_call) {
2464                         return NT_STATUS_FILE_NOT_AVAILABLE;
2465                 }
2466         } else {
2467                 if (cmp == 0) {
2468                         op->request_count += 1;
2469                         req->request_counters_updated = true;
2470                 } else if (cmp > 0) {
2471                         op->pre_request_count += op->request_count;
2472                         op->request_count = 1;
2473                         op->global->channel_sequence = channel_sequence;
2474                         op->global->channel_generation += generation_wrap;
2475                         update_open = true;
2476                         req->request_counters_updated = true;
2477                 } else if (modify_call) {
2478                         return NT_STATUS_FILE_NOT_AVAILABLE;
2479                 }
2480         }
2481         req->channel_generation = op->global->channel_generation;
2482
2483         if (update_open) {
2484                 status = smbXsrv_open_update(op);
2485         }
2486
2487         return status;
2488 }
2489
2490 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2491 {
2492         struct smbXsrv_connection *xconn = req->xconn;
2493         const struct smbd_smb2_dispatch_table *call = NULL;
2494         const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2495         const uint8_t *inhdr;
2496         uint16_t opcode;
2497         uint32_t flags;
2498         uint64_t mid;
2499         NTSTATUS status;
2500         NTSTATUS session_status;
2501         uint32_t allowed_flags;
2502         NTSTATUS return_value;
2503         struct smbXsrv_session *x = NULL;
2504         bool signing_required = false;
2505         bool encryption_desired = false;
2506         bool encryption_required = false;
2507
2508         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2509
2510         DO_PROFILE_INC(request);
2511
2512         SMB_ASSERT(!req->request_counters_updated);
2513
2514         /* TODO: verify more things */
2515
2516         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2517         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2518         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2519         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2520                 smb2_opcode_name(opcode),
2521                 (unsigned long long)mid));
2522
2523         if (xconn->protocol >= PROTOCOL_SMB2_02) {
2524                 /*
2525                  * once the protocol is negotiated
2526                  * SMB2_OP_NEGPROT is not allowed anymore
2527                  */
2528                 if (opcode == SMB2_OP_NEGPROT) {
2529                         /* drop the connection */
2530                         return NT_STATUS_INVALID_PARAMETER;
2531                 }
2532         } else {
2533                 /*
2534                  * if the protocol is not negotiated yet
2535                  * only SMB2_OP_NEGPROT is allowed.
2536                  */
2537                 if (opcode != SMB2_OP_NEGPROT) {
2538                         /* drop the connection */
2539                         return NT_STATUS_INVALID_PARAMETER;
2540                 }
2541         }
2542
2543         /*
2544          * Check if the client provided a valid session id.
2545          *
2546          * As some command don't require a valid session id
2547          * we defer the check of the session_status
2548          */
2549         session_status = smbd_smb2_request_check_session(req);
2550         x = req->session;
2551         if (x != NULL) {
2552                 signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
2553                 encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
2554                 encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
2555         }
2556
2557         req->async_internal = false;
2558         req->do_signing = false;
2559         if (opcode != SMB2_OP_SESSSETUP) {
2560                 req->do_encryption = encryption_desired;
2561         } else {
2562                 req->do_encryption = false;
2563         }
2564         req->was_encrypted = false;
2565         if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
2566                 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
2567                 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
2568
2569                 if (x != NULL && x->global->session_wire_id != tf_session_id) {
2570                         DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2571                                  "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2572                                  (unsigned long long)x->global->session_wire_id,
2573                                  (unsigned long long)tf_session_id));
2574                         /*
2575                          * TODO: windows allows this...
2576                          * should we drop the connection?
2577                          *
2578                          * For now we just return ACCESS_DENIED
2579                          * (Windows clients never trigger this)
2580                          * and wait for an update of [MS-SMB2].
2581                          */
2582                         return smbd_smb2_request_error(req,
2583                                         NT_STATUS_ACCESS_DENIED);
2584                 }
2585
2586                 req->was_encrypted = true;
2587                 req->do_encryption = true;
2588         }
2589
2590         if (encryption_required && !req->was_encrypted) {
2591                 req->do_encryption = true;
2592                 return smbd_smb2_request_error(req,
2593                                 NT_STATUS_ACCESS_DENIED);
2594         }
2595
2596         call = smbd_smb2_call(opcode);
2597         if (call == NULL) {
2598                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2599         }
2600
2601         allowed_flags = SMB2_HDR_FLAG_CHAINED |
2602                         SMB2_HDR_FLAG_SIGNED |
2603                         SMB2_HDR_FLAG_DFS;
2604         if (xconn->protocol >= PROTOCOL_SMB3_11) {
2605                 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2606         }
2607         if (opcode == SMB2_OP_NEGPROT) {
2608                 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
2609                         allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2610                 }
2611         }
2612         if (opcode == SMB2_OP_CANCEL) {
2613                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
2614         }
2615         if (xconn->protocol >= PROTOCOL_SMB2_22) {
2616                 allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
2617         }
2618         if ((flags & ~allowed_flags) != 0) {
2619                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2620         }
2621
2622         if (flags & SMB2_HDR_FLAG_CHAINED) {
2623                 /*
2624                  * This check is mostly for giving the correct error code
2625                  * for compounded requests.
2626                  */
2627                 if (!NT_STATUS_IS_OK(session_status)) {
2628                         return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2629                 }
2630         } else {
2631                 req->compat_chain_fsp = NULL;
2632         }
2633
2634         if (req->was_encrypted) {
2635                 signing_required = false;
2636         } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
2637                 struct smb2_signing_key *signing_key = NULL;
2638
2639                 if (x == NULL) {
2640                         /*
2641                          * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2642                          * If the SMB2 header of the SMB2 NEGOTIATE
2643                          * request has the SMB2_FLAGS_SIGNED bit set in the
2644                          * Flags field, the server MUST fail the request
2645                          * with STATUS_INVALID_PARAMETER.
2646                          *
2647                          * Microsoft test tool checks this.
2648                          */
2649
2650                         if ((opcode == SMB2_OP_NEGPROT) &&
2651                                         (flags & SMB2_HDR_FLAG_SIGNED)) {
2652                                 status = NT_STATUS_INVALID_PARAMETER;
2653                         } else {
2654                                 status = NT_STATUS_USER_SESSION_DELETED;
2655                         }
2656                         return smbd_smb2_request_error(req, status);
2657                 }
2658
2659                 signing_key = smbd_smb2_signing_key(x, xconn);
2660
2661                 /*
2662                  * If we have a signing key, we should
2663                  * sign the response
2664                  */
2665                 if (smb2_signing_key_valid(signing_key)) {
2666                         req->do_signing = true;
2667                 }
2668
2669                 status = smb2_signing_check_pdu(signing_key,
2670                                                 xconn->protocol,
2671                                                 SMBD_SMB2_IN_HDR_IOV(req),
2672                                                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2673                 if (!NT_STATUS_IS_OK(status)) {
2674                         return smbd_smb2_request_error(req, status);
2675                 }
2676
2677                 /*
2678                  * Now that we know the request was correctly signed
2679                  * we have to sign the response too.
2680                  */
2681                 req->do_signing = true;
2682
2683                 if (!NT_STATUS_IS_OK(session_status)) {
2684                         return smbd_smb2_request_error(req, session_status);
2685                 }
2686         } else if (opcode == SMB2_OP_CANCEL) {
2687                 /* Cancel requests are allowed to skip the signing */
2688         } else if (signing_required) {
2689                 /*
2690                  * If signing is required we try to sign
2691                  * a possible error response
2692                  */
2693                 req->do_signing = true;
2694                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
2695         }
2696
2697         if (flags & SMB2_HDR_FLAG_CHAINED) {
2698                 req->compound_related = true;
2699         }
2700
2701         if (call->need_session) {
2702                 if (!NT_STATUS_IS_OK(session_status)) {
2703                         return smbd_smb2_request_error(req, session_status);
2704                 }
2705         }
2706
2707         if (call->need_tcon) {
2708                 SMB_ASSERT(call->need_session);
2709
2710                 /*
2711                  * This call needs to be run as user.
2712                  *
2713                  * smbd_smb2_request_check_tcon()
2714                  * calls change_to_user() on success.
2715                  * Which implies set_current_user_info()
2716                  * and chdir_current_service().
2717                  */
2718                 status = smbd_smb2_request_check_tcon(req);
2719                 if (!NT_STATUS_IS_OK(status)) {
2720                         return smbd_smb2_request_error(req, status);
2721                 }
2722                 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
2723                         encryption_desired = true;
2724                 }
2725                 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
2726                         encryption_required = true;
2727                 }
2728                 if (encryption_required && !req->was_encrypted) {
2729                         req->do_encryption = true;
2730                         return smbd_smb2_request_error(req,
2731                                 NT_STATUS_ACCESS_DENIED);
2732                 } else if (encryption_desired) {
2733                         req->do_encryption = true;
2734                 }
2735         } else if (call->need_session) {
2736                 struct auth_session_info *session_info = NULL;
2737
2738                 /*
2739                  * Unless we also have need_tcon (see above),
2740                  * we still need to call set_current_user_info().
2741                  */
2742
2743                 session_info = req->session->global->auth_session_info;
2744                 if (session_info == NULL) {
2745                         return NT_STATUS_INVALID_HANDLE;
2746                 }
2747
2748                 set_current_user_info(session_info->unix_info->sanitized_username,
2749                                       session_info->unix_info->unix_name,
2750                                       session_info->info->domain_name);
2751         }
2752
2753         if (req->session) {
2754                 bool update_session_global = false;
2755                 bool update_tcon_global = false;
2756
2757                 smb2srv_update_crypto_flags(req, opcode,
2758                                             &update_session_global,
2759                                             &update_tcon_global);
2760
2761                 if (update_session_global) {
2762                         status = smbXsrv_session_update(x);
2763                         if (!NT_STATUS_IS_OK(status)) {
2764                                 return smbd_smb2_request_error(req, status);
2765                         }
2766                 }
2767                 if (update_tcon_global) {
2768                         status = smbXsrv_tcon_update(req->tcon);
2769                         if (!NT_STATUS_IS_OK(status)) {
2770                                 return smbd_smb2_request_error(req, status);
2771                         }
2772                 }
2773         }
2774
2775         if (call->fileid_ofs != 0) {
2776                 size_t needed = call->fileid_ofs + 16;
2777                 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2778                 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2779                 uint64_t file_id_persistent;
2780                 uint64_t file_id_volatile;
2781                 struct files_struct *fsp;
2782
2783                 SMB_ASSERT(call->need_tcon);
2784
2785                 if (needed > body_size) {
2786                         return smbd_smb2_request_error(req,
2787                                         NT_STATUS_INVALID_PARAMETER);
2788                 }
2789
2790                 file_id_persistent      = BVAL(body, call->fileid_ofs + 0);
2791                 file_id_volatile        = BVAL(body, call->fileid_ofs + 8);
2792
2793                 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2794                 if (fsp == NULL) {
2795                         if (!call->allow_invalid_fileid) {
2796                                 return smbd_smb2_request_error(req,
2797                                                 NT_STATUS_FILE_CLOSED);
2798                         }
2799
2800                         if (file_id_persistent != UINT64_MAX) {
2801                                 return smbd_smb2_request_error(req,
2802                                                 NT_STATUS_FILE_CLOSED);
2803                         }
2804                         if (file_id_volatile != UINT64_MAX) {
2805                                 return smbd_smb2_request_error(req,
2806                                                 NT_STATUS_FILE_CLOSED);
2807                         }
2808                 }
2809         }
2810
2811         status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
2812         if (!NT_STATUS_IS_OK(status)) {
2813                 return smbd_smb2_request_error(req, status);
2814         }
2815
2816         if (call->as_root) {
2817                 SMB_ASSERT(call->fileid_ofs == 0);
2818                 /* This call needs to be run as root */
2819                 change_to_root_user();
2820         } else {
2821                 SMB_ASSERT(call->need_tcon);
2822         }
2823
2824 #define _INBYTES(_r) \
2825         iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2826
2827         switch (opcode) {
2828         case SMB2_OP_NEGPROT:
2829                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
2830                                                req->profile, _INBYTES(req));
2831                 return_value = smbd_smb2_request_process_negprot(req);
2832                 break;
2833
2834         case SMB2_OP_SESSSETUP:
2835                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
2836                                                req->profile, _INBYTES(req));
2837                 return_value = smbd_smb2_request_process_sesssetup(req);
2838                 break;
2839
2840         case SMB2_OP_LOGOFF:
2841                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
2842                                                req->profile, _INBYTES(req));
2843                 return_value = smbd_smb2_request_process_logoff(req);
2844                 break;
2845
2846         case SMB2_OP_TCON:
2847                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
2848                                                req->profile, _INBYTES(req));
2849                 return_value = smbd_smb2_request_process_tcon(req);
2850                 break;
2851
2852         case SMB2_OP_TDIS:
2853                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
2854                                                req->profile, _INBYTES(req));
2855                 return_value = smbd_smb2_request_process_tdis(req);
2856                 break;
2857
2858         case SMB2_OP_CREATE:
2859                 if (req->subreq == NULL) {
2860                         SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
2861                                                        req->profile, _INBYTES(req));
2862                 } else {
2863                         SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
2864                 }
2865                 return_value = smbd_smb2_request_process_create(req);
2866                 break;
2867
2868         case SMB2_OP_CLOSE:
2869                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
2870                                                req->profile, _INBYTES(req));
2871                 return_value = smbd_smb2_request_process_close(req);
2872                 break;
2873
2874         case SMB2_OP_FLUSH:
2875                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
2876                                                req->profile, _INBYTES(req));
2877                 return_value = smbd_smb2_request_process_flush(req);
2878                 break;
2879
2880         case SMB2_OP_READ:
2881                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
2882                                                req->profile, _INBYTES(req));
2883                 return_value = smbd_smb2_request_process_read(req);
2884                 break;
2885
2886         case SMB2_OP_WRITE:
2887                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
2888                                                req->profile, _INBYTES(req));
2889                 return_value = smbd_smb2_request_process_write(req);
2890                 break;
2891
2892         case SMB2_OP_LOCK:
2893                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
2894                                                req->profile, _INBYTES(req));
2895                 return_value = smbd_smb2_request_process_lock(req);
2896                 break;
2897
2898         case SMB2_OP_IOCTL:
2899                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
2900                                                req->profile, _INBYTES(req));
2901                 return_value = smbd_smb2_request_process_ioctl(req);
2902                 break;
2903
2904         case SMB2_OP_CANCEL:
2905                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
2906                                                req->profile, _INBYTES(req));
2907                 return_value = smbd_smb2_request_process_cancel(req);
2908                 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
2909
2910                 /*
2911                  * We don't need the request anymore cancel requests never
2912                  * have a response.
2913                  *
2914                  * smbd_smb2_request_process_cancel() already called
2915                  * DLIST_REMOVE(xconn->smb2.requests, req);
2916                  */
2917                 TALLOC_FREE(req);
2918
2919                 break;
2920
2921         case SMB2_OP_KEEPALIVE:
2922                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
2923                                                req->profile, _INBYTES(req));
2924                 return_value = smbd_smb2_request_process_keepalive(req);
2925                 break;
2926
2927         case SMB2_OP_QUERY_DIRECTORY:
2928                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
2929                                                req->profile, _INBYTES(req));
2930                 return_value = smbd_smb2_request_process_query_directory(req);
2931                 break;
2932
2933         case SMB2_OP_NOTIFY:
2934                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
2935                                                req->profile, _INBYTES(req));
2936                 return_value = smbd_smb2_request_process_notify(req);
2937                 break;
2938
2939         case SMB2_OP_GETINFO:
2940                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
2941                                                req->profile, _INBYTES(req));
2942                 return_value = smbd_smb2_request_process_getinfo(req);
2943                 break;
2944
2945         case SMB2_OP_SETINFO:
2946                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
2947                                                req->profile, _INBYTES(req));
2948                 return_value = smbd_smb2_request_process_setinfo(req);
2949                 break;
2950
2951         case SMB2_OP_BREAK:
2952                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
2953                                                req->profile, _INBYTES(req));
2954                 return_value = smbd_smb2_request_process_break(req);
2955                 break;
2956
2957         default:
2958                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2959                 break;
2960         }
2961         return return_value;
2962 }
2963
2964 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
2965 {
2966         struct smbXsrv_connection *xconn = req->xconn;
2967         const uint8_t *inhdr;
2968         uint16_t channel_sequence;
2969         struct smbXsrv_open *op;
2970
2971         if (!req->request_counters_updated) {
2972                 return;
2973         }
2974
2975         req->request_counters_updated = false;
2976
2977         if (xconn->protocol < PROTOCOL_SMB2_22) {
2978                 return;
2979         }
2980
2981         if (req->compat_chain_fsp == NULL) {
2982                 return;
2983         }
2984
2985         op = req->compat_chain_fsp->op;
2986         if (op == NULL) {
2987                 return;
2988         }
2989
2990         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2991         channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2992
2993         if ((op->global->channel_sequence == channel_sequence) &&
2994             (op->global->channel_generation == req->channel_generation)) {
2995                 SMB_ASSERT(op->request_count > 0);
2996                 op->request_count -= 1;
2997         } else {
2998                 SMB_ASSERT(op->pre_request_count > 0);
2999                 op->pre_request_count -= 1;
3000         }
3001 }
3002
3003 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
3004 {
3005         struct smbXsrv_connection *xconn = req->xconn;
3006         int first_idx = 1;
3007         struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
3008         struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
3009         struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
3010         NTSTATUS status;
3011         bool ok;
3012
3013         req->subreq = NULL;
3014         TALLOC_FREE(req->async_te);
3015
3016         /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3017         smbd_smb2_request_reply_update_counts(req);
3018
3019         if (req->do_encryption &&
3020             (firsttf->iov_len == 0) &&
3021             (req->first_key.length == 0) &&
3022             (req->session != NULL) &&
3023             smb2_signing_key_valid(req->session->global->encryption_key))
3024         {
3025                 struct smb2_signing_key *encryption_key =
3026                         req->session->global->encryption_key;
3027                 uint8_t *tf;
3028                 uint64_t session_id = req->session->global->session_wire_id;
3029                 uint64_t nonce_high;
3030                 uint64_t nonce_low;
3031
3032                 status = smb2_get_new_nonce(req->session,
3033                                             &nonce_high,
3034                                             &nonce_low);
3035                 if (!NT_STATUS_IS_OK(status)) {
3036                         return status;
3037                 }
3038
3039                 /*
3040                  * We need to place the SMB2_TRANSFORM header before the
3041                  * first SMB2 header
3042                  */
3043
3044                 /*
3045                  * we need to remember the encryption key
3046                  * and defer the signing/encryption until
3047                  * we are sure that we do not change
3048                  * the header again.
3049                  */
3050                 req->first_key = data_blob_dup_talloc(req,
3051                                                       encryption_key->blob);
3052                 if (req->first_key.data == NULL) {
3053                         return NT_STATUS_NO_MEMORY;
3054                 }
3055
3056                 tf = talloc_zero_array(req, uint8_t,
3057                                        SMB2_TF_HDR_SIZE);
3058                 if (tf == NULL) {
3059                         return NT_STATUS_NO_MEMORY;
3060                 }
3061
3062                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3063                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
3064                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
3065                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
3066
3067                 firsttf->iov_base = (void *)tf;
3068                 firsttf->iov_len = SMB2_TF_HDR_SIZE;
3069         }
3070
3071         if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
3072             (req->last_key.length > 0) &&
3073             (firsttf->iov_len == 0))
3074         {
3075                 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
3076                 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
3077                 struct smb2_signing_key key = {
3078                         .blob = req->last_key,
3079                 };
3080
3081                 /*
3082                  * As we are sure the header of the last request in the
3083                  * compound chain will not change, we can to sign here
3084                  * with the last signing key we remembered.
3085                  */
3086                 status = smb2_signing_sign_pdu(&key,
3087                                                xconn->protocol,
3088                                                lasthdr,
3089                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3090                 smb2_signing_key_destructor(&key);
3091                 if (!NT_STATUS_IS_OK(status)) {
3092                         return status;
3093                 }
3094         }
3095         if (req->last_key.length > 0) {
3096                 data_blob_clear_free(&req->last_key);
3097         }
3098
3099         SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
3100                 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
3101
3102         req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
3103
3104         if (req->current_idx < req->out.vector_count) {
3105                 /*
3106                  * We must process the remaining compound
3107                  * SMB2 requests before any new incoming SMB2
3108                  * requests. This is because incoming SMB2
3109                  * requests may include a cancel for a
3110                  * compound request we haven't processed
3111                  * yet.
3112                  */
3113                 struct tevent_immediate *im = tevent_create_immediate(req);
3114                 if (!im) {
3115                         return NT_STATUS_NO_MEMORY;
3116                 }
3117
3118                 if (req->do_signing && firsttf->iov_len == 0) {
3119                         struct smbXsrv_session *x = req->session;
3120                         struct smb2_signing_key *signing_key =
3121                                 smbd_smb2_signing_key(x, xconn);
3122
3123                         /*
3124                          * we need to remember the signing key
3125                          * and defer the signing until
3126                          * we are sure that we do not change
3127                          * the header again.
3128                          */
3129                         req->last_key = data_blob_dup_talloc(req,
3130                                                              signing_key->blob);
3131                         if (req->last_key.data == NULL) {
3132                                 return NT_STATUS_NO_MEMORY;
3133                         }
3134                 }
3135
3136                 /*
3137                  * smbd_smb2_request_dispatch() will redo the impersonation.
3138                  * So we use req->xconn->client->raw_ev_ctx instead
3139                  * of req->ev_ctx here.
3140                  */
3141                 tevent_schedule_immediate(im,
3142                                         req->xconn->client->raw_ev_ctx,
3143                                         smbd_smb2_request_dispatch_immediate,
3144                                         req);
3145                 return NT_STATUS_OK;
3146         }
3147
3148         if (req->compound_related) {
3149                 req->compound_related = false;
3150         }
3151
3152         ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
3153         if (!ok) {
3154                 return NT_STATUS_INVALID_PARAMETER_MIX;
3155         }
3156
3157         /* Set credit for these operations (zero credits if this
3158            is a final reply for an async operation). */
3159         smb2_calculate_credits(req, req);
3160
3161         /*
3162          * now check if we need to sign the current response
3163          */
3164         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3165                 struct smb2_signing_key key = {
3166                         .blob = req->first_key,
3167                 };
3168                 status = smb2_signing_encrypt_pdu(&key,
3169                                         xconn->smb2.server.cipher,
3170                                         firsttf,
3171                                         req->out.vector_count - first_idx);
3172                 smb2_signing_key_destructor(&key);
3173                 if (!NT_STATUS_IS_OK(status)) {
3174                         return status;
3175                 }
3176         } else if (req->do_signing) {
3177                 struct smbXsrv_session *x = req->session;
3178                 struct smb2_signing_key *signing_key =
3179                         smbd_smb2_signing_key(x, xconn);
3180
3181                 status = smb2_signing_sign_pdu(signing_key,
3182                                                xconn->protocol,
3183                                                outhdr,
3184                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3185                 if (!NT_STATUS_IS_OK(status)) {
3186                         return status;
3187                 }
3188         }
3189         if (req->first_key.length > 0) {
3190                 data_blob_clear_free(&req->first_key);
3191         }
3192
3193         if (req->preauth != NULL) {
3194                 gnutls_hash_hd_t hash_hnd = NULL;
3195                 size_t i;
3196                 int rc;
3197
3198                 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3199                 if (rc < 0) {
3200                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3201                 }
3202                 rc = gnutls_hash(hash_hnd,
3203                             req->preauth->sha512_value,
3204                             sizeof(req->preauth->sha512_value));
3205                 if (rc < 0) {
3206                         gnutls_hash_deinit(hash_hnd, NULL);
3207                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3208                 }
3209                 for (i = 1; i < req->in.vector_count; i++) {
3210                         rc = gnutls_hash(hash_hnd,
3211                                          req->in.vector[i].iov_base,
3212                                          req->in.vector[i].iov_len);
3213                         if (rc < 0) {
3214                                 gnutls_hash_deinit(hash_hnd, NULL);
3215                                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3216                         }
3217                 }
3218                 if (rc < 0) {
3219                         gnutls_hash_deinit(hash_hnd, NULL);
3220                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3221                 }
3222                 gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3223
3224                 rc = gnutls_hash(hash_hnd,
3225                                  req->preauth->sha512_value,
3226                                  sizeof(req->preauth->sha512_value));
3227                 if (rc < 0) {
3228                         gnutls_hash_deinit(hash_hnd, NULL);
3229                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3230                 }
3231                 for (i = 1; i < req->out.vector_count; i++) {
3232                         rc = gnutls_hash(hash_hnd,
3233                                          req->out.vector[i].iov_base,
3234                                          req->out.vector[i].iov_len);
3235                         if (rc < 0) {
3236                                 gnutls_hash_deinit(hash_hnd, NULL);
3237                                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3238                         }
3239                 }
3240
3241                 gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3242
3243                 req->preauth = NULL;
3244         }
3245
3246         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3247         if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3248             outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3249                 /* Dynamic part is NULL. Chop it off,
3250                    We're going to send it via sendfile. */
3251                 req->out.vector_count -= 1;
3252         }
3253
3254         /*
3255          * We're done with this request -
3256          * move it off the "being processed" queue.
3257          */
3258         DLIST_REMOVE(xconn->smb2.requests, req);
3259
3260         req->queue_entry.mem_ctx = req;
3261         req->queue_entry.vector = req->out.vector;
3262         req->queue_entry.count = req->out.vector_count;
3263         DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3264         xconn->smb2.send_queue_len++;
3265
3266         status = smbd_smb2_flush_send_queue(xconn);
3267         if (!NT_STATUS_IS_OK(status)) {
3268                 return status;
3269         }
3270
3271         return NT_STATUS_OK;
3272 }
3273
3274 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3275
3276 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3277                                         struct tevent_immediate *im,
3278                                         void *private_data)
3279 {
3280         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3281                                         struct smbd_smb2_request);
3282         struct smbXsrv_connection *xconn = req->xconn;
3283         NTSTATUS status;
3284
3285         TALLOC_FREE(im);
3286
3287         if (DEBUGLEVEL >= 10) {
3288                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3289                         req->current_idx, req->in.vector_count));
3290                 print_req_vectors(req);
3291         }
3292
3293         status = smbd_smb2_request_dispatch(req);
3294         if (!NT_STATUS_IS_OK(status)) {
3295                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3296                 return;
3297         }
3298
3299         status = smbd_smb2_request_next_incoming(xconn);
3300         if (!NT_STATUS_IS_OK(status)) {
3301                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3302                 return;
3303         }
3304 }
3305
3306 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3307                                    NTSTATUS status,
3308                                    DATA_BLOB body, DATA_BLOB *dyn,
3309                                    const char *location)
3310 {
3311         uint8_t *outhdr;
3312         struct iovec *outbody_v;
3313         struct iovec *outdyn_v;
3314         uint32_t next_command_ofs;
3315         uint64_t mid;
3316
3317         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3318         mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
3319
3320         DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
3321                   "body[%u] dyn[%s:%u] at %s\n",
3322                   mid,
3323                   req->current_idx,
3324                   nt_errstr(status),
3325                   (unsigned int)body.length,
3326                   dyn ? "yes" : "no",
3327                   (unsigned int)(dyn ? dyn->length : 0),
3328                   location);
3329
3330         if (body.length < 2) {
3331                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3332         }
3333
3334         if ((body.length % 2) != 0) {
3335                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3336         }
3337
3338         outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3339         outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3340
3341         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3342         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3343
3344         outbody_v->iov_base = (void *)body.data;
3345         outbody_v->iov_len = body.length;
3346
3347         if (dyn) {
3348                 outdyn_v->iov_base = (void *)dyn->data;
3349                 outdyn_v->iov_len = dyn->length;
3350         } else {
3351                 outdyn_v->iov_base = NULL;
3352                 outdyn_v->iov_len = 0;
3353         }
3354
3355         /*
3356          * See if we need to recalculate the offset to the next response
3357          *
3358          * Note that all responses may require padding (including the very last
3359          * one).
3360          */
3361         if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3362                 next_command_ofs  = SMB2_HDR_BODY;
3363                 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3364                 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3365         }
3366
3367         if ((next_command_ofs % 8) != 0) {
3368                 size_t pad_size = 8 - (next_command_ofs % 8);
3369                 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3370                         /*
3371                          * if the dyn buffer is empty
3372                          * we can use it to add padding
3373                          */
3374                         uint8_t *pad;
3375
3376                         pad = talloc_zero_array(req,
3377                                                 uint8_t, pad_size);
3378                         if (pad == NULL) {
3379                                 return smbd_smb2_request_error(req,
3380                                                 NT_STATUS_NO_MEMORY);
3381                         }
3382
3383                         outdyn_v->iov_base = (void *)pad;
3384                         outdyn_v->iov_len = pad_size;
3385                 } else {
3386                         /*
3387                          * For now we copy the dynamic buffer
3388                          * and add the padding to the new buffer
3389                          */
3390                         size_t old_size;
3391                         uint8_t *old_dyn;
3392                         size_t new_size;
3393                         uint8_t *new_dyn;
3394
3395                         old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3396                         old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3397
3398                         new_size = old_size + pad_size;
3399                         new_dyn = talloc_zero_array(req,
3400                                                uint8_t, new_size);
3401                         if (new_dyn == NULL) {
3402                                 return smbd_smb2_request_error(req,
3403                                                 NT_STATUS_NO_MEMORY);
3404                         }
3405
3406                         memcpy(new_dyn, old_dyn, old_size);
3407                         memset(new_dyn + old_size, 0, pad_size);
3408
3409                         outdyn_v->iov_base = (void *)new_dyn;
3410                         outdyn_v->iov_len = new_size;
3411                 }
3412                 next_command_ofs += pad_size;
3413         }
3414
3415         if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3416                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3417         } else {
3418                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3419         }
3420         return smbd_smb2_request_reply(req);
3421 }
3422
3423 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3424                                     NTSTATUS status,
3425                                     DATA_BLOB *info,
3426                                     const char *location)
3427 {
3428         struct smbXsrv_connection *xconn = req->xconn;
3429         DATA_BLOB body;
3430         DATA_BLOB _dyn;
3431         uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3432         size_t unread_bytes = smbd_smb2_unread_bytes(req);
3433
3434         DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3435                    "at %s\n", req->current_idx, nt_errstr(status),
3436                    info ? " +info" : "", location);
3437
3438         if (unread_bytes) {
3439                 /* Recvfile error. Drain incoming socket. */
3440                 size_t ret;
3441
3442                 errno = 0;
3443                 ret = drain_socket(xconn->transport.sock, unread_bytes);
3444                 if (ret != unread_bytes) {
3445                         NTSTATUS error;
3446
3447                         if (errno == 0) {
3448                                 error = NT_STATUS_IO_DEVICE_ERROR;
3449                         } else {
3450                                 error = map_nt_error_from_unix_common(errno);
3451                         }
3452
3453                         DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3454                                   "ret[%u] errno[%d] => %s\n",
3455                                   (unsigned)unread_bytes,
3456                                   (unsigned)ret, errno, nt_errstr(error)));
3457                         return error;
3458                 }
3459         }
3460
3461         body.data = outhdr + SMB2_HDR_BODY;
3462         body.length = 8;
3463         SSVAL(body.data, 0, 9);
3464
3465         if (info) {
3466                 SIVAL(body.data, 0x04, info->length);
3467         } else {
3468                 /* Allocated size of req->out.vector[i].iov_base
3469                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3470                  * 1 byte without having to do an alloc.
3471                  */
3472                 info = &_dyn;
3473                 info->data = ((uint8_t *)outhdr) +
3474                         OUTVEC_ALLOC_SIZE - 1;
3475                 info->length = 1;
3476                 SCVAL(info->data, 0, 0);
3477         }
3478
3479         /*
3480          * Note: Even if there is an error, continue to process the request.
3481          * per MS-SMB2.
3482          */
3483
3484         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
3485 }
3486
3487
3488 struct smbd_smb2_send_break_state {
3489         struct smbd_smb2_send_queue queue_entry;
3490         uint8_t nbt_hdr[NBT_HDR_SIZE];
3491         uint8_t tf[SMB2_TF_HDR_SIZE];
3492         uint8_t hdr[SMB2_HDR_BODY];
3493         struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
3494         uint8_t body[1];
3495 };
3496
3497 static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
3498                                      struct smbXsrv_session *session,
3499                                      struct smbXsrv_tcon *tcon,
3500                                      const uint8_t *body,
3501                                      size_t body_len)
3502 {
3503         struct smbd_smb2_send_break_state *state;
3504         bool do_encryption = false;
3505         uint64_t session_wire_id = 0;
3506         uint64_t nonce_high = 0;
3507         uint64_t nonce_low = 0;
3508         NTSTATUS status;
3509         size_t statelen;
3510         bool ok;
3511
3512         if (session != NULL) {
3513                 session_wire_id = session->global->session_wire_id;
3514                 do_encryption = session->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3515                 if (tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3516                         do_encryption = true;
3517                 }
3518         }
3519
3520         statelen = offsetof(struct smbd_smb2_send_break_state, body) +
3521                 body_len;
3522
3523         state = talloc_zero_size(xconn, statelen);
3524         if (state == NULL) {
3525                 return NT_STATUS_NO_MEMORY;
3526         }
3527         talloc_set_name_const(state, "struct smbd_smb2_send_break_state");
3528
3529         if (do_encryption) {
3530                 status = smb2_get_new_nonce(session,
3531                                             &nonce_high,
3532                                             &nonce_low);
3533                 if (!NT_STATUS_IS_OK(status)) {
3534                         return status;
3535                 }
3536         }
3537
3538         SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3539         SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
3540         SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
3541         SBVAL(state->tf, SMB2_TF_SESSION_ID, session_wire_id);
3542
3543         SIVAL(state->hdr, 0,                            SMB2_MAGIC);
3544         SSVAL(state->hdr, SMB2_HDR_LENGTH,              SMB2_HDR_BODY);
3545         SSVAL(state->hdr, SMB2_HDR_EPOCH,               0);
3546         SIVAL(state->hdr, SMB2_HDR_STATUS,              0);
3547         SSVAL(state->hdr, SMB2_HDR_OPCODE,              SMB2_OP_BREAK);
3548         SSVAL(state->hdr, SMB2_HDR_CREDIT,              0);
3549         SIVAL(state->hdr, SMB2_HDR_FLAGS,               SMB2_HDR_FLAG_REDIRECT);
3550         SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND,        0);
3551         SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID,          UINT64_MAX);
3552         SIVAL(state->hdr, SMB2_HDR_PID,         0);
3553         SIVAL(state->hdr, SMB2_HDR_TID,         0);
3554         SBVAL(state->hdr, SMB2_HDR_SESSION_ID,          0);
3555         memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
3556
3557         state->vector[0] = (struct iovec) {
3558                 .iov_base = state->nbt_hdr,
3559                 .iov_len  = sizeof(state->nbt_hdr)
3560         };
3561
3562         if (do_encryption) {
3563                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3564                         .iov_base = state->tf,
3565                         .iov_len  = sizeof(state->tf)
3566                 };
3567         } else {
3568                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3569                         .iov_base = NULL,
3570                         .iov_len  = 0
3571                 };
3572         }
3573
3574         state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
3575                 .iov_base = state->hdr,
3576                 .iov_len  = sizeof(state->hdr)
3577         };
3578
3579         memcpy(state->body, body, body_len);
3580
3581         state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
3582                 .iov_base = state->body,
3583                 .iov_len  = body_len /* no sizeof(state->body) .. :-) */
3584         };
3585
3586         /*
3587          * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
3588          */
3589
3590         ok = smb2_setup_nbt_length(state->vector,
3591                                    1 + SMBD_SMB2_NUM_IOV_PER_REQ);
3592         if (!ok) {
3593                 return NT_STATUS_INVALID_PARAMETER_MIX;
3594         }
3595
3596         if (do_encryption) {
3597                 struct smb2_signing_key *encryption_key =
3598                         session->global->encryption_key;
3599
3600                 status = smb2_signing_encrypt_pdu(encryption_key,
3601                                         xconn->smb2.server.cipher,
3602                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
3603                                         SMBD_SMB2_NUM_IOV_PER_REQ);
3604                 if (!NT_STATUS_IS_OK(status)) {
3605                         return status;
3606                 }
3607         }
3608
3609         state->queue_entry.mem_ctx = state;
3610         state->queue_entry.vector = state->vector;
3611         state->queue_entry.count = ARRAY_SIZE(state->vector);
3612         DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
3613         xconn->smb2.send_queue_len++;
3614
3615         status = smbd_smb2_flush_send_queue(xconn);
3616         if (!NT_STATUS_IS_OK(status)) {
3617                 return status;
3618         }
3619
3620         return NT_STATUS_OK;
3621 }
3622
3623 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
3624                                      struct smbXsrv_session *session,
3625                                      struct smbXsrv_tcon *tcon,
3626                                      struct smbXsrv_open *op,
3627                                      uint8_t oplock_level)
3628 {
3629         uint8_t body[0x18];
3630
3631         SSVAL(body, 0x00, sizeof(body));
3632         SCVAL(body, 0x02, oplock_level);
3633         SCVAL(body, 0x03, 0);           /* reserved */
3634         SIVAL(body, 0x04, 0);           /* reserved */
3635         SBVAL(body, 0x08, op->global->open_persistent_id);
3636         SBVAL(body, 0x10, op->global->open_volatile_id);
3637
3638         return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3639 }
3640
3641 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
3642                                     uint16_t new_epoch,
3643                                     uint32_t lease_flags,
3644                                     struct smb2_lease_key *lease_key,
3645                                     uint32_t current_lease_state,
3646                                     uint32_t new_lease_state)
3647 {
3648         uint8_t body[0x2c];
3649
3650         SSVAL(body, 0x00, sizeof(body));
3651         SSVAL(body, 0x02, new_epoch);
3652         SIVAL(body, 0x04, lease_flags);
3653         SBVAL(body, 0x08, lease_key->data[0]);
3654         SBVAL(body, 0x10, lease_key->data[1]);
3655         SIVAL(body, 0x18, current_lease_state);
3656         SIVAL(body, 0x1c, new_lease_state);
3657         SIVAL(body, 0x20, 0);           /* BreakReason, MUST be 0 */
3658         SIVAL(body, 0x24, 0);           /* AccessMaskHint, MUST be 0 */
3659         SIVAL(body, 0x28, 0);           /* ShareMaskHint, MUST be 0 */
3660
3661         return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3662 }
3663
3664 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
3665 {
3666         NTSTATUS status;
3667         uint32_t flags;
3668         uint64_t file_id_persistent;
3669         uint64_t file_id_volatile;
3670         struct smbXsrv_open *op = NULL;
3671         struct files_struct *fsp = NULL;
3672         const uint8_t *body = NULL;
3673
3674         /*
3675          * This is only called with a pktbuf
3676          * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
3677          * bytes
3678          */
3679
3680         if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
3681                 /* Transform header. Cannot recvfile. */
3682                 return false;
3683         }
3684         if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
3685                 /* Not SMB2. Normal error path will cope. */
3686                 return false;
3687         }
3688         if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
3689                 /* Not SMB2. Normal error path will cope. */
3690                 return false;
3691         }
3692         if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
3693                 /* Needs to be a WRITE. */
3694                 return false;
3695         }
3696         if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
3697                 /* Chained. Cannot recvfile. */
3698                 return false;
3699         }
3700         flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
3701         if (flags & SMB2_HDR_FLAG_CHAINED) {
3702                 /* Chained. Cannot recvfile. */
3703                 return false;
3704         }
3705         if (flags & SMB2_HDR_FLAG_SIGNED) {
3706                 /* Signed. Cannot recvfile. */
3707                 return false;
3708         }
3709
3710         body = &state->pktbuf[SMB2_HDR_BODY];
3711
3712         file_id_persistent      = BVAL(body, 0x10);
3713         file_id_volatile        = BVAL(body, 0x18);
3714
3715         status = smb2srv_open_lookup(state->req->xconn,
3716                                      file_id_persistent,
3717                                      file_id_volatile,
3718                                      0, /* now */
3719                                      &op);
3720         if (!NT_STATUS_IS_OK(status)) {
3721                 return false;
3722         }
3723
3724         fsp = op->compat;
3725         if (fsp == NULL) {
3726                 return false;
3727         }
3728         if (fsp->conn == NULL) {
3729                 return false;
3730         }
3731
3732         if (IS_IPC(fsp->conn)) {
3733                 return false;
3734         }
3735         if (IS_PRINT(fsp->conn)) {
3736                 return false;
3737         }
3738         if (fsp->base_fsp != NULL) {
3739                 return false;
3740         }
3741
3742         DEBUG(10,("Doing recvfile write len = %u\n",
3743                 (unsigned int)(state->pktfull - state->pktlen)));
3744
3745         return true;
3746 }
3747
3748 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
3749 {
3750         struct smbd_server_connection *sconn = xconn->client->sconn;
3751         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3752         size_t max_send_queue_len;
3753         size_t cur_send_queue_len;
3754
3755         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3756                 /*
3757                  * we're not supposed to do any io
3758                  */
3759                 return NT_STATUS_OK;
3760         }
3761
3762         if (state->req != NULL) {
3763                 /*
3764                  * if there is already a tstream_readv_pdu
3765                  * pending, we are done.
3766                  */
3767                 return NT_STATUS_OK;
3768         }
3769
3770         max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
3771         cur_send_queue_len = xconn->smb2.send_queue_len;
3772
3773         if (cur_send_queue_len > max_send_queue_len) {
3774                 /*
3775                  * if we have a lot of requests to send,
3776                  * we wait until they are on the wire until we
3777                  * ask for the next request.
3778                  */
3779                 return NT_STATUS_OK;
3780         }
3781
3782         /* ask for the next request */
3783         ZERO_STRUCTP(state);
3784         state->req = smbd_smb2_request_allocate(xconn);
3785         if (state->req == NULL) {
3786                 return NT_STATUS_NO_MEMORY;
3787         }
3788         state->req->sconn = sconn;
3789         state->req->xconn = xconn;
3790         state->min_recv_size = lp_min_receive_file_size();
3791
3792         TEVENT_FD_READABLE(xconn->transport.fde);
3793
3794         return NT_STATUS_OK;
3795 }
3796
3797 NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
3798                                uint64_t expected_seq_low,
3799                                const uint8_t *inpdu, size_t size)
3800 {
3801         struct smbd_server_connection *sconn = xconn->client->sconn;
3802         NTSTATUS status;
3803         struct smbd_smb2_request *req = NULL;
3804
3805         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3806                  (unsigned int)size));
3807
3808         status = smbd_initialize_smb2(xconn, expected_seq_low);
3809         if (!NT_STATUS_IS_OK(status)) {
3810                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3811                 return status;
3812         }
3813
3814         status = smbd_smb2_request_create(xconn, inpdu, size, &req);
3815         if (!NT_STATUS_IS_OK(status)) {
3816                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3817                 return status;
3818         }
3819
3820         status = smbd_smb2_request_validate(req);
3821         if (!NT_STATUS_IS_OK(status)) {
3822                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3823                 return status;
3824         }
3825
3826         status = smbd_smb2_request_setup_out(req);
3827         if (!NT_STATUS_IS_OK(status)) {
3828                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3829                 return status;
3830         }
3831
3832 #ifdef WITH_PROFILE
3833         /*
3834          * this was already counted at the SMB1 layer =>
3835          * smbd_smb2_request_dispatch() should not count it twice.
3836          */
3837         if (profile_p->values.request_stats.count > 0) {
3838                 profile_p->values.request_stats.count--;
3839         }
3840 #endif
3841         status = smbd_smb2_request_dispatch(req);
3842         if (!NT_STATUS_IS_OK(status)) {
3843                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3844                 return status;
3845         }
3846
3847         status = smbd_smb2_request_next_incoming(xconn);
3848         if (!NT_STATUS_IS_OK(status)) {
3849                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3850                 return status;
3851         }
3852
3853         sconn->num_requests++;
3854         return NT_STATUS_OK;
3855 }
3856
3857 static int socket_error_from_errno(int ret,
3858                                    int sys_errno,
3859                                    bool *retry)
3860 {
3861         *retry = false;
3862
3863         if (ret >= 0) {
3864                 return 0;
3865         }
3866
3867         if (ret != -1) {
3868                 return EIO;
3869         }
3870
3871         if (sys_errno == 0) {
3872                 return EIO;
3873         }
3874
3875         if (sys_errno == EINTR) {
3876                 *retry = true;
3877                 return sys_errno;
3878         }
3879
3880         if (sys_errno == EINPROGRESS) {
3881                 *retry = true;
3882                 return sys_errno;
3883         }
3884
3885         if (sys_errno == EAGAIN) {
3886                 *retry = true;
3887                 return sys_errno;
3888         }
3889
3890         /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3891         if (sys_errno == ENOMEM) {
3892                 *retry = true;
3893                 return sys_errno;
3894         }
3895
3896 #ifdef EWOULDBLOCK
3897 #if EWOULDBLOCK != EAGAIN
3898         if (sys_errno == EWOULDBLOCK) {
3899                 *retry = true;
3900                 return sys_errno;
3901         }
3902 #endif
3903 #endif
3904
3905         return sys_errno;
3906 }
3907
3908 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
3909 {
3910         int ret;
3911         int err;
3912         bool retry;
3913         NTSTATUS status;
3914
3915         if (xconn->smb2.send_queue == NULL) {
3916                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3917                 return NT_STATUS_OK;
3918         }
3919
3920         while (xconn->smb2.send_queue != NULL) {
3921                 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
3922                 bool ok;
3923                 struct msghdr msg;
3924
3925                 if (e->sendfile_header != NULL) {
3926                         size_t size = 0;
3927                         size_t i = 0;
3928                         uint8_t *buf;
3929
3930                         status = NT_STATUS_INTERNAL_ERROR;
3931
3932                         for (i=0; i < e->count; i++) {
3933                                 size += e->vector[i].iov_len;
3934                         }
3935
3936                         if (size <= e->sendfile_header->length) {
3937                                 buf = e->sendfile_header->data;
3938                         } else {
3939                                 buf = talloc_array(e->mem_ctx, uint8_t, size);
3940                                 if (buf == NULL) {
3941                                         return NT_STATUS_NO_MEMORY;
3942                                 }
3943                         }
3944
3945                         size = 0;
3946                         for (i=0; i < e->count; i++) {
3947                                 memcpy(buf+size,
3948                                        e->vector[i].iov_base,
3949                                        e->vector[i].iov_len);
3950                                 size += e->vector[i].iov_len;
3951                         }
3952
3953                         e->sendfile_header->data = buf;
3954                         e->sendfile_header->length = size;
3955                         e->sendfile_status = &status;
3956                         e->count = 0;
3957
3958                         xconn->smb2.send_queue_len--;
3959                         DLIST_REMOVE(xconn->smb2.send_queue, e);
3960                         /*
3961                          * This triggers the sendfile path via
3962                          * the destructor.
3963                          */
3964                         talloc_free(e->mem_ctx);
3965
3966                         if (!NT_STATUS_IS_OK(status)) {
3967                                 smbXsrv_connection_disconnect_transport(xconn,
3968                                                                         status);
3969                                 return status;
3970                         }
3971                         continue;
3972                 }
3973
3974                 msg = (struct msghdr) {
3975                         .msg_iov = e->vector,
3976                         .msg_iovlen = e->count,
3977                 };
3978
3979                 ret = sendmsg(xconn->transport.sock, &msg, 0);
3980                 if (ret == 0) {
3981                         /* propagate end of file */
3982                         return NT_STATUS_INTERNAL_ERROR;
3983                 }
3984                 err = socket_error_from_errno(ret, errno, &retry);
3985                 if (retry) {
3986                         /* retry later */
3987                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3988                         return NT_STATUS_OK;
3989                 }
3990                 if (err != 0) {
3991                         status = map_nt_error_from_unix_common(err);
3992                         smbXsrv_connection_disconnect_transport(xconn,
3993                                                                 status);
3994                         return status;
3995                 }
3996
3997                 ok = iov_advance(&e->vector, &e->count, ret);
3998                 if (!ok) {
3999                         return NT_STATUS_INTERNAL_ERROR;
4000                 }
4001
4002                 if (e->count > 0) {
4003                         /* we have more to write */
4004                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
4005                         return NT_STATUS_OK;
4006                 }
4007
4008                 xconn->smb2.send_queue_len--;
4009                 DLIST_REMOVE(xconn->smb2.send_queue, e);
4010                 talloc_free(e->mem_ctx);
4011         }
4012
4013         /*
4014          * Restart reads if we were blocked on
4015          * draining the send queue.
4016          */
4017
4018         status = smbd_smb2_request_next_incoming(xconn);
4019         if (!NT_STATUS_IS_OK(status)) {
4020                 return status;
4021         }
4022
4023         return NT_STATUS_OK;
4024 }
4025
4026 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
4027                                      uint16_t fde_flags)
4028 {
4029         struct smbd_server_connection *sconn = xconn->client->sconn;
4030         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4031         struct smbd_smb2_request *req = NULL;
4032         size_t min_recvfile_size = UINT32_MAX;
4033         int ret;
4034         int err;
4035         bool retry;
4036         NTSTATUS status;
4037         NTTIME now;
4038         struct msghdr msg;
4039
4040         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4041                 /*
4042                  * we're not supposed to do any io
4043                  */
4044                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4045                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4046                 return NT_STATUS_OK;
4047         }
4048
4049         if (fde_flags & TEVENT_FD_WRITE) {
4050                 status = smbd_smb2_flush_send_queue(xconn);
4051                 if (!NT_STATUS_IS_OK(status)) {
4052                         return status;
4053                 }
4054         }
4055
4056         if (!(fde_flags & TEVENT_FD_READ)) {
4057                 return NT_STATUS_OK;
4058         }
4059
4060         if (state->req == NULL) {
4061                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4062                 return NT_STATUS_OK;
4063         }
4064
4065 again:
4066         if (!state->hdr.done) {
4067                 state->hdr.done = true;
4068
4069                 state->vector.iov_base = (void *)state->hdr.nbt;
4070                 state->vector.iov_len = NBT_HDR_SIZE;
4071         }
4072
4073         msg = (struct msghdr) {
4074                 .msg_iov = &state->vector,
4075                 .msg_iovlen = 1,
4076         };
4077
4078         ret = recvmsg(xconn->transport.sock, &msg, 0);
4079         if (ret == 0) {
4080                 /* propagate end of file */
4081                 status = NT_STATUS_END_OF_FILE;
4082                 smbXsrv_connection_disconnect_transport(xconn,
4083                                                         status);
4084                 return status;
4085         }
4086         err = socket_error_from_errno(ret, errno, &retry);
4087         if (retry) {
4088                 /* retry later */
4089                 TEVENT_FD_READABLE(xconn->transport.fde);
4090                 return NT_STATUS_OK;
4091         }
4092         if (err != 0) {
4093                 status = map_nt_error_from_unix_common(err);
4094                 smbXsrv_connection_disconnect_transport(xconn,
4095                                                         status);
4096                 return status;
4097         }
4098
4099         if (ret < state->vector.iov_len) {
4100                 uint8_t *base;
4101                 base = (uint8_t *)state->vector.iov_base;
4102                 base += ret;
4103                 state->vector.iov_base = (void *)base;
4104                 state->vector.iov_len -= ret;
4105                 /* we have more to read */
4106                 TEVENT_FD_READABLE(xconn->transport.fde);
4107                 return NT_STATUS_OK;
4108         }
4109
4110         if (state->pktlen > 0) {
4111                 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
4112                         /*
4113                          * Not a possible receivefile write.
4114                          * Read the rest of the data.
4115                          */
4116                         state->doing_receivefile = false;
4117
4118                         state->pktbuf = talloc_realloc(state->req,
4119                                                        state->pktbuf,
4120                                                        uint8_t,
4121                                                        state->pktfull);
4122                         if (state->pktbuf == NULL) {
4123                                 return NT_STATUS_NO_MEMORY;
4124                         }
4125
4126                         state->vector.iov_base = (void *)(state->pktbuf +
4127                                 state->pktlen);
4128                         state->vector.iov_len = (state->pktfull -
4129                                 state->pktlen);
4130
4131                         state->pktlen = state->pktfull;
4132                         goto again;
4133                 }
4134
4135                 /*
4136                  * Either this is a receivefile write so we've
4137                  * done a short read, or if not we have all the data.
4138                  */
4139                 goto got_full;
4140         }
4141
4142         /*
4143          * Now we analyze the NBT header
4144          */
4145         if (state->hdr.nbt[0] != 0x00) {
4146                 state->min_recv_size = 0;
4147         }
4148         state->pktfull = smb2_len(state->hdr.nbt);
4149         if (state->pktfull == 0) {
4150                 goto got_full;
4151         }
4152
4153         if (state->min_recv_size != 0) {
4154                 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4155                 min_recvfile_size += state->min_recv_size;
4156         }
4157
4158         if (state->pktfull > min_recvfile_size) {
4159                 /*
4160                  * Might be a receivefile write. Read the SMB2 HEADER +
4161                  * SMB2_WRITE header first. Set 'doing_receivefile'
4162                  * as we're *attempting* receivefile write. If this
4163                  * turns out not to be a SMB2_WRITE request or otherwise
4164                  * not suitable then we'll just read the rest of the data
4165                  * the next time this function is called.
4166                  */
4167                 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4168                 state->doing_receivefile = true;
4169         } else {
4170                 state->pktlen = state->pktfull;
4171         }
4172
4173         state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
4174         if (state->pktbuf == NULL) {
4175                 return NT_STATUS_NO_MEMORY;
4176         }
4177
4178         state->vector.iov_base = (void *)state->pktbuf;
4179         state->vector.iov_len = state->pktlen;
4180
4181         goto again;
4182
4183 got_full:
4184
4185         if (state->hdr.nbt[0] != 0x00) {
4186                 DEBUG(1,("ignore NBT[0x%02X] msg\n",
4187                          state->hdr.nbt[0]));
4188
4189                 req = state->req;
4190                 ZERO_STRUCTP(state);
4191                 state->req = req;
4192                 state->min_recv_size = lp_min_receive_file_size();
4193                 req = NULL;
4194                 goto again;
4195         }
4196
4197         req = state->req;
4198         state->req = NULL;
4199
4200         req->request_time = timeval_current();
4201         now = timeval_to_nttime(&req->request_time);
4202
4203         status = smbd_smb2_inbuf_parse_compound(xconn,
4204                                                 now,
4205                                                 state->pktbuf,
4206                                                 state->pktlen,
4207                                                 req,
4208                                                 &req->in.vector,
4209                                                 &req->in.vector_count);
4210         if (!NT_STATUS_IS_OK(status)) {
4211                 return status;
4212         }
4213
4214         if (state->doing_receivefile) {
4215                 req->smb1req = talloc_zero(req, struct smb_request);
4216                 if (req->smb1req == NULL) {
4217                         return NT_STATUS_NO_MEMORY;
4218                 }
4219                 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
4220         }
4221
4222         ZERO_STRUCTP(state);
4223
4224         req->current_idx = 1;
4225
4226         DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
4227                  req->current_idx, req->in.vector_count));
4228
4229         status = smbd_smb2_request_validate(req);
4230         if (!NT_STATUS_IS_OK(status)) {
4231                 return status;
4232         }
4233
4234         status = smbd_smb2_request_setup_out(req);
4235         if (!NT_STATUS_IS_OK(status)) {
4236                 return status;
4237         }
4238
4239         status = smbd_smb2_request_dispatch(req);
4240         if (!NT_STATUS_IS_OK(status)) {
4241                 return status;
4242         }
4243
4244         sconn->num_requests++;
4245
4246         /* The timeout_processing function isn't run nearly
4247            often enough to implement 'max log size' without
4248            overrunning the size of the file by many megabytes.
4249            This is especially true if we are running at debug
4250            level 10.  Checking every 50 SMB2s is a nice
4251            tradeoff of performance vs log file size overrun. */
4252
4253         if ((sconn->num_requests % 50) == 0 &&
4254             need_to_check_log_size()) {
4255                 change_to_root_user();
4256                 check_log_size();
4257         }
4258
4259         status = smbd_smb2_request_next_incoming(xconn);
4260         if (!NT_STATUS_IS_OK(status)) {
4261                 return status;
4262         }
4263
4264         return NT_STATUS_OK;
4265 }
4266
4267 static void smbd_smb2_connection_handler(struct tevent_context *ev,
4268                                          struct tevent_fd *fde,
4269                                          uint16_t flags,
4270                                          void *private_data)
4271 {
4272         struct smbXsrv_connection *xconn =
4273                 talloc_get_type_abort(private_data,
4274                 struct smbXsrv_connection);
4275         NTSTATUS status;
4276
4277         status = smbd_smb2_io_handler(xconn, flags);
4278         if (!NT_STATUS_IS_OK(status)) {
4279                 smbd_server_connection_terminate(xconn, nt_errstr(status));
4280                 return;
4281         }
4282 }