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