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