s3:smb2_server: add smbd_smb2_signing_key() helper function
[kai/samba-autobuild/.git] / source3 / smbd / smb2_server.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30 #include "../librpc/gen_ndr/krb5pac.h"
31 #include "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.capabilities & SMB2_CAP_ENCRYPTION)) {
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->protocol,
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->protocol,
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->protocol,
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         /* TODO: verify more things */
1949
1950         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1951         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
1952         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1953         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
1954                 smb2_opcode_name(opcode),
1955                 (unsigned long long)mid));
1956
1957         if (xconn->protocol >= PROTOCOL_SMB2_02) {
1958                 /*
1959                  * once the protocol is negotiated
1960                  * SMB2_OP_NEGPROT is not allowed anymore
1961                  */
1962                 if (opcode == SMB2_OP_NEGPROT) {
1963                         /* drop the connection */
1964                         return NT_STATUS_INVALID_PARAMETER;
1965                 }
1966         } else {
1967                 /*
1968                  * if the protocol is not negotiated yet
1969                  * only SMB2_OP_NEGPROT is allowed.
1970                  */
1971                 if (opcode != SMB2_OP_NEGPROT) {
1972                         /* drop the connection */
1973                         return NT_STATUS_INVALID_PARAMETER;
1974                 }
1975         }
1976
1977         /*
1978          * Check if the client provided a valid session id,
1979          * if so smbd_smb2_request_check_session() calls
1980          * set_current_user_info().
1981          *
1982          * As some command don't require a valid session id
1983          * we defer the check of the session_status
1984          */
1985         session_status = smbd_smb2_request_check_session(req);
1986         x = req->session;
1987         if (x != NULL) {
1988                 signing_required = x->global->signing_required;
1989                 encryption_required = x->global->encryption_required;
1990
1991                 if (opcode == SMB2_OP_SESSSETUP &&
1992                     x->global->signing_key.length > 0) {
1993                         signing_required = true;
1994                 }
1995         }
1996
1997         req->do_signing = false;
1998         req->do_encryption = false;
1999         if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
2000                 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
2001                 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
2002
2003                 if (x != NULL && x->global->session_wire_id != tf_session_id) {
2004                         DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
2005                                  "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
2006                                  (unsigned long long)x->global->session_wire_id,
2007                                  (unsigned long long)tf_session_id));
2008                         /*
2009                          * TODO: windows allows this...
2010                          * should we drop the connection?
2011                          *
2012                          * For now we just return ACCESS_DENIED
2013                          * (Windows clients never trigger this)
2014                          * and wait for an update of [MS-SMB2].
2015                          */
2016                         return smbd_smb2_request_error(req,
2017                                         NT_STATUS_ACCESS_DENIED);
2018                 }
2019
2020                 req->do_encryption = true;
2021         }
2022
2023         if (encryption_required && !req->do_encryption) {
2024                 return smbd_smb2_request_error(req,
2025                                 NT_STATUS_ACCESS_DENIED);
2026         }
2027
2028         call = smbd_smb2_call(opcode);
2029         if (call == NULL) {
2030                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2031         }
2032
2033         allowed_flags = SMB2_HDR_FLAG_CHAINED |
2034                         SMB2_HDR_FLAG_SIGNED |
2035                         SMB2_HDR_FLAG_DFS;
2036         if (opcode == SMB2_OP_CANCEL) {
2037                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
2038         }
2039         if ((flags & ~allowed_flags) != 0) {
2040                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2041         }
2042
2043         if (flags & SMB2_HDR_FLAG_CHAINED) {
2044                 /*
2045                  * This check is mostly for giving the correct error code
2046                  * for compounded requests.
2047                  */
2048                 if (!NT_STATUS_IS_OK(session_status)) {
2049                         return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2050                 }
2051         } else {
2052                 req->compat_chain_fsp = NULL;
2053         }
2054
2055         if (req->do_encryption) {
2056                 signing_required = false;
2057         } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
2058                 DATA_BLOB signing_key = data_blob_null;
2059
2060                 if (x == NULL) {
2061                         /*
2062                          * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
2063                          * If the SMB2 header of the SMB2 NEGOTIATE
2064                          * request has the SMB2_FLAGS_SIGNED bit set in the
2065                          * Flags field, the server MUST fail the request
2066                          * with STATUS_INVALID_PARAMETER.
2067                          *
2068                          * Microsoft test tool checks this.
2069                          */
2070
2071                         if ((opcode == SMB2_OP_NEGPROT) &&
2072                                         (flags & SMB2_HDR_FLAG_SIGNED)) {
2073                                 status = NT_STATUS_INVALID_PARAMETER;
2074                         } else {
2075                                 status = NT_STATUS_USER_SESSION_DELETED;
2076                         }
2077                         return smbd_smb2_request_error(req, status);
2078                 }
2079
2080                 signing_key = smbd_smb2_signing_key(x, xconn);
2081
2082                 /*
2083                  * If we have a signing key, we should
2084                  * sign the response
2085                  */
2086                 if (signing_key.length > 0) {
2087                         req->do_signing = true;
2088                 }
2089
2090                 status = smb2_signing_check_pdu(signing_key,
2091                                                 xconn->protocol,
2092                                                 SMBD_SMB2_IN_HDR_IOV(req),
2093                                                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2094                 if (!NT_STATUS_IS_OK(status)) {
2095                         return smbd_smb2_request_error(req, status);
2096                 }
2097
2098                 /*
2099                  * Now that we know the request was correctly signed
2100                  * we have to sign the response too.
2101                  */
2102                 req->do_signing = true;
2103
2104                 if (!NT_STATUS_IS_OK(session_status)) {
2105                         return smbd_smb2_request_error(req, session_status);
2106                 }
2107         } else if (opcode == SMB2_OP_CANCEL) {
2108                 /* Cancel requests are allowed to skip the signing */
2109         } else if (signing_required) {
2110                 /*
2111                  * If signing is required we try to sign
2112                  * a possible error response
2113                  */
2114                 req->do_signing = true;
2115                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
2116         }
2117
2118         if (flags & SMB2_HDR_FLAG_CHAINED) {
2119                 req->compound_related = true;
2120         }
2121
2122         if (call->need_session) {
2123                 if (!NT_STATUS_IS_OK(session_status)) {
2124                         return smbd_smb2_request_error(req, session_status);
2125                 }
2126         }
2127
2128         if (call->need_tcon) {
2129                 SMB_ASSERT(call->need_session);
2130
2131                 /*
2132                  * This call needs to be run as user.
2133                  *
2134                  * smbd_smb2_request_check_tcon()
2135                  * calls change_to_user() on success.
2136                  */
2137                 status = smbd_smb2_request_check_tcon(req);
2138                 if (!NT_STATUS_IS_OK(status)) {
2139                         return smbd_smb2_request_error(req, status);
2140                 }
2141                 if (req->tcon->global->encryption_required) {
2142                         encryption_required = true;
2143                 }
2144                 if (encryption_required && !req->do_encryption) {
2145                         return smbd_smb2_request_error(req,
2146                                 NT_STATUS_ACCESS_DENIED);
2147                 }
2148         }
2149
2150         if (call->fileid_ofs != 0) {
2151                 size_t needed = call->fileid_ofs + 16;
2152                 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2153                 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2154                 uint64_t file_id_persistent;
2155                 uint64_t file_id_volatile;
2156                 struct files_struct *fsp;
2157
2158                 SMB_ASSERT(call->need_tcon);
2159
2160                 if (needed > body_size) {
2161                         return smbd_smb2_request_error(req,
2162                                         NT_STATUS_INVALID_PARAMETER);
2163                 }
2164
2165                 file_id_persistent      = BVAL(body, call->fileid_ofs + 0);
2166                 file_id_volatile        = BVAL(body, call->fileid_ofs + 8);
2167
2168                 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2169                 if (fsp == NULL) {
2170                         if (!call->allow_invalid_fileid) {
2171                                 return smbd_smb2_request_error(req,
2172                                                 NT_STATUS_FILE_CLOSED);
2173                         }
2174
2175                         if (file_id_persistent != UINT64_MAX) {
2176                                 return smbd_smb2_request_error(req,
2177                                                 NT_STATUS_FILE_CLOSED);
2178                         }
2179                         if (file_id_volatile != UINT64_MAX) {
2180                                 return smbd_smb2_request_error(req,
2181                                                 NT_STATUS_FILE_CLOSED);
2182                         }
2183                 }
2184         }
2185
2186         if (call->as_root) {
2187                 SMB_ASSERT(call->fileid_ofs == 0);
2188                 /* This call needs to be run as root */
2189                 change_to_root_user();
2190         } else {
2191                 SMB_ASSERT(call->need_tcon);
2192         }
2193
2194         switch (opcode) {
2195         case SMB2_OP_NEGPROT:
2196                 {
2197                         START_PROFILE(smb2_negprot);
2198                         return_value = smbd_smb2_request_process_negprot(req);
2199                         END_PROFILE(smb2_negprot);
2200                 }
2201                 break;
2202
2203         case SMB2_OP_SESSSETUP:
2204                 {
2205                         START_PROFILE(smb2_sesssetup);
2206                         return_value = smbd_smb2_request_process_sesssetup(req);
2207                         END_PROFILE(smb2_sesssetup);
2208                 }
2209                 break;
2210
2211         case SMB2_OP_LOGOFF:
2212                 {
2213                         START_PROFILE(smb2_logoff);
2214                         return_value = smbd_smb2_request_process_logoff(req);
2215                         END_PROFILE(smb2_logoff);
2216                 }
2217                 break;
2218
2219         case SMB2_OP_TCON:
2220                 {
2221                         START_PROFILE(smb2_tcon);
2222                         return_value = smbd_smb2_request_process_tcon(req);
2223                         END_PROFILE(smb2_tcon);
2224                 }
2225                 break;
2226
2227         case SMB2_OP_TDIS:
2228                 {
2229                         START_PROFILE(smb2_tdis);
2230                         return_value = smbd_smb2_request_process_tdis(req);
2231                         END_PROFILE(smb2_tdis);
2232                 }
2233                 break;
2234
2235         case SMB2_OP_CREATE:
2236                 {
2237                         START_PROFILE(smb2_create);
2238                         return_value = smbd_smb2_request_process_create(req);
2239                         END_PROFILE(smb2_create);
2240                 }
2241                 break;
2242
2243         case SMB2_OP_CLOSE:
2244                 {
2245                         START_PROFILE(smb2_close);
2246                         return_value = smbd_smb2_request_process_close(req);
2247                         END_PROFILE(smb2_close);
2248                 }
2249                 break;
2250
2251         case SMB2_OP_FLUSH:
2252                 {
2253                         START_PROFILE(smb2_flush);
2254                         return_value = smbd_smb2_request_process_flush(req);
2255                         END_PROFILE(smb2_flush);
2256                 }
2257                 break;
2258
2259         case SMB2_OP_READ:
2260                 {
2261                         START_PROFILE(smb2_read);
2262                         return_value = smbd_smb2_request_process_read(req);
2263                         END_PROFILE(smb2_read);
2264                 }
2265                 break;
2266
2267         case SMB2_OP_WRITE:
2268                 {
2269                         START_PROFILE(smb2_write);
2270                         return_value = smbd_smb2_request_process_write(req);
2271                         END_PROFILE(smb2_write);
2272                 }
2273                 break;
2274
2275         case SMB2_OP_LOCK:
2276                 {
2277                         START_PROFILE(smb2_lock);
2278                         return_value = smbd_smb2_request_process_lock(req);
2279                         END_PROFILE(smb2_lock);
2280                 }
2281                 break;
2282
2283         case SMB2_OP_IOCTL:
2284                 {
2285                         START_PROFILE(smb2_ioctl);
2286                         return_value = smbd_smb2_request_process_ioctl(req);
2287                         END_PROFILE(smb2_ioctl);
2288                 }
2289                 break;
2290
2291         case SMB2_OP_CANCEL:
2292                 {
2293                         START_PROFILE(smb2_cancel);
2294                         return_value = smbd_smb2_request_process_cancel(req);
2295                         END_PROFILE(smb2_cancel);
2296                 }
2297                 break;
2298
2299         case SMB2_OP_KEEPALIVE:
2300                 {
2301                         START_PROFILE(smb2_keepalive);
2302                         return_value = smbd_smb2_request_process_keepalive(req);
2303                         END_PROFILE(smb2_keepalive);
2304                 }
2305                 break;
2306
2307         case SMB2_OP_FIND:
2308                 {
2309                         START_PROFILE(smb2_find);
2310                         return_value = smbd_smb2_request_process_find(req);
2311                         END_PROFILE(smb2_find);
2312                 }
2313                 break;
2314
2315         case SMB2_OP_NOTIFY:
2316                 {
2317                         START_PROFILE(smb2_notify);
2318                         return_value = smbd_smb2_request_process_notify(req);
2319                         END_PROFILE(smb2_notify);
2320                 }
2321                 break;
2322
2323         case SMB2_OP_GETINFO:
2324                 {
2325                         START_PROFILE(smb2_getinfo);
2326                         return_value = smbd_smb2_request_process_getinfo(req);
2327                         END_PROFILE(smb2_getinfo);
2328                 }
2329                 break;
2330
2331         case SMB2_OP_SETINFO:
2332                 {
2333                         START_PROFILE(smb2_setinfo);
2334                         return_value = smbd_smb2_request_process_setinfo(req);
2335                         END_PROFILE(smb2_setinfo);
2336                 }
2337                 break;
2338
2339         case SMB2_OP_BREAK:
2340                 {
2341                         START_PROFILE(smb2_break);
2342                         return_value = smbd_smb2_request_process_break(req);
2343                         END_PROFILE(smb2_break);
2344                 }
2345                 break;
2346
2347         default:
2348                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2349                 break;
2350         }
2351         return return_value;
2352 }
2353
2354 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
2355 {
2356         struct smbXsrv_connection *xconn = req->xconn;
2357         int first_idx = 1;
2358         struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
2359         struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
2360         struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
2361         NTSTATUS status;
2362
2363         req->subreq = NULL;
2364         TALLOC_FREE(req->async_te);
2365
2366         if (req->do_encryption &&
2367             (firsttf->iov_len == 0) &&
2368             (req->first_key.length == 0) &&
2369             (req->session != NULL) &&
2370             (req->session->global->encryption_key.length != 0))
2371         {
2372                 DATA_BLOB encryption_key = req->session->global->encryption_key;
2373                 uint8_t *tf;
2374                 uint64_t session_id = req->session->global->session_wire_id;
2375                 struct smbXsrv_session *x = req->session;
2376                 uint64_t nonce_high;
2377                 uint64_t nonce_low;
2378
2379                 nonce_high = x->nonce_high;
2380                 nonce_low = x->nonce_low;
2381
2382                 x->nonce_low += 1;
2383                 if (x->nonce_low == 0) {
2384                         x->nonce_low += 1;
2385                         x->nonce_high += 1;
2386                 }
2387
2388                 /*
2389                  * We need to place the SMB2_TRANSFORM header before the
2390                  * first SMB2 header
2391                  */
2392
2393                 /*
2394                  * we need to remember the encryption key
2395                  * and defer the signing/encryption until
2396                  * we are sure that we do not change
2397                  * the header again.
2398                  */
2399                 req->first_key = data_blob_dup_talloc(req, encryption_key);
2400                 if (req->first_key.data == NULL) {
2401                         return NT_STATUS_NO_MEMORY;
2402                 }
2403
2404                 tf = talloc_zero_array(req, uint8_t,
2405                                        SMB2_TF_HDR_SIZE);
2406                 if (tf == NULL) {
2407                         return NT_STATUS_NO_MEMORY;
2408                 }
2409
2410                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2411                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2412                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2413                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2414
2415                 firsttf->iov_base = (void *)tf;
2416                 firsttf->iov_len = SMB2_TF_HDR_SIZE;
2417         }
2418
2419         if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
2420             (req->last_key.length > 0) &&
2421             (firsttf->iov_len == 0))
2422         {
2423                 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
2424                 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
2425
2426                 /*
2427                  * As we are sure the header of the last request in the
2428                  * compound chain will not change, we can to sign here
2429                  * with the last signing key we remembered.
2430                  */
2431                 status = smb2_signing_sign_pdu(req->last_key,
2432                                                xconn->protocol,
2433                                                lasthdr,
2434                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2435                 if (!NT_STATUS_IS_OK(status)) {
2436                         return status;
2437                 }
2438         }
2439         if (req->last_key.length > 0) {
2440                 data_blob_clear_free(&req->last_key);
2441         }
2442
2443         req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
2444
2445         if (req->current_idx < req->out.vector_count) {
2446                 /*
2447                  * We must process the remaining compound
2448                  * SMB2 requests before any new incoming SMB2
2449                  * requests. This is because incoming SMB2
2450                  * requests may include a cancel for a
2451                  * compound request we haven't processed
2452                  * yet.
2453                  */
2454                 struct tevent_immediate *im = tevent_create_immediate(req);
2455                 if (!im) {
2456                         return NT_STATUS_NO_MEMORY;
2457                 }
2458
2459                 if (req->do_signing && firsttf->iov_len == 0) {
2460                         struct smbXsrv_session *x = req->session;
2461                         DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2462
2463                         /*
2464                          * we need to remember the signing key
2465                          * and defer the signing until
2466                          * we are sure that we do not change
2467                          * the header again.
2468                          */
2469                         req->last_key = data_blob_dup_talloc(req, signing_key);
2470                         if (req->last_key.data == NULL) {
2471                                 return NT_STATUS_NO_MEMORY;
2472                         }
2473                 }
2474
2475                 tevent_schedule_immediate(im,
2476                                         req->sconn->ev_ctx,
2477                                         smbd_smb2_request_dispatch_immediate,
2478                                         req);
2479                 return NT_STATUS_OK;
2480         }
2481
2482         if (req->compound_related) {
2483                 req->compound_related = false;
2484         }
2485
2486         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
2487
2488         /* Set credit for these operations (zero credits if this
2489            is a final reply for an async operation). */
2490         smb2_calculate_credits(req, req);
2491
2492         /*
2493          * now check if we need to sign the current response
2494          */
2495         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
2496                 status = smb2_signing_encrypt_pdu(req->first_key,
2497                                         xconn->protocol,
2498                                         firsttf,
2499                                         req->out.vector_count - first_idx);
2500                 if (!NT_STATUS_IS_OK(status)) {
2501                         return status;
2502                 }
2503         } else if (req->do_signing) {
2504                 struct smbXsrv_session *x = req->session;
2505                 DATA_BLOB signing_key = smbd_smb2_signing_key(x, xconn);
2506
2507                 status = smb2_signing_sign_pdu(signing_key,
2508                                                xconn->protocol,
2509                                                outhdr,
2510                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2511                 if (!NT_STATUS_IS_OK(status)) {
2512                         return status;
2513                 }
2514         }
2515         if (req->first_key.length > 0) {
2516                 data_blob_clear_free(&req->first_key);
2517         }
2518
2519         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2520         if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
2521             outdyn->iov_base == NULL && outdyn->iov_len != 0) {
2522                 /* Dynamic part is NULL. Chop it off,
2523                    We're going to send it via sendfile. */
2524                 req->out.vector_count -= 1;
2525         }
2526
2527         /*
2528          * We're done with this request -
2529          * move it off the "being processed" queue.
2530          */
2531         DLIST_REMOVE(xconn->smb2.requests, req);
2532
2533         req->queue_entry.mem_ctx = req;
2534         req->queue_entry.vector = req->out.vector;
2535         req->queue_entry.count = req->out.vector_count;
2536         DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry, NULL);
2537         xconn->smb2.send_queue_len++;
2538
2539         status = smbd_smb2_flush_send_queue(xconn);
2540         if (!NT_STATUS_IS_OK(status)) {
2541                 return status;
2542         }
2543
2544         return NT_STATUS_OK;
2545 }
2546
2547 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
2548
2549 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
2550                                         struct tevent_immediate *im,
2551                                         void *private_data)
2552 {
2553         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
2554                                         struct smbd_smb2_request);
2555         struct smbXsrv_connection *xconn = req->xconn;
2556         NTSTATUS status;
2557
2558         TALLOC_FREE(im);
2559
2560         if (DEBUGLEVEL >= 10) {
2561                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2562                         req->current_idx, req->in.vector_count));
2563                 print_req_vectors(req);
2564         }
2565
2566         status = smbd_smb2_request_dispatch(req);
2567         if (!NT_STATUS_IS_OK(status)) {
2568                 smbd_server_connection_terminate(xconn, nt_errstr(status));
2569                 return;
2570         }
2571
2572         status = smbd_smb2_request_next_incoming(xconn);
2573         if (!NT_STATUS_IS_OK(status)) {
2574                 smbd_server_connection_terminate(xconn, nt_errstr(status));
2575                 return;
2576         }
2577 }
2578
2579 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
2580                                    NTSTATUS status,
2581                                    DATA_BLOB body, DATA_BLOB *dyn,
2582                                    const char *location)
2583 {
2584         uint8_t *outhdr;
2585         struct iovec *outbody_v;
2586         struct iovec *outdyn_v;
2587         uint32_t next_command_ofs;
2588
2589         DEBUG(10,("smbd_smb2_request_done_ex: "
2590                   "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
2591                   req->current_idx, nt_errstr(status), (unsigned int)body.length,
2592                   dyn ? "yes": "no",
2593                   (unsigned int)(dyn ? dyn->length : 0),
2594                   location));
2595
2596         if (body.length < 2) {
2597                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2598         }
2599
2600         if ((body.length % 2) != 0) {
2601                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2602         }
2603
2604         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2605         outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
2606         outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
2607
2608         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
2609         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
2610
2611         outbody_v->iov_base = (void *)body.data;
2612         outbody_v->iov_len = body.length;
2613
2614         if (dyn) {
2615                 outdyn_v->iov_base = (void *)dyn->data;
2616                 outdyn_v->iov_len = dyn->length;
2617         } else {
2618                 outdyn_v->iov_base = NULL;
2619                 outdyn_v->iov_len = 0;
2620         }
2621
2622         /* see if we need to recalculate the offset to the next response */
2623         if (next_command_ofs > 0) {
2624                 next_command_ofs  = SMB2_HDR_BODY;
2625                 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
2626                 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
2627         }
2628
2629         if ((next_command_ofs % 8) != 0) {
2630                 size_t pad_size = 8 - (next_command_ofs % 8);
2631                 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
2632                         /*
2633                          * if the dyn buffer is empty
2634                          * we can use it to add padding
2635                          */
2636                         uint8_t *pad;
2637
2638                         pad = talloc_zero_array(req,
2639                                                 uint8_t, pad_size);
2640                         if (pad == NULL) {
2641                                 return smbd_smb2_request_error(req,
2642                                                 NT_STATUS_NO_MEMORY);
2643                         }
2644
2645                         outdyn_v->iov_base = (void *)pad;
2646                         outdyn_v->iov_len = pad_size;
2647                 } else {
2648                         /*
2649                          * For now we copy the dynamic buffer
2650                          * and add the padding to the new buffer
2651                          */
2652                         size_t old_size;
2653                         uint8_t *old_dyn;
2654                         size_t new_size;
2655                         uint8_t *new_dyn;
2656
2657                         old_size = SMBD_SMB2_OUT_DYN_LEN(req);
2658                         old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
2659
2660                         new_size = old_size + pad_size;
2661                         new_dyn = talloc_zero_array(req,
2662                                                uint8_t, new_size);
2663                         if (new_dyn == NULL) {
2664                                 return smbd_smb2_request_error(req,
2665                                                 NT_STATUS_NO_MEMORY);
2666                         }
2667
2668                         memcpy(new_dyn, old_dyn, old_size);
2669                         memset(new_dyn + old_size, 0, pad_size);
2670
2671                         outdyn_v->iov_base = (void *)new_dyn;
2672                         outdyn_v->iov_len = new_size;
2673                 }
2674                 next_command_ofs += pad_size;
2675         }
2676
2677         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
2678
2679         return smbd_smb2_request_reply(req);
2680 }
2681
2682 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
2683                                     NTSTATUS status,
2684                                     DATA_BLOB *info,
2685                                     const char *location)
2686 {
2687         struct smbXsrv_connection *xconn = req->xconn;
2688         DATA_BLOB body;
2689         DATA_BLOB _dyn;
2690         uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2691         size_t unread_bytes = smbd_smb2_unread_bytes(req);
2692
2693         DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n",
2694                   req->current_idx, nt_errstr(status), info ? " +info" : "",
2695                   location));
2696
2697         if (unread_bytes) {
2698                 /* Recvfile error. Drain incoming socket. */
2699                 size_t ret;
2700
2701                 errno = 0;
2702                 ret = drain_socket(xconn->transport.sock, unread_bytes);
2703                 if (ret != unread_bytes) {
2704                         NTSTATUS error;
2705
2706                         if (errno == 0) {
2707                                 error = NT_STATUS_IO_DEVICE_ERROR;
2708                         } else {
2709                                 error = map_nt_error_from_unix_common(errno);
2710                         }
2711
2712                         DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
2713                                   "ret[%u] errno[%d] => %s\n",
2714                                   (unsigned)unread_bytes,
2715                                   (unsigned)ret, errno, nt_errstr(error)));
2716                         return error;
2717                 }
2718         }
2719
2720         body.data = outhdr + SMB2_HDR_BODY;
2721         body.length = 8;
2722         SSVAL(body.data, 0, 9);
2723
2724         if (info) {
2725                 SIVAL(body.data, 0x04, info->length);
2726         } else {
2727                 /* Allocated size of req->out.vector[i].iov_base
2728                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
2729                  * 1 byte without having to do an alloc.
2730                  */
2731                 info = &_dyn;
2732                 info->data = ((uint8_t *)outhdr) +
2733                         OUTVEC_ALLOC_SIZE - 1;
2734                 info->length = 1;
2735                 SCVAL(info->data, 0, 0);
2736         }
2737
2738         /*
2739          * Note: Even if there is an error, continue to process the request.
2740          * per MS-SMB2.
2741          */
2742
2743         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
2744 }
2745
2746
2747 struct smbd_smb2_send_break_state {
2748         struct smbd_smb2_send_queue queue_entry;
2749         uint8_t nbt_hdr[NBT_HDR_SIZE];
2750         uint8_t tf[SMB2_TF_HDR_SIZE];
2751         uint8_t hdr[SMB2_HDR_BODY];
2752         struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
2753         uint8_t body[1];
2754 };
2755
2756 static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
2757                                      struct smbXsrv_session *session,
2758                                      struct smbXsrv_tcon *tcon,
2759                                      const uint8_t *body,
2760                                      size_t body_len)
2761 {
2762         struct smbd_smb2_send_break_state *state;
2763         bool do_encryption = session->global->encryption_required;
2764         uint64_t nonce_high = 0;
2765         uint64_t nonce_low = 0;
2766         NTSTATUS status;
2767         size_t statelen;
2768
2769         if (tcon->global->encryption_required) {
2770                 do_encryption = true;
2771         }
2772
2773         statelen = offsetof(struct smbd_smb2_send_break_state, body) +
2774                 body_len;
2775
2776         state = talloc_zero_size(xconn, statelen);
2777         if (state == NULL) {
2778                 return NT_STATUS_NO_MEMORY;
2779         }
2780         talloc_set_name_const(state, "struct smbd_smb2_send_break_state");
2781
2782         if (do_encryption) {
2783                 nonce_high = session->nonce_high;
2784                 nonce_low = session->nonce_low;
2785
2786                 session->nonce_low += 1;
2787                 if (session->nonce_low == 0) {
2788                         session->nonce_low += 1;
2789                         session->nonce_high += 1;
2790                 }
2791         }
2792
2793         SIVAL(state->tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2794         SBVAL(state->tf, SMB2_TF_NONCE+0, nonce_low);
2795         SBVAL(state->tf, SMB2_TF_NONCE+8, nonce_high);
2796         SBVAL(state->tf, SMB2_TF_SESSION_ID, session->global->session_wire_id);
2797
2798         SIVAL(state->hdr, 0,                            SMB2_MAGIC);
2799         SSVAL(state->hdr, SMB2_HDR_LENGTH,              SMB2_HDR_BODY);
2800         SSVAL(state->hdr, SMB2_HDR_EPOCH,               0);
2801         SIVAL(state->hdr, SMB2_HDR_STATUS,              0);
2802         SSVAL(state->hdr, SMB2_HDR_OPCODE,              SMB2_OP_BREAK);
2803         SSVAL(state->hdr, SMB2_HDR_CREDIT,              0);
2804         SIVAL(state->hdr, SMB2_HDR_FLAGS,               SMB2_HDR_FLAG_REDIRECT);
2805         SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND,        0);
2806         SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID,          UINT64_MAX);
2807         SIVAL(state->hdr, SMB2_HDR_PID,         0);
2808         SIVAL(state->hdr, SMB2_HDR_TID,         0);
2809         SBVAL(state->hdr, SMB2_HDR_SESSION_ID,          0);
2810         memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
2811
2812         state->vector[0] = (struct iovec) {
2813                 .iov_base = state->nbt_hdr,
2814                 .iov_len  = sizeof(state->nbt_hdr)
2815         };
2816
2817         if (do_encryption) {
2818                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
2819                         .iov_base = state->tf,
2820                         .iov_len  = sizeof(state->tf)
2821                 };
2822         } else {
2823                 state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
2824                         .iov_base = NULL,
2825                         .iov_len  = 0
2826                 };
2827         }
2828
2829         state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
2830                 .iov_base = state->hdr,
2831                 .iov_len  = sizeof(state->hdr)
2832         };
2833
2834         memcpy(state->body, body, body_len);
2835
2836         state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
2837                 .iov_base = state->body,
2838                 .iov_len  = body_len /* no sizeof(state->body) .. :-) */
2839         };
2840
2841         /*
2842          * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
2843          */
2844
2845         smb2_setup_nbt_length(state->vector, 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2846
2847         if (do_encryption) {
2848                 DATA_BLOB encryption_key = session->global->encryption_key;
2849
2850                 status = smb2_signing_encrypt_pdu(encryption_key,
2851                                         xconn->protocol,
2852                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2853                                         SMBD_SMB2_NUM_IOV_PER_REQ);
2854                 if (!NT_STATUS_IS_OK(status)) {
2855                         return status;
2856                 }
2857         }
2858
2859         state->queue_entry.mem_ctx = state;
2860         state->queue_entry.vector = state->vector;
2861         state->queue_entry.count = ARRAY_SIZE(state->vector);
2862         DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry, NULL);
2863         xconn->smb2.send_queue_len++;
2864
2865         status = smbd_smb2_flush_send_queue(xconn);
2866         if (!NT_STATUS_IS_OK(status)) {
2867                 return status;
2868         }
2869
2870         return NT_STATUS_OK;
2871 }
2872
2873 NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
2874                                      struct smbXsrv_session *session,
2875                                      struct smbXsrv_tcon *tcon,
2876                                      struct smbXsrv_open *op,
2877                                      uint8_t oplock_level)
2878 {
2879         uint8_t body[0x18];
2880
2881         SSVAL(body, 0x00, sizeof(body));
2882         SCVAL(body, 0x02, oplock_level);
2883         SCVAL(body, 0x03, 0);           /* reserved */
2884         SIVAL(body, 0x04, 0);           /* reserved */
2885         SBVAL(body, 0x08, op->global->open_persistent_id);
2886         SBVAL(body, 0x10, op->global->open_volatile_id);
2887
2888         return smbd_smb2_send_break(xconn, session, tcon, body, sizeof(body));
2889 }
2890
2891 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
2892 {
2893         NTSTATUS status;
2894         uint32_t flags;
2895         uint64_t file_id_persistent;
2896         uint64_t file_id_volatile;
2897         struct smbXsrv_open *op = NULL;
2898         struct files_struct *fsp = NULL;
2899         const uint8_t *body = NULL;
2900
2901         /*
2902          * This is only called with a pktbuf
2903          * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
2904          * bytes
2905          */
2906
2907         if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
2908                 /* Transform header. Cannot recvfile. */
2909                 return false;
2910         }
2911         if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
2912                 /* Not SMB2. Normal error path will cope. */
2913                 return false;
2914         }
2915         if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
2916                 /* Not SMB2. Normal error path will cope. */
2917                 return false;
2918         }
2919         if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
2920                 /* Needs to be a WRITE. */
2921                 return false;
2922         }
2923         if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
2924                 /* Chained. Cannot recvfile. */
2925                 return false;
2926         }
2927         flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
2928         if (flags & SMB2_HDR_FLAG_CHAINED) {
2929                 /* Chained. Cannot recvfile. */
2930                 return false;
2931         }
2932         if (flags & SMB2_HDR_FLAG_SIGNED) {
2933                 /* Signed. Cannot recvfile. */
2934                 return false;
2935         }
2936
2937         body = &state->pktbuf[SMB2_HDR_BODY];
2938
2939         file_id_persistent      = BVAL(body, 0x10);
2940         file_id_volatile        = BVAL(body, 0x18);
2941
2942         status = smb2srv_open_lookup(state->req->xconn,
2943                                      file_id_persistent,
2944                                      file_id_volatile,
2945                                      0, /* now */
2946                                      &op);
2947         if (!NT_STATUS_IS_OK(status)) {
2948                 return false;
2949         }
2950
2951         fsp = op->compat;
2952         if (fsp == NULL) {
2953                 return false;
2954         }
2955         if (fsp->conn == NULL) {
2956                 return false;
2957         }
2958
2959         if (IS_IPC(fsp->conn)) {
2960                 return false;
2961         }
2962         if (IS_PRINT(fsp->conn)) {
2963                 return false;
2964         }
2965
2966         DEBUG(10,("Doing recvfile write len = %u\n",
2967                 (unsigned int)(state->pktfull - state->pktlen)));
2968
2969         return true;
2970 }
2971
2972 static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
2973 {
2974         struct smbd_server_connection *sconn = xconn->client->sconn;
2975         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
2976         size_t max_send_queue_len;
2977         size_t cur_send_queue_len;
2978
2979         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2980                 /*
2981                  * we're not supposed to do any io
2982                  */
2983                 return NT_STATUS_OK;
2984         }
2985
2986         if (state->req != NULL) {
2987                 /*
2988                  * if there is already a tstream_readv_pdu
2989                  * pending, we are done.
2990                  */
2991                 return NT_STATUS_OK;
2992         }
2993
2994         max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
2995         cur_send_queue_len = xconn->smb2.send_queue_len;
2996
2997         if (cur_send_queue_len > max_send_queue_len) {
2998                 /*
2999                  * if we have a lot of requests to send,
3000                  * we wait until they are on the wire until we
3001                  * ask for the next request.
3002                  */
3003                 return NT_STATUS_OK;
3004         }
3005
3006         /* ask for the next request */
3007         ZERO_STRUCTP(state);
3008         state->req = smbd_smb2_request_allocate(xconn);
3009         if (state->req == NULL) {
3010                 return NT_STATUS_NO_MEMORY;
3011         }
3012         state->req->sconn = sconn;
3013         state->req->xconn = xconn;
3014         state->min_recv_size = lp_min_receive_file_size();
3015
3016         TEVENT_FD_READABLE(xconn->transport.fde);
3017
3018         return NT_STATUS_OK;
3019 }
3020
3021 void smbd_smb2_first_negprot(struct smbXsrv_connection *xconn,
3022                              const uint8_t *inpdu, size_t size)
3023 {
3024         struct smbd_server_connection *sconn = xconn->client->sconn;
3025         NTSTATUS status;
3026         struct smbd_smb2_request *req = NULL;
3027
3028         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3029                  (unsigned int)size));
3030
3031         status = smbd_initialize_smb2(xconn);
3032         if (!NT_STATUS_IS_OK(status)) {
3033                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3034                 return;
3035         }
3036
3037         status = smbd_smb2_request_create(xconn, inpdu, size, &req);
3038         if (!NT_STATUS_IS_OK(status)) {
3039                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3040                 return;
3041         }
3042
3043         status = smbd_smb2_request_validate(req);
3044         if (!NT_STATUS_IS_OK(status)) {
3045                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3046                 return;
3047         }
3048
3049         status = smbd_smb2_request_setup_out(req);
3050         if (!NT_STATUS_IS_OK(status)) {
3051                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3052                 return;
3053         }
3054
3055         status = smbd_smb2_request_dispatch(req);
3056         if (!NT_STATUS_IS_OK(status)) {
3057                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3058                 return;
3059         }
3060
3061         status = smbd_smb2_request_next_incoming(xconn);
3062         if (!NT_STATUS_IS_OK(status)) {
3063                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3064                 return;
3065         }
3066
3067         sconn->num_requests++;
3068 }
3069
3070 static int socket_error_from_errno(int ret,
3071                                    int sys_errno,
3072                                    bool *retry)
3073 {
3074         *retry = false;
3075
3076         if (ret >= 0) {
3077                 return 0;
3078         }
3079
3080         if (ret != -1) {
3081                 return EIO;
3082         }
3083
3084         if (sys_errno == 0) {
3085                 return EIO;
3086         }
3087
3088         if (sys_errno == EINTR) {
3089                 *retry = true;
3090                 return sys_errno;
3091         }
3092
3093         if (sys_errno == EINPROGRESS) {
3094                 *retry = true;
3095                 return sys_errno;
3096         }
3097
3098         if (sys_errno == EAGAIN) {
3099                 *retry = true;
3100                 return sys_errno;
3101         }
3102
3103         /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
3104         if (sys_errno == ENOMEM) {
3105                 *retry = true;
3106                 return sys_errno;
3107         }
3108
3109 #ifdef EWOULDBLOCK
3110 #if EWOULDBLOCK != EAGAIN
3111         if (sys_errno == EWOULDBLOCK) {
3112                 *retry = true;
3113                 return sys_errno;
3114         }
3115 #endif
3116 #endif
3117
3118         return sys_errno;
3119 }
3120
3121 static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
3122 {
3123         int ret;
3124         int err;
3125         bool retry;
3126
3127         if (xconn->smb2.send_queue == NULL) {
3128                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3129                 return NT_STATUS_OK;
3130         }
3131
3132         while (xconn->smb2.send_queue != NULL) {
3133                 struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
3134
3135                 if (e->sendfile_header != NULL) {
3136                         NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
3137                         size_t size = 0;
3138                         size_t i = 0;
3139                         uint8_t *buf;
3140
3141                         for (i=0; i < e->count; i++) {
3142                                 size += e->vector[i].iov_len;
3143                         }
3144
3145                         if (size <= e->sendfile_header->length) {
3146                                 buf = e->sendfile_header->data;
3147                         } else {
3148                                 buf = talloc_array(e->mem_ctx, uint8_t, size);
3149                                 if (buf == NULL) {
3150                                         return NT_STATUS_NO_MEMORY;
3151                                 }
3152                         }
3153
3154                         size = 0;
3155                         for (i=0; i < e->count; i++) {
3156                                 memcpy(buf+size,
3157                                        e->vector[i].iov_base,
3158                                        e->vector[i].iov_len);
3159                                 size += e->vector[i].iov_len;
3160                         }
3161
3162                         e->sendfile_header->data = buf;
3163                         e->sendfile_header->length = size;
3164                         e->sendfile_status = &status;
3165                         e->count = 0;
3166
3167                         xconn->smb2.send_queue_len--;
3168                         DLIST_REMOVE(xconn->smb2.send_queue, e);
3169                         /*
3170                          * This triggers the sendfile path via
3171                          * the destructor.
3172                          */
3173                         talloc_free(e->mem_ctx);
3174
3175                         if (!NT_STATUS_IS_OK(status)) {
3176                                 return status;
3177                         }
3178                         continue;
3179                 }
3180
3181                 ret = writev(xconn->transport.sock, e->vector, e->count);
3182                 if (ret == 0) {
3183                         /* propagate end of file */
3184                         return NT_STATUS_INTERNAL_ERROR;
3185                 }
3186                 err = socket_error_from_errno(ret, errno, &retry);
3187                 if (retry) {
3188                         /* retry later */
3189                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3190                         return NT_STATUS_OK;
3191                 }
3192                 if (err != 0) {
3193                         return map_nt_error_from_unix_common(err);
3194                 }
3195                 while (ret > 0) {
3196                         if (ret < e->vector[0].iov_len) {
3197                                 uint8_t *base;
3198                                 base = (uint8_t *)e->vector[0].iov_base;
3199                                 base += ret;
3200                                 e->vector[0].iov_base = (void *)base;
3201                                 e->vector[0].iov_len -= ret;
3202                                 break;
3203                         }
3204                         ret -= e->vector[0].iov_len;
3205                         e->vector += 1;
3206                         e->count -= 1;
3207                 }
3208
3209                 /*
3210                  * there're maybe some empty vectors at the end
3211                  * which we need to skip, otherwise we would get
3212                  * ret == 0 from the readv() call and return EPIPE
3213                  */
3214                 while (e->count > 0) {
3215                         if (e->vector[0].iov_len > 0) {
3216                                 break;
3217                         }
3218                         e->vector += 1;
3219                         e->count -= 1;
3220                 }
3221
3222                 if (e->count > 0) {
3223                         /* we have more to write */
3224                         TEVENT_FD_WRITEABLE(xconn->transport.fde);
3225                         return NT_STATUS_OK;
3226                 }
3227
3228                 xconn->smb2.send_queue_len--;
3229                 DLIST_REMOVE(xconn->smb2.send_queue, e);
3230                 talloc_free(e->mem_ctx);
3231         }
3232
3233         return NT_STATUS_OK;
3234 }
3235
3236 static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
3237                                      uint16_t fde_flags)
3238 {
3239         struct smbd_server_connection *sconn = xconn->client->sconn;
3240         struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
3241         struct smbd_smb2_request *req = NULL;
3242         size_t min_recvfile_size = UINT32_MAX;
3243         int ret;
3244         int err;
3245         bool retry;
3246         NTSTATUS status;
3247         NTTIME now;
3248
3249         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
3250                 /*
3251                  * we're not supposed to do any io
3252                  */
3253                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3254                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
3255                 return NT_STATUS_OK;
3256         }
3257
3258         if (fde_flags & TEVENT_FD_WRITE) {
3259                 status = smbd_smb2_flush_send_queue(xconn);
3260                 if (!NT_STATUS_IS_OK(status)) {
3261                         return status;
3262                 }
3263         }
3264
3265         if (!(fde_flags & TEVENT_FD_READ)) {
3266                 return NT_STATUS_OK;
3267         }
3268
3269         if (state->req == NULL) {
3270                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
3271                 return NT_STATUS_OK;
3272         }
3273
3274 again:
3275         if (!state->hdr.done) {
3276                 state->hdr.done = true;
3277
3278                 state->vector.iov_base = (void *)state->hdr.nbt;
3279                 state->vector.iov_len = NBT_HDR_SIZE;
3280         }
3281
3282         ret = readv(xconn->transport.sock, &state->vector, 1);
3283         if (ret == 0) {
3284                 /* propagate end of file */
3285                 return NT_STATUS_END_OF_FILE;
3286         }
3287         err = socket_error_from_errno(ret, errno, &retry);
3288         if (retry) {
3289                 /* retry later */
3290                 TEVENT_FD_READABLE(xconn->transport.fde);
3291                 return NT_STATUS_OK;
3292         }
3293         if (err != 0) {
3294                 return map_nt_error_from_unix_common(err);
3295         }
3296
3297         if (ret < state->vector.iov_len) {
3298                 uint8_t *base;
3299                 base = (uint8_t *)state->vector.iov_base;
3300                 base += ret;
3301                 state->vector.iov_base = (void *)base;
3302                 state->vector.iov_len -= ret;
3303                 /* we have more to read */
3304                 TEVENT_FD_READABLE(xconn->transport.fde);
3305                 return NT_STATUS_OK;
3306         }
3307
3308         if (state->pktlen > 0) {
3309                 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
3310                         /*
3311                          * Not a possible receivefile write.
3312                          * Read the rest of the data.
3313                          */
3314                         state->doing_receivefile = false;
3315
3316                         state->pktbuf = talloc_realloc(state->req,
3317                                                        state->pktbuf,
3318                                                        uint8_t,
3319                                                        state->pktfull);
3320                         if (state->pktbuf == NULL) {
3321                                 return NT_STATUS_NO_MEMORY;
3322                         }
3323
3324                         state->vector.iov_base = (void *)(state->pktbuf +
3325                                 state->pktlen);
3326                         state->vector.iov_len = (state->pktfull -
3327                                 state->pktlen);
3328
3329                         state->pktlen = state->pktfull;
3330                         goto again;
3331                 }
3332
3333                 /*
3334                  * Either this is a receivefile write so we've
3335                  * done a short read, or if not we have all the data.
3336                  */
3337                 goto got_full;
3338         }
3339
3340         /*
3341          * Now we analyze the NBT header
3342          */
3343         if (state->hdr.nbt[0] != 0x00) {
3344                 state->min_recv_size = 0;
3345         }
3346         state->pktfull = smb2_len(state->hdr.nbt);
3347         if (state->pktfull == 0) {
3348                 goto got_full;
3349         }
3350
3351         if (state->min_recv_size != 0) {
3352                 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3353                 min_recvfile_size += state->min_recv_size;
3354         }
3355
3356         if (state->pktfull > min_recvfile_size) {
3357                 /*
3358                  * Might be a receivefile write. Read the SMB2 HEADER +
3359                  * SMB2_WRITE header first. Set 'doing_receivefile'
3360                  * as we're *attempting* receivefile write. If this
3361                  * turns out not to be a SMB2_WRITE request or otherwise
3362                  * not suitable then we'll just read the rest of the data
3363                  * the next time this function is called.
3364                  */
3365                 state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3366                 state->doing_receivefile = true;
3367         } else {
3368                 state->pktlen = state->pktfull;
3369         }
3370
3371         state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
3372         if (state->pktbuf == NULL) {
3373                 return NT_STATUS_NO_MEMORY;
3374         }
3375
3376         state->vector.iov_base = (void *)state->pktbuf;
3377         state->vector.iov_len = state->pktlen;
3378
3379         goto again;
3380
3381 got_full:
3382
3383         if (state->hdr.nbt[0] != 0x00) {
3384                 DEBUG(1,("ignore NBT[0x%02X] msg\n",
3385                          state->hdr.nbt[0]));
3386
3387                 req = state->req;
3388                 ZERO_STRUCTP(state);
3389                 state->req = req;
3390                 state->min_recv_size = lp_min_receive_file_size();
3391                 req = NULL;
3392                 goto again;
3393         }
3394
3395         req = state->req;
3396         state->req = NULL;
3397
3398         req->request_time = timeval_current();
3399         now = timeval_to_nttime(&req->request_time);
3400
3401         status = smbd_smb2_inbuf_parse_compound(xconn,
3402                                                 now,
3403                                                 state->pktbuf,
3404                                                 state->pktlen,
3405                                                 req,
3406                                                 &req->in.vector,
3407                                                 &req->in.vector_count);
3408         if (!NT_STATUS_IS_OK(status)) {
3409                 return status;
3410         }
3411
3412         if (state->doing_receivefile) {
3413                 req->smb1req = talloc_zero(req, struct smb_request);
3414                 if (req->smb1req == NULL) {
3415                         return NT_STATUS_NO_MEMORY;
3416                 }
3417                 req->smb1req->unread_bytes = state->pktfull - state->pktlen;
3418         }
3419
3420         ZERO_STRUCTP(state);
3421
3422         req->current_idx = 1;
3423
3424         DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
3425                  req->current_idx, req->in.vector_count));
3426
3427         status = smbd_smb2_request_validate(req);
3428         if (!NT_STATUS_IS_OK(status)) {
3429                 return status;
3430         }
3431
3432         status = smbd_smb2_request_setup_out(req);
3433         if (!NT_STATUS_IS_OK(status)) {
3434                 return status;
3435         }
3436
3437         status = smbd_smb2_request_dispatch(req);
3438         if (!NT_STATUS_IS_OK(status)) {
3439                 return status;
3440         }
3441
3442         sconn->num_requests++;
3443
3444         /* The timeout_processing function isn't run nearly
3445            often enough to implement 'max log size' without
3446            overrunning the size of the file by many megabytes.
3447            This is especially true if we are running at debug
3448            level 10.  Checking every 50 SMB2s is a nice
3449            tradeoff of performance vs log file size overrun. */
3450
3451         if ((sconn->num_requests % 50) == 0 &&
3452             need_to_check_log_size()) {
3453                 change_to_root_user();
3454                 check_log_size();
3455         }
3456
3457         status = smbd_smb2_request_next_incoming(xconn);
3458         if (!NT_STATUS_IS_OK(status)) {
3459                 return status;
3460         }
3461
3462         return NT_STATUS_OK;
3463 }
3464
3465 static void smbd_smb2_connection_handler(struct tevent_context *ev,
3466                                          struct tevent_fd *fde,
3467                                          uint16_t flags,
3468                                          void *private_data)
3469 {
3470         struct smbXsrv_connection *xconn =
3471                 talloc_get_type_abort(private_data,
3472                 struct smbXsrv_connection);
3473         NTSTATUS status;
3474
3475         status = smbd_smb2_io_handler(xconn, flags);
3476         if (!NT_STATUS_IS_OK(status)) {
3477                 smbd_server_connection_terminate(xconn, nt_errstr(status));
3478                 return;
3479         }
3480 }