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