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