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