s3:smb2_server: add smbd_smb2_send_lease_break() helper function
[samba.git] / source3 / smbd / smb2_server.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30 #include "../librpc/gen_ndr/krb5pac.h"
31 #include "auth.h"
32
33 static void smbd_smb2_connection_handler(struct tevent_context *ev,
34                                          struct tevent_fd *fde,
35                                          uint16_t flags,
36                                          void *private_data);
37 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
38
39 static const struct smbd_smb2_dispatch_table {
40         uint16_t opcode;
41         const char *name;
42         bool need_session;
43         bool need_tcon;
44         bool as_root;
45         uint16_t fileid_ofs;
46         bool allow_invalid_fileid;
47 } smbd_smb2_table[] = {
48 #define _OP(o) .opcode = o, .name = #o
49         {
50                 _OP(SMB2_OP_NEGPROT),
51                 .as_root = true,
52         },{
53                 _OP(SMB2_OP_SESSSETUP),
54                 .as_root = true,
55         },{
56                 _OP(SMB2_OP_LOGOFF),
57                 .need_session = true,
58                 .as_root = true,
59         },{
60                 _OP(SMB2_OP_TCON),
61                 .need_session = true,
62                 /*
63                  * This call needs to be run as root.
64                  *
65                  * smbd_smb2_request_process_tcon()
66                  * calls make_connection_snum(), which will call
67                  * change_to_user(), when needed.
68                  */
69                 .as_root = true,
70         },{
71                 _OP(SMB2_OP_TDIS),
72                 .need_session = true,
73                 .need_tcon = true,
74                 .as_root = true,
75         },{
76                 _OP(SMB2_OP_CREATE),
77                 .need_session = true,
78                 .need_tcon = true,
79         },{
80                 _OP(SMB2_OP_CLOSE),
81                 .need_session = true,
82                 .need_tcon = true,
83                 .fileid_ofs = 0x08,
84         },{
85                 _OP(SMB2_OP_FLUSH),
86                 .need_session = true,
87                 .need_tcon = true,
88                 .fileid_ofs = 0x08,
89         },{
90                 _OP(SMB2_OP_READ),
91                 .need_session = true,
92                 .need_tcon = true,
93                 .fileid_ofs = 0x10,
94         },{
95                 _OP(SMB2_OP_WRITE),
96                 .need_session = true,
97                 .need_tcon = true,
98                 .fileid_ofs = 0x10,
99         },{
100                 _OP(SMB2_OP_LOCK),
101                 .need_session = true,
102                 .need_tcon = true,
103                 .fileid_ofs = 0x08,
104         },{
105                 _OP(SMB2_OP_IOCTL),
106                 .need_session = true,
107                 .need_tcon = true,
108                 .fileid_ofs = 0x08,
109                 .allow_invalid_fileid = true,
110         },{
111                 _OP(SMB2_OP_CANCEL),
112                 .as_root = true,
113         },{
114                 _OP(SMB2_OP_KEEPALIVE),
115                 .as_root = true,
116         },{
117                 _OP(SMB2_OP_FIND),
118                 .need_session = true,
119                 .need_tcon = true,
120                 .fileid_ofs = 0x08,
121         },{
122                 _OP(SMB2_OP_NOTIFY),
123                 .need_session = true,
124                 .need_tcon = true,
125                 .fileid_ofs = 0x08,
126         },{
127                 _OP(SMB2_OP_GETINFO),
128                 .need_session = true,
129                 .need_tcon = true,
130                 .fileid_ofs = 0x18,
131         },{
132                 _OP(SMB2_OP_SETINFO),
133                 .need_session = true,
134                 .need_tcon = true,
135                 .fileid_ofs = 0x10,
136         },{
137                 _OP(SMB2_OP_BREAK),
138                 .need_session = true,
139                 .need_tcon = true,
140                 /*
141                  * we do not set
142                  * .fileid_ofs here
143                  * as LEASE breaks does not
144                  * have a file id
145                  */
146         }
147 };
148
149 const char *smb2_opcode_name(uint16_t opcode)
150 {
151         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
152                 return "Bad SMB2 opcode";
153         }
154         return smbd_smb2_table[opcode].name;
155 }
156
157 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
158 {
159         const struct smbd_smb2_dispatch_table *ret = NULL;
160
161         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
162                 return NULL;
163         }
164
165         ret = &smbd_smb2_table[opcode];
166
167         SMB_ASSERT(ret->opcode == opcode);
168
169         return ret;
170 }
171
172 static void print_req_vectors(const struct smbd_smb2_request *req)
173 {
174         int i;
175
176         for (i = 0; i < req->in.vector_count; i++) {
177                 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
178                         (unsigned int)i,
179                         (unsigned int)req->in.vector[i].iov_len);
180         }
181         for (i = 0; i < req->out.vector_count; i++) {
182                 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
183                         (unsigned int)i,
184                         (unsigned int)req->out.vector[i].iov_len);
185         }
186 }
187
188 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
189 {
190         if (size < (4 + SMB2_HDR_BODY)) {
191                 return false;
192         }
193
194         if (IVAL(inbuf, 4) != SMB2_MAGIC) {
195                 return false;
196         }
197
198         return true;
199 }
200
201 static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn)
202 {
203         TALLOC_FREE(xconn->transport.fde);
204
205         xconn->smb2.credits.seq_low = 0;
206         xconn->smb2.credits.seq_range = 1;
207         xconn->smb2.credits.granted = 1;
208         xconn->smb2.credits.max = lp_smb2_max_credits();
209         xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
210                                                    xconn->smb2.credits.max);
211         if (xconn->smb2.credits.bitmap == NULL) {
212                 return NT_STATUS_NO_MEMORY;
213         }
214
215         xconn->transport.fde = tevent_add_fd(xconn->ev_ctx,
216                                         xconn,
217                                         xconn->transport.sock,
218                                         TEVENT_FD_READ,
219                                         smbd_smb2_connection_handler,
220                                         xconn);
221         if (xconn->transport.fde == NULL) {
222                 return NT_STATUS_NO_MEMORY;
223         }
224
225         /* Ensure child is set to non-blocking mode */
226         set_blocking(xconn->transport.sock, false);
227         return NT_STATUS_OK;
228 }
229
230 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
231 #define _smb2_setlen(_buf,len) do { \
232         uint8_t *buf = (uint8_t *)_buf; \
233         buf[0] = 0; \
234         buf[1] = ((len)&0xFF0000)>>16; \
235         buf[2] = ((len)&0xFF00)>>8; \
236         buf[3] = (len)&0xFF; \
237 } while (0)
238
239 static void smb2_setup_nbt_length(struct iovec *vector, int count)
240 {
241         size_t len = 0;
242         int i;
243
244         for (i=1; i < count; i++) {
245                 len += vector[i].iov_len;
246         }
247
248         _smb2_setlen(vector[0].iov_base, len);
249 }
250
251 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
252 {
253         if (req->first_key.length > 0) {
254                 data_blob_clear_free(&req->first_key);
255         }
256         if (req->last_key.length > 0) {
257                 data_blob_clear_free(&req->last_key);
258         }
259         return 0;
260 }
261
262 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
263 {
264         TALLOC_CTX *mem_pool;
265         struct smbd_smb2_request *req;
266
267 #if 0
268         /* Enable this to find subtle valgrind errors. */
269         mem_pool = talloc_init("smbd_smb2_request_allocate");
270 #else
271         mem_pool = talloc_tos();
272 #endif
273         if (mem_pool == NULL) {
274                 return NULL;
275         }
276
277         req = talloc_zero(mem_pool, struct smbd_smb2_request);
278         if (req == NULL) {
279                 talloc_free(mem_pool);
280                 return NULL;
281         }
282         talloc_reparent(mem_pool, mem_ctx, req);
283 #if 0
284         TALLOC_FREE(mem_pool);
285 #endif
286
287         req->last_session_id = UINT64_MAX;
288         req->last_tid = UINT32_MAX;
289
290         talloc_set_destructor(req, smbd_smb2_request_destructor);
291
292         return req;
293 }
294
295 static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
296                                                NTTIME now,
297                                                uint8_t *buf,
298                                                size_t buflen,
299                                                struct smbd_smb2_request *req,
300                                                struct iovec **piov,
301                                                int *pnum_iov)
302 {
303         TALLOC_CTX *mem_ctx = req;
304         struct iovec *iov;
305         int num_iov = 1;
306         size_t taken = 0;
307         uint8_t *first_hdr = buf;
308         size_t verified_buflen = 0;
309         uint8_t *tf = NULL;
310         size_t tf_len = 0;
311
312         /*
313          * Note: index '0' is reserved for the transport protocol
314          */
315         iov = req->in._vector;
316
317         while (taken < buflen) {
318                 size_t len = buflen - taken;
319                 uint8_t *hdr = first_hdr + taken;
320                 struct iovec *cur;
321                 size_t full_size;
322                 size_t next_command_ofs;
323                 uint16_t body_size;
324                 uint8_t *body = NULL;
325                 uint32_t dyn_size;
326                 uint8_t *dyn = NULL;
327                 struct iovec *iov_alloc = NULL;
328
329                 if (iov != req->in._vector) {
330                         iov_alloc = iov;
331                 }
332
333                 if (verified_buflen > taken) {
334                         len = verified_buflen - taken;
335                 } else {
336                         tf = NULL;
337                         tf_len = 0;
338                 }
339
340                 if (len < 4) {
341                         DEBUG(10, ("%d bytes left, expected at least %d\n",
342                                    (int)len, 4));
343                         goto inval;
344                 }
345                 if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
346                         struct smbXsrv_session *s = NULL;
347                         uint64_t uid;
348                         struct iovec tf_iov[2];
349                         NTSTATUS status;
350                         size_t enc_len;
351
352                         if (xconn->protocol < PROTOCOL_SMB2_24) {
353                                 DEBUG(10, ("Got SMB2_TRANSFORM header, "
354                                            "but dialect[0x%04X] is used\n",
355                                            xconn->smb2.server.dialect));
356                                 goto inval;
357                         }
358
359                         if (xconn->smb2.server.cipher == 0) {
360                                 DEBUG(10, ("Got SMB2_TRANSFORM header, "
361                                            "but not negotiated "
362                                            "client[0x%08X] server[0x%08X]\n",
363                                            xconn->smb2.client.capabilities,
364                                            xconn->smb2.server.capabilities));
365                                 goto inval;
366                         }
367
368                         if (len < SMB2_TF_HDR_SIZE) {
369                                 DEBUG(1, ("%d bytes left, expected at least %d\n",
370                                            (int)len, SMB2_TF_HDR_SIZE));
371                                 goto inval;
372                         }
373                         tf = hdr;
374                         tf_len = SMB2_TF_HDR_SIZE;
375                         taken += tf_len;
376
377                         hdr = first_hdr + taken;
378                         enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
379                         uid = BVAL(tf, SMB2_TF_SESSION_ID);
380
381                         if (len < SMB2_TF_HDR_SIZE + enc_len) {
382                                 DEBUG(1, ("%d bytes left, expected at least %d\n",
383                                            (int)len,
384                                            (int)(SMB2_TF_HDR_SIZE + enc_len)));
385                                 goto inval;
386                         }
387
388                         status = smb2srv_session_lookup(xconn, uid, now, &s);
389                         if (s == NULL) {
390                                 DEBUG(1, ("invalid session[%llu] in "
391                                           "SMB2_TRANSFORM header\n",
392                                            (unsigned long long)uid));
393                                 TALLOC_FREE(iov_alloc);
394                                 return NT_STATUS_USER_SESSION_DELETED;
395                         }
396
397                         tf_iov[0].iov_base = (void *)tf;
398                         tf_iov[0].iov_len = tf_len;
399                         tf_iov[1].iov_base = (void *)hdr;
400                         tf_iov[1].iov_len = enc_len;
401
402                         status = smb2_signing_decrypt_pdu(s->global->decryption_key,
403                                                           xconn->smb2.server.cipher,
404                                                           tf_iov, 2);
405                         if (!NT_STATUS_IS_OK(status)) {
406                                 TALLOC_FREE(iov_alloc);
407                                 return status;
408                         }
409
410                         verified_buflen = taken + enc_len;
411                         len = enc_len;
412                 }
413
414                 /*
415                  * We need the header plus the body length field
416                  */
417
418                 if (len < SMB2_HDR_BODY + 2) {
419                         DEBUG(10, ("%d bytes left, expected at least %d\n",
420                                    (int)len, SMB2_HDR_BODY));
421                         goto inval;
422                 }
423                 if (IVAL(hdr, 0) != SMB2_MAGIC) {
424                         DEBUG(10, ("Got non-SMB2 PDU: %x\n",
425                                    IVAL(hdr, 0)));
426                         goto inval;
427                 }
428                 if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
429                         DEBUG(10, ("Got HDR len %d, expected %d\n",
430                                    SVAL(hdr, 4), SMB2_HDR_BODY));
431                         goto inval;
432                 }
433
434                 full_size = len;
435                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
436                 body_size = SVAL(hdr, SMB2_HDR_BODY);
437
438                 if (next_command_ofs != 0) {
439                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
440                                 goto inval;
441                         }
442                         if (next_command_ofs > full_size) {
443                                 goto inval;
444                         }
445                         full_size = next_command_ofs;
446                 }
447                 if (body_size < 2) {
448                         goto inval;
449                 }
450                 body_size &= 0xfffe;
451
452                 if (body_size > (full_size - SMB2_HDR_BODY)) {
453                         /*
454                          * let the caller handle the error
455                          */
456                         body_size = full_size - SMB2_HDR_BODY;
457                 }
458                 body = hdr + SMB2_HDR_BODY;
459                 dyn = body + body_size;
460                 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
461
462                 if (num_iov >= ARRAY_SIZE(req->in._vector)) {
463                         struct iovec *iov_tmp = NULL;
464
465                         iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
466                                                  struct iovec,
467                                                  num_iov +
468                                                  SMBD_SMB2_NUM_IOV_PER_REQ);
469                         if (iov_tmp == NULL) {
470                                 TALLOC_FREE(iov_alloc);
471                                 return NT_STATUS_NO_MEMORY;
472                         }
473
474                         if (iov_alloc == NULL) {
475                                 memcpy(iov_tmp,
476                                        req->in._vector,
477                                        sizeof(req->in._vector));
478                         }
479
480                         iov = iov_tmp;
481                 }
482                 cur = &iov[num_iov];
483                 num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
484
485                 cur[SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
486                 cur[SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
487                 cur[SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
488                 cur[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
489                 cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
490                 cur[SMBD_SMB2_BODY_IOV_OFS].iov_len  = body_size;
491                 cur[SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
492                 cur[SMBD_SMB2_DYN_IOV_OFS].iov_len   = dyn_size;
493
494                 taken += full_size;
495         }
496
497         *piov = iov;
498         *pnum_iov = num_iov;
499         return NT_STATUS_OK;
500
501 inval:
502         if (iov != req->in._vector) {
503                 TALLOC_FREE(iov);
504         }
505         return NT_STATUS_INVALID_PARAMETER;
506 }
507
508 static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
509                                          const uint8_t *_inpdu, size_t size,
510                                          struct smbd_smb2_request **_req)
511 {
512         struct smbd_server_connection *sconn = xconn->client->sconn;
513         struct smbd_smb2_request *req;
514         uint32_t protocol_version;
515         uint8_t *inpdu = NULL;
516         const uint8_t *inhdr = NULL;
517         uint16_t cmd;
518         uint32_t next_command_ofs;
519         NTSTATUS status;
520         NTTIME now;
521
522         if (size < (SMB2_HDR_BODY + 2)) {
523                 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
524                 return NT_STATUS_INVALID_PARAMETER;
525         }
526
527         inhdr = _inpdu;
528
529         protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
530         if (protocol_version != SMB2_MAGIC) {
531                 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
532                          protocol_version));
533                 return NT_STATUS_INVALID_PARAMETER;
534         }
535
536         cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
537         if (cmd != SMB2_OP_NEGPROT) {
538                 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
539                          cmd));
540                 return NT_STATUS_INVALID_PARAMETER;
541         }
542
543         next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
544         if (next_command_ofs != 0) {
545                 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
546                          next_command_ofs));
547                 return NT_STATUS_INVALID_PARAMETER;
548         }
549
550         req = smbd_smb2_request_allocate(xconn);
551         if (req == NULL) {
552                 return NT_STATUS_NO_MEMORY;
553         }
554         req->sconn = sconn;
555         req->xconn = xconn;
556
557         inpdu = talloc_memdup(req, _inpdu, size);
558         if (inpdu == NULL) {
559                 return NT_STATUS_NO_MEMORY;
560         }
561
562         req->request_time = timeval_current();
563         now = timeval_to_nttime(&req->request_time);
564
565         status = smbd_smb2_inbuf_parse_compound(xconn,
566                                                 now,
567                                                 inpdu,
568                                                 size,
569                                                 req, &req->in.vector,
570                                                 &req->in.vector_count);
571         if (!NT_STATUS_IS_OK(status)) {
572                 TALLOC_FREE(req);
573                 return status;
574         }
575
576         req->current_idx = 1;
577
578         *_req = req;
579         return NT_STATUS_OK;
580 }
581
582 static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
583                                           uint64_t message_id, uint64_t seq_id)
584 {
585         struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
586         unsigned int offset;
587         uint64_t seq_tmp;
588
589         seq_tmp = xconn->smb2.credits.seq_low;
590         if (seq_id < seq_tmp) {
591                 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
592                         "%llu (sequence id %llu) "
593                         "(granted = %u, low = %llu, range = %u)\n",
594                         (unsigned long long)message_id,
595                         (unsigned long long)seq_id,
596                         (unsigned int)xconn->smb2.credits.granted,
597                         (unsigned long long)xconn->smb2.credits.seq_low,
598                         (unsigned int)xconn->smb2.credits.seq_range));
599                 return false;
600         }
601
602         seq_tmp += xconn->smb2.credits.seq_range;
603         if (seq_id >= seq_tmp) {
604                 DEBUG(0,("smb2_validate_sequence_number: bad message_id "
605                         "%llu (sequence id %llu) "
606                         "(granted = %u, low = %llu, range = %u)\n",
607                         (unsigned long long)message_id,
608                         (unsigned long long)seq_id,
609                         (unsigned int)xconn->smb2.credits.granted,
610                         (unsigned long long)xconn->smb2.credits.seq_low,
611                         (unsigned int)xconn->smb2.credits.seq_range));
612                 return false;
613         }
614
615         offset = seq_id % xconn->smb2.credits.max;
616
617         if (bitmap_query(credits_bm, offset)) {
618                 DEBUG(0,("smb2_validate_sequence_number: duplicate message_id "
619                         "%llu (sequence id %llu) "
620                         "(granted = %u, low = %llu, range = %u) "
621                         "(bm offset %u)\n",
622                         (unsigned long long)message_id,
623                         (unsigned long long)seq_id,
624                         (unsigned int)xconn->smb2.credits.granted,
625                         (unsigned long long)xconn->smb2.credits.seq_low,
626                         (unsigned int)xconn->smb2.credits.seq_range,
627                         offset));
628                 return false;
629         }
630
631         /* Mark the message_ids as seen in the bitmap. */
632         bitmap_set(credits_bm, offset);
633
634         if (seq_id != xconn->smb2.credits.seq_low) {
635                 return true;
636         }
637
638         /*
639          * Move the window forward by all the message_id's
640          * already seen.
641          */
642         while (bitmap_query(credits_bm, offset)) {
643                 DEBUG(10,("smb2_validate_sequence_number: clearing "
644                           "id %llu (position %u) from bitmap\n",
645                           (unsigned long long)(xconn->smb2.credits.seq_low),
646                           offset));
647                 bitmap_clear(credits_bm, offset);
648
649                 xconn->smb2.credits.seq_low += 1;
650                 xconn->smb2.credits.seq_range -= 1;
651                 offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
652         }
653
654         return true;
655 }
656
657 static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
658                                      const uint8_t *inhdr)
659 {
660         uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
661         uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
662         uint16_t credit_charge = 1;
663         uint64_t i;
664
665         if (opcode == SMB2_OP_CANCEL) {
666                 /* SMB2_CANCEL requests by definition resend messageids. */
667                 return true;
668         }
669
670         if (xconn->smb2.credits.multicredit) {
671                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
672                 credit_charge = MAX(credit_charge, 1);
673         }
674
675         DEBUG(11, ("smb2_validate_message_id: mid %llu (charge %llu), "
676                    "credits_granted %llu, "
677                    "seqnum low/range: %llu/%llu\n",
678                    (unsigned long long) message_id,
679                    (unsigned long long) credit_charge,
680                    (unsigned long long) xconn->smb2.credits.granted,
681                    (unsigned long long) xconn->smb2.credits.seq_low,
682                    (unsigned long long) xconn->smb2.credits.seq_range));
683
684         if (xconn->smb2.credits.granted < credit_charge) {
685                 DEBUG(0, ("smb2_validate_message_id: client used more "
686                           "credits than granted, mid %llu, charge %llu, "
687                           "credits_granted %llu, "
688                           "seqnum low/range: %llu/%llu\n",
689                           (unsigned long long) message_id,
690                           (unsigned long long) credit_charge,
691                           (unsigned long long) xconn->smb2.credits.granted,
692                           (unsigned long long) xconn->smb2.credits.seq_low,
693                           (unsigned long long) xconn->smb2.credits.seq_range));
694                 return false;
695         }
696
697         /*
698          * now check the message ids
699          *
700          * for multi-credit requests we need to check all current mid plus
701          * the implicit mids caused by the credit charge
702          * e.g. current mid = 15, charge 5 => mark 15-19 as used
703          */
704
705         for (i = 0; i <= (credit_charge-1); i++) {
706                 uint64_t id = message_id + i;
707                 bool ok;
708
709                 DEBUG(11, ("Iterating mid %llu charge %u (sequence %llu)\n",
710                            (unsigned long long)message_id,
711                            credit_charge,
712                            (unsigned long long)id));
713
714                 ok = smb2_validate_sequence_number(xconn, message_id, id);
715                 if (!ok) {
716                         return false;
717                 }
718         }
719
720         /* substract used credits */
721         xconn->smb2.credits.granted -= credit_charge;
722
723         return true;
724 }
725
726 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
727 {
728         int count;
729         int idx;
730
731         count = req->in.vector_count;
732
733         if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
734                 /* It's not a SMB2 request */
735                 return NT_STATUS_INVALID_PARAMETER;
736         }
737
738         for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
739                 struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
740                 struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
741                 const uint8_t *inhdr = NULL;
742
743                 if (hdr->iov_len != SMB2_HDR_BODY) {
744                         return NT_STATUS_INVALID_PARAMETER;
745                 }
746
747                 if (body->iov_len < 2) {
748                         return NT_STATUS_INVALID_PARAMETER;
749                 }
750
751                 inhdr = (const uint8_t *)hdr->iov_base;
752
753                 /* Check the SMB2 header */
754                 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
755                         return NT_STATUS_INVALID_PARAMETER;
756                 }
757
758                 if (!smb2_validate_message_id(req->xconn, inhdr)) {
759                         return NT_STATUS_INVALID_PARAMETER;
760                 }
761         }
762
763         return NT_STATUS_OK;
764 }
765
766 static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
767                                       const struct iovec *in_vector,
768                                       struct iovec *out_vector)
769 {
770         const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
771         uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
772         uint16_t credit_charge = 1;
773         uint16_t credits_requested;
774         uint32_t out_flags;
775         uint16_t cmd;
776         NTSTATUS out_status;
777         uint16_t credits_granted = 0;
778         uint64_t credits_possible;
779         uint16_t current_max_credits;
780
781         /*
782          * first we grant only 1/16th of the max range.
783          *
784          * Windows also starts with the 1/16th and then grants
785          * more later. I was only able to trigger higher
786          * values, when using a very high credit charge.
787          *
788          * TODO: scale up depending on load, free memory
789          *       or other stuff.
790          *       Maybe also on the relationship between number
791          *       of requests and the used sequence number.
792          *       Which means we would grant more credits
793          *       for client which use multi credit requests.
794          */
795         current_max_credits = xconn->smb2.credits.max / 16;
796         current_max_credits = MAX(current_max_credits, 1);
797
798         if (xconn->smb2.credits.multicredit) {
799                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
800                 credit_charge = MAX(credit_charge, 1);
801         }
802
803         cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
804         credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
805         out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
806         out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
807
808         SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
809
810         if (xconn->smb2.credits.max < credit_charge) {
811                 smbd_server_connection_terminate(xconn,
812                         "client error: credit charge > max credits\n");
813                 return;
814         }
815
816         if (out_flags & SMB2_HDR_FLAG_ASYNC) {
817                 /*
818                  * In case we already send an async interim
819                  * response, we should not grant
820                  * credits on the final response.
821                  */
822                 credits_granted = 0;
823         } else if (credits_requested > 0) {
824                 uint16_t additional_max = 0;
825                 uint16_t additional_credits = credits_requested - 1;
826
827                 switch (cmd) {
828                 case SMB2_OP_NEGPROT:
829                         break;
830                 case SMB2_OP_SESSSETUP:
831                         /*
832                          * Windows 2012 RC1 starts to grant
833                          * additional credits
834                          * with a successful session setup
835                          */
836                         if (NT_STATUS_IS_OK(out_status)) {
837                                 additional_max = 32;
838                         }
839                         break;
840                 default:
841                         /*
842                          * We match windows and only grant additional credits
843                          * in chunks of 32.
844                          */
845                         additional_max = 32;
846                         break;
847                 }
848
849                 additional_credits = MIN(additional_credits, additional_max);
850
851                 credits_granted = credit_charge + additional_credits;
852         } else if (xconn->smb2.credits.granted == 0) {
853                 /*
854                  * Make sure the client has always at least one credit
855                  */
856                 credits_granted = 1;
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                 if (opcode == SMB2_OP_SESSSETUP &&
1994                     x->global->signing_key.length > 0) {
1995                         signing_required = true;
1996                 }
1997         }
1998
1999         req->do_signing = false;
2000         req->do_encryption = false;
2001         if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
2002                 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
2003                 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
2004
2005                 if (x != NULL && x->global->session_wire_id != tf_session_id) {
2006                         DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2007                                  "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2008                                  (unsigned long long)x->global->session_wire_id,
2009                                  (unsigned long long)tf_session_id));
2010                         /*
2011                          * TODO: windows allows this...
2012                          * should we drop the connection?
2013                          *
2014                          * For now we just return ACCESS_DENIED
2015                          * (Windows clients never trigger this)
2016                          * and wait for an update of [MS-SMB2].
2017                          */
2018                         return smbd_smb2_request_error(req,
2019                                         NT_STATUS_ACCESS_DENIED);
2020                 }
2021
2022                 req->do_encryption = true;
2023         }
2024
2025         if (encryption_required && !req->do_encryption) {
2026                 return smbd_smb2_request_error(req,
2027                                 NT_STATUS_ACCESS_DENIED);
2028         }
2029
2030         call = smbd_smb2_call(opcode);
2031         if (call == NULL) {
2032                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2033         }
2034
2035         allowed_flags = SMB2_HDR_FLAG_CHAINED |
2036                         SMB2_HDR_FLAG_SIGNED |
2037                         SMB2_HDR_FLAG_DFS;
2038         if (opcode == SMB2_OP_CANCEL) {
2039                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
2040         }
2041         if ((flags & ~allowed_flags) != 0) {
2042                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2043         }
2044
2045         if (flags & SMB2_HDR_FLAG_CHAINED) {
2046                 /*
2047                  * This check is mostly for giving the correct error code
2048                  * for compounded requests.
2049                  */
2050                 if (!NT_STATUS_IS_OK(session_status)) {
2051                         return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2052                 }
2053         } else {
2054                 req->compat_chain_fsp = NULL;
2055         }
2056
2057         if (req->do_encryption) {
2058                 signing_required = false;
2059         } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
2060                 DATA_BLOB signing_key = data_blob_null;
2061
2062                 if (x == NULL) {
2063                         /*
2064                          * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2065                          * If the SMB2 header of the SMB2 NEGOTIATE
2066                          * request has the SMB2_FLAGS_SIGNED bit set in the
2067                          * Flags field, the server MUST fail the request
2068                          * with STATUS_INVALID_PARAMETER.
2069                          *
2070                          * Microsoft test tool checks this.
2071                          */
2072
2073                         if ((opcode == SMB2_OP_NEGPROT) &&
2074                                         (flags & SMB2_HDR_FLAG_SIGNED)) {
2075                                 status = NT_STATUS_INVALID_PARAMETER;
2076                         } else {
2077                                 status = NT_STATUS_USER_SESSION_DELETED;
2078                         }
2079                         return smbd_smb2_request_error(req, status);
2080                 }
2081
2082                 signing_key = smbd_smb2_signing_key(x, xconn);
2083
2084                 /*
2085                  * If we have a signing key, we should
2086                  * sign the response
2087                  */
2088                 if (signing_key.length > 0) {
2089                         req->do_signing = true;
2090                 }
2091
2092                 status = smb2_signing_check_pdu(signing_key,
2093                                                 xconn->protocol,
2094                                                 SMBD_SMB2_IN_HDR_IOV(req),
2095                                                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2096                 if (!NT_STATUS_IS_OK(status)) {
2097                         return smbd_smb2_request_error(req, status);
2098                 }
2099
2100                 /*
2101                  * Now that we know the request was correctly signed
2102                  * we have to sign the response too.
2103                  */
2104                 req->do_signing = true;
2105
2106                 if (!NT_STATUS_IS_OK(session_status)) {
2107                         return smbd_smb2_request_error(req, session_status);
2108                 }
2109         } else if (opcode == SMB2_OP_CANCEL) {
2110                 /* Cancel requests are allowed to skip the signing */
2111         } else if (signing_required) {
2112                 /*
2113                  * If signing is required we try to sign
2114                  * a possible error response
2115                  */
2116                 req->do_signing = true;
2117                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
2118         }
2119
2120         if (flags & SMB2_HDR_FLAG_CHAINED) {
2121                 req->compound_related = true;
2122         }
2123
2124         if (call->need_session) {
2125                 if (!NT_STATUS_IS_OK(session_status)) {
2126                         return smbd_smb2_request_error(req, session_status);
2127                 }
2128         }
2129
2130         if (call->need_tcon) {
2131                 SMB_ASSERT(call->need_session);
2132
2133                 /*
2134                  * This call needs to be run as user.
2135                  *
2136                  * smbd_smb2_request_check_tcon()
2137                  * calls change_to_user() on success.
2138                  */
2139                 status = smbd_smb2_request_check_tcon(req);
2140                 if (!NT_STATUS_IS_OK(status)) {
2141                         return smbd_smb2_request_error(req, status);
2142                 }
2143                 if (req->tcon->global->encryption_required) {
2144                         encryption_required = true;
2145                 }
2146                 if (encryption_required && !req->do_encryption) {
2147                         return smbd_smb2_request_error(req,
2148                                 NT_STATUS_ACCESS_DENIED);
2149                 }
2150         }
2151
2152         if (call->fileid_ofs != 0) {
2153                 size_t needed = call->fileid_ofs + 16;
2154                 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2155                 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2156                 uint64_t file_id_persistent;
2157                 uint64_t file_id_volatile;
2158                 struct files_struct *fsp;
2159
2160                 SMB_ASSERT(call->need_tcon);
2161
2162                 if (needed > body_size) {
2163                         return smbd_smb2_request_error(req,
2164                                         NT_STATUS_INVALID_PARAMETER);
2165                 }
2166
2167                 file_id_persistent      = BVAL(body, call->fileid_ofs + 0);
2168                 file_id_volatile        = BVAL(body, call->fileid_ofs + 8);
2169
2170                 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2171                 if (fsp == NULL) {
2172                         if (!call->allow_invalid_fileid) {
2173                                 return smbd_smb2_request_error(req,
2174                                                 NT_STATUS_FILE_CLOSED);
2175                         }
2176
2177                         if (file_id_persistent != UINT64_MAX) {
2178                                 return smbd_smb2_request_error(req,
2179                                                 NT_STATUS_FILE_CLOSED);
2180                         }
2181                         if (file_id_volatile != UINT64_MAX) {
2182                                 return smbd_smb2_request_error(req,
2183                                                 NT_STATUS_FILE_CLOSED);
2184                         }
2185                 }
2186         }
2187
2188         if (call->as_root) {
2189                 SMB_ASSERT(call->fileid_ofs == 0);
2190                 /* This call needs to be run as root */
2191                 change_to_root_user();
2192         } else {
2193                 SMB_ASSERT(call->need_tcon);
2194         }
2195
2196 #define _INBYTES(_r) \
2197         iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
2198
2199         switch (opcode) {
2200         case SMB2_OP_NEGPROT:
2201                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
2202                                                req->profile, _INBYTES(req));
2203                 return_value = smbd_smb2_request_process_negprot(req);
2204                 break;
2205
2206         case SMB2_OP_SESSSETUP:
2207                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
2208                                                req->profile, _INBYTES(req));
2209                 return_value = smbd_smb2_request_process_sesssetup(req);
2210                 break;
2211
2212         case SMB2_OP_LOGOFF:
2213                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
2214                                                req->profile, _INBYTES(req));
2215                 return_value = smbd_smb2_request_process_logoff(req);
2216                 break;
2217
2218         case SMB2_OP_TCON:
2219                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
2220                                                req->profile, _INBYTES(req));
2221                 return_value = smbd_smb2_request_process_tcon(req);
2222                 break;
2223
2224         case SMB2_OP_TDIS:
2225                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
2226                                                req->profile, _INBYTES(req));
2227                 return_value = smbd_smb2_request_process_tdis(req);
2228                 break;
2229
2230         case SMB2_OP_CREATE:
2231                 if (req->subreq == NULL) {
2232                         SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
2233                                                        req->profile, _INBYTES(req));
2234                 } else {
2235                         SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
2236                 }
2237                 return_value = smbd_smb2_request_process_create(req);
2238                 break;
2239
2240         case SMB2_OP_CLOSE:
2241                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
2242                                                req->profile, _INBYTES(req));
2243                 return_value = smbd_smb2_request_process_close(req);
2244                 break;
2245
2246         case SMB2_OP_FLUSH:
2247                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
2248                                                req->profile, _INBYTES(req));
2249                 return_value = smbd_smb2_request_process_flush(req);
2250                 break;
2251
2252         case SMB2_OP_READ:
2253                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
2254                                                req->profile, _INBYTES(req));
2255                 return_value = smbd_smb2_request_process_read(req);
2256                 break;
2257
2258         case SMB2_OP_WRITE:
2259                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
2260                                                req->profile, _INBYTES(req));
2261                 return_value = smbd_smb2_request_process_write(req);
2262                 break;
2263
2264         case SMB2_OP_LOCK:
2265                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
2266                                                req->profile, _INBYTES(req));
2267                 return_value = smbd_smb2_request_process_lock(req);
2268                 break;
2269
2270         case SMB2_OP_IOCTL:
2271                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
2272                                                req->profile, _INBYTES(req));
2273                 return_value = smbd_smb2_request_process_ioctl(req);
2274                 break;
2275
2276         case SMB2_OP_CANCEL:
2277                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
2278                                                req->profile, _INBYTES(req));
2279                 return_value = smbd_smb2_request_process_cancel(req);
2280                 SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
2281                 break;
2282
2283         case SMB2_OP_KEEPALIVE:
2284                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
2285                                                req->profile, _INBYTES(req));
2286                 return_value = smbd_smb2_request_process_keepalive(req);
2287                 break;
2288
2289         case SMB2_OP_FIND:
2290                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
2291                                                req->profile, _INBYTES(req));
2292                 return_value = smbd_smb2_request_process_find(req);
2293                 break;
2294
2295         case SMB2_OP_NOTIFY:
2296                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
2297                                                req->profile, _INBYTES(req));
2298                 return_value = smbd_smb2_request_process_notify(req);
2299                 break;
2300
2301         case SMB2_OP_GETINFO:
2302                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
2303                                                req->profile, _INBYTES(req));
2304                 return_value = smbd_smb2_request_process_getinfo(req);
2305                 break;
2306
2307         case SMB2_OP_SETINFO:
2308                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
2309                                                req->profile, _INBYTES(req));
2310                 return_value = smbd_smb2_request_process_setinfo(req);
2311                 break;
2312
2313         case SMB2_OP_BREAK:
2314                 SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
2315                                                req->profile, _INBYTES(req));
2316                 return_value = smbd_smb2_request_process_break(req);
2317                 break;
2318
2319         default:
2320                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2321                 break;
2322         }
2323         return return_value;
2324 }
2325
2326 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
2327 {
2328         struct smbXsrv_connection *xconn = req->xconn;
2329         int first_idx = 1;
2330         struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
2331         struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
2332         struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
2333         NTSTATUS status;
2334
2335         req->subreq = NULL;
2336         TALLOC_FREE(req->async_te);
2337
2338         if (req->do_encryption &&
2339             (firsttf->iov_len == 0) &&
2340             (req->first_key.length == 0) &&
2341             (req->session != NULL) &&
2342             (req->session->global->encryption_key.length != 0))
2343         {
2344                 DATA_BLOB encryption_key = req->session->global->encryption_key;
2345                 uint8_t *tf;
2346                 uint64_t session_id = req->session->global->session_wire_id;
2347                 struct smbXsrv_session *x = req->session;
2348                 uint64_t nonce_high;
2349                 uint64_t nonce_low;
2350
2351                 nonce_high = x->nonce_high;
2352                 nonce_low = x->nonce_low;
2353
2354                 x->nonce_low += 1;
2355                 if (x->nonce_low == 0) {
2356                         x->nonce_low += 1;
2357                         x->nonce_high += 1;
2358                 }
2359
2360                 /*
2361                  * We need to place the SMB2_TRANSFORM header before the
2362                  * first SMB2 header
2363                  */
2364
2365                 /*
2366                  * we need to remember the encryption key
2367                  * and defer the signing/encryption until
2368                  * we are sure that we do not change
2369                  * the header again.
2370                  */
2371                 req->first_key = data_blob_dup_talloc(req, encryption_key);
2372                 if (req->first_key.data == NULL) {
2373                         return NT_STATUS_NO_MEMORY;
2374                 }
2375
2376                 tf = talloc_zero_array(req, uint8_t,
2377                                        SMB2_TF_HDR_SIZE);
2378                 if (tf == NULL) {
2379                         return NT_STATUS_NO_MEMORY;
2380                 }
2381
2382                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2383                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2384                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2385                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2386
2387                 firsttf->iov_base = (void *)tf;
2388                 firsttf->iov_len = SMB2_TF_HDR_SIZE;
2389         }
2390
2391         if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
2392             (req->last_key.length > 0) &&
2393             (firsttf->iov_len == 0))
2394         {
2395                 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
2396                 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
2397
2398                 /*
2399                  * As we are sure the header of the last request in the
2400                  * compound chain will not change, we can to sign here
2401                  * with the last signing key we remembered.
2402                  */
2403                 status = smb2_signing_sign_pdu(req->last_key,
2404                                                xconn->protocol,
2405                                                lasthdr,
2406                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2407                 if (!NT_STATUS_IS_OK(status)) {
2408                         return status;
2409                 }
2410         }
2411         if (req->last_key.length > 0) {
2412                 data_blob_clear_free(&req->last_key);
2413         }
2414
2415         SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
2416                 iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
2417
2418         req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
2419
2420         if (req->current_idx < req->out.vector_count) {
2421                 /*
2422                  * We must process the remaining compound
2423                  * SMB2 requests before any new incoming SMB2
2424                  * requests. This is because incoming SMB2
2425                  * requests may include a cancel for a
2426                  * compound request we haven't processed
2427                  * yet.
2428                  */
2429                 struct tevent_immediate *im = tevent_create_immediate(req);
2430                 if (!im) {
2431                         return NT_STATUS_NO_MEMORY;
2432                 }
2433
2434                 if (req->do_signing && firsttf->iov_len == 0) {
2435                         struct smbXsrv_session *x = req->session;
2436                         DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2437
2438                         /*
2439                          * we need to remember the signing key
2440                          * and defer the signing until
2441                          * we are sure that we do not change
2442                          * the header again.
2443                          */
2444                         req->last_key = data_blob_dup_talloc(req, signing_key);
2445                         if (req->last_key.data == NULL) {
2446                                 return NT_STATUS_NO_MEMORY;
2447                         }
2448                 }
2449
2450                 tevent_schedule_immediate(im,
2451                                         req->sconn->ev_ctx,
2452                                         smbd_smb2_request_dispatch_immediate,
2453                                         req);
2454                 return NT_STATUS_OK;
2455         }
2456
2457         if (req->compound_related) {
2458                 req->compound_related = false;
2459         }
2460
2461         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
2462
2463         /* Set credit for these operations (zero credits if this
2464            is a final reply for an async operation). */
2465         smb2_calculate_credits(req, req);
2466
2467         /*
2468          * now check if we need to sign the current response
2469          */
2470         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
2471                 status = smb2_signing_encrypt_pdu(req->first_key,
2472                                         xconn->smb2.server.cipher,
2473                                         firsttf,
2474                                         req->out.vector_count - first_idx);
2475                 if (!NT_STATUS_IS_OK(status)) {
2476                         return status;
2477                 }
2478         } else if (req->do_signing) {
2479                 struct smbXsrv_session *x = req->session;
2480                 DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2481
2482                 status = smb2_signing_sign_pdu(signing_key,
2483                                                xconn->protocol,
2484                                                outhdr,
2485                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2486                 if (!NT_STATUS_IS_OK(status)) {
2487                         return status;
2488                 }
2489         }
2490         if (req->first_key.length > 0) {
2491                 data_blob_clear_free(&req->first_key);
2492         }
2493
2494         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2495         if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
2496             outdyn->iov_base == NULL && outdyn->iov_len != 0) {
2497                 /* Dynamic part is NULL. Chop it off,
2498                    We're going to send it via sendfile. */
2499                 req->out.vector_count -= 1;
2500         }
2501
2502         /*
2503          * We're done with this request -
2504          * move it off the "being processed" queue.
2505          */
2506         DLIST_REMOVE(xconn->smb2.requests, req);
2507
2508         req->queue_entry.mem_ctx = req;
2509         req->queue_entry.vector = req->out.vector;
2510         req->queue_entry.count = req->out.vector_count;
2511         DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry, NULL);
2512         xconn->smb2.send_queue_len++;
2513
2514         status = smbd_smb2_flush_send_queue(xconn);
2515         if (!NT_STATUS_IS_OK(status)) {
2516                 return status;
2517         }
2518
2519         return NT_STATUS_OK;
2520 }
2521
2522 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
2523
2524 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
2525                                         struct tevent_immediate *im,
2526                                         void *private_data)
2527 {
2528         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
2529                                         struct smbd_smb2_request);
2530         struct smbXsrv_connection *xconn = req->xconn;
2531         NTSTATUS status;
2532
2533         TALLOC_FREE(im);
2534
2535         if (DEBUGLEVEL >= 10) {
2536                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2537                         req->current_idx, req->in.vector_count));
2538                 print_req_vectors(req);
2539         }
2540
2541         status = smbd_smb2_request_dispatch(req);
2542         if (!NT_STATUS_IS_OK(status)) {
2543                 smbd_server_connection_terminate(xconn, nt_errstr(status));
2544                 return;
2545         }
2546
2547         status = smbd_smb2_request_next_incoming(xconn);
2548         if (!NT_STATUS_IS_OK(status)) {
2549                 smbd_server_connection_terminate(xconn, nt_errstr(status));
2550                 return;
2551         }
2552 }
2553
2554 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
2555                                    NTSTATUS status,
2556                                    DATA_BLOB body, DATA_BLOB *dyn,
2557                                    const char *location)
2558 {
2559         uint8_t *outhdr;
2560         struct iovec *outbody_v;
2561         struct iovec *outdyn_v;
2562         uint32_t next_command_ofs;
2563
2564         DEBUG(10,("smbd_smb2_request_done_ex: "
2565                   "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
2566                   req->current_idx, nt_errstr(status), (unsigned int)body.length,
2567                   dyn ? "yes": "no",
2568                   (unsigned int)(dyn ? dyn->length : 0),
2569                   location));
2570
2571         if (body.length < 2) {
2572                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2573         }
2574
2575         if ((body.length % 2) != 0) {
2576                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2577         }
2578
2579         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2580         outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
2581         outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
2582
2583         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
2584         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
2585
2586         outbody_v->iov_base = (void *)body.data;
2587         outbody_v->iov_len = body.length;
2588
2589         if (dyn) {
2590                 outdyn_v->iov_base = (void *)dyn->data;
2591                 outdyn_v->iov_len = dyn->length;
2592         } else {
2593                 outdyn_v->iov_base = NULL;
2594                 outdyn_v->iov_len = 0;
2595         }
2596
2597         /* see if we need to recalculate the offset to the next response */
2598         if (next_command_ofs > 0) {
2599                 next_command_ofs  = SMB2_HDR_BODY;
2600                 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
2601                 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
2602         }
2603
2604         if ((next_command_ofs % 8) != 0) {
2605                 size_t pad_size = 8 - (next_command_ofs % 8);
2606                 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
2607                         /*
2608                          * if the dyn buffer is empty
2609                          * we can use it to add padding
2610                          */
2611                         uint8_t *pad;
2612
2613                         pad = talloc_zero_array(req,
2614                                                 uint8_t, pad_size);
2615                         if (pad == NULL) {
2616                                 return smbd_smb2_request_error(req,
2617                                                 NT_STATUS_NO_MEMORY);
2618                         }
2619
2620                         outdyn_v->iov_base = (void *)pad;
2621                         outdyn_v->iov_len = pad_size;
2622                 } else {
2623                         /*
2624                          * For now we copy the dynamic buffer
2625                          * and add the padding to the new buffer
2626                          */
2627                         size_t old_size;
2628                         uint8_t *old_dyn;
2629                         size_t new_size;
2630                         uint8_t *new_dyn;
2631
2632                         old_size = SMBD_SMB2_OUT_DYN_LEN(req);
2633                         old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
2634
2635                         new_size = old_size + pad_size;
2636                         new_dyn = talloc_zero_array(req,
2637                                                uint8_t, new_size);
2638                         if (new_dyn == NULL) {
2639                                 return smbd_smb2_request_error(req,
2640                                                 NT_STATUS_NO_MEMORY);
2641                         }
2642
2643                         memcpy(new_dyn, old_dyn, old_size);
2644                         memset(new_dyn + old_size, 0, pad_size);
2645
2646                         outdyn_v->iov_base = (void *)new_dyn;
2647                         outdyn_v->iov_len = new_size;
2648                 }
2649                 next_command_ofs += pad_size;
2650         }
2651
2652         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
2653
2654         return smbd_smb2_request_reply(req);
2655 }
2656
2657 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
2658                                     NTSTATUS status,
2659                                     DATA_BLOB *info,
2660                                     const char *location)
2661 {
2662         struct smbXsrv_connection *xconn = req->xconn;
2663         DATA_BLOB body;
2664         DATA_BLOB _dyn;
2665         uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2666         size_t unread_bytes = smbd_smb2_unread_bytes(req);
2667
2668         DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n",
2669                   req->current_idx, nt_errstr(status), info ? " +info" : "",
2670                   location));
2671
2672         if (unread_bytes) {
2673                 /* Recvfile error. Drain incoming socket. */
2674                 size_t ret;
2675
2676                 errno = 0;
2677                 ret = drain_socket(xconn->transport.sock, unread_bytes);
2678                 if (ret != unread_bytes) {
2679                         NTSTATUS error;
2680
2681                         if (errno == 0) {
2682                                 error = NT_STATUS_IO_DEVICE_ERROR;
2683                         } else {
2684                                 error = map_nt_error_from_unix_common(errno);
2685                         }
2686
2687                         DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
2688                                   "ret[%u] errno[%d] => %s\n",
2689                                   (unsigned)unread_bytes,
2690                                   (unsigned)ret, errno, nt_errstr(error)));
2691                         return error;
2692                 }
2693         }
2694
2695         body.data = outhdr + SMB2_HDR_BODY;
2696         body.length = 8;
2697         SSVAL(body.data, 0, 9);
2698
2699         if (info) {
2700                 SIVAL(body.data, 0x04, info->length);
2701         } else {
2702                 /* Allocated size of req->out.vector[i].iov_base
2703                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
2704                  * 1 byte without having to do an alloc.
2705                  */
2706                 info = &_dyn;
2707                 info->data = ((uint8_t *)outhdr) +
2708                         OUTVEC_ALLOC_SIZE - 1;
2709                 info->length = 1;
2710                 SCVAL(info->data, 0, 0);
2711         }
2712
2713         /*
2714          * Note: Even if there is an error, continue to process the request.
2715          * per MS-SMB2.
2716          */
2717
2718         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
2719 }
2720
2721
2722 struct smbd_smb2_send_break_state {
2723         struct smbd_smb2_send_queue queue_entry;
2724         uint8_t nbt_hdr[NBT_HDR_SIZE];
2725         uint8_t tf[SMB2_TF_HDR_SIZE];
2726         uint8_t hdr[SMB2_HDR_BODY];
2727         struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
2728         uint8_t body[1];
2729 };
2730
2731 static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
2732                                      struct smbXsrv_session *session,
2733                                      struct smbXsrv_tcon *tcon,
2734                                      const uint8_t *body,
2735                                      size_t body_len)
2736 {
2737         struct smbd_smb2_send_break_state *state;
2738         bool do_encryption = false;
2739         uint64_t session_wire_id = 0;
2740         uint64_t nonce_high = 0;
2741         uint64_t nonce_low = 0;
2742         NTSTATUS status;
2743         size_t statelen;
2744
2745         if (session != NULL) {
2746                 session_wire_id = session->global->session_wire_id;
2747                 do_encryption = session->global->encryption_required;
2748                 if (tcon->global->encryption_required) {
2749                         do_encryption = true;
2750                 }
2751         }
2752
2753         statelen = offsetof(struct smbd_smb2_send_break_state, body) +
2754                 body_len;
2755
2756         state = talloc_zero_size(xconn, statelen);
2757         if (state == NULL) {
2758                 return NT_STATUS_NO_MEMORY;
2759         }
2760         talloc_set_name_const(state, "struct smbd_smb2_send_break_state");
2761
2762         if (do_encryption) {
2763                 nonce_high = session->nonce_high;
2764                 nonce_low = session->nonce_low;
2765
2766                 session->nonce_low += 1;
2767                 if (session->nonce_low == 0) {
2768                         session->nonce_low += 1;
2769                         session->nonce_high += 1;
2770                 }
2771         }
2772
2773         SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2774         SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
2775         SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
2776         SBVAL(state->tf, SMB2_TF_SESSION_ID, session_wire_id);
2777
2778         SIVAL(state->hdr, 0,                            SMB2_MAGIC);
2779         SSVAL(state->hdr, SMB2_HDR_LENGTH,              SMB2_HDR_BODY);
2780         SSVAL(state->hdr, SMB2_HDR_EPOCH,               0);
2781         SIVAL(state->hdr, SMB2_HDR_STATUS,              0);
2782         SSVAL(state->hdr, SMB2_HDR_OPCODE,              SMB2_OP_BREAK);
2783         SSVAL(state->hdr, SMB2_HDR_CREDIT,              0);
2784         SIVAL(state->hdr, SMB2_HDR_FLAGS,               SMB2_HDR_FLAG_REDIRECT);
2785         SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND,        0);
2786         SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID,          UINT64_MAX);
2787         SIVAL(state->hdr, SMB2_HDR_PID,         0);
2788         SIVAL(state->hdr, SMB2_HDR_TID,         0);
2789         SBVAL(state->hdr, SMB2_HDR_SESSION_ID,          0);
2790         memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
2791
2792         state->vector[0] = (struct iovec) {
2793                 .iov_base = state->nbt_hdr,
2794                 .iov_len  = sizeof(state->nbt_hdr)
2795         };
2796
2797         if (do_encryption) {
2798                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
2799                         .iov_base = state->tf,
2800                         .iov_len  = sizeof(state->tf)
2801                 };
2802         } else {
2803                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
2804                         .iov_base = NULL,
2805                         .iov_len  = 0
2806                 };
2807         }
2808
2809         state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
2810                 .iov_base = state->hdr,
2811                 .iov_len  = sizeof(state->hdr)
2812         };
2813
2814         memcpy(state->body, body, body_len);
2815
2816         state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
2817                 .iov_base = state->body,
2818                 .iov_len  = body_len /* no sizeof(state->body) .. :-) */
2819         };
2820
2821         /*
2822          * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
2823          */
2824
2825         smb2_setup_nbt_length(state->vector, 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2826
2827         if (do_encryption) {
2828                 DATA_BLOB encryption_key = session->global->encryption_key;
2829
2830                 status = smb2_signing_encrypt_pdu(encryption_key,
2831                                         xconn->smb2.server.cipher,
2832                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2833                                         SMBD_SMB2_NUM_IOV_PER_REQ);
2834                 if (!NT_STATUS_IS_OK(status)) {
2835                         return status;
2836                 }
2837         }
2838
2839         state->queue_entry.mem_ctx = state;
2840         state->queue_entry.vector = state->vector;
2841         state->queue_entry.count = ARRAY_SIZE(state->vector);
2842         DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry, NULL);
2843         xconn->smb2.send_queue_len++;
2844
2845         status = smbd_smb2_flush_send_queue(xconn);
2846         if (!NT_STATUS_IS_OK(status)) {
2847                 return status;
2848         }
2849
2850         return NT_STATUS_OK;
2851 }
2852
2853 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
2854                                      struct smbXsrv_session *session,
2855                                      struct smbXsrv_tcon *tcon,
2856                                      struct smbXsrv_open *op,
2857                                      uint8_t oplock_level)
2858 {
2859         uint8_t body[0x18];
2860
2861         SSVAL(body, 0x00, sizeof(body));
2862         SCVAL(body, 0x02, oplock_level);
2863         SCVAL(body, 0x03, 0);           /* reserved */
2864         SIVAL(body, 0x04, 0);           /* reserved */
2865         SBVAL(body, 0x08, op->global->open_persistent_id);
2866         SBVAL(body, 0x10, op->global->open_volatile_id);
2867
2868         return smbd_smb2_send_break(xconn, session, tcon, body, sizeof(body));
2869 }
2870
2871 NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
2872                                     uint16_t new_epoch,
2873                                     uint32_t lease_flags,
2874                                     struct smb2_lease_key *lease_key,
2875                                     uint32_t current_lease_state,
2876                                     uint32_t new_lease_state)
2877 {
2878         uint8_t body[0x2c];
2879
2880         SSVAL(body, 0x00, sizeof(body));
2881         SSVAL(body, 0x02, new_epoch);
2882         SIVAL(body, 0x04, lease_flags);
2883         SBVAL(body, 0x08, lease_key->data[0]);
2884         SBVAL(body, 0x10, lease_key->data[1]);
2885         SIVAL(body, 0x18, current_lease_state);
2886         SIVAL(body, 0x1c, new_lease_state);
2887         SIVAL(body, 0x20, 0);           /* BreakReason, MUST be 0 */
2888         SIVAL(body, 0x24, 0);           /* AccessMaskHint, MUST be 0 */
2889         SIVAL(body, 0x28, 0);           /* ShareMaskHint, MUST be 0 */
2890
2891         return smbd_smb2_send_break(xconn, NULL, NULL, body, sizeof(body));
2892 }
2893
2894 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
2895 {
2896         NTSTATUS status;
2897         uint32_t flags;
2898         uint64_t file_id_persistent;
2899         uint64_t file_id_volatile;
2900         struct smbXsrv_open *op = NULL;
2901         struct files_struct *fsp = NULL;
2902         const uint8_t *body = NULL;
2903
2904         /*
2905          * This is only called with a pktbuf
2906          * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
2907          * bytes
2908          */
2909
2910         if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
2911                 /* Transform header. Cannot recvfile. */
2912                 return false;
2913         }
2914         if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
2915                 /* Not SMB2. Normal error path will cope. */
2916                 return false;
2917         }
2918         if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
2919                 /* Not SMB2. Normal error path will cope. */
2920                 return false;
2921         }
2922         if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
2923                 /* Needs to be a WRITE. */
2924                 return false;
2925         }
2926         if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
2927                 /* Chained. Cannot recvfile. */
2928                 return false;
2929         }
2930         flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
2931         if (flags & SMB2_HDR_FLAG_CHAINED) {
2932                 /* Chained. Cannot recvfile. */
2933                 return false;
2934         }
2935         if (flags & SMB2_HDR_FLAG_SIGNED) {
2936                 /* Signed. Cannot recvfile. */
2937                 return false;
2938         }
2939
2940         body = &state->pktbuf[SMB2_HDR_BODY];
2941
2942         file_id_persistent      = BVAL(body, 0x10);
2943         file_id_volatile        = BVAL(body, 0x18);
2944
2945         status = smb2srv_open_lookup(state->req->xconn,
2946                                      file_id_persistent,
2947                                      file_id_volatile,
2948                                      0, /* now */
2949                                      &op);
2950         if (!NT_STATUS_IS_OK(status)) {
2951                 return false;
2952         }
2953
2954         fsp = op->compat;
2955         if (fsp == NULL) {
2956                 return false;
2957         }
2958         if (fsp->conn == NULL) {
2959                 return false;
2960         }
2961
2962         if (IS_IPC(fsp->conn)) {
2963                 return false;
2964         }
2965         if (IS_PRINT(fsp->conn)) {
2966                 return false;
2967         }
2968
2969         DEBUG(10,("Doing recvfile write len = %u\n",
2970                 (unsigned int)(state->pktfull - state->pktlen)));
2971
2972         return true;
2973 }
2974
2975 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
2976 {
2977         struct smbd_server_connection *sconn = xconn->client->sconn;
2978         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
2979         size_t max_send_queue_len;
2980         size_t cur_send_queue_len;
2981
2982         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2983                 /*
2984                  * we're not supposed to do any io
2985                  */
2986                 return NT_STATUS_OK;
2987         }
2988
2989         if (state->req != NULL) {
2990                 /*
2991                  * if there is already a tstream_readv_pdu
2992                  * pending, we are done.
2993                  */
2994                 return NT_STATUS_OK;
2995         }
2996
2997         max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
2998         cur_send_queue_len = xconn->smb2.send_queue_len;
2999
3000         if (cur_send_queue_len > max_send_queue_len) {
3001                 /*
3002                  * if we have a lot of requests to send,
3003                  * we wait until they are on the wire until we
3004                  * ask for the next request.
3005                  */
3006                 return NT_STATUS_OK;
3007         }
3008
3009         /* ask for the next request */
3010         ZERO_STRUCTP(state);
3011         state->req = smbd_smb2_request_allocate(xconn);
3012         if (state->req == NULL) {
3013                 return NT_STATUS_NO_MEMORY;
3014         }
3015         state->req->sconn = sconn;
3016         state->req->xconn = xconn;
3017         state->min_recv_size = lp_min_receive_file_size();
3018
3019         TEVENT_FD_READABLE(xconn->transport.fde);
3020
3021         return NT_STATUS_OK;
3022 }
3023
3024 void smbd_smb2_first_negprot(struct smbXsrv_connection *xconn,
3025                              const uint8_t *inpdu, size_t size)
3026 {
3027         struct smbd_server_connection *sconn = xconn->client->sconn;
3028         NTSTATUS status;
3029         struct smbd_smb2_request *req = NULL;
3030
3031         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3032                  (unsigned int)size));
3033
3034         status = smbd_initialize_smb2(xconn);
3035         if (!NT_STATUS_IS_OK(status)) {
3036                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3037                 return;
3038         }
3039
3040         status = smbd_smb2_request_create(xconn, inpdu, size, &req);
3041         if (!NT_STATUS_IS_OK(status)) {
3042                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3043                 return;
3044         }
3045
3046         status = smbd_smb2_request_validate(req);
3047         if (!NT_STATUS_IS_OK(status)) {
3048                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3049                 return;
3050         }
3051
3052         status = smbd_smb2_request_setup_out(req);
3053         if (!NT_STATUS_IS_OK(status)) {
3054                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3055                 return;
3056         }
3057
3058 #ifdef WITH_PROFILE
3059         /*
3060          * this was already counted at the SMB1 layer =>
3061          * smbd_smb2_request_dispatch() should not count it twice.
3062          */
3063         if (profile_p->request_stats.count > 0) {
3064                 profile_p->request_stats.count--;
3065         }
3066 #endif
3067         status = smbd_smb2_request_dispatch(req);
3068         if (!NT_STATUS_IS_OK(status)) {
3069                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3070                 return;
3071         }
3072
3073         status = smbd_smb2_request_next_incoming(xconn);
3074         if (!NT_STATUS_IS_OK(status)) {
3075                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3076                 return;
3077         }
3078
3079         sconn->num_requests++;
3080 }
3081
3082 static int socket_error_from_errno(int ret,
3083                                    int sys_errno,
3084                                    bool *retry)
3085 {
3086         *retry = false;
3087
3088         if (ret >= 0) {
3089                 return 0;
3090         }
3091
3092         if (ret != -1) {
3093                 return EIO;
3094         }
3095
3096         if (sys_errno == 0) {
3097                 return EIO;
3098         }
3099
3100         if (sys_errno == EINTR) {
3101                 *retry = true;
3102                 return sys_errno;
3103         }
3104
3105         if (sys_errno == EINPROGRESS) {
3106                 *retry = true;
3107                 return sys_errno;
3108         }
3109
3110         if (sys_errno == EAGAIN) {
3111                 *retry = true;
3112                 return sys_errno;
3113         }
3114
3115         /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3116         if (sys_errno == ENOMEM) {
3117                 *retry = true;
3118                 return sys_errno;
3119         }
3120
3121 #ifdef EWOULDBLOCK
3122 #if EWOULDBLOCK != EAGAIN
3123         if (sys_errno == EWOULDBLOCK) {
3124                 *retry = true;
3125                 return sys_errno;
3126         }
3127 #endif
3128 #endif
3129
3130         return sys_errno;
3131 }
3132
3133 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
3134 {
3135         int ret;
3136         int err;
3137         bool retry;
3138
3139         if (xconn->smb2.send_queue == NULL) {
3140                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3141                 return NT_STATUS_OK;
3142         }
3143
3144         while (xconn->smb2.send_queue != NULL) {
3145                 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
3146
3147                 if (e->sendfile_header != NULL) {
3148                         NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
3149                         size_t size = 0;
3150                         size_t i = 0;
3151                         uint8_t *buf;
3152
3153                         for (i=0; i < e->count; i++) {
3154                                 size += e->vector[i].iov_len;
3155                         }
3156
3157                         if (size <= e->sendfile_header->length) {
3158                                 buf = e->sendfile_header->data;
3159                         } else {
3160                                 buf = talloc_array(e->mem_ctx, uint8_t, size);
3161                                 if (buf == NULL) {
3162                                         return NT_STATUS_NO_MEMORY;
3163                                 }
3164                         }
3165
3166                         size = 0;
3167                         for (i=0; i < e->count; i++) {
3168                                 memcpy(buf+size,
3169                                        e->vector[i].iov_base,
3170                                        e->vector[i].iov_len);
3171                                 size += e->vector[i].iov_len;
3172                         }
3173
3174                         e->sendfile_header->data = buf;
3175                         e->sendfile_header->length = size;
3176                         e->sendfile_status = &status;
3177                         e->count = 0;
3178
3179                         xconn->smb2.send_queue_len--;
3180                         DLIST_REMOVE(xconn->smb2.send_queue, e);
3181                         /*
3182                          * This triggers the sendfile path via
3183                          * the destructor.
3184                          */
3185                         talloc_free(e->mem_ctx);
3186
3187                         if (!NT_STATUS_IS_OK(status)) {
3188                                 return status;
3189                         }
3190                         continue;
3191                 }
3192
3193                 ret = writev(xconn->transport.sock, e->vector, e->count);
3194                 if (ret == 0) {
3195                         /* propagate end of file */
3196                         return NT_STATUS_INTERNAL_ERROR;
3197                 }
3198                 err = socket_error_from_errno(ret, errno, &retry);
3199                 if (retry) {
3200                         /* retry later */
3201                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3202                         return NT_STATUS_OK;
3203                 }
3204                 if (err != 0) {
3205                         return map_nt_error_from_unix_common(err);
3206                 }
3207                 while (ret > 0) {
3208                         if (ret < e->vector[0].iov_len) {
3209                                 uint8_t *base;
3210                                 base = (uint8_t *)e->vector[0].iov_base;
3211                                 base += ret;
3212                                 e->vector[0].iov_base = (void *)base;
3213                                 e->vector[0].iov_len -= ret;
3214                                 break;
3215                         }
3216                         ret -= e->vector[0].iov_len;
3217                         e->vector += 1;
3218                         e->count -= 1;
3219                 }
3220
3221                 /*
3222                  * there're maybe some empty vectors at the end
3223                  * which we need to skip, otherwise we would get
3224                  * ret == 0 from the readv() call and return EPIPE
3225                  */
3226                 while (e->count > 0) {
3227                         if (e->vector[0].iov_len > 0) {
3228                                 break;
3229                         }
3230                         e->vector += 1;
3231                         e->count -= 1;
3232                 }
3233
3234                 if (e->count > 0) {
3235                         /* we have more to write */
3236                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3237                         return NT_STATUS_OK;
3238                 }
3239
3240                 xconn->smb2.send_queue_len--;
3241                 DLIST_REMOVE(xconn->smb2.send_queue, e);
3242                 talloc_free(e->mem_ctx);
3243         }
3244
3245         return NT_STATUS_OK;
3246 }
3247
3248 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
3249                                      uint16_t fde_flags)
3250 {
3251         struct smbd_server_connection *sconn = xconn->client->sconn;
3252         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3253         struct smbd_smb2_request *req = NULL;
3254         size_t min_recvfile_size = UINT32_MAX;
3255         int ret;
3256         int err;
3257         bool retry;
3258         NTSTATUS status;
3259         NTTIME now;
3260
3261         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3262                 /*
3263                  * we're not supposed to do any io
3264                  */
3265                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3266                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3267                 return NT_STATUS_OK;
3268         }
3269
3270         if (fde_flags & TEVENT_FD_WRITE) {
3271                 status = smbd_smb2_flush_send_queue(xconn);
3272                 if (!NT_STATUS_IS_OK(status)) {
3273                         return status;
3274                 }
3275         }
3276
3277         if (!(fde_flags & TEVENT_FD_READ)) {
3278                 return NT_STATUS_OK;
3279         }
3280
3281         if (state->req == NULL) {
3282                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3283                 return NT_STATUS_OK;
3284         }
3285
3286 again:
3287         if (!state->hdr.done) {
3288                 state->hdr.done = true;
3289
3290                 state->vector.iov_base = (void *)state->hdr.nbt;
3291                 state->vector.iov_len = NBT_HDR_SIZE;
3292         }
3293
3294         ret = readv(xconn->transport.sock, &state->vector, 1);
3295         if (ret == 0) {
3296                 /* propagate end of file */
3297                 return NT_STATUS_END_OF_FILE;
3298         }
3299         err = socket_error_from_errno(ret, errno, &retry);
3300         if (retry) {
3301                 /* retry later */
3302                 TEVENT_FD_READABLE(xconn->transport.fde);
3303                 return NT_STATUS_OK;
3304         }
3305         if (err != 0) {
3306                 return map_nt_error_from_unix_common(err);
3307         }
3308
3309         if (ret < state->vector.iov_len) {
3310                 uint8_t *base;
3311                 base = (uint8_t *)state->vector.iov_base;
3312                 base += ret;
3313                 state->vector.iov_base = (void *)base;
3314                 state->vector.iov_len -= ret;
3315                 /* we have more to read */
3316                 TEVENT_FD_READABLE(xconn->transport.fde);
3317                 return NT_STATUS_OK;
3318         }
3319
3320         if (state->pktlen > 0) {
3321                 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
3322                         /*
3323                          * Not a possible receivefile write.
3324                          * Read the rest of the data.
3325                          */
3326                         state->doing_receivefile = false;
3327
3328                         state->pktbuf = talloc_realloc(state->req,
3329                                                        state->pktbuf,
3330                                                        uint8_t,
3331                                                        state->pktfull);
3332                         if (state->pktbuf == NULL) {
3333                                 return NT_STATUS_NO_MEMORY;
3334                         }
3335
3336                         state->vector.iov_base = (void *)(state->pktbuf +
3337                                 state->pktlen);
3338                         state->vector.iov_len = (state->pktfull -
3339                                 state->pktlen);
3340
3341                         state->pktlen = state->pktfull;
3342                         goto again;
3343                 }
3344
3345                 /*
3346                  * Either this is a receivefile write so we've
3347                  * done a short read, or if not we have all the data.
3348                  */
3349                 goto got_full;
3350         }
3351
3352         /*
3353          * Now we analyze the NBT header
3354          */
3355         if (state->hdr.nbt[0] != 0x00) {
3356                 state->min_recv_size = 0;
3357         }
3358         state->pktfull = smb2_len(state->hdr.nbt);
3359         if (state->pktfull == 0) {
3360                 goto got_full;
3361         }
3362
3363         if (state->min_recv_size != 0) {
3364                 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3365                 min_recvfile_size += state->min_recv_size;
3366         }
3367
3368         if (state->pktfull > min_recvfile_size) {
3369                 /*
3370                  * Might be a receivefile write. Read the SMB2 HEADER +
3371                  * SMB2_WRITE header first. Set 'doing_receivefile'
3372                  * as we're *attempting* receivefile write. If this
3373                  * turns out not to be a SMB2_WRITE request or otherwise
3374                  * not suitable then we'll just read the rest of the data
3375                  * the next time this function is called.
3376                  */
3377                 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3378                 state->doing_receivefile = true;
3379         } else {
3380                 state->pktlen = state->pktfull;
3381         }
3382
3383         state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
3384         if (state->pktbuf == NULL) {
3385                 return NT_STATUS_NO_MEMORY;
3386         }
3387
3388         state->vector.iov_base = (void *)state->pktbuf;
3389         state->vector.iov_len = state->pktlen;
3390
3391         goto again;
3392
3393 got_full:
3394
3395         if (state->hdr.nbt[0] != 0x00) {
3396                 DEBUG(1,("ignore NBT[0x%02X] msg\n",
3397                          state->hdr.nbt[0]));
3398
3399                 req = state->req;
3400                 ZERO_STRUCTP(state);
3401                 state->req = req;
3402                 state->min_recv_size = lp_min_receive_file_size();
3403                 req = NULL;
3404                 goto again;
3405         }
3406
3407         req = state->req;
3408         state->req = NULL;
3409
3410         req->request_time = timeval_current();
3411         now = timeval_to_nttime(&req->request_time);
3412
3413         status = smbd_smb2_inbuf_parse_compound(xconn,
3414                                                 now,
3415                                                 state->pktbuf,
3416                                                 state->pktlen,
3417                                                 req,
3418                                                 &req->in.vector,
3419                                                 &req->in.vector_count);
3420         if (!NT_STATUS_IS_OK(status)) {
3421                 return status;
3422         }
3423
3424         if (state->doing_receivefile) {
3425                 req->smb1req = talloc_zero(req, struct smb_request);
3426                 if (req->smb1req == NULL) {
3427                         return NT_STATUS_NO_MEMORY;
3428                 }
3429                 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
3430         }
3431
3432         ZERO_STRUCTP(state);
3433
3434         req->current_idx = 1;
3435
3436         DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
3437                  req->current_idx, req->in.vector_count));
3438
3439         status = smbd_smb2_request_validate(req);
3440         if (!NT_STATUS_IS_OK(status)) {
3441                 return status;
3442         }
3443
3444         status = smbd_smb2_request_setup_out(req);
3445         if (!NT_STATUS_IS_OK(status)) {
3446                 return status;
3447         }
3448
3449         status = smbd_smb2_request_dispatch(req);
3450         if (!NT_STATUS_IS_OK(status)) {
3451                 return status;
3452         }
3453
3454         sconn->num_requests++;
3455
3456         /* The timeout_processing function isn't run nearly
3457            often enough to implement 'max log size' without
3458            overrunning the size of the file by many megabytes.
3459            This is especially true if we are running at debug
3460            level 10.  Checking every 50 SMB2s is a nice
3461            tradeoff of performance vs log file size overrun. */
3462
3463         if ((sconn->num_requests % 50) == 0 &&
3464             need_to_check_log_size()) {
3465                 change_to_root_user();
3466                 check_log_size();
3467         }
3468
3469         status = smbd_smb2_request_next_incoming(xconn);
3470         if (!NT_STATUS_IS_OK(status)) {
3471                 return status;
3472         }
3473
3474         return NT_STATUS_OK;
3475 }
3476
3477 static void smbd_smb2_connection_handler(struct tevent_context *ev,
3478                                          struct tevent_fd *fde,
3479                                          uint16_t flags,
3480                                          void *private_data)
3481 {
3482         struct smbXsrv_connection *xconn =
3483                 talloc_get_type_abort(private_data,
3484                 struct smbXsrv_connection);
3485         NTSTATUS status;
3486
3487         status = smbd_smb2_io_handler(xconn, flags);
3488         if (!NT_STATUS_IS_OK(status)) {
3489                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3490                 return;
3491         }
3492 }