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