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