smbd: make canonicalize_snapshot_path() public
[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,
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                 struct smb2_signing_key key = {
1340                         .blob = req->first_key,
1341                 };
1342                 status = smb2_signing_encrypt_pdu(&key,
1343                                         xconn->smb2.server.cipher,
1344                                         firsttf,
1345                                         nreq->out.vector_count - first_idx);
1346                 smb2_signing_key_destructor(&key);
1347                 if (!NT_STATUS_IS_OK(status)) {
1348                         return status;
1349                 }
1350         } else if (req->last_key.length > 0) {
1351                 struct smb2_signing_key key = {
1352                         .blob = req->last_key,
1353                 };
1354
1355                 status = smb2_signing_sign_pdu(&key,
1356                                                xconn->protocol,
1357                                                outhdr_v,
1358                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1359                 smb2_signing_key_destructor(&key);
1360                 if (!NT_STATUS_IS_OK(status)) {
1361                         return status;
1362                 }
1363         }
1364
1365         nreq->queue_entry.mem_ctx = nreq;
1366         nreq->queue_entry.vector = nreq->out.vector;
1367         nreq->queue_entry.count = nreq->out.vector_count;
1368         DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
1369         xconn->smb2.send_queue_len++;
1370
1371         status = smbd_smb2_flush_send_queue(xconn);
1372         if (!NT_STATUS_IS_OK(status)) {
1373                 return status;
1374         }
1375
1376         return NT_STATUS_OK;
1377 }
1378
1379 struct smbd_smb2_request_pending_state {
1380         struct smbd_smb2_send_queue queue_entry;
1381         uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1382         struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1383 };
1384
1385 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1386                                             struct tevent_timer *te,
1387                                             struct timeval current_time,
1388                                             void *private_data);
1389
1390 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1391                                          struct tevent_req *subreq,
1392                                          uint32_t defer_time)
1393 {
1394         NTSTATUS status;
1395         struct timeval defer_endtime;
1396         uint8_t *outhdr = NULL;
1397         uint32_t flags;
1398
1399         if (!tevent_req_is_in_progress(subreq)) {
1400                 /*
1401                  * This is a performance optimization,
1402                  * it avoids one tevent_loop iteration,
1403                  * which means we avoid one
1404                  * talloc_stackframe_pool/talloc_free pair.
1405                  */
1406                 tevent_req_notify_callback(subreq);
1407                 return NT_STATUS_OK;
1408         }
1409
1410         req->subreq = subreq;
1411         subreq = NULL;
1412
1413         if (req->async_te) {
1414                 /* We're already async. */
1415                 return NT_STATUS_OK;
1416         }
1417
1418         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1419         flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1420         if (flags & SMB2_HDR_FLAG_ASYNC) {
1421                 /* We're already async. */
1422                 return NT_STATUS_OK;
1423         }
1424
1425         if (req->async_internal || defer_time == 0) {
1426                 /*
1427                  * An SMB2 request implementation wants to handle the request
1428                  * asynchronously "internally" while keeping synchronous
1429                  * behaviour for the SMB2 request. This means we don't send an
1430                  * interim response and we can allow processing of compound SMB2
1431                  * requests (cf the subsequent check) for all cases.
1432                  */
1433                 return NT_STATUS_OK;
1434         }
1435
1436         if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
1437                 /*
1438                  * We're trying to go async in a compound request
1439                  * chain. This is only allowed for opens that cause an
1440                  * oplock break or for the last operation in the
1441                  * chain, otherwise it is not allowed. See
1442                  * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
1443                  */
1444                 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1445
1446                 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
1447                         /*
1448                          * Cancel the outstanding request.
1449                          */
1450                         bool ok = tevent_req_cancel(req->subreq);
1451                         if (ok) {
1452                                 return NT_STATUS_OK;
1453                         }
1454                         TALLOC_FREE(req->subreq);
1455                         return smbd_smb2_request_error(req,
1456                                 NT_STATUS_INTERNAL_ERROR);
1457                 }
1458         }
1459
1460         if (DEBUGLEVEL >= 10) {
1461                 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1462                         (unsigned int)req->current_idx );
1463                 print_req_vectors(req);
1464         }
1465
1466         if (req->current_idx > 1) {
1467                 /*
1468                  * We're going async in a compound
1469                  * chain after the first request has
1470                  * already been processed. Send an
1471                  * interim response containing the
1472                  * set of replies already generated.
1473                  */
1474                 int idx = req->current_idx;
1475
1476                 status = smb2_send_async_interim_response(req);
1477                 if (!NT_STATUS_IS_OK(status)) {
1478                         return status;
1479                 }
1480                 if (req->first_key.length > 0) {
1481                         data_blob_clear_free(&req->first_key);
1482                 }
1483
1484                 req->current_idx = 1;
1485
1486                 /*
1487                  * Re-arrange the in.vectors to remove what
1488                  * we just sent.
1489                  */
1490                 memmove(&req->in.vector[1],
1491                         &req->in.vector[idx],
1492                         sizeof(req->in.vector[0])*(req->in.vector_count - idx));
1493                 req->in.vector_count = 1 + (req->in.vector_count - idx);
1494
1495                 /* Re-arrange the out.vectors to match. */
1496                 memmove(&req->out.vector[1],
1497                         &req->out.vector[idx],
1498                         sizeof(req->out.vector[0])*(req->out.vector_count - idx));
1499                 req->out.vector_count = 1 + (req->out.vector_count - idx);
1500
1501                 if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
1502                         /*
1503                          * We only have one remaining request as
1504                          * we've processed everything else.
1505                          * This is no longer a compound request.
1506                          */
1507                         req->compound_related = false;
1508                         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1509                         flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
1510                         SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
1511                 }
1512         }
1513         if (req->last_key.length > 0) {
1514                 data_blob_clear_free(&req->last_key);
1515         }
1516
1517         /*
1518          * smbd_smb2_request_pending_timer() just send a packet
1519          * to the client and doesn't need any impersonation.
1520          * So we use req->xconn->client->raw_ev_ctx instead
1521          * of req->ev_ctx here.
1522          */
1523         defer_endtime = timeval_current_ofs_usec(defer_time);
1524         req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
1525                                          req, defer_endtime,
1526                                          smbd_smb2_request_pending_timer,
1527                                          req);
1528         if (req->async_te == NULL) {
1529                 return NT_STATUS_NO_MEMORY;
1530         }
1531
1532         return NT_STATUS_OK;
1533 }
1534
1535 static
1536 struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
1537                                                struct smbXsrv_connection *xconn)
1538 {
1539         struct smbXsrv_channel_global0 *c = NULL;
1540         NTSTATUS status;
1541         struct smb2_signing_key *key = NULL;
1542
1543         status = smbXsrv_session_find_channel(session, xconn, &c);
1544         if (NT_STATUS_IS_OK(status)) {
1545                 key = c->signing_key;
1546         }
1547
1548         if (!smb2_signing_key_valid(key)) {
1549                 key = session->global->signing_key;
1550         }
1551
1552         return key;
1553 }
1554
1555 static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
1556                                    uint64_t *new_nonce_high,
1557                                    uint64_t *new_nonce_low)
1558 {
1559         uint64_t nonce_high;
1560         uint64_t nonce_low;
1561
1562         session->nonce_low += 1;
1563         if (session->nonce_low == 0) {
1564                 session->nonce_low += 1;
1565                 session->nonce_high += 1;
1566         }
1567
1568         /*
1569          * CCM and GCM algorithms must never have their
1570          * nonce wrap, or the security of the whole
1571          * communication and the keys is destroyed.
1572          * We must drop the connection once we have
1573          * transfered too much data.
1574          *
1575          * NOTE: We assume nonces greater than 8 bytes.
1576          */
1577         if (session->nonce_high >= session->nonce_high_max) {
1578                 return NT_STATUS_ENCRYPTION_FAILED;
1579         }
1580
1581         nonce_high = session->nonce_high_random;
1582         nonce_high += session->nonce_high;
1583         nonce_low = session->nonce_low;
1584
1585         *new_nonce_high = nonce_high;
1586         *new_nonce_low = nonce_low;
1587         return NT_STATUS_OK;
1588 }
1589
1590 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1591                                             struct tevent_timer *te,
1592                                             struct timeval current_time,
1593                                             void *private_data)
1594 {
1595         struct smbd_smb2_request *req =
1596                 talloc_get_type_abort(private_data,
1597                 struct smbd_smb2_request);
1598         struct smbXsrv_connection *xconn = req->xconn;
1599         struct smbd_smb2_request_pending_state *state = NULL;
1600         uint8_t *outhdr = NULL;
1601         const uint8_t *inhdr = NULL;
1602         uint8_t *tf = NULL;
1603         uint8_t *hdr = NULL;
1604         uint8_t *body = NULL;
1605         uint8_t *dyn = NULL;
1606         uint32_t flags = 0;
1607         uint64_t message_id = 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
1620         async_id = message_id; /* keep it simple for now... */
1621
1622         SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1623         SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
1624
1625         DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1626                 "going async\n",
1627                 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
1628                 (unsigned long long)async_id ));
1629
1630         /*
1631          * What we send is identical to a smbd_smb2_request_error
1632          * packet with an error status of STATUS_PENDING. Make use
1633          * of this fact sometime when refactoring. JRA.
1634          */
1635
1636         state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
1637         if (state == NULL) {
1638                 smbd_server_connection_terminate(xconn,
1639                                                  nt_errstr(NT_STATUS_NO_MEMORY));
1640                 return;
1641         }
1642
1643         tf = state->buf + NBT_HDR_SIZE;
1644
1645         hdr = tf + SMB2_TF_HDR_SIZE;
1646         body = hdr + SMB2_HDR_BODY;
1647         dyn = body + 8;
1648
1649         if (req->do_encryption) {
1650                 uint64_t nonce_high = 0;
1651                 uint64_t nonce_low = 0;
1652                 uint64_t session_id = req->session->global->session_wire_id;
1653
1654                 status = smb2_get_new_nonce(req->session,
1655                                             &nonce_high,
1656                                             &nonce_low);
1657                 if (!NT_STATUS_IS_OK(status)) {
1658                         smbd_server_connection_terminate(xconn,
1659                                                          nt_errstr(status));
1660                         return;
1661                 }
1662
1663                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
1664                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
1665                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
1666                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
1667         }
1668
1669         SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1670         SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1671         SSVAL(hdr, SMB2_HDR_EPOCH, 0);
1672         SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
1673         SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
1674
1675         SIVAL(hdr, SMB2_HDR_FLAGS, flags);
1676         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
1677         SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
1678         SBVAL(hdr, SMB2_HDR_PID, async_id);
1679         SBVAL(hdr, SMB2_HDR_SESSION_ID,
1680                 BVAL(outhdr, SMB2_HDR_SESSION_ID));
1681         memcpy(hdr+SMB2_HDR_SIGNATURE,
1682                outhdr+SMB2_HDR_SIGNATURE, 16);
1683
1684         SSVAL(body, 0x00, 0x08 + 1);
1685
1686         SCVAL(body, 0x02, 0);
1687         SCVAL(body, 0x03, 0);
1688         SIVAL(body, 0x04, 0);
1689         /* Match W2K8R2... */
1690         SCVAL(dyn,  0x00, 0x21);
1691
1692         state->vector[0].iov_base = (void *)state->buf;
1693         state->vector[0].iov_len = NBT_HDR_SIZE;
1694
1695         if (req->do_encryption) {
1696                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
1697                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    =
1698                                                         SMB2_TF_HDR_SIZE;
1699         } else {
1700                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
1701                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
1702         }
1703
1704         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
1705         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
1706
1707         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
1708         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
1709
1710         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
1711         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = 1;
1712
1713         ok = smb2_setup_nbt_length(state->vector,
1714                                    1 + SMBD_SMB2_NUM_IOV_PER_REQ);
1715         if (!ok) {
1716                 smbd_server_connection_terminate(
1717                         xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
1718                 return;
1719         }
1720
1721         /* Ensure we correctly go through crediting. Grant
1722            the credits now, and zero credits on the final
1723            response. */
1724         smb2_set_operation_credit(req->xconn,
1725                         SMBD_SMB2_IN_HDR_IOV(req),
1726                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
1727
1728         SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1729
1730         if (DEBUGLVL(10)) {
1731                 int i;
1732
1733                 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
1734                         dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1735                                 (unsigned int)i,
1736                                 (unsigned int)ARRAY_SIZE(state->vector),
1737                                 (unsigned int)state->vector[i].iov_len);
1738                 }
1739         }
1740
1741         if (req->do_encryption) {
1742                 struct smbXsrv_session *x = req->session;
1743                 struct smb2_signing_key *encryption_key = x->global->encryption_key;
1744
1745                 status = smb2_signing_encrypt_pdu(encryption_key,
1746                                         xconn->smb2.server.cipher,
1747                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
1748                                         SMBD_SMB2_NUM_IOV_PER_REQ);
1749                 if (!NT_STATUS_IS_OK(status)) {
1750                         smbd_server_connection_terminate(xconn,
1751                                                 nt_errstr(status));
1752                         return;
1753                 }
1754         } else if (req->do_signing) {
1755                 struct smbXsrv_session *x = req->session;
1756                 struct smb2_signing_key *signing_key =
1757                         smbd_smb2_signing_key(x, xconn);
1758
1759                 status = smb2_signing_sign_pdu(signing_key,
1760                                         xconn->protocol,
1761                                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS],
1762                                         SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1763                 if (!NT_STATUS_IS_OK(status)) {
1764                         smbd_server_connection_terminate(xconn,
1765                                                 nt_errstr(status));
1766                         return;
1767                 }
1768         }
1769
1770         state->queue_entry.mem_ctx = state;
1771         state->queue_entry.vector = state->vector;
1772         state->queue_entry.count = ARRAY_SIZE(state->vector);
1773         DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
1774         xconn->smb2.send_queue_len++;
1775
1776         status = smbd_smb2_flush_send_queue(xconn);
1777         if (!NT_STATUS_IS_OK(status)) {
1778                 smbd_server_connection_terminate(xconn,
1779                                                  nt_errstr(status));
1780                 return;
1781         }
1782 }
1783
1784 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
1785 {
1786         struct smbXsrv_connection *xconn = req->xconn;
1787         struct smbd_smb2_request *cur;
1788         const uint8_t *inhdr;
1789         uint32_t flags;
1790         uint64_t search_message_id;
1791         uint64_t search_async_id;
1792         uint64_t found_id;
1793
1794         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1795
1796         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1797         search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1798         search_async_id = BVAL(inhdr, SMB2_HDR_PID);
1799
1800         /*
1801          * We don't need the request anymore cancel requests never
1802          * have a response.
1803          *
1804          * We defer the TALLOC_FREE(req) to the caller.
1805          */
1806         DLIST_REMOVE(xconn->smb2.requests, req);
1807
1808         for (cur = xconn->smb2.requests; cur; cur = cur->next) {
1809                 const uint8_t *outhdr;
1810                 uint64_t message_id;
1811                 uint64_t async_id;
1812
1813                 if (cur->compound_related) {
1814                         /*
1815                          * Never cancel anything in a compound request.
1816                          * Way too hard to deal with the result.
1817                          */
1818                         continue;
1819                 }
1820
1821                 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
1822
1823                 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1824                 async_id = BVAL(outhdr, SMB2_HDR_PID);
1825
1826                 if (flags & SMB2_HDR_FLAG_ASYNC) {
1827                         if (search_async_id == async_id) {
1828                                 found_id = async_id;
1829                                 break;
1830                         }
1831                 } else {
1832                         if (search_message_id == message_id) {
1833                                 found_id = message_id;
1834                                 break;
1835                         }
1836                 }
1837         }
1838
1839         if (cur && cur->subreq) {
1840                 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
1841                 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1842                         "cancel opcode[%s] mid %llu\n",
1843                         smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
1844                         (unsigned long long)found_id ));
1845                 tevent_req_cancel(cur->subreq);
1846         }
1847
1848         return NT_STATUS_OK;
1849 }
1850
1851 /*************************************************************
1852  Ensure an incoming tid is a valid one for us to access.
1853  Change to the associated uid credentials and chdir to the
1854  valid tid directory.
1855 *************************************************************/
1856
1857 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
1858 {
1859         const uint8_t *inhdr;
1860         uint32_t in_flags;
1861         uint32_t in_tid;
1862         struct smbXsrv_tcon *tcon;
1863         NTSTATUS status;
1864         NTTIME now = timeval_to_nttime(&req->request_time);
1865
1866         req->tcon = NULL;
1867
1868         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1869
1870         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1871         in_tid = IVAL(inhdr, SMB2_HDR_TID);
1872
1873         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1874                 in_tid = req->last_tid;
1875         }
1876
1877         req->last_tid = 0;
1878
1879         status = smb2srv_tcon_lookup(req->session,
1880                                      in_tid, now, &tcon);
1881         if (!NT_STATUS_IS_OK(status)) {
1882                 return status;
1883         }
1884
1885         if (!change_to_user_and_service(
1886                     tcon->compat,
1887                     req->session->global->session_wire_id))
1888         {
1889                 return NT_STATUS_ACCESS_DENIED;
1890         }
1891
1892         req->tcon = tcon;
1893         req->last_tid = in_tid;
1894
1895         return NT_STATUS_OK;
1896 }
1897
1898 /*************************************************************
1899  Ensure an incoming session_id is a valid one for us to access.
1900 *************************************************************/
1901
1902 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
1903 {
1904         const uint8_t *inhdr;
1905         uint32_t in_flags;
1906         uint16_t in_opcode;
1907         uint64_t in_session_id;
1908         struct smbXsrv_session *session = NULL;
1909         struct auth_session_info *session_info;
1910         NTSTATUS status;
1911         NTTIME now = timeval_to_nttime(&req->request_time);
1912
1913         req->session = NULL;
1914         req->tcon = NULL;
1915
1916         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1917
1918         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1919         in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
1920         in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
1921
1922         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1923                 in_session_id = req->last_session_id;
1924         }
1925
1926         req->last_session_id = 0;
1927
1928         /* look an existing session up */
1929         switch (in_opcode) {
1930         case SMB2_OP_SESSSETUP:
1931                 /*
1932                  * For a session bind request, we don't have the
1933                  * channel set up at this point yet, so we defer
1934                  * the verification that the connection belongs
1935                  * to the session to the session setup code, which
1936                  * can look at the session binding flags.
1937                  */
1938                 status = smb2srv_session_lookup_client(req->xconn->client,
1939                                                        in_session_id, now,
1940                                                        &session);
1941                 break;
1942         default:
1943                 status = smb2srv_session_lookup_conn(req->xconn,
1944                                                      in_session_id, now,
1945                                                      &session);
1946                 break;
1947         }
1948         if (session) {
1949                 req->session = session;
1950                 req->last_session_id = in_session_id;
1951         }
1952         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1953                 switch (in_opcode) {
1954                 case SMB2_OP_SESSSETUP:
1955                         status = NT_STATUS_OK;
1956                         break;
1957                 case SMB2_OP_LOGOFF:
1958                 case SMB2_OP_CLOSE:
1959                 case SMB2_OP_LOCK:
1960                 case SMB2_OP_CANCEL:
1961                 case SMB2_OP_KEEPALIVE:
1962                         /*
1963                          * [MS-SMB2] 3.3.5.2.9 Verifying the Session
1964                          * specifies that LOGOFF, CLOSE and (UN)LOCK
1965                          * should always be processed even on expired sessions.
1966                          *
1967                          * Also see the logic in
1968                          * smbd_smb2_request_process_lock().
1969                          *
1970                          * The smb2.session.expire2 test shows that
1971                          * CANCEL and KEEPALIVE/ECHO should also
1972                          * be processed.
1973                          */
1974                         status = NT_STATUS_OK;
1975                         break;
1976                 default:
1977                         break;
1978                 }
1979         }
1980         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1981                 switch (in_opcode) {
1982                 case SMB2_OP_TCON:
1983                 case SMB2_OP_CREATE:
1984                 case SMB2_OP_GETINFO:
1985                 case SMB2_OP_SETINFO:
1986                         return NT_STATUS_INVALID_HANDLE;
1987                 default:
1988                         /*
1989                          * Notice the check for
1990                          * (session_info == NULL)
1991                          * below.
1992                          */
1993                         status = NT_STATUS_OK;
1994                         break;
1995                 }
1996         }
1997         if (!NT_STATUS_IS_OK(status)) {
1998                 return status;
1999         }
2000
2001         session_info = session->global->auth_session_info;
2002         if (session_info == NULL) {
2003                 return NT_STATUS_INVALID_HANDLE;
2004         }
2005
2006         return NT_STATUS_OK;
2007 }
2008
2009 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
2010                                                 uint32_t data_length)
2011 {
2012         struct smbXsrv_connection *xconn = req->xconn;
2013         uint16_t needed_charge;
2014         uint16_t credit_charge = 1;
2015         const uint8_t *inhdr;
2016
2017         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2018
2019         if (xconn->smb2.credits.multicredit) {
2020                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
2021                 credit_charge = MAX(credit_charge, 1);
2022         }
2023
2024         needed_charge = (data_length - 1)/ 65536 + 1;
2025
2026         DBGC_DEBUG(DBGC_SMB2_CREDITS,
2027                    "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2028                    (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
2029                    credit_charge, needed_charge);
2030
2031         if (needed_charge > credit_charge) {
2032                 DBGC_WARNING(DBGC_SMB2_CREDITS,
2033                           "CreditCharge too low, given %d, needed %d\n",
2034                           credit_charge, needed_charge);
2035                 return NT_STATUS_INVALID_PARAMETER;
2036         }
2037
2038         return NT_STATUS_OK;
2039 }
2040
2041 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
2042                                         size_t expected_body_size)
2043 {
2044         struct iovec *inhdr_v;
2045         const uint8_t *inhdr;
2046         uint16_t opcode;
2047         const uint8_t *inbody;
2048         size_t body_size;
2049         size_t min_dyn_size = expected_body_size & 0x00000001;
2050         int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2051
2052         /*
2053          * The following should be checked already.
2054          */
2055         if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2056                 return NT_STATUS_INTERNAL_ERROR;
2057         }
2058         if (req->current_idx > max_idx) {
2059                 return NT_STATUS_INTERNAL_ERROR;
2060         }
2061
2062         inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2063         if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2064                 return NT_STATUS_INTERNAL_ERROR;
2065         }
2066         if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2067                 return NT_STATUS_INTERNAL_ERROR;
2068         }
2069
2070         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2071         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2072
2073         switch (opcode) {
2074         case SMB2_OP_IOCTL:
2075         case SMB2_OP_GETINFO:
2076                 min_dyn_size = 0;
2077                 break;
2078         case SMB2_OP_WRITE:
2079                 if (req->smb1req != NULL && req->smb1req->unread_bytes > 0) {
2080                         if (req->smb1req->unread_bytes < min_dyn_size) {
2081                                 return NT_STATUS_INVALID_PARAMETER;
2082                         }
2083
2084                         min_dyn_size = 0;
2085                 }
2086                 break;
2087         }
2088
2089         /*
2090          * Now check the expected body size,
2091          * where the last byte might be in the
2092          * dynamic section..
2093          */
2094         if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2095                 return NT_STATUS_INVALID_PARAMETER;
2096         }
2097         if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2098                 return NT_STATUS_INVALID_PARAMETER;
2099         }
2100
2101         inbody = SMBD_SMB2_IN_BODY_PTR(req);
2102
2103         body_size = SVAL(inbody, 0x00);
2104         if (body_size != expected_body_size) {
2105                 return NT_STATUS_INVALID_PARAMETER;
2106         }
2107
2108         return NT_STATUS_OK;
2109 }
2110
2111 bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2112 {
2113         return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2114                 &&
2115                 (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2116                                      SMBXSRV_ENCRYPTION_DESIRED |
2117                                      SMBXSRV_ENCRYPTION_REQUIRED)));
2118 }
2119
2120 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2121 {
2122         return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2123                 (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2124 }
2125
2126 /* Set a flag if not already set, return true if set */
2127 bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2128 {
2129         if ((flag == 0) || (*flags & flag)) {
2130                 return false;
2131         }
2132
2133         *flags |= flag;
2134         return true;
2135 }
2136
2137 /*
2138  * Update encryption state tracking flags, this can be used to
2139  * determine whether whether the session or tcon is "encrypted".
2140  */
2141 static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2142                                         uint16_t opcode,
2143                                         bool *update_session_globalp,
2144                                         bool *update_tcon_globalp)
2145 {
2146         /* Default: assume unecrypted and unsigned */
2147         struct smbXsrv_session *session = req->session;
2148         struct smbXsrv_tcon *tcon = req->tcon;
2149         uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2150         uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2151         bool update_session = false;
2152         bool update_tcon = false;
2153
2154         if (req->was_encrypted && req->do_encryption) {
2155                 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2156                 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2157         } else {
2158                 /* Unencrypted packet, can be signed */
2159                 if (req->do_signing) {
2160                         sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2161                 } else if (opcode == SMB2_OP_CANCEL) {
2162                         /* Cancel requests are allowed to skip signing */
2163                         sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2164                 }
2165         }
2166
2167         update_session |= smbXsrv_set_crypto_flag(
2168                 &session->global->encryption_flags, encrypt_flag);
2169         update_session |= smbXsrv_set_crypto_flag(
2170                 &session->global->signing_flags, sign_flag);
2171
2172         if (tcon) {
2173                 update_tcon |= smbXsrv_set_crypto_flag(
2174                         &tcon->global->encryption_flags, encrypt_flag);
2175                 update_tcon |= smbXsrv_set_crypto_flag(
2176                         &tcon->global->signing_flags, sign_flag);
2177         }
2178
2179         *update_session_globalp = update_session;
2180         *update_tcon_globalp = update_tcon;
2181         return;
2182 }
2183
2184 bool smbXsrv_is_signed(uint8_t signing_flags)
2185 {
2186         /*
2187          * Signing is always enabled, so unless we got an unsigned
2188          * packet and at least one signed packet that was not
2189          * encrypted, the session or tcon is "signed".
2190          */
2191         return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2192                 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2193 }
2194
2195 bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2196 {
2197         return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2198                 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2199 }
2200
2201 static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2202                                 struct smbd_smb2_request *req,
2203                                 bool modify_call)
2204 {
2205         struct smbXsrv_connection *xconn = req->xconn;
2206         const uint8_t *inhdr;
2207         uint16_t channel_sequence;
2208         uint8_t generation_wrap = 0;
2209         uint32_t flags;
2210         int cmp;
2211         struct smbXsrv_open *op;
2212         bool update_open = false;
2213         NTSTATUS status = NT_STATUS_OK;
2214
2215         SMB_ASSERT(!req->request_counters_updated);
2216
2217         if (xconn->protocol < PROTOCOL_SMB2_22) {
2218                 return NT_STATUS_OK;
2219         }
2220
2221         if (req->compat_chain_fsp == NULL) {
2222                 return NT_STATUS_OK;
2223         }
2224
2225         op = req->compat_chain_fsp->op;
2226         if (op == NULL) {
2227                 return NT_STATUS_OK;
2228         }
2229
2230         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2231         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2232         channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2233
2234         cmp = channel_sequence - op->global->channel_sequence;
2235         if (cmp < 0) {
2236                 /*
2237                  * csn wrap. We need to watch out for long-running
2238                  * requests that are still sitting on a previously
2239                  * used csn. SMB2_OP_NOTIFY can take VERY long.
2240                  */
2241                 generation_wrap += 1;
2242         }
2243
2244         if (abs(cmp) > INT16_MAX) {
2245                 /*
2246                  * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2247                  *
2248                  * If the channel sequence number of the request and the one
2249                  * known to the server are not equal, the channel sequence
2250                  * number and outstanding request counts are only updated
2251                  * "... if the unsigned difference using 16-bit arithmetic
2252                  * between ChannelSequence and Open.ChannelSequence is less than
2253                  * or equal to 0x7FFF ...".
2254                  * Otherwise, an error is returned for the modifying
2255                  * calls write, set_info, and ioctl.
2256                  *
2257                  * There are currently two issues with the description:
2258                  *
2259                  * * For the other calls, the document seems to imply
2260                  *   that processing continues without adapting the
2261                  *   counters (if the sequence numbers are not equal).
2262                  *
2263                  *   TODO: This needs clarification!
2264                  *
2265                  * * Also, the behaviour if the difference is larger
2266                  *   than 0x7FFF is not clear. The document seems to
2267                  *   imply that if such a difference is reached,
2268                  *   the server starts to ignore the counters or
2269                  *   in the case of the modifying calls, return errors.
2270                  *
2271                  *   TODO: This needs clarification!
2272                  *
2273                  * At this point Samba tries to be a little more
2274                  * clever than the description in the MS-SMB2 document
2275                  * by heuristically detecting and properly treating
2276                  * a 16 bit overflow of the client-submitted sequence
2277                  * number:
2278                  *
2279                  * If the stored channel sequence number is more than
2280                  * 0x7FFF larger than the one from the request, then
2281                  * the client-provided sequence number has likely
2282                  * overflown. We treat this case as valid instead
2283                  * of as failure.
2284                  *
2285                  * The MS-SMB2 behaviour would be setting cmp = -1.
2286                  */
2287                 cmp *= -1;
2288         }
2289
2290         if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2291                 if (cmp == 0 && op->pre_request_count == 0) {
2292                         op->request_count += 1;
2293                         req->request_counters_updated = true;
2294                 } else if (cmp > 0 && op->pre_request_count == 0) {
2295                         op->pre_request_count += op->request_count;
2296                         op->request_count = 1;
2297                         op->global->channel_sequence = channel_sequence;
2298                         op->global->channel_generation += generation_wrap;
2299                         update_open = true;
2300                         req->request_counters_updated = true;
2301                 } else if (modify_call) {
2302                         return NT_STATUS_FILE_NOT_AVAILABLE;
2303                 }
2304         } else {
2305                 if (cmp == 0) {
2306                         op->request_count += 1;
2307                         req->request_counters_updated = true;
2308                 } else if (cmp > 0) {
2309                         op->pre_request_count += op->request_count;
2310                         op->request_count = 1;
2311                         op->global->channel_sequence = channel_sequence;
2312                         op->global->channel_generation += generation_wrap;
2313                         update_open = true;
2314                         req->request_counters_updated = true;
2315                 } else if (modify_call) {
2316                         return NT_STATUS_FILE_NOT_AVAILABLE;
2317                 }
2318         }
2319         req->channel_generation = op->global->channel_generation;
2320
2321         if (update_open) {
2322                 status = smbXsrv_open_update(op);
2323         }
2324
2325         return status;
2326 }
2327
2328 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2329 {
2330         struct smbXsrv_connection *xconn = req->xconn;
2331         const struct smbd_smb2_dispatch_table *call = NULL;
2332         const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2333         const uint8_t *inhdr;
2334         uint16_t opcode;
2335         uint32_t flags;
2336         uint64_t mid;
2337         NTSTATUS status;
2338         NTSTATUS session_status;
2339         uint32_t allowed_flags;
2340         NTSTATUS return_value;
2341         struct smbXsrv_session *x = NULL;
2342         bool signing_required = false;
2343         bool encryption_desired = false;
2344         bool encryption_required = false;
2345
2346         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2347
2348         DO_PROFILE_INC(request);
2349
2350         SMB_ASSERT(!req->request_counters_updated);
2351
2352         /* TODO: verify more things */
2353
2354         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2355         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2356         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2357         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2358                 smb2_opcode_name(opcode),
2359                 (unsigned long long)mid));
2360
2361         if (xconn->protocol >= PROTOCOL_SMB2_02) {
2362                 /*
2363                  * once the protocol is negotiated
2364                  * SMB2_OP_NEGPROT is not allowed anymore
2365                  */
2366                 if (opcode == SMB2_OP_NEGPROT) {
2367                         /* drop the connection */
2368                         return NT_STATUS_INVALID_PARAMETER;
2369                 }
2370         } else {
2371                 /*
2372                  * if the protocol is not negotiated yet
2373                  * only SMB2_OP_NEGPROT is allowed.
2374                  */
2375                 if (opcode != SMB2_OP_NEGPROT) {
2376                         /* drop the connection */
2377                         return NT_STATUS_INVALID_PARAMETER;
2378                 }
2379         }
2380
2381         /*
2382          * Check if the client provided a valid session id.
2383          *
2384          * As some command don't require a valid session id
2385          * we defer the check of the session_status
2386          */
2387         session_status = smbd_smb2_request_check_session(req);
2388         x = req->session;
2389         if (x != NULL) {
2390                 signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
2391                 encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
2392                 encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
2393         }
2394
2395         req->async_internal = false;
2396         req->do_signing = false;
2397         if (opcode != SMB2_OP_SESSSETUP) {
2398                 req->do_encryption = encryption_desired;
2399         } else {
2400                 req->do_encryption = false;
2401         }
2402         req->was_encrypted = false;
2403         if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
2404                 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
2405                 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
2406
2407                 if (x != NULL && x->global->session_wire_id != tf_session_id) {
2408                         DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2409                                  "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2410                                  (unsigned long long)x->global->session_wire_id,
2411                                  (unsigned long long)tf_session_id));
2412                         /*
2413                          * TODO: windows allows this...
2414                          * should we drop the connection?
2415                          *
2416                          * For now we just return ACCESS_DENIED
2417                          * (Windows clients never trigger this)
2418                          * and wait for an update of [MS-SMB2].
2419                          */
2420                         return smbd_smb2_request_error(req,
2421                                         NT_STATUS_ACCESS_DENIED);
2422                 }
2423
2424                 req->was_encrypted = true;
2425                 req->do_encryption = true;
2426         }
2427
2428         if (encryption_required && !req->was_encrypted) {
2429                 req->do_encryption = true;
2430                 return smbd_smb2_request_error(req,
2431                                 NT_STATUS_ACCESS_DENIED);
2432         }
2433
2434         call = smbd_smb2_call(opcode);
2435         if (call == NULL) {
2436                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2437         }
2438
2439         allowed_flags = SMB2_HDR_FLAG_CHAINED |
2440                         SMB2_HDR_FLAG_SIGNED |
2441                         SMB2_HDR_FLAG_DFS;
2442         if (xconn->protocol >= PROTOCOL_SMB3_11) {
2443                 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2444         }
2445         if (opcode == SMB2_OP_NEGPROT) {
2446                 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
2447                         allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2448                 }
2449         }
2450         if (opcode == SMB2_OP_CANCEL) {
2451                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
2452         }
2453         if (xconn->protocol >= PROTOCOL_SMB2_22) {
2454                 allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
2455         }
2456         if ((flags & ~allowed_flags) != 0) {
2457                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2458         }
2459
2460         if (flags & SMB2_HDR_FLAG_CHAINED) {
2461                 /*
2462                  * This check is mostly for giving the correct error code
2463                  * for compounded requests.
2464                  */
2465                 if (!NT_STATUS_IS_OK(session_status)) {
2466                         return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2467                 }
2468         } else {
2469                 req->compat_chain_fsp = NULL;
2470         }
2471
2472         if (req->was_encrypted) {
2473                 signing_required = false;
2474         } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
2475                 struct smb2_signing_key *signing_key = NULL;
2476
2477                 if (x == NULL) {
2478                         /*
2479                          * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2480                          * If the SMB2 header of the SMB2 NEGOTIATE
2481                          * request has the SMB2_FLAGS_SIGNED bit set in the
2482                          * Flags field, the server MUST fail the request
2483                          * with STATUS_INVALID_PARAMETER.
2484                          *
2485                          * Microsoft test tool checks this.
2486                          */
2487
2488                         if ((opcode == SMB2_OP_NEGPROT) &&
2489                                         (flags & SMB2_HDR_FLAG_SIGNED)) {
2490                                 status = NT_STATUS_INVALID_PARAMETER;
2491                         } else {
2492                                 status = NT_STATUS_USER_SESSION_DELETED;
2493                         }
2494                         return smbd_smb2_request_error(req, status);
2495                 }
2496
2497                 signing_key = smbd_smb2_signing_key(x, xconn);
2498
2499                 /*
2500                  * If we have a signing key, we should
2501                  * sign the response
2502                  */
2503                 if (smb2_signing_key_valid(signing_key)) {
2504                         req->do_signing = true;
2505                 }
2506
2507                 status = smb2_signing_check_pdu(signing_key,
2508                                                 xconn->protocol,
2509                                                 SMBD_SMB2_IN_HDR_IOV(req),
2510                                                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2511                 if (!NT_STATUS_IS_OK(status)) {
2512                         return smbd_smb2_request_error(req, status);
2513                 }
2514
2515                 /*
2516                  * Now that we know the request was correctly signed
2517                  * we have to sign the response too.
2518                  */
2519                 req->do_signing = true;
2520
2521                 if (!NT_STATUS_IS_OK(session_status)) {
2522                         return smbd_smb2_request_error(req, session_status);
2523                 }
2524         } else if (opcode == SMB2_OP_CANCEL) {
2525                 /* Cancel requests are allowed to skip the signing */
2526         } else if (signing_required) {
2527                 /*
2528                  * If signing is required we try to sign
2529                  * a possible error response
2530                  */
2531                 req->do_signing = true;
2532                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
2533         }
2534
2535         if (flags & SMB2_HDR_FLAG_CHAINED) {
2536                 req->compound_related = true;
2537         }
2538
2539         if (call->need_session) {
2540                 if (!NT_STATUS_IS_OK(session_status)) {
2541                         return smbd_smb2_request_error(req, session_status);
2542                 }
2543         }
2544
2545         if (call->need_tcon) {
2546                 SMB_ASSERT(call->need_session);
2547
2548                 /*
2549                  * This call needs to be run as user.
2550                  *
2551                  * smbd_smb2_request_check_tcon()
2552                  * calls change_to_user() on success.
2553                  * Which implies set_current_user_info()
2554                  * and chdir_current_service().
2555                  */
2556                 status = smbd_smb2_request_check_tcon(req);
2557                 if (!NT_STATUS_IS_OK(status)) {
2558                         return smbd_smb2_request_error(req, status);
2559                 }
2560                 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
2561                         encryption_desired = true;
2562                 }
2563                 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
2564                         encryption_required = true;
2565                 }
2566                 if (encryption_required && !req->was_encrypted) {
2567                         req->do_encryption = true;
2568                         return smbd_smb2_request_error(req,
2569                                 NT_STATUS_ACCESS_DENIED);
2570                 } else if (encryption_desired) {
2571                         req->do_encryption = true;
2572                 }
2573         } else if (call->need_session) {
2574                 struct auth_session_info *session_info = NULL;
2575
2576                 /*
2577                  * Unless we also have need_tcon (see above),
2578                  * we still need to call set_current_user_info().
2579                  */
2580
2581                 session_info = req->session->global->auth_session_info;
2582                 if (session_info == NULL) {
2583                         return NT_STATUS_INVALID_HANDLE;
2584                 }
2585
2586                 set_current_user_info(session_info->unix_info->sanitized_username,
2587                                       session_info->unix_info->unix_name,
2588                                       session_info->info->domain_name);
2589         }
2590
2591         if (req->session) {
2592                 bool update_session_global = false;
2593                 bool update_tcon_global = false;
2594
2595                 smb2srv_update_crypto_flags(req, opcode,
2596                                             &update_session_global,
2597                                             &update_tcon_global);
2598
2599                 if (update_session_global) {
2600                         status = smbXsrv_session_update(x);
2601                         if (!NT_STATUS_IS_OK(status)) {
2602                                 return smbd_smb2_request_error(req, status);
2603                         }
2604                 }
2605                 if (update_tcon_global) {
2606                         status = smbXsrv_tcon_update(req->tcon);
2607                         if (!NT_STATUS_IS_OK(status)) {
2608                                 return smbd_smb2_request_error(req, status);
2609                         }
2610                 }
2611         }
2612
2613         if (call->fileid_ofs != 0) {
2614                 size_t needed = call->fileid_ofs + 16;
2615                 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2616                 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2617                 uint64_t file_id_persistent;
2618                 uint64_t file_id_volatile;
2619                 struct files_struct *fsp;
2620
2621                 SMB_ASSERT(call->need_tcon);
2622
2623                 if (needed > body_size) {
2624                         return smbd_smb2_request_error(req,
2625                                         NT_STATUS_INVALID_PARAMETER);
2626                 }
2627
2628                 file_id_persistent      = BVAL(body, call->fileid_ofs + 0);
2629                 file_id_volatile        = BVAL(body, call->fileid_ofs + 8);
2630
2631                 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2632                 if (fsp == NULL) {
2633                         if (!call->allow_invalid_fileid) {
2634                                 return smbd_smb2_request_error(req,
2635                                                 NT_STATUS_FILE_CLOSED);
2636                         }
2637
2638                         if (file_id_persistent != UINT64_MAX) {
2639                                 return smbd_smb2_request_error(req,
2640                                                 NT_STATUS_FILE_CLOSED);
2641                         }
2642                         if (file_id_volatile != UINT64_MAX) {
2643                                 return smbd_smb2_request_error(req,
2644                                                 NT_STATUS_FILE_CLOSED);
2645                         }
2646                 }
2647         }
2648
2649         status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
2650         if (!NT_STATUS_IS_OK(status)) {
2651                 return smbd_smb2_request_error(req, status);
2652         }
2653
2654         if (call->as_root) {
2655                 SMB_ASSERT(call->fileid_ofs == 0);
2656                 /* This call needs to be run as root */
2657                 change_to_root_user();
2658         } else {
2659                 SMB_ASSERT(call->need_tcon);
2660         }
2661
2662 #define _INBYTES(_r) \
2663         iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2664
2665         switch (opcode) {
2666         case SMB2_OP_NEGPROT:
2667                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
2668                                                req->profile, _INBYTES(req));
2669                 return_value = smbd_smb2_request_process_negprot(req);
2670                 break;
2671
2672         case SMB2_OP_SESSSETUP:
2673                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
2674                                                req->profile, _INBYTES(req));
2675                 return_value = smbd_smb2_request_process_sesssetup(req);
2676                 break;
2677
2678         case SMB2_OP_LOGOFF:
2679                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
2680                                                req->profile, _INBYTES(req));
2681                 return_value = smbd_smb2_request_process_logoff(req);
2682                 break;
2683
2684         case SMB2_OP_TCON:
2685                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
2686                                                req->profile, _INBYTES(req));
2687                 return_value = smbd_smb2_request_process_tcon(req);
2688                 break;
2689
2690         case SMB2_OP_TDIS:
2691                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
2692                                                req->profile, _INBYTES(req));
2693                 return_value = smbd_smb2_request_process_tdis(req);
2694                 break;
2695
2696         case SMB2_OP_CREATE:
2697                 if (req->subreq == NULL) {
2698                         SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
2699                                                        req->profile, _INBYTES(req));
2700                 } else {
2701                         SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
2702                 }
2703                 return_value = smbd_smb2_request_process_create(req);
2704                 break;
2705
2706         case SMB2_OP_CLOSE:
2707                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
2708                                                req->profile, _INBYTES(req));
2709                 return_value = smbd_smb2_request_process_close(req);
2710                 break;
2711
2712         case SMB2_OP_FLUSH:
2713                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
2714                                                req->profile, _INBYTES(req));
2715                 return_value = smbd_smb2_request_process_flush(req);
2716                 break;
2717
2718         case SMB2_OP_READ:
2719                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
2720                                                req->profile, _INBYTES(req));
2721                 return_value = smbd_smb2_request_process_read(req);
2722                 break;
2723
2724         case SMB2_OP_WRITE:
2725                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
2726                                                req->profile, _INBYTES(req));
2727                 return_value = smbd_smb2_request_process_write(req);
2728                 break;
2729
2730         case SMB2_OP_LOCK:
2731                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
2732                                                req->profile, _INBYTES(req));
2733                 return_value = smbd_smb2_request_process_lock(req);
2734                 break;
2735
2736         case SMB2_OP_IOCTL:
2737                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
2738                                                req->profile, _INBYTES(req));
2739                 return_value = smbd_smb2_request_process_ioctl(req);
2740                 break;
2741
2742         case SMB2_OP_CANCEL:
2743                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
2744                                                req->profile, _INBYTES(req));
2745                 return_value = smbd_smb2_request_process_cancel(req);
2746                 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
2747
2748                 /*
2749                  * We don't need the request anymore cancel requests never
2750                  * have a response.
2751                  *
2752                  * smbd_smb2_request_process_cancel() already called
2753                  * DLIST_REMOVE(xconn->smb2.requests, req);
2754                  */
2755                 TALLOC_FREE(req);
2756
2757                 break;
2758
2759         case SMB2_OP_KEEPALIVE:
2760                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
2761                                                req->profile, _INBYTES(req));
2762                 return_value = smbd_smb2_request_process_keepalive(req);
2763                 break;
2764
2765         case SMB2_OP_QUERY_DIRECTORY:
2766                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
2767                                                req->profile, _INBYTES(req));
2768                 return_value = smbd_smb2_request_process_query_directory(req);
2769                 break;
2770
2771         case SMB2_OP_NOTIFY:
2772                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
2773                                                req->profile, _INBYTES(req));
2774                 return_value = smbd_smb2_request_process_notify(req);
2775                 break;
2776
2777         case SMB2_OP_GETINFO:
2778                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
2779                                                req->profile, _INBYTES(req));
2780                 return_value = smbd_smb2_request_process_getinfo(req);
2781                 break;
2782
2783         case SMB2_OP_SETINFO:
2784                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
2785                                                req->profile, _INBYTES(req));
2786                 return_value = smbd_smb2_request_process_setinfo(req);
2787                 break;
2788
2789         case SMB2_OP_BREAK:
2790                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
2791                                                req->profile, _INBYTES(req));
2792                 return_value = smbd_smb2_request_process_break(req);
2793                 break;
2794
2795         default:
2796                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2797                 break;
2798         }
2799         return return_value;
2800 }
2801
2802 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
2803 {
2804         struct smbXsrv_connection *xconn = req->xconn;
2805         const uint8_t *inhdr;
2806         uint16_t channel_sequence;
2807         struct smbXsrv_open *op;
2808
2809         if (!req->request_counters_updated) {
2810                 return;
2811         }
2812
2813         req->request_counters_updated = false;
2814
2815         if (xconn->protocol < PROTOCOL_SMB2_22) {
2816                 return;
2817         }
2818
2819         if (req->compat_chain_fsp == NULL) {
2820                 return;
2821         }
2822
2823         op = req->compat_chain_fsp->op;
2824         if (op == NULL) {
2825                 return;
2826         }
2827
2828         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2829         channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2830
2831         if ((op->global->channel_sequence == channel_sequence) &&
2832             (op->global->channel_generation == req->channel_generation)) {
2833                 SMB_ASSERT(op->request_count > 0);
2834                 op->request_count -= 1;
2835         } else {
2836                 SMB_ASSERT(op->pre_request_count > 0);
2837                 op->pre_request_count -= 1;
2838         }
2839 }
2840
2841 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
2842 {
2843         struct smbXsrv_connection *xconn = req->xconn;
2844         int first_idx = 1;
2845         struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
2846         struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
2847         struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
2848         NTSTATUS status;
2849         bool ok;
2850
2851         req->subreq = NULL;
2852         TALLOC_FREE(req->async_te);
2853
2854         /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
2855         smbd_smb2_request_reply_update_counts(req);
2856
2857         if (req->do_encryption &&
2858             (firsttf->iov_len == 0) &&
2859             (req->first_key.length == 0) &&
2860             (req->session != NULL) &&
2861             smb2_signing_key_valid(req->session->global->encryption_key))
2862         {
2863                 struct smb2_signing_key *encryption_key =
2864                         req->session->global->encryption_key;
2865                 uint8_t *tf;
2866                 uint64_t session_id = req->session->global->session_wire_id;
2867                 uint64_t nonce_high;
2868                 uint64_t nonce_low;
2869
2870                 status = smb2_get_new_nonce(req->session,
2871                                             &nonce_high,
2872                                             &nonce_low);
2873                 if (!NT_STATUS_IS_OK(status)) {
2874                         return status;
2875                 }
2876
2877                 /*
2878                  * We need to place the SMB2_TRANSFORM header before the
2879                  * first SMB2 header
2880                  */
2881
2882                 /*
2883                  * we need to remember the encryption key
2884                  * and defer the signing/encryption until
2885                  * we are sure that we do not change
2886                  * the header again.
2887                  */
2888                 req->first_key = data_blob_dup_talloc(req,
2889                                                       encryption_key->blob);
2890                 if (req->first_key.data == NULL) {
2891                         return NT_STATUS_NO_MEMORY;
2892                 }
2893
2894                 tf = talloc_zero_array(req, uint8_t,
2895                                        SMB2_TF_HDR_SIZE);
2896                 if (tf == NULL) {
2897                         return NT_STATUS_NO_MEMORY;
2898                 }
2899
2900                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2901                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2902                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2903                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2904
2905                 firsttf->iov_base = (void *)tf;
2906                 firsttf->iov_len = SMB2_TF_HDR_SIZE;
2907         }
2908
2909         if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
2910             (req->last_key.length > 0) &&
2911             (firsttf->iov_len == 0))
2912         {
2913                 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
2914                 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
2915                 struct smb2_signing_key key = {
2916                         .blob = req->last_key,
2917                 };
2918
2919                 /*
2920                  * As we are sure the header of the last request in the
2921                  * compound chain will not change, we can to sign here
2922                  * with the last signing key we remembered.
2923                  */
2924                 status = smb2_signing_sign_pdu(&key,
2925                                                xconn->protocol,
2926                                                lasthdr,
2927                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2928                 smb2_signing_key_destructor(&key);
2929                 if (!NT_STATUS_IS_OK(status)) {
2930                         return status;
2931                 }
2932         }
2933         if (req->last_key.length > 0) {
2934                 data_blob_clear_free(&req->last_key);
2935         }
2936
2937         SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
2938                 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
2939
2940         req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
2941
2942         if (req->current_idx < req->out.vector_count) {
2943                 /*
2944                  * We must process the remaining compound
2945                  * SMB2 requests before any new incoming SMB2
2946                  * requests. This is because incoming SMB2
2947                  * requests may include a cancel for a
2948                  * compound request we haven't processed
2949                  * yet.
2950                  */
2951                 struct tevent_immediate *im = tevent_create_immediate(req);
2952                 if (!im) {
2953                         return NT_STATUS_NO_MEMORY;
2954                 }
2955
2956                 if (req->do_signing && firsttf->iov_len == 0) {
2957                         struct smbXsrv_session *x = req->session;
2958                         struct smb2_signing_key *signing_key =
2959                                 smbd_smb2_signing_key(x, xconn);
2960
2961                         /*
2962                          * we need to remember the signing key
2963                          * and defer the signing until
2964                          * we are sure that we do not change
2965                          * the header again.
2966                          */
2967                         req->last_key = data_blob_dup_talloc(req,
2968                                                              signing_key->blob);
2969                         if (req->last_key.data == NULL) {
2970                                 return NT_STATUS_NO_MEMORY;
2971                         }
2972                 }
2973
2974                 /*
2975                  * smbd_smb2_request_dispatch() will redo the impersonation.
2976                  * So we use req->xconn->client->raw_ev_ctx instead
2977                  * of req->ev_ctx here.
2978                  */
2979                 tevent_schedule_immediate(im,
2980                                         req->xconn->client->raw_ev_ctx,
2981                                         smbd_smb2_request_dispatch_immediate,
2982                                         req);
2983                 return NT_STATUS_OK;
2984         }
2985
2986         if (req->compound_related) {
2987                 req->compound_related = false;
2988         }
2989
2990         ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
2991         if (!ok) {
2992                 return NT_STATUS_INVALID_PARAMETER_MIX;
2993         }
2994
2995         /* Set credit for these operations (zero credits if this
2996            is a final reply for an async operation). */
2997         smb2_calculate_credits(req, req);
2998
2999         /*
3000          * now check if we need to sign the current response
3001          */
3002         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3003                 struct smb2_signing_key key = {
3004                         .blob = req->first_key,
3005                 };
3006                 status = smb2_signing_encrypt_pdu(&key,
3007                                         xconn->smb2.server.cipher,
3008                                         firsttf,
3009                                         req->out.vector_count - first_idx);
3010                 smb2_signing_key_destructor(&key);
3011                 if (!NT_STATUS_IS_OK(status)) {
3012                         return status;
3013                 }
3014         } else if (req->do_signing) {
3015                 struct smbXsrv_session *x = req->session;
3016                 struct smb2_signing_key *signing_key =
3017                         smbd_smb2_signing_key(x, xconn);
3018
3019                 status = smb2_signing_sign_pdu(signing_key,
3020                                                xconn->protocol,
3021                                                outhdr,
3022                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3023                 if (!NT_STATUS_IS_OK(status)) {
3024                         return status;
3025                 }
3026         }
3027         if (req->first_key.length > 0) {
3028                 data_blob_clear_free(&req->first_key);
3029         }
3030
3031         if (req->preauth != NULL) {
3032                 gnutls_hash_hd_t hash_hnd = NULL;
3033                 size_t i;
3034                 int rc;
3035
3036                 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3037                 if (rc < 0) {
3038                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3039                 }
3040                 rc = gnutls_hash(hash_hnd,
3041                             req->preauth->sha512_value,
3042                             sizeof(req->preauth->sha512_value));
3043                 if (rc < 0) {
3044                         gnutls_hash_deinit(hash_hnd, NULL);
3045                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3046                 }
3047                 for (i = 1; i < req->in.vector_count; i++) {
3048                         rc = gnutls_hash(hash_hnd,
3049                                          req->in.vector[i].iov_base,
3050                                          req->in.vector[i].iov_len);
3051                         if (rc < 0) {
3052                                 gnutls_hash_deinit(hash_hnd, NULL);
3053                                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3054                         }
3055                 }
3056                 if (rc < 0) {
3057                         gnutls_hash_deinit(hash_hnd, NULL);
3058                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3059                 }
3060                 gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3061
3062                 rc = gnutls_hash(hash_hnd,
3063                                  req->preauth->sha512_value,
3064                                  sizeof(req->preauth->sha512_value));
3065                 if (rc < 0) {
3066                         gnutls_hash_deinit(hash_hnd, NULL);
3067                         return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3068                 }
3069                 for (i = 1; i < req->out.vector_count; i++) {
3070                         rc = gnutls_hash(hash_hnd,
3071                                          req->out.vector[i].iov_base,
3072                                          req->out.vector[i].iov_len);
3073                         if (rc < 0) {
3074                                 gnutls_hash_deinit(hash_hnd, NULL);
3075                                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3076                         }
3077                 }
3078
3079                 gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3080
3081                 req->preauth = NULL;
3082         }
3083
3084         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3085         if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3086             outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3087                 /* Dynamic part is NULL. Chop it off,
3088                    We're going to send it via sendfile. */
3089                 req->out.vector_count -= 1;
3090         }
3091
3092         /*
3093          * We're done with this request -
3094          * move it off the "being processed" queue.
3095          */
3096         DLIST_REMOVE(xconn->smb2.requests, req);
3097
3098         req->queue_entry.mem_ctx = req;
3099         req->queue_entry.vector = req->out.vector;
3100         req->queue_entry.count = req->out.vector_count;
3101         DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3102         xconn->smb2.send_queue_len++;
3103
3104         status = smbd_smb2_flush_send_queue(xconn);
3105         if (!NT_STATUS_IS_OK(status)) {
3106                 return status;
3107         }
3108
3109         return NT_STATUS_OK;
3110 }
3111
3112 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3113
3114 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3115                                         struct tevent_immediate *im,
3116                                         void *private_data)
3117 {
3118         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3119                                         struct smbd_smb2_request);
3120         struct smbXsrv_connection *xconn = req->xconn;
3121         NTSTATUS status;
3122
3123         TALLOC_FREE(im);
3124
3125         if (DEBUGLEVEL >= 10) {
3126                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3127                         req->current_idx, req->in.vector_count));
3128                 print_req_vectors(req);
3129         }
3130
3131         status = smbd_smb2_request_dispatch(req);
3132         if (!NT_STATUS_IS_OK(status)) {
3133                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3134                 return;
3135         }
3136
3137         status = smbd_smb2_request_next_incoming(xconn);
3138         if (!NT_STATUS_IS_OK(status)) {
3139                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3140                 return;
3141         }
3142 }
3143
3144 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3145                                    NTSTATUS status,
3146                                    DATA_BLOB body, DATA_BLOB *dyn,
3147                                    const char *location)
3148 {
3149         uint8_t *outhdr;
3150         struct iovec *outbody_v;
3151         struct iovec *outdyn_v;
3152         uint32_t next_command_ofs;
3153         uint64_t mid;
3154
3155         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3156         mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
3157
3158         DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
3159                   "body[%u] dyn[%s:%u] at %s\n",
3160                   mid,
3161                   req->current_idx,
3162                   nt_errstr(status),
3163                   (unsigned int)body.length,
3164                   dyn ? "yes" : "no",
3165                   (unsigned int)(dyn ? dyn->length : 0),
3166                   location);
3167
3168         if (body.length < 2) {
3169                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3170         }
3171
3172         if ((body.length % 2) != 0) {
3173                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3174         }
3175
3176         outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3177         outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3178
3179         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3180         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3181
3182         outbody_v->iov_base = (void *)body.data;
3183         outbody_v->iov_len = body.length;
3184
3185         if (dyn) {
3186                 outdyn_v->iov_base = (void *)dyn->data;
3187                 outdyn_v->iov_len = dyn->length;
3188         } else {
3189                 outdyn_v->iov_base = NULL;
3190                 outdyn_v->iov_len = 0;
3191         }
3192
3193         /*
3194          * See if we need to recalculate the offset to the next response
3195          *
3196          * Note that all responses may require padding (including the very last
3197          * one).
3198          */
3199         if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3200                 next_command_ofs  = SMB2_HDR_BODY;
3201                 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3202                 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3203         }
3204
3205         if ((next_command_ofs % 8) != 0) {
3206                 size_t pad_size = 8 - (next_command_ofs % 8);
3207                 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3208                         /*
3209                          * if the dyn buffer is empty
3210                          * we can use it to add padding
3211                          */
3212                         uint8_t *pad;
3213
3214                         pad = talloc_zero_array(req,
3215                                                 uint8_t, pad_size);
3216                         if (pad == NULL) {
3217                                 return smbd_smb2_request_error(req,
3218                                                 NT_STATUS_NO_MEMORY);
3219                         }
3220
3221                         outdyn_v->iov_base = (void *)pad;
3222                         outdyn_v->iov_len = pad_size;
3223                 } else {
3224                         /*
3225                          * For now we copy the dynamic buffer
3226                          * and add the padding to the new buffer
3227                          */
3228                         size_t old_size;
3229                         uint8_t *old_dyn;
3230                         size_t new_size;
3231                         uint8_t *new_dyn;
3232
3233                         old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3234                         old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3235
3236                         new_size = old_size + pad_size;
3237                         new_dyn = talloc_zero_array(req,
3238                                                uint8_t, new_size);
3239                         if (new_dyn == NULL) {
3240                                 return smbd_smb2_request_error(req,
3241                                                 NT_STATUS_NO_MEMORY);
3242                         }
3243
3244                         memcpy(new_dyn, old_dyn, old_size);
3245                         memset(new_dyn + old_size, 0, pad_size);
3246
3247                         outdyn_v->iov_base = (void *)new_dyn;
3248                         outdyn_v->iov_len = new_size;
3249                 }
3250                 next_command_ofs += pad_size;
3251         }
3252
3253         if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3254                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3255         } else {
3256                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3257         }
3258         return smbd_smb2_request_reply(req);
3259 }
3260
3261 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3262                                     NTSTATUS status,
3263                                     DATA_BLOB *info,
3264                                     const char *location)
3265 {
3266         struct smbXsrv_connection *xconn = req->xconn;
3267         DATA_BLOB body;
3268         DATA_BLOB _dyn;
3269         uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3270         size_t unread_bytes = smbd_smb2_unread_bytes(req);
3271
3272         DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3273                    "at %s\n", req->current_idx, nt_errstr(status),
3274                    info ? " +info" : "", location);
3275
3276         if (unread_bytes) {
3277                 /* Recvfile error. Drain incoming socket. */
3278                 size_t ret;
3279
3280                 errno = 0;
3281                 ret = drain_socket(xconn->transport.sock, unread_bytes);
3282                 if (ret != unread_bytes) {
3283                         NTSTATUS error;
3284
3285                         if (errno == 0) {
3286                                 error = NT_STATUS_IO_DEVICE_ERROR;
3287                         } else {
3288                                 error = map_nt_error_from_unix_common(errno);
3289                         }
3290
3291                         DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3292                                   "ret[%u] errno[%d] => %s\n",
3293                                   (unsigned)unread_bytes,
3294                                   (unsigned)ret, errno, nt_errstr(error)));
3295                         return error;
3296                 }
3297         }
3298
3299         body.data = outhdr + SMB2_HDR_BODY;
3300         body.length = 8;
3301         SSVAL(body.data, 0, 9);
3302
3303         if (info) {
3304                 SIVAL(body.data, 0x04, info->length);
3305         } else {
3306                 /* Allocated size of req->out.vector[i].iov_base
3307                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3308                  * 1 byte without having to do an alloc.
3309                  */
3310                 info = &_dyn;
3311                 info->data = ((uint8_t *)outhdr) +
3312                         OUTVEC_ALLOC_SIZE - 1;
3313                 info->length = 1;
3314                 SCVAL(info->data, 0, 0);
3315         }
3316
3317         /*
3318          * Note: Even if there is an error, continue to process the request.
3319          * per MS-SMB2.
3320          */
3321
3322         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
3323 }
3324
3325
3326 struct smbd_smb2_send_break_state {
3327         struct smbd_smb2_send_queue queue_entry;
3328         uint8_t nbt_hdr[NBT_HDR_SIZE];
3329         uint8_t tf[SMB2_TF_HDR_SIZE];
3330         uint8_t hdr[SMB2_HDR_BODY];
3331         struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
3332         uint8_t body[1];
3333 };
3334
3335 static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
3336                                      struct smbXsrv_session *session,
3337                                      struct smbXsrv_tcon *tcon,
3338                                      const uint8_t *body,
3339                                      size_t body_len)
3340 {
3341         struct smbd_smb2_send_break_state *state;
3342         bool do_encryption = false;
3343         uint64_t session_wire_id = 0;
3344         uint64_t nonce_high = 0;
3345         uint64_t nonce_low = 0;
3346         NTSTATUS status;
3347         size_t statelen;
3348         bool ok;
3349
3350         if (session != NULL) {
3351                 session_wire_id = session->global->session_wire_id;
3352                 do_encryption = session->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3353                 if (tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3354                         do_encryption = true;
3355                 }
3356         }
3357
3358         statelen = offsetof(struct smbd_smb2_send_break_state, body) +
3359                 body_len;
3360
3361         state = talloc_zero_size(xconn, statelen);
3362         if (state == NULL) {
3363                 return NT_STATUS_NO_MEMORY;
3364         }
3365         talloc_set_name_const(state, "struct smbd_smb2_send_break_state");
3366
3367         if (do_encryption) {
3368                 status = smb2_get_new_nonce(session,
3369                                             &nonce_high,
3370                                             &nonce_low);
3371                 if (!NT_STATUS_IS_OK(status)) {
3372                         return status;
3373                 }
3374         }
3375
3376         SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3377         SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
3378         SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
3379         SBVAL(state->tf, SMB2_TF_SESSION_ID, session_wire_id);
3380
3381         SIVAL(state->hdr, 0,                            SMB2_MAGIC);
3382         SSVAL(state->hdr, SMB2_HDR_LENGTH,              SMB2_HDR_BODY);
3383         SSVAL(state->hdr, SMB2_HDR_EPOCH,               0);
3384         SIVAL(state->hdr, SMB2_HDR_STATUS,              0);
3385         SSVAL(state->hdr, SMB2_HDR_OPCODE,              SMB2_OP_BREAK);
3386         SSVAL(state->hdr, SMB2_HDR_CREDIT,              0);
3387         SIVAL(state->hdr, SMB2_HDR_FLAGS,               SMB2_HDR_FLAG_REDIRECT);
3388         SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND,        0);
3389         SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID,          UINT64_MAX);
3390         SIVAL(state->hdr, SMB2_HDR_PID,         0);
3391         SIVAL(state->hdr, SMB2_HDR_TID,         0);
3392         SBVAL(state->hdr, SMB2_HDR_SESSION_ID,          0);
3393         memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
3394
3395         state->vector[0] = (struct iovec) {
3396                 .iov_base = state->nbt_hdr,
3397                 .iov_len  = sizeof(state->nbt_hdr)
3398         };
3399
3400         if (do_encryption) {
3401                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3402                         .iov_base = state->tf,
3403                         .iov_len  = sizeof(state->tf)
3404                 };
3405         } else {
3406                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3407                         .iov_base = NULL,
3408                         .iov_len  = 0
3409                 };
3410         }
3411
3412         state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
3413                 .iov_base = state->hdr,
3414                 .iov_len  = sizeof(state->hdr)
3415         };
3416
3417         memcpy(state->body, body, body_len);
3418
3419         state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
3420                 .iov_base = state->body,
3421                 .iov_len  = body_len /* no sizeof(state->body) .. :-) */
3422         };
3423
3424         /*
3425          * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
3426          */
3427
3428         ok = smb2_setup_nbt_length(state->vector,
3429                                    1 + SMBD_SMB2_NUM_IOV_PER_REQ);
3430         if (!ok) {
3431                 return NT_STATUS_INVALID_PARAMETER_MIX;
3432         }
3433
3434         if (do_encryption) {
3435                 struct smb2_signing_key *encryption_key =
3436                         session->global->encryption_key;
3437
3438                 status = smb2_signing_encrypt_pdu(encryption_key,
3439                                         xconn->smb2.server.cipher,
3440                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
3441                                         SMBD_SMB2_NUM_IOV_PER_REQ);
3442                 if (!NT_STATUS_IS_OK(status)) {
3443                         return status;
3444                 }
3445         }
3446
3447         state->queue_entry.mem_ctx = state;
3448         state->queue_entry.vector = state->vector;
3449         state->queue_entry.count = ARRAY_SIZE(state->vector);
3450         DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
3451         xconn->smb2.send_queue_len++;
3452
3453         status = smbd_smb2_flush_send_queue(xconn);
3454         if (!NT_STATUS_IS_OK(status)) {
3455                 return status;
3456         }
3457
3458         return NT_STATUS_OK;
3459 }
3460
3461 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
3462                                      struct smbXsrv_session *session,
3463                                      struct smbXsrv_tcon *tcon,
3464                                      struct smbXsrv_open *op,
3465                                      uint8_t oplock_level)
3466 {
3467         uint8_t body[0x18];
3468
3469         SSVAL(body, 0x00, sizeof(body));
3470         SCVAL(body, 0x02, oplock_level);
3471         SCVAL(body, 0x03, 0);           /* reserved */
3472         SIVAL(body, 0x04, 0);           /* reserved */
3473         SBVAL(body, 0x08, op->global->open_persistent_id);
3474         SBVAL(body, 0x10, op->global->open_volatile_id);
3475
3476         return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3477 }
3478
3479 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
3480                                     uint16_t new_epoch,
3481                                     uint32_t lease_flags,
3482                                     struct smb2_lease_key *lease_key,
3483                                     uint32_t current_lease_state,
3484                                     uint32_t new_lease_state)
3485 {
3486         uint8_t body[0x2c];
3487
3488         SSVAL(body, 0x00, sizeof(body));
3489         SSVAL(body, 0x02, new_epoch);
3490         SIVAL(body, 0x04, lease_flags);
3491         SBVAL(body, 0x08, lease_key->data[0]);
3492         SBVAL(body, 0x10, lease_key->data[1]);
3493         SIVAL(body, 0x18, current_lease_state);
3494         SIVAL(body, 0x1c, new_lease_state);
3495         SIVAL(body, 0x20, 0);           /* BreakReason, MUST be 0 */
3496         SIVAL(body, 0x24, 0);           /* AccessMaskHint, MUST be 0 */
3497         SIVAL(body, 0x28, 0);           /* ShareMaskHint, MUST be 0 */
3498
3499         return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3500 }
3501
3502 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
3503 {
3504         NTSTATUS status;
3505         uint32_t flags;
3506         uint64_t file_id_persistent;
3507         uint64_t file_id_volatile;
3508         struct smbXsrv_open *op = NULL;
3509         struct files_struct *fsp = NULL;
3510         const uint8_t *body = NULL;
3511
3512         /*
3513          * This is only called with a pktbuf
3514          * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
3515          * bytes
3516          */
3517
3518         if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
3519                 /* Transform header. Cannot recvfile. */
3520                 return false;
3521         }
3522         if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
3523                 /* Not SMB2. Normal error path will cope. */
3524                 return false;
3525         }
3526         if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
3527                 /* Not SMB2. Normal error path will cope. */
3528                 return false;
3529         }
3530         if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
3531                 /* Needs to be a WRITE. */
3532                 return false;
3533         }
3534         if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
3535                 /* Chained. Cannot recvfile. */
3536                 return false;
3537         }
3538         flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
3539         if (flags & SMB2_HDR_FLAG_CHAINED) {
3540                 /* Chained. Cannot recvfile. */
3541                 return false;
3542         }
3543         if (flags & SMB2_HDR_FLAG_SIGNED) {
3544                 /* Signed. Cannot recvfile. */
3545                 return false;
3546         }
3547
3548         body = &state->pktbuf[SMB2_HDR_BODY];
3549
3550         file_id_persistent      = BVAL(body, 0x10);
3551         file_id_volatile        = BVAL(body, 0x18);
3552
3553         status = smb2srv_open_lookup(state->req->xconn,
3554                                      file_id_persistent,
3555                                      file_id_volatile,
3556                                      0, /* now */
3557                                      &op);
3558         if (!NT_STATUS_IS_OK(status)) {
3559                 return false;
3560         }
3561
3562         fsp = op->compat;
3563         if (fsp == NULL) {
3564                 return false;
3565         }
3566         if (fsp->conn == NULL) {
3567                 return false;
3568         }
3569
3570         if (IS_IPC(fsp->conn)) {
3571                 return false;
3572         }
3573         if (IS_PRINT(fsp->conn)) {
3574                 return false;
3575         }
3576         if (fsp->base_fsp != NULL) {
3577                 return false;
3578         }
3579
3580         DEBUG(10,("Doing recvfile write len = %u\n",
3581                 (unsigned int)(state->pktfull - state->pktlen)));
3582
3583         return true;
3584 }
3585
3586 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
3587 {
3588         struct smbd_server_connection *sconn = xconn->client->sconn;
3589         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3590         size_t max_send_queue_len;
3591         size_t cur_send_queue_len;
3592
3593         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3594                 /*
3595                  * we're not supposed to do any io
3596                  */
3597                 return NT_STATUS_OK;
3598         }
3599
3600         if (state->req != NULL) {
3601                 /*
3602                  * if there is already a tstream_readv_pdu
3603                  * pending, we are done.
3604                  */
3605                 return NT_STATUS_OK;
3606         }
3607
3608         max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
3609         cur_send_queue_len = xconn->smb2.send_queue_len;
3610
3611         if (cur_send_queue_len > max_send_queue_len) {
3612                 /*
3613                  * if we have a lot of requests to send,
3614                  * we wait until they are on the wire until we
3615                  * ask for the next request.
3616                  */
3617                 return NT_STATUS_OK;
3618         }
3619
3620         /* ask for the next request */
3621         ZERO_STRUCTP(state);
3622         state->req = smbd_smb2_request_allocate(xconn);
3623         if (state->req == NULL) {
3624                 return NT_STATUS_NO_MEMORY;
3625         }
3626         state->req->sconn = sconn;
3627         state->req->xconn = xconn;
3628         state->min_recv_size = lp_min_receive_file_size();
3629
3630         TEVENT_FD_READABLE(xconn->transport.fde);
3631
3632         return NT_STATUS_OK;
3633 }
3634
3635 NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
3636                                uint64_t expected_seq_low,
3637                                const uint8_t *inpdu, size_t size)
3638 {
3639         struct smbd_server_connection *sconn = xconn->client->sconn;
3640         NTSTATUS status;
3641         struct smbd_smb2_request *req = NULL;
3642
3643         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3644                  (unsigned int)size));
3645
3646         status = smbd_initialize_smb2(xconn, expected_seq_low);
3647         if (!NT_STATUS_IS_OK(status)) {
3648                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3649                 return status;
3650         }
3651
3652         status = smbd_smb2_request_create(xconn, inpdu, size, &req);
3653         if (!NT_STATUS_IS_OK(status)) {
3654                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3655                 return status;
3656         }
3657
3658         status = smbd_smb2_request_validate(req);
3659         if (!NT_STATUS_IS_OK(status)) {
3660                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3661                 return status;
3662         }
3663
3664         status = smbd_smb2_request_setup_out(req);
3665         if (!NT_STATUS_IS_OK(status)) {
3666                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3667                 return status;
3668         }
3669
3670 #ifdef WITH_PROFILE
3671         /*
3672          * this was already counted at the SMB1 layer =>
3673          * smbd_smb2_request_dispatch() should not count it twice.
3674          */
3675         if (profile_p->values.request_stats.count > 0) {
3676                 profile_p->values.request_stats.count--;
3677         }
3678 #endif
3679         status = smbd_smb2_request_dispatch(req);
3680         if (!NT_STATUS_IS_OK(status)) {
3681                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3682                 return status;
3683         }
3684
3685         status = smbd_smb2_request_next_incoming(xconn);
3686         if (!NT_STATUS_IS_OK(status)) {
3687                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3688                 return status;
3689         }
3690
3691         sconn->num_requests++;
3692         return NT_STATUS_OK;
3693 }
3694
3695 static int socket_error_from_errno(int ret,
3696                                    int sys_errno,
3697                                    bool *retry)
3698 {
3699         *retry = false;
3700
3701         if (ret >= 0) {
3702                 return 0;
3703         }
3704
3705         if (ret != -1) {
3706                 return EIO;
3707         }
3708
3709         if (sys_errno == 0) {
3710                 return EIO;
3711         }
3712
3713         if (sys_errno == EINTR) {
3714                 *retry = true;
3715                 return sys_errno;
3716         }
3717
3718         if (sys_errno == EINPROGRESS) {
3719                 *retry = true;
3720                 return sys_errno;
3721         }
3722
3723         if (sys_errno == EAGAIN) {
3724                 *retry = true;
3725                 return sys_errno;
3726         }
3727
3728         /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3729         if (sys_errno == ENOMEM) {
3730                 *retry = true;
3731                 return sys_errno;
3732         }
3733
3734 #ifdef EWOULDBLOCK
3735 #if EWOULDBLOCK != EAGAIN
3736         if (sys_errno == EWOULDBLOCK) {
3737                 *retry = true;
3738                 return sys_errno;
3739         }
3740 #endif
3741 #endif
3742
3743         return sys_errno;
3744 }
3745
3746 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
3747 {
3748         int ret;
3749         int err;
3750         bool retry;
3751         NTSTATUS status;
3752
3753         if (xconn->smb2.send_queue == NULL) {
3754                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3755                 return NT_STATUS_OK;
3756         }
3757
3758         while (xconn->smb2.send_queue != NULL) {
3759                 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
3760                 bool ok;
3761                 struct msghdr msg;
3762
3763                 if (e->sendfile_header != NULL) {
3764                         size_t size = 0;
3765                         size_t i = 0;
3766                         uint8_t *buf;
3767
3768                         status = NT_STATUS_INTERNAL_ERROR;
3769
3770                         for (i=0; i < e->count; i++) {
3771                                 size += e->vector[i].iov_len;
3772                         }
3773
3774                         if (size <= e->sendfile_header->length) {
3775                                 buf = e->sendfile_header->data;
3776                         } else {
3777                                 buf = talloc_array(e->mem_ctx, uint8_t, size);
3778                                 if (buf == NULL) {
3779                                         return NT_STATUS_NO_MEMORY;
3780                                 }
3781                         }
3782
3783                         size = 0;
3784                         for (i=0; i < e->count; i++) {
3785                                 memcpy(buf+size,
3786                                        e->vector[i].iov_base,
3787                                        e->vector[i].iov_len);
3788                                 size += e->vector[i].iov_len;
3789                         }
3790
3791                         e->sendfile_header->data = buf;
3792                         e->sendfile_header->length = size;
3793                         e->sendfile_status = &status;
3794                         e->count = 0;
3795
3796                         xconn->smb2.send_queue_len--;
3797                         DLIST_REMOVE(xconn->smb2.send_queue, e);
3798                         /*
3799                          * This triggers the sendfile path via
3800                          * the destructor.
3801                          */
3802                         talloc_free(e->mem_ctx);
3803
3804                         if (!NT_STATUS_IS_OK(status)) {
3805                                 return status;
3806                         }
3807                         continue;
3808                 }
3809
3810                 msg = (struct msghdr) {
3811                         .msg_iov = e->vector,
3812                         .msg_iovlen = e->count,
3813                 };
3814
3815                 ret = sendmsg(xconn->transport.sock, &msg, 0);
3816                 if (ret == 0) {
3817                         /* propagate end of file */
3818                         return NT_STATUS_INTERNAL_ERROR;
3819                 }
3820                 err = socket_error_from_errno(ret, errno, &retry);
3821                 if (retry) {
3822                         /* retry later */
3823                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3824                         return NT_STATUS_OK;
3825                 }
3826                 if (err != 0) {
3827                         return map_nt_error_from_unix_common(err);
3828                 }
3829
3830                 ok = iov_advance(&e->vector, &e->count, ret);
3831                 if (!ok) {
3832                         return NT_STATUS_INTERNAL_ERROR;
3833                 }
3834
3835                 if (e->count > 0) {
3836                         /* we have more to write */
3837                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3838                         return NT_STATUS_OK;
3839                 }
3840
3841                 xconn->smb2.send_queue_len--;
3842                 DLIST_REMOVE(xconn->smb2.send_queue, e);
3843                 talloc_free(e->mem_ctx);
3844         }
3845
3846         /*
3847          * Restart reads if we were blocked on
3848          * draining the send queue.
3849          */
3850
3851         status = smbd_smb2_request_next_incoming(xconn);
3852         if (!NT_STATUS_IS_OK(status)) {
3853                 return status;
3854         }
3855
3856         return NT_STATUS_OK;
3857 }
3858
3859 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
3860                                      uint16_t fde_flags)
3861 {
3862         struct smbd_server_connection *sconn = xconn->client->sconn;
3863         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3864         struct smbd_smb2_request *req = NULL;
3865         size_t min_recvfile_size = UINT32_MAX;
3866         int ret;
3867         int err;
3868         bool retry;
3869         NTSTATUS status;
3870         NTTIME now;
3871         struct msghdr msg;
3872
3873         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3874                 /*
3875                  * we're not supposed to do any io
3876                  */
3877                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3878                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3879                 return NT_STATUS_OK;
3880         }
3881
3882         if (fde_flags & TEVENT_FD_WRITE) {
3883                 status = smbd_smb2_flush_send_queue(xconn);
3884                 if (!NT_STATUS_IS_OK(status)) {
3885                         return status;
3886                 }
3887         }
3888
3889         if (!(fde_flags & TEVENT_FD_READ)) {
3890                 return NT_STATUS_OK;
3891         }
3892
3893         if (state->req == NULL) {
3894                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3895                 return NT_STATUS_OK;
3896         }
3897
3898 again:
3899         if (!state->hdr.done) {
3900                 state->hdr.done = true;
3901
3902                 state->vector.iov_base = (void *)state->hdr.nbt;
3903                 state->vector.iov_len = NBT_HDR_SIZE;
3904         }
3905
3906         msg = (struct msghdr) {
3907                 .msg_iov = &state->vector,
3908                 .msg_iovlen = 1,
3909         };
3910
3911         ret = recvmsg(xconn->transport.sock, &msg, 0);
3912         if (ret == 0) {
3913                 /* propagate end of file */
3914                 return NT_STATUS_END_OF_FILE;
3915         }
3916         err = socket_error_from_errno(ret, errno, &retry);
3917         if (retry) {
3918                 /* retry later */
3919                 TEVENT_FD_READABLE(xconn->transport.fde);
3920                 return NT_STATUS_OK;
3921         }
3922         if (err != 0) {
3923                 return map_nt_error_from_unix_common(err);
3924         }
3925
3926         if (ret < state->vector.iov_len) {
3927                 uint8_t *base;
3928                 base = (uint8_t *)state->vector.iov_base;
3929                 base += ret;
3930                 state->vector.iov_base = (void *)base;
3931                 state->vector.iov_len -= ret;
3932                 /* we have more to read */
3933                 TEVENT_FD_READABLE(xconn->transport.fde);
3934                 return NT_STATUS_OK;
3935         }
3936
3937         if (state->pktlen > 0) {
3938                 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
3939                         /*
3940                          * Not a possible receivefile write.
3941                          * Read the rest of the data.
3942                          */
3943                         state->doing_receivefile = false;
3944
3945                         state->pktbuf = talloc_realloc(state->req,
3946                                                        state->pktbuf,
3947                                                        uint8_t,
3948                                                        state->pktfull);
3949                         if (state->pktbuf == NULL) {
3950                                 return NT_STATUS_NO_MEMORY;
3951                         }
3952
3953                         state->vector.iov_base = (void *)(state->pktbuf +
3954                                 state->pktlen);
3955                         state->vector.iov_len = (state->pktfull -
3956                                 state->pktlen);
3957
3958                         state->pktlen = state->pktfull;
3959                         goto again;
3960                 }
3961
3962                 /*
3963                  * Either this is a receivefile write so we've
3964                  * done a short read, or if not we have all the data.
3965                  */
3966                 goto got_full;
3967         }
3968
3969         /*
3970          * Now we analyze the NBT header
3971          */
3972         if (state->hdr.nbt[0] != 0x00) {
3973                 state->min_recv_size = 0;
3974         }
3975         state->pktfull = smb2_len(state->hdr.nbt);
3976         if (state->pktfull == 0) {
3977                 goto got_full;
3978         }
3979
3980         if (state->min_recv_size != 0) {
3981                 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3982                 min_recvfile_size += state->min_recv_size;
3983         }
3984
3985         if (state->pktfull > min_recvfile_size) {
3986                 /*
3987                  * Might be a receivefile write. Read the SMB2 HEADER +
3988                  * SMB2_WRITE header first. Set 'doing_receivefile'
3989                  * as we're *attempting* receivefile write. If this
3990                  * turns out not to be a SMB2_WRITE request or otherwise
3991                  * not suitable then we'll just read the rest of the data
3992                  * the next time this function is called.
3993                  */
3994                 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3995                 state->doing_receivefile = true;
3996         } else {
3997                 state->pktlen = state->pktfull;
3998         }
3999
4000         state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
4001         if (state->pktbuf == NULL) {
4002                 return NT_STATUS_NO_MEMORY;
4003         }
4004
4005         state->vector.iov_base = (void *)state->pktbuf;
4006         state->vector.iov_len = state->pktlen;
4007
4008         goto again;
4009
4010 got_full:
4011
4012         if (state->hdr.nbt[0] != 0x00) {
4013                 DEBUG(1,("ignore NBT[0x%02X] msg\n",
4014                          state->hdr.nbt[0]));
4015
4016                 req = state->req;
4017                 ZERO_STRUCTP(state);
4018                 state->req = req;
4019                 state->min_recv_size = lp_min_receive_file_size();
4020                 req = NULL;
4021                 goto again;
4022         }
4023
4024         req = state->req;
4025         state->req = NULL;
4026
4027         req->request_time = timeval_current();
4028         now = timeval_to_nttime(&req->request_time);
4029
4030         status = smbd_smb2_inbuf_parse_compound(xconn,
4031                                                 now,
4032                                                 state->pktbuf,
4033                                                 state->pktlen,
4034                                                 req,
4035                                                 &req->in.vector,
4036                                                 &req->in.vector_count);
4037         if (!NT_STATUS_IS_OK(status)) {
4038                 return status;
4039         }
4040
4041         if (state->doing_receivefile) {
4042                 req->smb1req = talloc_zero(req, struct smb_request);
4043                 if (req->smb1req == NULL) {
4044                         return NT_STATUS_NO_MEMORY;
4045                 }
4046                 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
4047         }
4048
4049         ZERO_STRUCTP(state);
4050
4051         req->current_idx = 1;
4052
4053         DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
4054                  req->current_idx, req->in.vector_count));
4055
4056         status = smbd_smb2_request_validate(req);
4057         if (!NT_STATUS_IS_OK(status)) {
4058                 return status;
4059         }
4060
4061         status = smbd_smb2_request_setup_out(req);
4062         if (!NT_STATUS_IS_OK(status)) {
4063                 return status;
4064         }
4065
4066         status = smbd_smb2_request_dispatch(req);
4067         if (!NT_STATUS_IS_OK(status)) {
4068                 return status;
4069         }
4070
4071         sconn->num_requests++;
4072
4073         /* The timeout_processing function isn't run nearly
4074            often enough to implement 'max log size' without
4075            overrunning the size of the file by many megabytes.
4076            This is especially true if we are running at debug
4077            level 10.  Checking every 50 SMB2s is a nice
4078            tradeoff of performance vs log file size overrun. */
4079
4080         if ((sconn->num_requests % 50) == 0 &&
4081             need_to_check_log_size()) {
4082                 change_to_root_user();
4083                 check_log_size();
4084         }
4085
4086         status = smbd_smb2_request_next_incoming(xconn);
4087         if (!NT_STATUS_IS_OK(status)) {
4088                 return status;
4089         }
4090
4091         return NT_STATUS_OK;
4092 }
4093
4094 static void smbd_smb2_connection_handler(struct tevent_context *ev,
4095                                          struct tevent_fd *fde,
4096                                          uint16_t flags,
4097                                          void *private_data)
4098 {
4099         struct smbXsrv_connection *xconn =
4100                 talloc_get_type_abort(private_data,
4101                 struct smbXsrv_connection);
4102         NTSTATUS status;
4103
4104         status = smbd_smb2_io_handler(xconn, flags);
4105         if (!NT_STATUS_IS_OK(status)) {
4106                 smbd_server_connection_terminate(xconn, nt_errstr(status));
4107                 return;
4108         }
4109 }