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