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