smbd: Remove a "!" from an if-condition for easier readability
[vlendec/samba-autobuild/.git] / source3 / smbd / smb2_server.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30 #include "../librpc/gen_ndr/krb5pac.h"
31 #include "lib/util/iov_buf.h"
32 #include "auth.h"
33 #include "lib/crypto/sha512.h"
34
35 static void smbd_smb2_connection_handler(struct tevent_context *ev,
36                                          struct tevent_fd *fde,
37                                          uint16_t flags,
38                                          void *private_data);
39 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
40
41 static const struct smbd_smb2_dispatch_table {
42         uint16_t opcode;
43         const char *name;
44         bool need_session;
45         bool need_tcon;
46         bool as_root;
47         uint16_t fileid_ofs;
48         bool allow_invalid_fileid;
49         bool modify;
50 } smbd_smb2_table[] = {
51 #define _OP(o) .opcode = o, .name = #o
52         {
53                 _OP(SMB2_OP_NEGPROT),
54                 .as_root = true,
55         },{
56                 _OP(SMB2_OP_SESSSETUP),
57                 .as_root = true,
58         },{
59                 _OP(SMB2_OP_LOGOFF),
60                 .need_session = true,
61                 .as_root = true,
62         },{
63                 _OP(SMB2_OP_TCON),
64                 .need_session = true,
65                 /*
66                  * This call needs to be run as root.
67                  *
68                  * smbd_smb2_request_process_tcon()
69                  * calls make_connection_snum(), which will call
70                  * change_to_user(), when needed.
71                  */
72                 .as_root = true,
73         },{
74                 _OP(SMB2_OP_TDIS),
75                 .need_session = true,
76                 .need_tcon = true,
77                 .as_root = true,
78         },{
79                 _OP(SMB2_OP_CREATE),
80                 .need_session = true,
81                 .need_tcon = true,
82         },{
83                 _OP(SMB2_OP_CLOSE),
84                 .need_session = true,
85                 .need_tcon = true,
86                 .fileid_ofs = 0x08,
87         },{
88                 _OP(SMB2_OP_FLUSH),
89                 .need_session = true,
90                 .need_tcon = true,
91                 .fileid_ofs = 0x08,
92         },{
93                 _OP(SMB2_OP_READ),
94                 .need_session = true,
95                 .need_tcon = true,
96                 .fileid_ofs = 0x10,
97         },{
98                 _OP(SMB2_OP_WRITE),
99                 .need_session = true,
100                 .need_tcon = true,
101                 .fileid_ofs = 0x10,
102                 .modify = true,
103         },{
104                 _OP(SMB2_OP_LOCK),
105                 .need_session = true,
106                 .need_tcon = true,
107                 .fileid_ofs = 0x08,
108         },{
109                 _OP(SMB2_OP_IOCTL),
110                 .need_session = true,
111                 .need_tcon = true,
112                 .fileid_ofs = 0x08,
113                 .allow_invalid_fileid = true,
114                 .modify = true,
115         },{
116                 _OP(SMB2_OP_CANCEL),
117                 .as_root = true,
118         },{
119                 _OP(SMB2_OP_KEEPALIVE),
120                 .as_root = true,
121         },{
122                 _OP(SMB2_OP_QUERY_DIRECTORY),
123                 .need_session = true,
124                 .need_tcon = true,
125                 .fileid_ofs = 0x08,
126         },{
127                 _OP(SMB2_OP_NOTIFY),
128                 .need_session = true,
129                 .need_tcon = true,
130                 .fileid_ofs = 0x08,
131         },{
132                 _OP(SMB2_OP_GETINFO),
133                 .need_session = true,
134                 .need_tcon = true,
135                 .fileid_ofs = 0x18,
136         },{
137                 _OP(SMB2_OP_SETINFO),
138                 .need_session = true,
139                 .need_tcon = true,
140                 .fileid_ofs = 0x10,
141                 .modify = true,
142         },{
143                 _OP(SMB2_OP_BREAK),
144                 .need_session = true,
145                 .need_tcon = true,
146                 /*
147                  * we do not set
148                  * .fileid_ofs here
149                  * as LEASE breaks does not
150                  * have a file id
151                  */
152         }
153 };
154
155 const char *smb2_opcode_name(uint16_t opcode)
156 {
157         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
158                 return "Bad SMB2 opcode";
159         }
160         return smbd_smb2_table[opcode].name;
161 }
162
163 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
164 {
165         const struct smbd_smb2_dispatch_table *ret = NULL;
166
167         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
168                 return NULL;
169         }
170
171         ret = &smbd_smb2_table[opcode];
172
173         SMB_ASSERT(ret->opcode == opcode);
174
175         return ret;
176 }
177
178 static void print_req_vectors(const struct smbd_smb2_request *req)
179 {
180         int i;
181
182         for (i = 0; i < req->in.vector_count; i++) {
183                 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
184                         (unsigned int)i,
185                         (unsigned int)req->in.vector[i].iov_len);
186         }
187         for (i = 0; i < req->out.vector_count; i++) {
188                 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
189                         (unsigned int)i,
190                         (unsigned int)req->out.vector[i].iov_len);
191         }
192 }
193
194 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
195 {
196         if (size < (4 + SMB2_HDR_BODY)) {
197                 return false;
198         }
199
200         if (IVAL(inbuf, 4) != SMB2_MAGIC) {
201                 return false;
202         }
203
204         return true;
205 }
206
207 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                 case SMB2_OP_LOGOFF:
1906                 case SMB2_OP_CLOSE:
1907                 case SMB2_OP_LOCK:
1908                 case SMB2_OP_CANCEL:
1909                 case SMB2_OP_KEEPALIVE:
1910                         /*
1911                          * [MS-SMB2] 3.3.5.2.9 Verifying the Session
1912                          * specifies that LOGOFF, CLOSE and (UN)LOCK
1913                          * should always be processed even on expired sessions.
1914                          *
1915                          * Also see the logic in
1916                          * smbd_smb2_request_process_lock().
1917                          *
1918                          * The smb2.session.expire2 test shows that
1919                          * CANCEL and KEEPALIVE/ECHO should also
1920                          * be processed.
1921                          */
1922                         status = NT_STATUS_OK;
1923                         break;
1924                 default:
1925                         break;
1926                 }
1927         }
1928         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1929                 switch (in_opcode) {
1930                 case SMB2_OP_TCON:
1931                 case SMB2_OP_CREATE:
1932                 case SMB2_OP_GETINFO:
1933                 case SMB2_OP_SETINFO:
1934                         return NT_STATUS_INVALID_HANDLE;
1935                 default:
1936                         /*
1937                          * Notice the check for
1938                          * (session_info == NULL)
1939                          * below.
1940                          */
1941                         status = NT_STATUS_OK;
1942                         break;
1943                 }
1944         }
1945         if (!NT_STATUS_IS_OK(status)) {
1946                 return status;
1947         }
1948
1949         session_info = session->global->auth_session_info;
1950         if (session_info == NULL) {
1951                 return NT_STATUS_INVALID_HANDLE;
1952         }
1953
1954         if (in_session_id != req->xconn->client->last_session_id) {
1955                 req->xconn->client->last_session_id = in_session_id;
1956                 set_current_user_info(session_info->unix_info->sanitized_username,
1957                                       session_info->unix_info->unix_name,
1958                                       session_info->info->domain_name);
1959         }
1960
1961         return NT_STATUS_OK;
1962 }
1963
1964 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
1965                                                 uint32_t data_length)
1966 {
1967         struct smbXsrv_connection *xconn = req->xconn;
1968         uint16_t needed_charge;
1969         uint16_t credit_charge = 1;
1970         const uint8_t *inhdr;
1971
1972         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1973
1974         if (xconn->smb2.credits.multicredit) {
1975                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
1976                 credit_charge = MAX(credit_charge, 1);
1977         }
1978
1979         needed_charge = (data_length - 1)/ 65536 + 1;
1980
1981         DEBUG(10, ("mid %llu, CreditCharge: %d, NeededCharge: %d\n",
1982                    (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
1983                    credit_charge, needed_charge));
1984
1985         if (needed_charge > credit_charge) {
1986                 DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
1987                           credit_charge, needed_charge));
1988                 return NT_STATUS_INVALID_PARAMETER;
1989         }
1990
1991         return NT_STATUS_OK;
1992 }
1993
1994 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
1995                                         size_t expected_body_size)
1996 {
1997         struct iovec *inhdr_v;
1998         const uint8_t *inhdr;
1999         uint16_t opcode;
2000         const uint8_t *inbody;
2001         size_t body_size;
2002         size_t min_dyn_size = expected_body_size & 0x00000001;
2003         int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2004
2005         /*
2006          * The following should be checked already.
2007          */
2008         if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2009                 return NT_STATUS_INTERNAL_ERROR;
2010         }
2011         if (req->current_idx > max_idx) {
2012                 return NT_STATUS_INTERNAL_ERROR;
2013         }
2014
2015         inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2016         if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2017                 return NT_STATUS_INTERNAL_ERROR;
2018         }
2019         if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2020                 return NT_STATUS_INTERNAL_ERROR;
2021         }
2022
2023         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2024         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2025
2026         switch (opcode) {
2027         case SMB2_OP_IOCTL:
2028         case SMB2_OP_GETINFO:
2029                 min_dyn_size = 0;
2030                 break;
2031         case SMB2_OP_WRITE:
2032                 if (req->smb1req != NULL && req->smb1req->unread_bytes > 0) {
2033                         if (req->smb1req->unread_bytes < min_dyn_size) {
2034                                 return NT_STATUS_INVALID_PARAMETER;
2035                         }
2036
2037                         min_dyn_size = 0;
2038                 }
2039                 break;
2040         }
2041
2042         /*
2043          * Now check the expected body size,
2044          * where the last byte might be in the
2045          * dynamic section..
2046          */
2047         if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2048                 return NT_STATUS_INVALID_PARAMETER;
2049         }
2050         if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2051                 return NT_STATUS_INVALID_PARAMETER;
2052         }
2053
2054         inbody = SMBD_SMB2_IN_BODY_PTR(req);
2055
2056         body_size = SVAL(inbody, 0x00);
2057         if (body_size != expected_body_size) {
2058                 return NT_STATUS_INVALID_PARAMETER;
2059         }
2060
2061         return NT_STATUS_OK;
2062 }
2063
2064 bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2065 {
2066         return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2067                 &&
2068                 (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2069                                      SMBXSRV_ENCRYPTION_DESIRED |
2070                                      SMBXSRV_ENCRYPTION_REQUIRED)));
2071 }
2072
2073 bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2074 {
2075         return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2076                 (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2077 }
2078
2079 /* Set a flag if not already set, return true if set */
2080 bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2081 {
2082         if ((flag == 0) || (*flags & flag)) {
2083                 return false;
2084         }
2085
2086         *flags |= flag;
2087         return true;
2088 }
2089
2090 /*
2091  * Update encryption state tracking flags, this can be used to
2092  * determine whether whether the session or tcon is "encrypted".
2093  */
2094 static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2095                                         uint16_t opcode,
2096                                         bool *update_session_globalp,
2097                                         bool *update_tcon_globalp)
2098 {
2099         /* Default: assume unecrypted and unsigned */
2100         struct smbXsrv_session *session = req->session;
2101         struct smbXsrv_tcon *tcon = req->tcon;
2102         uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2103         uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2104         bool update_session = false;
2105         bool update_tcon = false;
2106
2107         if (req->was_encrypted && req->do_encryption) {
2108                 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2109                 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2110         } else {
2111                 /* Unencrypted packet, can be signed */
2112                 if (req->do_signing) {
2113                         sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2114                 } else if (opcode == SMB2_OP_CANCEL) {
2115                         /* Cancel requests are allowed to skip signing */
2116                         sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2117                 }
2118         }
2119
2120         update_session |= smbXsrv_set_crypto_flag(
2121                 &session->global->encryption_flags, encrypt_flag);
2122         update_session |= smbXsrv_set_crypto_flag(
2123                 &session->global->signing_flags, sign_flag);
2124
2125         if (tcon) {
2126                 update_tcon |= smbXsrv_set_crypto_flag(
2127                         &tcon->global->encryption_flags, encrypt_flag);
2128                 update_tcon |= smbXsrv_set_crypto_flag(
2129                         &tcon->global->signing_flags, sign_flag);
2130         }
2131
2132         *update_session_globalp = update_session;
2133         *update_tcon_globalp = update_tcon;
2134         return;
2135 }
2136
2137 bool smbXsrv_is_signed(uint8_t signing_flags)
2138 {
2139         /*
2140          * Signing is always enabled, so unless we got an unsigned
2141          * packet and at least one signed packet that was not
2142          * encrypted, the session or tcon is "signed".
2143          */
2144         return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2145                 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2146 }
2147
2148 bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2149 {
2150         return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2151                 (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2152 }
2153
2154 static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2155                                 struct smbd_smb2_request *req,
2156                                 bool modify_call)
2157 {
2158         struct smbXsrv_connection *xconn = req->xconn;
2159         const uint8_t *inhdr;
2160         uint16_t channel_sequence;
2161         uint32_t flags;
2162         int cmp;
2163         struct smbXsrv_open *op;
2164         bool update_open = false;
2165         NTSTATUS status = NT_STATUS_OK;
2166
2167         req->request_counters_updated = false;
2168
2169         if (xconn->protocol < PROTOCOL_SMB2_22) {
2170                 return NT_STATUS_OK;
2171         }
2172
2173         if (req->compat_chain_fsp == NULL) {
2174                 return NT_STATUS_OK;
2175         }
2176
2177         op = req->compat_chain_fsp->op;
2178         if (op == NULL) {
2179                 return NT_STATUS_OK;
2180         }
2181
2182         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2183         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2184         channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2185
2186         cmp = channel_sequence - op->global->channel_sequence;
2187
2188         if (abs(cmp) > INT16_MAX) {
2189                 /*
2190                  * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2191                  *
2192                  * If the channel sequence number of the request and the one
2193                  * known to the server are not equal, the channel sequence
2194                  * number and outstanding request counts are only updated
2195                  * "... if the unsigned difference using 16-bit arithmetic
2196                  * between ChannelSequence and Open.ChannelSequence is less than
2197                  * or equal to 0x7FFF ...".
2198                  * Otherwise, an error is returned for the modifying
2199                  * calls write, set_info, and ioctl.
2200                  *
2201                  * There are currently two issues with the description:
2202                  *
2203                  * * For the other calls, the document seems to imply
2204                  *   that processing continues without adapting the
2205                  *   counters (if the sequence numbers are not equal).
2206                  *
2207                  *   TODO: This needs clarification!
2208                  *
2209                  * * Also, the behaviour if the difference is larger
2210                  *   than 0x7FFF is not clear. The document seems to
2211                  *   imply that if such a difference is reached,
2212                  *   the server starts to ignore the counters or
2213                  *   in the case of the modifying calls, return errors.
2214                  *
2215                  *   TODO: This needs clarification!
2216                  *
2217                  * At this point Samba tries to be a little more
2218                  * clever than the description in the MS-SMB2 document
2219                  * by heuristically detecting and properly treating
2220                  * a 16 bit overflow of the client-submitted sequence
2221                  * number:
2222                  *
2223                  * If the stored channel sequence number is more than
2224                  * 0x7FFF larger than the one from the request, then
2225                  * the client-provided sequence number has likely
2226                  * overflown. We treat this case as valid instead
2227                  * of as failure.
2228                  *
2229                  * The MS-SMB2 behaviour would be setting cmp = -1.
2230                  */
2231                 cmp *= -1;
2232         }
2233
2234         if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2235                 if (cmp == 0 && op->pre_request_count == 0) {
2236                         op->request_count += 1;
2237                         req->request_counters_updated = true;
2238                 } else if (cmp > 0 && op->pre_request_count == 0) {
2239                         op->pre_request_count += op->request_count;
2240                         op->request_count = 1;
2241                         op->global->channel_sequence = channel_sequence;
2242                         update_open = true;
2243                         req->request_counters_updated = true;
2244                 } else if (modify_call) {
2245                         return NT_STATUS_FILE_NOT_AVAILABLE;
2246                 }
2247         } else {
2248                 if (cmp == 0) {
2249                         op->request_count += 1;
2250                         req->request_counters_updated = true;
2251                 } else if (cmp > 0) {
2252                         op->pre_request_count += op->request_count;
2253                         op->request_count = 1;
2254                         op->global->channel_sequence = channel_sequence;
2255                         update_open = true;
2256                         req->request_counters_updated = true;
2257                 } else if (modify_call) {
2258                         return NT_STATUS_FILE_NOT_AVAILABLE;
2259                 }
2260         }
2261
2262         if (update_open) {
2263                 status = smbXsrv_open_update(op);
2264         }
2265
2266         return status;
2267 }
2268
2269 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2270 {
2271         struct smbXsrv_connection *xconn = req->xconn;
2272         const struct smbd_smb2_dispatch_table *call = NULL;
2273         const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2274         const uint8_t *inhdr;
2275         uint16_t opcode;
2276         uint32_t flags;
2277         uint64_t mid;
2278         NTSTATUS status;
2279         NTSTATUS session_status;
2280         uint32_t allowed_flags;
2281         NTSTATUS return_value;
2282         struct smbXsrv_session *x = NULL;
2283         bool signing_required = false;
2284         bool encryption_desired = false;
2285         bool encryption_required = false;
2286
2287         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2288
2289         DO_PROFILE_INC(request);
2290
2291         /* TODO: verify more things */
2292
2293         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2294         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2295         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2296         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
2297                 smb2_opcode_name(opcode),
2298                 (unsigned long long)mid));
2299
2300         if (xconn->protocol >= PROTOCOL_SMB2_02) {
2301                 /*
2302                  * once the protocol is negotiated
2303                  * SMB2_OP_NEGPROT is not allowed anymore
2304                  */
2305                 if (opcode == SMB2_OP_NEGPROT) {
2306                         /* drop the connection */
2307                         return NT_STATUS_INVALID_PARAMETER;
2308                 }
2309         } else {
2310                 /*
2311                  * if the protocol is not negotiated yet
2312                  * only SMB2_OP_NEGPROT is allowed.
2313                  */
2314                 if (opcode != SMB2_OP_NEGPROT) {
2315                         /* drop the connection */
2316                         return NT_STATUS_INVALID_PARAMETER;
2317                 }
2318         }
2319
2320         /*
2321          * Check if the client provided a valid session id,
2322          * if so smbd_smb2_request_check_session() calls
2323          * set_current_user_info().
2324          *
2325          * As some command don't require a valid session id
2326          * we defer the check of the session_status
2327          */
2328         session_status = smbd_smb2_request_check_session(req);
2329         x = req->session;
2330         if (x != NULL) {
2331                 signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
2332                 encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
2333                 encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
2334         }
2335
2336         req->async_internal = false;
2337         req->do_signing = false;
2338         req->do_encryption = false;
2339         req->was_encrypted = false;
2340         if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
2341                 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
2342                 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
2343
2344                 if (x != NULL && x->global->session_wire_id != tf_session_id) {
2345                         DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2346                                  "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2347                                  (unsigned long long)x->global->session_wire_id,
2348                                  (unsigned long long)tf_session_id));
2349                         /*
2350                          * TODO: windows allows this...
2351                          * should we drop the connection?
2352                          *
2353                          * For now we just return ACCESS_DENIED
2354                          * (Windows clients never trigger this)
2355                          * and wait for an update of [MS-SMB2].
2356                          */
2357                         return smbd_smb2_request_error(req,
2358                                         NT_STATUS_ACCESS_DENIED);
2359                 }
2360
2361                 req->was_encrypted = true;
2362         }
2363
2364         if (encryption_required && !req->was_encrypted) {
2365                 return smbd_smb2_request_error(req,
2366                                 NT_STATUS_ACCESS_DENIED);
2367         }
2368
2369         call = smbd_smb2_call(opcode);
2370         if (call == NULL) {
2371                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2372         }
2373
2374         allowed_flags = SMB2_HDR_FLAG_CHAINED |
2375                         SMB2_HDR_FLAG_SIGNED |
2376                         SMB2_HDR_FLAG_DFS;
2377         if (xconn->protocol >= PROTOCOL_SMB3_11) {
2378                 allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2379         }
2380         if (opcode == SMB2_OP_NEGPROT) {
2381                 if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
2382                         allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
2383                 }
2384         }
2385         if (opcode == SMB2_OP_CANCEL) {
2386                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
2387         }
2388         if (xconn->protocol >= PROTOCOL_SMB2_22) {
2389                 allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
2390         }
2391         if ((flags & ~allowed_flags) != 0) {
2392                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2393         }
2394
2395         if (flags & SMB2_HDR_FLAG_CHAINED) {
2396                 /*
2397                  * This check is mostly for giving the correct error code
2398                  * for compounded requests.
2399                  */
2400                 if (!NT_STATUS_IS_OK(session_status)) {
2401                         return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2402                 }
2403         } else {
2404                 req->compat_chain_fsp = NULL;
2405         }
2406
2407         if (req->was_encrypted) {
2408                 signing_required = false;
2409         } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
2410                 DATA_BLOB signing_key = data_blob_null;
2411
2412                 if (x == NULL) {
2413                         /*
2414                          * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2415                          * If the SMB2 header of the SMB2 NEGOTIATE
2416                          * request has the SMB2_FLAGS_SIGNED bit set in the
2417                          * Flags field, the server MUST fail the request
2418                          * with STATUS_INVALID_PARAMETER.
2419                          *
2420                          * Microsoft test tool checks this.
2421                          */
2422
2423                         if ((opcode == SMB2_OP_NEGPROT) &&
2424                                         (flags & SMB2_HDR_FLAG_SIGNED)) {
2425                                 status = NT_STATUS_INVALID_PARAMETER;
2426                         } else {
2427                                 status = NT_STATUS_USER_SESSION_DELETED;
2428                         }
2429                         return smbd_smb2_request_error(req, status);
2430                 }
2431
2432                 signing_key = smbd_smb2_signing_key(x, xconn);
2433
2434                 /*
2435                  * If we have a signing key, we should
2436                  * sign the response
2437                  */
2438                 if (signing_key.length > 0) {
2439                         req->do_signing = true;
2440                 }
2441
2442                 status = smb2_signing_check_pdu(signing_key,
2443                                                 xconn->protocol,
2444                                                 SMBD_SMB2_IN_HDR_IOV(req),
2445                                                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2446                 if (!NT_STATUS_IS_OK(status)) {
2447                         return smbd_smb2_request_error(req, status);
2448                 }
2449
2450                 /*
2451                  * Now that we know the request was correctly signed
2452                  * we have to sign the response too.
2453                  */
2454                 req->do_signing = true;
2455
2456                 if (!NT_STATUS_IS_OK(session_status)) {
2457                         return smbd_smb2_request_error(req, session_status);
2458                 }
2459         } else if (opcode == SMB2_OP_CANCEL) {
2460                 /* Cancel requests are allowed to skip the signing */
2461         } else if (signing_required) {
2462                 /*
2463                  * If signing is required we try to sign
2464                  * a possible error response
2465                  */
2466                 req->do_signing = true;
2467                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
2468         }
2469
2470         if (flags & SMB2_HDR_FLAG_CHAINED) {
2471                 req->compound_related = true;
2472         }
2473
2474         if (call->need_session) {
2475                 if (!NT_STATUS_IS_OK(session_status)) {
2476                         return smbd_smb2_request_error(req, session_status);
2477                 }
2478         }
2479
2480         if (call->need_tcon) {
2481                 SMB_ASSERT(call->need_session);
2482
2483                 /*
2484                  * This call needs to be run as user.
2485                  *
2486                  * smbd_smb2_request_check_tcon()
2487                  * calls change_to_user() on success.
2488                  */
2489                 status = smbd_smb2_request_check_tcon(req);
2490                 if (!NT_STATUS_IS_OK(status)) {
2491                         return smbd_smb2_request_error(req, status);
2492                 }
2493                 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
2494                         encryption_desired = true;
2495                 }
2496                 if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
2497                         encryption_required = true;
2498                 }
2499                 if (encryption_required && !req->was_encrypted) {
2500                         return smbd_smb2_request_error(req,
2501                                 NT_STATUS_ACCESS_DENIED);
2502                 }
2503         }
2504
2505         if (req->was_encrypted || encryption_desired) {
2506                 req->do_encryption = true;
2507         }
2508
2509         if (req->session) {
2510                 bool update_session_global = false;
2511                 bool update_tcon_global = false;
2512
2513                 smb2srv_update_crypto_flags(req, opcode,
2514                                             &update_session_global,
2515                                             &update_tcon_global);
2516
2517                 if (update_session_global) {
2518                         status = smbXsrv_session_update(x);
2519                         if (!NT_STATUS_IS_OK(status)) {
2520                                 return smbd_smb2_request_error(req, status);
2521                         }
2522                 }
2523                 if (update_tcon_global) {
2524                         status = smbXsrv_tcon_update(req->tcon);
2525                         if (!NT_STATUS_IS_OK(status)) {
2526                                 return smbd_smb2_request_error(req, status);
2527                         }
2528                 }
2529         }
2530
2531         if (call->fileid_ofs != 0) {
2532                 size_t needed = call->fileid_ofs + 16;
2533                 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2534                 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2535                 uint64_t file_id_persistent;
2536                 uint64_t file_id_volatile;
2537                 struct files_struct *fsp;
2538
2539                 SMB_ASSERT(call->need_tcon);
2540
2541                 if (needed > body_size) {
2542                         return smbd_smb2_request_error(req,
2543                                         NT_STATUS_INVALID_PARAMETER);
2544                 }
2545
2546                 file_id_persistent      = BVAL(body, call->fileid_ofs + 0);
2547                 file_id_volatile        = BVAL(body, call->fileid_ofs + 8);
2548
2549                 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2550                 if (fsp == NULL) {
2551                         if (!call->allow_invalid_fileid) {
2552                                 return smbd_smb2_request_error(req,
2553                                                 NT_STATUS_FILE_CLOSED);
2554                         }
2555
2556                         if (file_id_persistent != UINT64_MAX) {
2557                                 return smbd_smb2_request_error(req,
2558                                                 NT_STATUS_FILE_CLOSED);
2559                         }
2560                         if (file_id_volatile != UINT64_MAX) {
2561                                 return smbd_smb2_request_error(req,
2562                                                 NT_STATUS_FILE_CLOSED);
2563                         }
2564                 }
2565         }
2566
2567         status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
2568         if (!NT_STATUS_IS_OK(status)) {
2569                 return smbd_smb2_request_error(req, status);
2570         }
2571
2572         if (call->as_root) {
2573                 SMB_ASSERT(call->fileid_ofs == 0);
2574                 /* This call needs to be run as root */
2575                 change_to_root_user();
2576         } else {
2577                 SMB_ASSERT(call->need_tcon);
2578         }
2579
2580 #define _INBYTES(_r) \
2581         iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2582
2583         switch (opcode) {
2584         case SMB2_OP_NEGPROT:
2585                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
2586                                                req->profile, _INBYTES(req));
2587                 return_value = smbd_smb2_request_process_negprot(req);
2588                 break;
2589
2590         case SMB2_OP_SESSSETUP:
2591                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
2592                                                req->profile, _INBYTES(req));
2593                 return_value = smbd_smb2_request_process_sesssetup(req);
2594                 break;
2595
2596         case SMB2_OP_LOGOFF:
2597                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
2598                                                req->profile, _INBYTES(req));
2599                 return_value = smbd_smb2_request_process_logoff(req);
2600                 break;
2601
2602         case SMB2_OP_TCON:
2603                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
2604                                                req->profile, _INBYTES(req));
2605                 return_value = smbd_smb2_request_process_tcon(req);
2606                 break;
2607
2608         case SMB2_OP_TDIS:
2609                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
2610                                                req->profile, _INBYTES(req));
2611                 return_value = smbd_smb2_request_process_tdis(req);
2612                 break;
2613
2614         case SMB2_OP_CREATE:
2615                 if (req->subreq == NULL) {
2616                         SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
2617                                                        req->profile, _INBYTES(req));
2618                 } else {
2619                         SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
2620                 }
2621                 return_value = smbd_smb2_request_process_create(req);
2622                 break;
2623
2624         case SMB2_OP_CLOSE:
2625                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
2626                                                req->profile, _INBYTES(req));
2627                 return_value = smbd_smb2_request_process_close(req);
2628                 break;
2629
2630         case SMB2_OP_FLUSH:
2631                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
2632                                                req->profile, _INBYTES(req));
2633                 return_value = smbd_smb2_request_process_flush(req);
2634                 break;
2635
2636         case SMB2_OP_READ:
2637                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
2638                                                req->profile, _INBYTES(req));
2639                 return_value = smbd_smb2_request_process_read(req);
2640                 break;
2641
2642         case SMB2_OP_WRITE:
2643                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
2644                                                req->profile, _INBYTES(req));
2645                 return_value = smbd_smb2_request_process_write(req);
2646                 break;
2647
2648         case SMB2_OP_LOCK:
2649                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
2650                                                req->profile, _INBYTES(req));
2651                 return_value = smbd_smb2_request_process_lock(req);
2652                 break;
2653
2654         case SMB2_OP_IOCTL:
2655                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
2656                                                req->profile, _INBYTES(req));
2657                 return_value = smbd_smb2_request_process_ioctl(req);
2658                 break;
2659
2660         case SMB2_OP_CANCEL:
2661                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
2662                                                req->profile, _INBYTES(req));
2663                 return_value = smbd_smb2_request_process_cancel(req);
2664                 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
2665
2666                 /*
2667                  * We don't need the request anymore cancel requests never
2668                  * have a response.
2669                  *
2670                  * smbd_smb2_request_process_cancel() already called
2671                  * DLIST_REMOVE(xconn->smb2.requests, req);
2672                  */
2673                 TALLOC_FREE(req);
2674
2675                 break;
2676
2677         case SMB2_OP_KEEPALIVE:
2678                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
2679                                                req->profile, _INBYTES(req));
2680                 return_value = smbd_smb2_request_process_keepalive(req);
2681                 break;
2682
2683         case SMB2_OP_QUERY_DIRECTORY:
2684                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
2685                                                req->profile, _INBYTES(req));
2686                 return_value = smbd_smb2_request_process_query_directory(req);
2687                 break;
2688
2689         case SMB2_OP_NOTIFY:
2690                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
2691                                                req->profile, _INBYTES(req));
2692                 return_value = smbd_smb2_request_process_notify(req);
2693                 break;
2694
2695         case SMB2_OP_GETINFO:
2696                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
2697                                                req->profile, _INBYTES(req));
2698                 return_value = smbd_smb2_request_process_getinfo(req);
2699                 break;
2700
2701         case SMB2_OP_SETINFO:
2702                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
2703                                                req->profile, _INBYTES(req));
2704                 return_value = smbd_smb2_request_process_setinfo(req);
2705                 break;
2706
2707         case SMB2_OP_BREAK:
2708                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
2709                                                req->profile, _INBYTES(req));
2710                 return_value = smbd_smb2_request_process_break(req);
2711                 break;
2712
2713         default:
2714                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2715                 break;
2716         }
2717         return return_value;
2718 }
2719
2720 static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
2721 {
2722         struct smbXsrv_connection *xconn = req->xconn;
2723         const uint8_t *inhdr;
2724         uint16_t channel_sequence;
2725         struct smbXsrv_open *op;
2726
2727         if (!req->request_counters_updated) {
2728                 return;
2729         }
2730
2731         if (xconn->protocol < PROTOCOL_SMB2_22) {
2732                 return;
2733         }
2734
2735         if (req->compat_chain_fsp == NULL) {
2736                 return;
2737         }
2738
2739         op = req->compat_chain_fsp->op;
2740         if (op == NULL) {
2741                 return;
2742         }
2743
2744         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2745         channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2746
2747         if (op->global->channel_sequence == channel_sequence) {
2748                 SMB_ASSERT(op->request_count > 0);
2749                 op->request_count -= 1;
2750         } else {
2751                 SMB_ASSERT(op->pre_request_count > 0);
2752                 op->pre_request_count -= 1;
2753         }
2754 }
2755
2756 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
2757 {
2758         struct smbXsrv_connection *xconn = req->xconn;
2759         int first_idx = 1;
2760         struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
2761         struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
2762         struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
2763         NTSTATUS status;
2764         bool ok;
2765
2766         req->subreq = NULL;
2767         TALLOC_FREE(req->async_te);
2768
2769         /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
2770         smbd_smb2_request_reply_update_counts(req);
2771
2772         if (req->do_encryption &&
2773             (firsttf->iov_len == 0) &&
2774             (req->first_key.length == 0) &&
2775             (req->session != NULL) &&
2776             (req->session->global->encryption_key.length != 0))
2777         {
2778                 DATA_BLOB encryption_key = req->session->global->encryption_key;
2779                 uint8_t *tf;
2780                 uint64_t session_id = req->session->global->session_wire_id;
2781                 uint64_t nonce_high;
2782                 uint64_t nonce_low;
2783
2784                 status = smb2_get_new_nonce(req->session,
2785                                             &nonce_high,
2786                                             &nonce_low);
2787                 if (!NT_STATUS_IS_OK(status)) {
2788                         return status;
2789                 }
2790
2791                 /*
2792                  * We need to place the SMB2_TRANSFORM header before the
2793                  * first SMB2 header
2794                  */
2795
2796                 /*
2797                  * we need to remember the encryption key
2798                  * and defer the signing/encryption until
2799                  * we are sure that we do not change
2800                  * the header again.
2801                  */
2802                 req->first_key = data_blob_dup_talloc(req, encryption_key);
2803                 if (req->first_key.data == NULL) {
2804                         return NT_STATUS_NO_MEMORY;
2805                 }
2806
2807                 tf = talloc_zero_array(req, uint8_t,
2808                                        SMB2_TF_HDR_SIZE);
2809                 if (tf == NULL) {
2810                         return NT_STATUS_NO_MEMORY;
2811                 }
2812
2813                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2814                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2815                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2816                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2817
2818                 firsttf->iov_base = (void *)tf;
2819                 firsttf->iov_len = SMB2_TF_HDR_SIZE;
2820         }
2821
2822         if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
2823             (req->last_key.length > 0) &&
2824             (firsttf->iov_len == 0))
2825         {
2826                 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
2827                 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
2828
2829                 /*
2830                  * As we are sure the header of the last request in the
2831                  * compound chain will not change, we can to sign here
2832                  * with the last signing key we remembered.
2833                  */
2834                 status = smb2_signing_sign_pdu(req->last_key,
2835                                                xconn->protocol,
2836                                                lasthdr,
2837                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2838                 if (!NT_STATUS_IS_OK(status)) {
2839                         return status;
2840                 }
2841         }
2842         if (req->last_key.length > 0) {
2843                 data_blob_clear_free(&req->last_key);
2844         }
2845
2846         SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
2847                 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
2848
2849         req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
2850
2851         if (req->current_idx < req->out.vector_count) {
2852                 /*
2853                  * We must process the remaining compound
2854                  * SMB2 requests before any new incoming SMB2
2855                  * requests. This is because incoming SMB2
2856                  * requests may include a cancel for a
2857                  * compound request we haven't processed
2858                  * yet.
2859                  */
2860                 struct tevent_immediate *im = tevent_create_immediate(req);
2861                 if (!im) {
2862                         return NT_STATUS_NO_MEMORY;
2863                 }
2864
2865                 if (req->do_signing && firsttf->iov_len == 0) {
2866                         struct smbXsrv_session *x = req->session;
2867                         DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2868
2869                         /*
2870                          * we need to remember the signing key
2871                          * and defer the signing until
2872                          * we are sure that we do not change
2873                          * the header again.
2874                          */
2875                         req->last_key = data_blob_dup_talloc(req, signing_key);
2876                         if (req->last_key.data == NULL) {
2877                                 return NT_STATUS_NO_MEMORY;
2878                         }
2879                 }
2880
2881                 tevent_schedule_immediate(im,
2882                                         req->sconn->ev_ctx,
2883                                         smbd_smb2_request_dispatch_immediate,
2884                                         req);
2885                 return NT_STATUS_OK;
2886         }
2887
2888         if (req->compound_related) {
2889                 req->compound_related = false;
2890         }
2891
2892         ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
2893         if (!ok) {
2894                 return NT_STATUS_INVALID_PARAMETER_MIX;
2895         }
2896
2897         /* Set credit for these operations (zero credits if this
2898            is a final reply for an async operation). */
2899         smb2_calculate_credits(req, req);
2900
2901         /*
2902          * now check if we need to sign the current response
2903          */
2904         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
2905                 status = smb2_signing_encrypt_pdu(req->first_key,
2906                                         xconn->smb2.server.cipher,
2907                                         firsttf,
2908                                         req->out.vector_count - first_idx);
2909                 if (!NT_STATUS_IS_OK(status)) {
2910                         return status;
2911                 }
2912         } else if (req->do_signing) {
2913                 struct smbXsrv_session *x = req->session;
2914                 DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2915
2916                 status = smb2_signing_sign_pdu(signing_key,
2917                                                xconn->protocol,
2918                                                outhdr,
2919                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2920                 if (!NT_STATUS_IS_OK(status)) {
2921                         return status;
2922                 }
2923         }
2924         if (req->first_key.length > 0) {
2925                 data_blob_clear_free(&req->first_key);
2926         }
2927
2928         if (req->preauth != NULL) {
2929                 struct hc_sha512state sctx;
2930                 int i;
2931
2932                 samba_SHA512_Init(&sctx);
2933                 samba_SHA512_Update(&sctx, req->preauth->sha512_value,
2934                                     sizeof(req->preauth->sha512_value));
2935                 for (i = 1; i < req->in.vector_count; i++) {
2936                         samba_SHA512_Update(&sctx,
2937                                             req->in.vector[i].iov_base,
2938                                             req->in.vector[i].iov_len);
2939                 }
2940                 samba_SHA512_Final(req->preauth->sha512_value, &sctx);
2941
2942                 samba_SHA512_Init(&sctx);
2943                 samba_SHA512_Update(&sctx, req->preauth->sha512_value,
2944                                     sizeof(req->preauth->sha512_value));
2945                 for (i = 1; i < req->out.vector_count; i++) {
2946                         samba_SHA512_Update(&sctx,
2947                                             req->out.vector[i].iov_base,
2948                                             req->out.vector[i].iov_len);
2949                 }
2950                 samba_SHA512_Final(req->preauth->sha512_value, &sctx);
2951
2952                 req->preauth = NULL;
2953         }
2954
2955         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2956         if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
2957             outdyn->iov_base == NULL && outdyn->iov_len != 0) {
2958                 /* Dynamic part is NULL. Chop it off,
2959                    We're going to send it via sendfile. */
2960                 req->out.vector_count -= 1;
2961         }
2962
2963         /*
2964          * We're done with this request -
2965          * move it off the "being processed" queue.
2966          */
2967         DLIST_REMOVE(xconn->smb2.requests, req);
2968
2969         req->queue_entry.mem_ctx = req;
2970         req->queue_entry.vector = req->out.vector;
2971         req->queue_entry.count = req->out.vector_count;
2972         DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
2973         xconn->smb2.send_queue_len++;
2974
2975         status = smbd_smb2_flush_send_queue(xconn);
2976         if (!NT_STATUS_IS_OK(status)) {
2977                 return status;
2978         }
2979
2980         return NT_STATUS_OK;
2981 }
2982
2983 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
2984
2985 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
2986                                         struct tevent_immediate *im,
2987                                         void *private_data)
2988 {
2989         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
2990                                         struct smbd_smb2_request);
2991         struct smbXsrv_connection *xconn = req->xconn;
2992         NTSTATUS status;
2993
2994         TALLOC_FREE(im);
2995
2996         if (DEBUGLEVEL >= 10) {
2997                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2998                         req->current_idx, req->in.vector_count));
2999                 print_req_vectors(req);
3000         }
3001
3002         status = smbd_smb2_request_dispatch(req);
3003         if (!NT_STATUS_IS_OK(status)) {
3004                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3005                 return;
3006         }
3007
3008         status = smbd_smb2_request_next_incoming(xconn);
3009         if (!NT_STATUS_IS_OK(status)) {
3010                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3011                 return;
3012         }
3013 }
3014
3015 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3016                                    NTSTATUS status,
3017                                    DATA_BLOB body, DATA_BLOB *dyn,
3018                                    const char *location)
3019 {
3020         uint8_t *outhdr;
3021         struct iovec *outbody_v;
3022         struct iovec *outdyn_v;
3023         uint32_t next_command_ofs;
3024
3025         DEBUG(10,("smbd_smb2_request_done_ex: "
3026                   "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
3027                   req->current_idx, nt_errstr(status), (unsigned int)body.length,
3028                   dyn ? "yes": "no",
3029                   (unsigned int)(dyn ? dyn->length : 0),
3030                   location));
3031
3032         if (body.length < 2) {
3033                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3034         }
3035
3036         if ((body.length % 2) != 0) {
3037                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3038         }
3039
3040         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3041         outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3042         outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3043
3044         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3045         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3046
3047         outbody_v->iov_base = (void *)body.data;
3048         outbody_v->iov_len = body.length;
3049
3050         if (dyn) {
3051                 outdyn_v->iov_base = (void *)dyn->data;
3052                 outdyn_v->iov_len = dyn->length;
3053         } else {
3054                 outdyn_v->iov_base = NULL;
3055                 outdyn_v->iov_len = 0;
3056         }
3057
3058         /*
3059          * See if we need to recalculate the offset to the next response
3060          *
3061          * Note that all responses may require padding (including the very last
3062          * one).
3063          */
3064         if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3065                 next_command_ofs  = SMB2_HDR_BODY;
3066                 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3067                 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3068         }
3069
3070         if ((next_command_ofs % 8) != 0) {
3071                 size_t pad_size = 8 - (next_command_ofs % 8);
3072                 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3073                         /*
3074                          * if the dyn buffer is empty
3075                          * we can use it to add padding
3076                          */
3077                         uint8_t *pad;
3078
3079                         pad = talloc_zero_array(req,
3080                                                 uint8_t, pad_size);
3081                         if (pad == NULL) {
3082                                 return smbd_smb2_request_error(req,
3083                                                 NT_STATUS_NO_MEMORY);
3084                         }
3085
3086                         outdyn_v->iov_base = (void *)pad;
3087                         outdyn_v->iov_len = pad_size;
3088                 } else {
3089                         /*
3090                          * For now we copy the dynamic buffer
3091                          * and add the padding to the new buffer
3092                          */
3093                         size_t old_size;
3094                         uint8_t *old_dyn;
3095                         size_t new_size;
3096                         uint8_t *new_dyn;
3097
3098                         old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3099                         old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3100
3101                         new_size = old_size + pad_size;
3102                         new_dyn = talloc_zero_array(req,
3103                                                uint8_t, new_size);
3104                         if (new_dyn == NULL) {
3105                                 return smbd_smb2_request_error(req,
3106                                                 NT_STATUS_NO_MEMORY);
3107                         }
3108
3109                         memcpy(new_dyn, old_dyn, old_size);
3110                         memset(new_dyn + old_size, 0, pad_size);
3111
3112                         outdyn_v->iov_base = (void *)new_dyn;
3113                         outdyn_v->iov_len = new_size;
3114                 }
3115                 next_command_ofs += pad_size;
3116         }
3117
3118         if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3119                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3120         } else {
3121                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3122         }
3123         return smbd_smb2_request_reply(req);
3124 }
3125
3126 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3127                                     NTSTATUS status,
3128                                     DATA_BLOB *info,
3129                                     const char *location)
3130 {
3131         struct smbXsrv_connection *xconn = req->xconn;
3132         DATA_BLOB body;
3133         DATA_BLOB _dyn;
3134         uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3135         size_t unread_bytes = smbd_smb2_unread_bytes(req);
3136
3137         DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3138                    "at %s\n", req->current_idx, nt_errstr(status),
3139                    info ? " +info" : "", location);
3140
3141         if (unread_bytes) {
3142                 /* Recvfile error. Drain incoming socket. */
3143                 size_t ret;
3144
3145                 errno = 0;
3146                 ret = drain_socket(xconn->transport.sock, unread_bytes);
3147                 if (ret != unread_bytes) {
3148                         NTSTATUS error;
3149
3150                         if (errno == 0) {
3151                                 error = NT_STATUS_IO_DEVICE_ERROR;
3152                         } else {
3153                                 error = map_nt_error_from_unix_common(errno);
3154                         }
3155
3156                         DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3157                                   "ret[%u] errno[%d] => %s\n",
3158                                   (unsigned)unread_bytes,
3159                                   (unsigned)ret, errno, nt_errstr(error)));
3160                         return error;
3161                 }
3162         }
3163
3164         body.data = outhdr + SMB2_HDR_BODY;
3165         body.length = 8;
3166         SSVAL(body.data, 0, 9);
3167
3168         if (info) {
3169                 SIVAL(body.data, 0x04, info->length);
3170         } else {
3171                 /* Allocated size of req->out.vector[i].iov_base
3172                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3173                  * 1 byte without having to do an alloc.
3174                  */
3175                 info = &_dyn;
3176                 info->data = ((uint8_t *)outhdr) +
3177                         OUTVEC_ALLOC_SIZE - 1;
3178                 info->length = 1;
3179                 SCVAL(info->data, 0, 0);
3180         }
3181
3182         /*
3183          * Note: Even if there is an error, continue to process the request.
3184          * per MS-SMB2.
3185          */
3186
3187         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
3188 }
3189
3190
3191 struct smbd_smb2_send_break_state {
3192         struct smbd_smb2_send_queue queue_entry;
3193         uint8_t nbt_hdr[NBT_HDR_SIZE];
3194         uint8_t tf[SMB2_TF_HDR_SIZE];
3195         uint8_t hdr[SMB2_HDR_BODY];
3196         struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
3197         uint8_t body[1];
3198 };
3199
3200 static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
3201                                      struct smbXsrv_session *session,
3202                                      struct smbXsrv_tcon *tcon,
3203                                      const uint8_t *body,
3204                                      size_t body_len)
3205 {
3206         struct smbd_smb2_send_break_state *state;
3207         bool do_encryption = false;
3208         uint64_t session_wire_id = 0;
3209         uint64_t nonce_high = 0;
3210         uint64_t nonce_low = 0;
3211         NTSTATUS status;
3212         size_t statelen;
3213         bool ok;
3214
3215         if (session != NULL) {
3216                 session_wire_id = session->global->session_wire_id;
3217                 do_encryption = session->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3218                 if (tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3219                         do_encryption = true;
3220                 }
3221         }
3222
3223         statelen = offsetof(struct smbd_smb2_send_break_state, body) +
3224                 body_len;
3225
3226         state = talloc_zero_size(xconn, statelen);
3227         if (state == NULL) {
3228                 return NT_STATUS_NO_MEMORY;
3229         }
3230         talloc_set_name_const(state, "struct smbd_smb2_send_break_state");
3231
3232         if (do_encryption) {
3233                 status = smb2_get_new_nonce(session,
3234                                             &nonce_high,
3235                                             &nonce_low);
3236                 if (!NT_STATUS_IS_OK(status)) {
3237                         return status;
3238                 }
3239         }
3240
3241         SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3242         SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
3243         SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
3244         SBVAL(state->tf, SMB2_TF_SESSION_ID, session_wire_id);
3245
3246         SIVAL(state->hdr, 0,                            SMB2_MAGIC);
3247         SSVAL(state->hdr, SMB2_HDR_LENGTH,              SMB2_HDR_BODY);
3248         SSVAL(state->hdr, SMB2_HDR_EPOCH,               0);
3249         SIVAL(state->hdr, SMB2_HDR_STATUS,              0);
3250         SSVAL(state->hdr, SMB2_HDR_OPCODE,              SMB2_OP_BREAK);
3251         SSVAL(state->hdr, SMB2_HDR_CREDIT,              0);
3252         SIVAL(state->hdr, SMB2_HDR_FLAGS,               SMB2_HDR_FLAG_REDIRECT);
3253         SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND,        0);
3254         SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID,          UINT64_MAX);
3255         SIVAL(state->hdr, SMB2_HDR_PID,         0);
3256         SIVAL(state->hdr, SMB2_HDR_TID,         0);
3257         SBVAL(state->hdr, SMB2_HDR_SESSION_ID,          0);
3258         memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
3259
3260         state->vector[0] = (struct iovec) {
3261                 .iov_base = state->nbt_hdr,
3262                 .iov_len  = sizeof(state->nbt_hdr)
3263         };
3264
3265         if (do_encryption) {
3266                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3267                         .iov_base = state->tf,
3268                         .iov_len  = sizeof(state->tf)
3269                 };
3270         } else {
3271                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
3272                         .iov_base = NULL,
3273                         .iov_len  = 0
3274                 };
3275         }
3276
3277         state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
3278                 .iov_base = state->hdr,
3279                 .iov_len  = sizeof(state->hdr)
3280         };
3281
3282         memcpy(state->body, body, body_len);
3283
3284         state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
3285                 .iov_base = state->body,
3286                 .iov_len  = body_len /* no sizeof(state->body) .. :-) */
3287         };
3288
3289         /*
3290          * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
3291          */
3292
3293         ok = smb2_setup_nbt_length(state->vector,
3294                                    1 + SMBD_SMB2_NUM_IOV_PER_REQ);
3295         if (!ok) {
3296                 return NT_STATUS_INVALID_PARAMETER_MIX;
3297         }
3298
3299         if (do_encryption) {
3300                 DATA_BLOB encryption_key = session->global->encryption_key;
3301
3302                 status = smb2_signing_encrypt_pdu(encryption_key,
3303                                         xconn->smb2.server.cipher,
3304                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
3305                                         SMBD_SMB2_NUM_IOV_PER_REQ);
3306                 if (!NT_STATUS_IS_OK(status)) {
3307                         return status;
3308                 }
3309         }
3310
3311         state->queue_entry.mem_ctx = state;
3312         state->queue_entry.vector = state->vector;
3313         state->queue_entry.count = ARRAY_SIZE(state->vector);
3314         DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
3315         xconn->smb2.send_queue_len++;
3316
3317         status = smbd_smb2_flush_send_queue(xconn);
3318         if (!NT_STATUS_IS_OK(status)) {
3319                 return status;
3320         }
3321
3322         return NT_STATUS_OK;
3323 }
3324
3325 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
3326                                      struct smbXsrv_session *session,
3327                                      struct smbXsrv_tcon *tcon,
3328                                      struct smbXsrv_open *op,
3329                                      uint8_t oplock_level)
3330 {
3331         uint8_t body[0x18];
3332
3333         SSVAL(body, 0x00, sizeof(body));
3334         SCVAL(body, 0x02, oplock_level);
3335         SCVAL(body, 0x03, 0);           /* reserved */
3336         SIVAL(body, 0x04, 0);           /* reserved */
3337         SBVAL(body, 0x08, op->global->open_persistent_id);
3338         SBVAL(body, 0x10, op->global->open_volatile_id);
3339
3340         return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3341 }
3342
3343 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
3344                                     uint16_t new_epoch,
3345                                     uint32_t lease_flags,
3346                                     struct smb2_lease_key *lease_key,
3347                                     uint32_t current_lease_state,
3348                                     uint32_t new_lease_state)
3349 {
3350         uint8_t body[0x2c];
3351
3352         SSVAL(body, 0x00, sizeof(body));
3353         SSVAL(body, 0x02, new_epoch);
3354         SIVAL(body, 0x04, lease_flags);
3355         SBVAL(body, 0x08, lease_key->data[0]);
3356         SBVAL(body, 0x10, lease_key->data[1]);
3357         SIVAL(body, 0x18, current_lease_state);
3358         SIVAL(body, 0x1c, new_lease_state);
3359         SIVAL(body, 0x20, 0);           /* BreakReason, MUST be 0 */
3360         SIVAL(body, 0x24, 0);           /* AccessMaskHint, MUST be 0 */
3361         SIVAL(body, 0x28, 0);           /* ShareMaskHint, MUST be 0 */
3362
3363         return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
3364 }
3365
3366 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
3367 {
3368         NTSTATUS status;
3369         uint32_t flags;
3370         uint64_t file_id_persistent;
3371         uint64_t file_id_volatile;
3372         struct smbXsrv_open *op = NULL;
3373         struct files_struct *fsp = NULL;
3374         const uint8_t *body = NULL;
3375
3376         /*
3377          * This is only called with a pktbuf
3378          * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
3379          * bytes
3380          */
3381
3382         if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
3383                 /* Transform header. Cannot recvfile. */
3384                 return false;
3385         }
3386         if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
3387                 /* Not SMB2. Normal error path will cope. */
3388                 return false;
3389         }
3390         if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
3391                 /* Not SMB2. Normal error path will cope. */
3392                 return false;
3393         }
3394         if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
3395                 /* Needs to be a WRITE. */
3396                 return false;
3397         }
3398         if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
3399                 /* Chained. Cannot recvfile. */
3400                 return false;
3401         }
3402         flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
3403         if (flags & SMB2_HDR_FLAG_CHAINED) {
3404                 /* Chained. Cannot recvfile. */
3405                 return false;
3406         }
3407         if (flags & SMB2_HDR_FLAG_SIGNED) {
3408                 /* Signed. Cannot recvfile. */
3409                 return false;
3410         }
3411
3412         body = &state->pktbuf[SMB2_HDR_BODY];
3413
3414         file_id_persistent      = BVAL(body, 0x10);
3415         file_id_volatile        = BVAL(body, 0x18);
3416
3417         status = smb2srv_open_lookup(state->req->xconn,
3418                                      file_id_persistent,
3419                                      file_id_volatile,
3420                                      0, /* now */
3421                                      &op);
3422         if (!NT_STATUS_IS_OK(status)) {
3423                 return false;
3424         }
3425
3426         fsp = op->compat;
3427         if (fsp == NULL) {
3428                 return false;
3429         }
3430         if (fsp->conn == NULL) {
3431                 return false;
3432         }
3433
3434         if (IS_IPC(fsp->conn)) {
3435                 return false;
3436         }
3437         if (IS_PRINT(fsp->conn)) {
3438                 return false;
3439         }
3440
3441         DEBUG(10,("Doing recvfile write len = %u\n",
3442                 (unsigned int)(state->pktfull - state->pktlen)));
3443
3444         return true;
3445 }
3446
3447 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
3448 {
3449         struct smbd_server_connection *sconn = xconn->client->sconn;
3450         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3451         size_t max_send_queue_len;
3452         size_t cur_send_queue_len;
3453
3454         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3455                 /*
3456                  * we're not supposed to do any io
3457                  */
3458                 return NT_STATUS_OK;
3459         }
3460
3461         if (state->req != NULL) {
3462                 /*
3463                  * if there is already a tstream_readv_pdu
3464                  * pending, we are done.
3465                  */
3466                 return NT_STATUS_OK;
3467         }
3468
3469         max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
3470         cur_send_queue_len = xconn->smb2.send_queue_len;
3471
3472         if (cur_send_queue_len > max_send_queue_len) {
3473                 /*
3474                  * if we have a lot of requests to send,
3475                  * we wait until they are on the wire until we
3476                  * ask for the next request.
3477                  */
3478                 return NT_STATUS_OK;
3479         }
3480
3481         /* ask for the next request */
3482         ZERO_STRUCTP(state);
3483         state->req = smbd_smb2_request_allocate(xconn);
3484         if (state->req == NULL) {
3485                 return NT_STATUS_NO_MEMORY;
3486         }
3487         state->req->sconn = sconn;
3488         state->req->xconn = xconn;
3489         state->min_recv_size = lp_min_receive_file_size();
3490
3491         TEVENT_FD_READABLE(xconn->transport.fde);
3492
3493         return NT_STATUS_OK;
3494 }
3495
3496 void smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
3497                                uint64_t expected_seq_low,
3498                                const uint8_t *inpdu, size_t size)
3499 {
3500         struct smbd_server_connection *sconn = xconn->client->sconn;
3501         NTSTATUS status;
3502         struct smbd_smb2_request *req = NULL;
3503
3504         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3505                  (unsigned int)size));
3506
3507         status = smbd_initialize_smb2(xconn, expected_seq_low);
3508         if (!NT_STATUS_IS_OK(status)) {
3509                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3510                 return;
3511         }
3512
3513         status = smbd_smb2_request_create(xconn, inpdu, size, &req);
3514         if (!NT_STATUS_IS_OK(status)) {
3515                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3516                 return;
3517         }
3518
3519         status = smbd_smb2_request_validate(req);
3520         if (!NT_STATUS_IS_OK(status)) {
3521                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3522                 return;
3523         }
3524
3525         status = smbd_smb2_request_setup_out(req);
3526         if (!NT_STATUS_IS_OK(status)) {
3527                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3528                 return;
3529         }
3530
3531 #ifdef WITH_PROFILE
3532         /*
3533          * this was already counted at the SMB1 layer =>
3534          * smbd_smb2_request_dispatch() should not count it twice.
3535          */
3536         if (profile_p->values.request_stats.count > 0) {
3537                 profile_p->values.request_stats.count--;
3538         }
3539 #endif
3540         status = smbd_smb2_request_dispatch(req);
3541         if (!NT_STATUS_IS_OK(status)) {
3542                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3543                 return;
3544         }
3545
3546         status = smbd_smb2_request_next_incoming(xconn);
3547         if (!NT_STATUS_IS_OK(status)) {
3548                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3549                 return;
3550         }
3551
3552         sconn->num_requests++;
3553 }
3554
3555 static int socket_error_from_errno(int ret,
3556                                    int sys_errno,
3557                                    bool *retry)
3558 {
3559         *retry = false;
3560
3561         if (ret >= 0) {
3562                 return 0;
3563         }
3564
3565         if (ret != -1) {
3566                 return EIO;
3567         }
3568
3569         if (sys_errno == 0) {
3570                 return EIO;
3571         }
3572
3573         if (sys_errno == EINTR) {
3574                 *retry = true;
3575                 return sys_errno;
3576         }
3577
3578         if (sys_errno == EINPROGRESS) {
3579                 *retry = true;
3580                 return sys_errno;
3581         }
3582
3583         if (sys_errno == EAGAIN) {
3584                 *retry = true;
3585                 return sys_errno;
3586         }
3587
3588         /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3589         if (sys_errno == ENOMEM) {
3590                 *retry = true;
3591                 return sys_errno;
3592         }
3593
3594 #ifdef EWOULDBLOCK
3595 #if EWOULDBLOCK != EAGAIN
3596         if (sys_errno == EWOULDBLOCK) {
3597                 *retry = true;
3598                 return sys_errno;
3599         }
3600 #endif
3601 #endif
3602
3603         return sys_errno;
3604 }
3605
3606 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
3607 {
3608         int ret;
3609         int err;
3610         bool retry;
3611         NTSTATUS status;
3612
3613         if (xconn->smb2.send_queue == NULL) {
3614                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3615                 return NT_STATUS_OK;
3616         }
3617
3618         while (xconn->smb2.send_queue != NULL) {
3619                 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
3620                 bool ok;
3621
3622                 if (e->sendfile_header != NULL) {
3623                         size_t size = 0;
3624                         size_t i = 0;
3625                         uint8_t *buf;
3626
3627                         status = NT_STATUS_INTERNAL_ERROR;
3628
3629                         for (i=0; i < e->count; i++) {
3630                                 size += e->vector[i].iov_len;
3631                         }
3632
3633                         if (size <= e->sendfile_header->length) {
3634                                 buf = e->sendfile_header->data;
3635                         } else {
3636                                 buf = talloc_array(e->mem_ctx, uint8_t, size);
3637                                 if (buf == NULL) {
3638                                         return NT_STATUS_NO_MEMORY;
3639                                 }
3640                         }
3641
3642                         size = 0;
3643                         for (i=0; i < e->count; i++) {
3644                                 memcpy(buf+size,
3645                                        e->vector[i].iov_base,
3646                                        e->vector[i].iov_len);
3647                                 size += e->vector[i].iov_len;
3648                         }
3649
3650                         e->sendfile_header->data = buf;
3651                         e->sendfile_header->length = size;
3652                         e->sendfile_status = &status;
3653                         e->count = 0;
3654
3655                         xconn->smb2.send_queue_len--;
3656                         DLIST_REMOVE(xconn->smb2.send_queue, e);
3657                         /*
3658                          * This triggers the sendfile path via
3659                          * the destructor.
3660                          */
3661                         talloc_free(e->mem_ctx);
3662
3663                         if (!NT_STATUS_IS_OK(status)) {
3664                                 return status;
3665                         }
3666                         continue;
3667                 }
3668
3669                 ret = writev(xconn->transport.sock, e->vector, e->count);
3670                 if (ret == 0) {
3671                         /* propagate end of file */
3672                         return NT_STATUS_INTERNAL_ERROR;
3673                 }
3674                 err = socket_error_from_errno(ret, errno, &retry);
3675                 if (retry) {
3676                         /* retry later */
3677                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3678                         return NT_STATUS_OK;
3679                 }
3680                 if (err != 0) {
3681                         return map_nt_error_from_unix_common(err);
3682                 }
3683
3684                 ok = iov_advance(&e->vector, &e->count, ret);
3685                 if (!ok) {
3686                         return NT_STATUS_INTERNAL_ERROR;
3687                 }
3688
3689                 if (e->count > 0) {
3690                         /* we have more to write */
3691                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3692                         return NT_STATUS_OK;
3693                 }
3694
3695                 xconn->smb2.send_queue_len--;
3696                 DLIST_REMOVE(xconn->smb2.send_queue, e);
3697                 talloc_free(e->mem_ctx);
3698         }
3699
3700         /*
3701          * Restart reads if we were blocked on
3702          * draining the send queue.
3703          */
3704
3705         status = smbd_smb2_request_next_incoming(xconn);
3706         if (!NT_STATUS_IS_OK(status)) {
3707                 return status;
3708         }
3709
3710         return NT_STATUS_OK;
3711 }
3712
3713 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
3714                                      uint16_t fde_flags)
3715 {
3716         struct smbd_server_connection *sconn = xconn->client->sconn;
3717         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3718         struct smbd_smb2_request *req = NULL;
3719         size_t min_recvfile_size = UINT32_MAX;
3720         int ret;
3721         int err;
3722         bool retry;
3723         NTSTATUS status;
3724         NTTIME now;
3725
3726         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3727                 /*
3728                  * we're not supposed to do any io
3729                  */
3730                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3731                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3732                 return NT_STATUS_OK;
3733         }
3734
3735         if (fde_flags & TEVENT_FD_WRITE) {
3736                 status = smbd_smb2_flush_send_queue(xconn);
3737                 if (!NT_STATUS_IS_OK(status)) {
3738                         return status;
3739                 }
3740         }
3741
3742         if (!(fde_flags & TEVENT_FD_READ)) {
3743                 return NT_STATUS_OK;
3744         }
3745
3746         if (state->req == NULL) {
3747                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3748                 return NT_STATUS_OK;
3749         }
3750
3751 again:
3752         if (!state->hdr.done) {
3753                 state->hdr.done = true;
3754
3755                 state->vector.iov_base = (void *)state->hdr.nbt;
3756                 state->vector.iov_len = NBT_HDR_SIZE;
3757         }
3758
3759         ret = readv(xconn->transport.sock, &state->vector, 1);
3760         if (ret == 0) {
3761                 /* propagate end of file */
3762                 return NT_STATUS_END_OF_FILE;
3763         }
3764         err = socket_error_from_errno(ret, errno, &retry);
3765         if (retry) {
3766                 /* retry later */
3767                 TEVENT_FD_READABLE(xconn->transport.fde);
3768                 return NT_STATUS_OK;
3769         }
3770         if (err != 0) {
3771                 return map_nt_error_from_unix_common(err);
3772         }
3773
3774         if (ret < state->vector.iov_len) {
3775                 uint8_t *base;
3776                 base = (uint8_t *)state->vector.iov_base;
3777                 base += ret;
3778                 state->vector.iov_base = (void *)base;
3779                 state->vector.iov_len -= ret;
3780                 /* we have more to read */
3781                 TEVENT_FD_READABLE(xconn->transport.fde);
3782                 return NT_STATUS_OK;
3783         }
3784
3785         if (state->pktlen > 0) {
3786                 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
3787                         /*
3788                          * Not a possible receivefile write.
3789                          * Read the rest of the data.
3790                          */
3791                         state->doing_receivefile = false;
3792
3793                         state->pktbuf = talloc_realloc(state->req,
3794                                                        state->pktbuf,
3795                                                        uint8_t,
3796                                                        state->pktfull);
3797                         if (state->pktbuf == NULL) {
3798                                 return NT_STATUS_NO_MEMORY;
3799                         }
3800
3801                         state->vector.iov_base = (void *)(state->pktbuf +
3802                                 state->pktlen);
3803                         state->vector.iov_len = (state->pktfull -
3804                                 state->pktlen);
3805
3806                         state->pktlen = state->pktfull;
3807                         goto again;
3808                 }
3809
3810                 /*
3811                  * Either this is a receivefile write so we've
3812                  * done a short read, or if not we have all the data.
3813                  */
3814                 goto got_full;
3815         }
3816
3817         /*
3818          * Now we analyze the NBT header
3819          */
3820         if (state->hdr.nbt[0] != 0x00) {
3821                 state->min_recv_size = 0;
3822         }
3823         state->pktfull = smb2_len(state->hdr.nbt);
3824         if (state->pktfull == 0) {
3825                 goto got_full;
3826         }
3827
3828         if (state->min_recv_size != 0) {
3829                 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3830                 min_recvfile_size += state->min_recv_size;
3831         }
3832
3833         if (state->pktfull > min_recvfile_size) {
3834                 /*
3835                  * Might be a receivefile write. Read the SMB2 HEADER +
3836                  * SMB2_WRITE header first. Set 'doing_receivefile'
3837                  * as we're *attempting* receivefile write. If this
3838                  * turns out not to be a SMB2_WRITE request or otherwise
3839                  * not suitable then we'll just read the rest of the data
3840                  * the next time this function is called.
3841                  */
3842                 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3843                 state->doing_receivefile = true;
3844         } else {
3845                 state->pktlen = state->pktfull;
3846         }
3847
3848         state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
3849         if (state->pktbuf == NULL) {
3850                 return NT_STATUS_NO_MEMORY;
3851         }
3852
3853         state->vector.iov_base = (void *)state->pktbuf;
3854         state->vector.iov_len = state->pktlen;
3855
3856         goto again;
3857
3858 got_full:
3859
3860         if (state->hdr.nbt[0] != 0x00) {
3861                 DEBUG(1,("ignore NBT[0x%02X] msg\n",
3862                          state->hdr.nbt[0]));
3863
3864                 req = state->req;
3865                 ZERO_STRUCTP(state);
3866                 state->req = req;
3867                 state->min_recv_size = lp_min_receive_file_size();
3868                 req = NULL;
3869                 goto again;
3870         }
3871
3872         req = state->req;
3873         state->req = NULL;
3874
3875         req->request_time = timeval_current();
3876         now = timeval_to_nttime(&req->request_time);
3877
3878         status = smbd_smb2_inbuf_parse_compound(xconn,
3879                                                 now,
3880                                                 state->pktbuf,
3881                                                 state->pktlen,
3882                                                 req,
3883                                                 &req->in.vector,
3884                                                 &req->in.vector_count);
3885         if (!NT_STATUS_IS_OK(status)) {
3886                 return status;
3887         }
3888
3889         if (state->doing_receivefile) {
3890                 req->smb1req = talloc_zero(req, struct smb_request);
3891                 if (req->smb1req == NULL) {
3892                         return NT_STATUS_NO_MEMORY;
3893                 }
3894                 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
3895         }
3896
3897         ZERO_STRUCTP(state);
3898
3899         req->current_idx = 1;
3900
3901         DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
3902                  req->current_idx, req->in.vector_count));
3903
3904         status = smbd_smb2_request_validate(req);
3905         if (!NT_STATUS_IS_OK(status)) {
3906                 return status;
3907         }
3908
3909         status = smbd_smb2_request_setup_out(req);
3910         if (!NT_STATUS_IS_OK(status)) {
3911                 return status;
3912         }
3913
3914         status = smbd_smb2_request_dispatch(req);
3915         if (!NT_STATUS_IS_OK(status)) {
3916                 return status;
3917         }
3918
3919         sconn->num_requests++;
3920
3921         /* The timeout_processing function isn't run nearly
3922            often enough to implement 'max log size' without
3923            overrunning the size of the file by many megabytes.
3924            This is especially true if we are running at debug
3925            level 10.  Checking every 50 SMB2s is a nice
3926            tradeoff of performance vs log file size overrun. */
3927
3928         if ((sconn->num_requests % 50) == 0 &&
3929             need_to_check_log_size()) {
3930                 change_to_root_user();
3931                 check_log_size();
3932         }
3933
3934         status = smbd_smb2_request_next_incoming(xconn);
3935         if (!NT_STATUS_IS_OK(status)) {
3936                 return status;
3937         }
3938
3939         return NT_STATUS_OK;
3940 }
3941
3942 static void smbd_smb2_connection_handler(struct tevent_context *ev,
3943                                          struct tevent_fd *fde,
3944                                          uint16_t flags,
3945                                          void *private_data)
3946 {
3947         struct smbXsrv_connection *xconn =
3948                 talloc_get_type_abort(private_data,
3949                 struct smbXsrv_connection);
3950         NTSTATUS status;
3951
3952         status = smbd_smb2_io_handler(xconn, flags);
3953         if (!NT_STATUS_IS_OK(status)) {
3954                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3955                 return;
3956         }
3957 }