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