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