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