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