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