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