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