lib/util Move bitmap.c to lib/util
[mat/samba.git] / source3 / smbd / smb2_server.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30
31 #define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
32
33 static const char *smb2_names[] = {
34         "SMB2_NEGPROT",
35         "SMB2_SESSSETUP",
36         "SMB2_LOGOFF",
37         "SMB2_TCON",
38         "SMB2_TDIS",
39         "SMB2_CREATE",
40         "SMB2_CLOSE",
41         "SMB2_FLUSH",
42         "SMB2_READ",
43         "SMB2_WRITE",
44         "SMB2_LOCK",
45         "SMB2_IOCTL",
46         "SMB2_CANCEL",
47         "SMB2_KEEPALIVE",
48         "SMB2_FIND",
49         "SMB2_NOTIFY",
50         "SMB2_GETINFO",
51         "SMB2_SETINFO",
52         "SMB2_BREAK"
53 };
54
55 const char *smb2_opcode_name(uint16_t opcode)
56 {
57         if (opcode > 0x12) {
58                 return "Bad SMB2 opcode";
59         }
60         return smb2_names[opcode];
61 }
62
63 static void print_req_vectors(struct smbd_smb2_request *req)
64 {
65         int i;
66
67         for (i = 0; i < req->in.vector_count; i++) {
68                 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
69                         (unsigned int)i,
70                         (unsigned int)req->in.vector[i].iov_len);
71         }
72         for (i = 0; i < req->out.vector_count; i++) {
73                 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
74                         (unsigned int)i,
75                         (unsigned int)req->out.vector[i].iov_len);
76         }
77 }
78
79 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
80 {
81         if (size < (4 + SMB2_HDR_BODY)) {
82                 return false;
83         }
84
85         if (IVAL(inbuf, 4) != SMB2_MAGIC) {
86                 return false;
87         }
88
89         return true;
90 }
91
92 static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *sconn)
93 {
94         NTSTATUS status;
95         int ret;
96
97         TALLOC_FREE(sconn->smb1.fde);
98
99         sconn->smb2.event_ctx = server_event_context();
100
101         sconn->smb2.recv_queue = tevent_queue_create(sconn, "smb2 recv queue");
102         if (sconn->smb2.recv_queue == NULL) {
103                 return NT_STATUS_NO_MEMORY;
104         }
105
106         sconn->smb2.send_queue = tevent_queue_create(sconn, "smb2 send queue");
107         if (sconn->smb2.send_queue == NULL) {
108                 return NT_STATUS_NO_MEMORY;
109         }
110
111         sconn->smb2.sessions.idtree = idr_init(sconn);
112         if (sconn->smb2.sessions.idtree == NULL) {
113                 return NT_STATUS_NO_MEMORY;
114         }
115         sconn->smb2.sessions.limit = 0x0000FFFE;
116         sconn->smb2.sessions.list = NULL;
117         sconn->smb2.seqnum_low = 0;
118         sconn->smb2.credits_granted = 0;
119         sconn->smb2.max_credits = lp_smb2_max_credits();
120         sconn->smb2.credits_bitmap = bitmap_talloc(sconn,
121                         DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR*sconn->smb2.max_credits);
122         if (sconn->smb2.credits_bitmap == NULL) {
123                 return NT_STATUS_NO_MEMORY;
124         }
125
126         ret = tstream_bsd_existing_socket(sconn, sconn->sock,
127                                           &sconn->smb2.stream);
128         if (ret == -1) {
129                 status = map_nt_error_from_unix(errno);
130                 return status;
131         }
132
133         /* Ensure child is set to non-blocking mode */
134         set_blocking(sconn->sock, false);
135         return NT_STATUS_OK;
136 }
137
138 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
139 #define _smb2_setlen(_buf,len) do { \
140         uint8_t *buf = (uint8_t *)_buf; \
141         buf[0] = 0; \
142         buf[1] = ((len)&0xFF0000)>>16; \
143         buf[2] = ((len)&0xFF00)>>8; \
144         buf[3] = (len)&0xFF; \
145 } while (0)
146
147 static void smb2_setup_nbt_length(struct iovec *vector, int count)
148 {
149         size_t len = 0;
150         int i;
151
152         for (i=1; i < count; i++) {
153                 len += vector[i].iov_len;
154         }
155
156         _smb2_setlen(vector[0].iov_base, len);
157 }
158
159 static int smbd_smb2_request_parent_destructor(struct smbd_smb2_request **req)
160 {
161         if (*req) {
162                 (*req)->parent = NULL;
163                 (*req)->mem_pool = NULL;
164         }
165
166         return 0;
167 }
168
169 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
170 {
171         if (req->parent) {
172                 *req->parent = NULL;
173                 talloc_free(req->mem_pool);
174         }
175
176         return 0;
177 }
178
179 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
180 {
181         TALLOC_CTX *mem_pool;
182         struct smbd_smb2_request **parent;
183         struct smbd_smb2_request *req;
184
185 #if 0
186         /* Enable this to find subtle valgrind errors. */
187         mem_pool = talloc_init("smbd_smb2_request_allocate");
188 #else
189         mem_pool = talloc_pool(mem_ctx, 8192);
190 #endif
191         if (mem_pool == NULL) {
192                 return NULL;
193         }
194
195         parent = talloc(mem_pool, struct smbd_smb2_request *);
196         if (parent == NULL) {
197                 talloc_free(mem_pool);
198                 return NULL;
199         }
200
201         req = talloc_zero(parent, struct smbd_smb2_request);
202         if (req == NULL) {
203                 talloc_free(mem_pool);
204                 return NULL;
205         }
206         *parent         = req;
207         req->mem_pool   = mem_pool;
208         req->parent     = parent;
209
210         talloc_set_destructor(parent, smbd_smb2_request_parent_destructor);
211         talloc_set_destructor(req, smbd_smb2_request_destructor);
212
213         return req;
214 }
215
216 static NTSTATUS smbd_smb2_request_create(struct smbd_server_connection *sconn,
217                                          const uint8_t *inbuf, size_t size,
218                                          struct smbd_smb2_request **_req)
219 {
220         struct smbd_smb2_request *req;
221         uint32_t protocol_version;
222         const uint8_t *inhdr = NULL;
223         off_t ofs = 0;
224         uint16_t cmd;
225         uint32_t next_command_ofs;
226
227         if (size < (4 + SMB2_HDR_BODY + 2)) {
228                 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
229                 return NT_STATUS_INVALID_PARAMETER;
230         }
231
232         inhdr = inbuf + 4;
233
234         protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
235         if (protocol_version != SMB2_MAGIC) {
236                 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
237                          protocol_version));
238                 return NT_STATUS_INVALID_PARAMETER;
239         }
240
241         cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
242         if (cmd != SMB2_OP_NEGPROT) {
243                 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
244                          cmd));
245                 return NT_STATUS_INVALID_PARAMETER;
246         }
247
248         next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
249         if (next_command_ofs != 0) {
250                 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
251                          next_command_ofs));
252                 return NT_STATUS_INVALID_PARAMETER;
253         }
254
255         req = smbd_smb2_request_allocate(sconn);
256         if (req == NULL) {
257                 return NT_STATUS_NO_MEMORY;
258         }
259         req->sconn = sconn;
260
261         talloc_steal(req, inbuf);
262
263         req->in.vector = talloc_array(req, struct iovec, 4);
264         if (req->in.vector == NULL) {
265                 TALLOC_FREE(req);
266                 return NT_STATUS_NO_MEMORY;
267         }
268         req->in.vector_count = 4;
269
270         memcpy(req->in.nbt_hdr, inbuf, 4);
271
272         ofs = 0;
273         req->in.vector[0].iov_base      = discard_const_p(void, req->in.nbt_hdr);
274         req->in.vector[0].iov_len       = 4;
275         ofs += req->in.vector[0].iov_len;
276
277         req->in.vector[1].iov_base      = discard_const_p(void, (inbuf + ofs));
278         req->in.vector[1].iov_len       = SMB2_HDR_BODY;
279         ofs += req->in.vector[1].iov_len;
280
281         req->in.vector[2].iov_base      = discard_const_p(void, (inbuf + ofs));
282         req->in.vector[2].iov_len       = SVAL(inbuf, ofs) & 0xFFFE;
283         ofs += req->in.vector[2].iov_len;
284
285         if (ofs > size) {
286                 return NT_STATUS_INVALID_PARAMETER;
287         }
288
289         req->in.vector[3].iov_base      = discard_const_p(void, (inbuf + ofs));
290         req->in.vector[3].iov_len       = size - ofs;
291         ofs += req->in.vector[3].iov_len;
292
293         req->current_idx = 1;
294
295         *_req = req;
296         return NT_STATUS_OK;
297 }
298
299 static bool smb2_validate_message_id(struct smbd_server_connection *sconn,
300                                 const uint8_t *inhdr)
301 {
302         uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
303         struct bitmap *credits_bm = sconn->smb2.credits_bitmap;
304         uint16_t opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
305         unsigned int bitmap_offset;
306
307         if (opcode == SMB2_OP_CANCEL) {
308                 /* SMB2_CANCEL requests by definition resend messageids. */
309                 return true;
310         }
311
312         if (message_id < sconn->smb2.seqnum_low ||
313                         message_id > (sconn->smb2.seqnum_low +
314                         (sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR))) {
315                 DEBUG(0,("smb2_validate_message_id: bad message_id "
316                         "%llu (low = %llu, max = %lu)\n",
317                         (unsigned long long)message_id,
318                         (unsigned long long)sconn->smb2.seqnum_low,
319                         (unsigned long)sconn->smb2.max_credits ));
320                 return false;
321         }
322
323         /* client just used a credit. */
324         SMB_ASSERT(sconn->smb2.credits_granted > 0);
325         sconn->smb2.credits_granted -= 1;
326
327         /* Mark the message_id as seen in the bitmap. */
328         bitmap_offset = (unsigned int)(message_id %
329                         (uint64_t)(sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR));
330         if (bitmap_query(credits_bm, bitmap_offset)) {
331                 DEBUG(0,("smb2_validate_message_id: duplicate message_id "
332                         "%llu (bm offset %u)\n",
333                         (unsigned long long)message_id,
334                         bitmap_offset));
335                 return false;
336         }
337         bitmap_set(credits_bm, bitmap_offset);
338
339         if (message_id == sconn->smb2.seqnum_low + 1) {
340                 /* Move the window forward by all the message_id's
341                    already seen. */
342                 while (bitmap_query(credits_bm, bitmap_offset)) {
343                         DEBUG(10,("smb2_validate_message_id: clearing "
344                                 "id %llu (position %u) from bitmap\n",
345                                 (unsigned long long)(sconn->smb2.seqnum_low + 1),
346                                 bitmap_offset ));
347                         bitmap_clear(credits_bm, bitmap_offset);
348                         sconn->smb2.seqnum_low += 1;
349                         bitmap_offset = (bitmap_offset + 1) %
350                                 (sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR);
351                 }
352         }
353
354         return true;
355 }
356
357 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
358 {
359         int count;
360         int idx;
361         bool compound_related = false;
362
363         count = req->in.vector_count;
364
365         if (count < 4) {
366                 /* It's not a SMB2 request */
367                 return NT_STATUS_INVALID_PARAMETER;
368         }
369
370         for (idx=1; idx < count; idx += 3) {
371                 const uint8_t *inhdr = NULL;
372                 uint32_t flags;
373
374                 if (req->in.vector[idx].iov_len != SMB2_HDR_BODY) {
375                         return NT_STATUS_INVALID_PARAMETER;
376                 }
377
378                 if (req->in.vector[idx+1].iov_len < 2) {
379                         return NT_STATUS_INVALID_PARAMETER;
380                 }
381
382                 inhdr = (const uint8_t *)req->in.vector[idx].iov_base;
383
384                 /* Check the SMB2 header */
385                 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
386                         return NT_STATUS_INVALID_PARAMETER;
387                 }
388
389                 if (!smb2_validate_message_id(req->sconn, inhdr)) {
390                         return NT_STATUS_INVALID_PARAMETER;
391                 }
392
393                 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
394                 if (idx == 1) {
395                         /*
396                          * the 1st request should never have the
397                          * SMB2_HDR_FLAG_CHAINED flag set
398                          */
399                         if (flags & SMB2_HDR_FLAG_CHAINED) {
400                                 req->next_status = NT_STATUS_INVALID_PARAMETER;
401                                 return NT_STATUS_OK;
402                         }
403                 } else if (idx == 4) {
404                         /*
405                          * the 2nd request triggers related vs. unrelated
406                          * compounded requests
407                          */
408                         if (flags & SMB2_HDR_FLAG_CHAINED) {
409                                 compound_related = true;
410                         }
411                 } else if (idx > 4) {
412 #if 0
413                         /*
414                          * It seems the this tests are wrong
415                          * see the SMB2-COMPOUND test
416                          */
417
418                         /*
419                          * all other requests should match the 2nd one
420                          */
421                         if (flags & SMB2_HDR_FLAG_CHAINED) {
422                                 if (!compound_related) {
423                                         req->next_status =
424                                                 NT_STATUS_INVALID_PARAMETER;
425                                         return NT_STATUS_OK;
426                                 }
427                         } else {
428                                 if (compound_related) {
429                                         req->next_status =
430                                                 NT_STATUS_INVALID_PARAMETER;
431                                         return NT_STATUS_OK;
432                                 }
433                         }
434 #endif
435                 }
436         }
437
438         return NT_STATUS_OK;
439 }
440
441 static void smb2_set_operation_credit(struct smbd_server_connection *sconn,
442                         const struct iovec *in_vector,
443                         struct iovec *out_vector)
444 {
445         uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
446         uint16_t credits_requested = 0;
447         uint16_t credits_granted = 0;
448
449         if (in_vector != NULL) {
450                 const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
451                 credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
452         }
453
454         SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
455
456         /* Remember what we gave out. */
457         credits_granted = MIN(credits_requested, (sconn->smb2.max_credits -
458                 sconn->smb2.credits_granted));
459
460         if (credits_granted == 0 && sconn->smb2.credits_granted == 0) {
461                 /* First negprot packet, or ensure the client credits can
462                    never drop to zero. */
463                 credits_granted = 1;
464         }
465
466         SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
467         sconn->smb2.credits_granted += credits_granted;
468
469         DEBUG(10,("smb2_set_operation_credit: requested %u, "
470                 "granted %u, total granted %u\n",
471                 (unsigned int)credits_requested,
472                 (unsigned int)credits_granted,
473                 (unsigned int)sconn->smb2.credits_granted ));
474 }
475
476 static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
477                                 struct smbd_smb2_request *outreq)
478 {
479         int count, idx;
480
481         count = outreq->out.vector_count;
482
483         for (idx=1; idx < count; idx += 3) {
484                 smb2_set_operation_credit(outreq->sconn,
485                         &inreq->in.vector[idx],
486                         &outreq->out.vector[idx]);
487         }
488 }
489
490 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
491 {
492         struct iovec *vector;
493         int count;
494         int idx;
495
496         count = req->in.vector_count;
497         vector = talloc_zero_array(req, struct iovec, count);
498         if (vector == NULL) {
499                 return NT_STATUS_NO_MEMORY;
500         }
501
502         vector[0].iov_base      = req->out.nbt_hdr;
503         vector[0].iov_len       = 4;
504         SIVAL(req->out.nbt_hdr, 0, 0);
505
506         for (idx=1; idx < count; idx += 3) {
507                 const uint8_t *inhdr = NULL;
508                 uint32_t in_flags;
509                 uint8_t *outhdr = NULL;
510                 uint8_t *outbody = NULL;
511                 uint32_t next_command_ofs = 0;
512                 struct iovec *current = &vector[idx];
513
514                 if ((idx + 3) < count) {
515                         /* we have a next command -
516                          * setup for the error case. */
517                         next_command_ofs = SMB2_HDR_BODY + 9;
518                 }
519
520                 inhdr = (const uint8_t *)req->in.vector[idx].iov_base;
521                 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
522
523                 outhdr = talloc_zero_array(vector, uint8_t,
524                                       OUTVEC_ALLOC_SIZE);
525                 if (outhdr == NULL) {
526                         return NT_STATUS_NO_MEMORY;
527                 }
528
529                 outbody = outhdr + SMB2_HDR_BODY;
530
531                 current[0].iov_base     = (void *)outhdr;
532                 current[0].iov_len      = SMB2_HDR_BODY;
533
534                 current[1].iov_base     = (void *)outbody;
535                 current[1].iov_len      = 8;
536
537                 current[2].iov_base     = NULL;
538                 current[2].iov_len      = 0;
539
540                 /* setup the SMB2 header */
541                 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID,     SMB2_MAGIC);
542                 SSVAL(outhdr, SMB2_HDR_LENGTH,          SMB2_HDR_BODY);
543                 SSVAL(outhdr, SMB2_HDR_EPOCH,           0);
544                 SIVAL(outhdr, SMB2_HDR_STATUS,
545                       NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
546                 SSVAL(outhdr, SMB2_HDR_OPCODE,
547                       SVAL(inhdr, SMB2_HDR_OPCODE));
548                 SIVAL(outhdr, SMB2_HDR_FLAGS,
549                       IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
550                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND,    next_command_ofs);
551                 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
552                       BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
553                 SIVAL(outhdr, SMB2_HDR_PID,
554                       IVAL(inhdr, SMB2_HDR_PID));
555                 SIVAL(outhdr, SMB2_HDR_TID,
556                       IVAL(inhdr, SMB2_HDR_TID));
557                 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
558                       BVAL(inhdr, SMB2_HDR_SESSION_ID));
559                 memset(outhdr + SMB2_HDR_SIGNATURE, 0, 16);
560
561                 /* setup error body header */
562                 SSVAL(outbody, 0x00, 0x08 + 1);
563                 SSVAL(outbody, 0x02, 0);
564                 SIVAL(outbody, 0x04, 0);
565         }
566
567         req->out.vector = vector;
568         req->out.vector_count = count;
569
570         /* setup the length of the NBT packet */
571         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
572
573         DLIST_ADD_END(req->sconn->smb2.requests, req, struct smbd_smb2_request *);
574
575         return NT_STATUS_OK;
576 }
577
578 void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
579                                          const char *reason,
580                                          const char *location)
581 {
582         DEBUG(10,("smbd_server_connection_terminate_ex: reason[%s] at %s\n",
583                   reason, location));
584         exit_server_cleanly(reason);
585 }
586
587 static bool dup_smb2_vec3(TALLOC_CTX *ctx,
588                         struct iovec *outvec,
589                         const struct iovec *srcvec)
590 {
591         /* vec[0] is always boilerplate and must
592          * be allocated with size OUTVEC_ALLOC_SIZE. */
593
594         outvec[0].iov_base = talloc_memdup(ctx,
595                                 srcvec[0].iov_base,
596                                 OUTVEC_ALLOC_SIZE);
597         if (!outvec[0].iov_base) {
598                 return false;
599         }
600         outvec[0].iov_len = SMB2_HDR_BODY;
601
602         /*
603          * If this is a "standard" vec[1] of length 8,
604          * pointing to srcvec[0].iov_base + SMB2_HDR_BODY,
605          * then duplicate this. Else use talloc_memdup().
606          */
607
608         if (srcvec[1].iov_len == 8 &&
609                         srcvec[1].iov_base ==
610                                 ((uint8_t *)srcvec[0].iov_base) +
611                                         SMB2_HDR_BODY) {
612                 outvec[1].iov_base = ((uint8_t *)outvec[0].iov_base) +
613                                         SMB2_HDR_BODY;
614                 outvec[1].iov_len = 8;
615         } else {
616                 outvec[1].iov_base = talloc_memdup(ctx,
617                                 srcvec[1].iov_base,
618                                 srcvec[1].iov_len);
619                 if (!outvec[1].iov_base) {
620                         return false;
621                 }
622                 outvec[1].iov_len = srcvec[1].iov_len;
623         }
624
625         /*
626          * If this is a "standard" vec[2] of length 1,
627          * pointing to srcvec[0].iov_base + (OUTVEC_ALLOC_SIZE - 1)
628          * then duplicate this. Else use talloc_memdup().
629          */
630
631         if (srcvec[2].iov_base &&
632                         srcvec[2].iov_len) {
633                 if (srcvec[2].iov_base ==
634                                 ((uint8_t *)srcvec[0].iov_base) +
635                                         (OUTVEC_ALLOC_SIZE - 1) &&
636                                 srcvec[2].iov_len == 1) {
637                         /* Common SMB2 error packet case. */
638                         outvec[2].iov_base = ((uint8_t *)outvec[0].iov_base) +
639                                 (OUTVEC_ALLOC_SIZE - 1);
640                 } else {
641                         outvec[2].iov_base = talloc_memdup(ctx,
642                                         srcvec[2].iov_base,
643                                         srcvec[2].iov_len);
644                         if (!outvec[2].iov_base) {
645                                 return false;
646                         }
647                 }
648                 outvec[2].iov_len = srcvec[2].iov_len;
649         } else {
650                 outvec[2].iov_base = NULL;
651                 outvec[2].iov_len = 0;
652         }
653         return true;
654 }
655
656 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
657 {
658         struct smbd_smb2_request *newreq = NULL;
659         struct iovec *outvec = NULL;
660         int count = req->out.vector_count;
661         int i;
662
663         newreq = smbd_smb2_request_allocate(req->sconn);
664         if (!newreq) {
665                 return NULL;
666         }
667
668         newreq->sconn = req->sconn;
669         newreq->session = req->session;
670         newreq->do_signing = req->do_signing;
671         newreq->current_idx = req->current_idx;
672         newreq->async = false;
673         newreq->cancelled = false;
674         /* Note we are leaving:
675                 ->tcon
676                 ->smb1req
677                 ->compat_chain_fsp
678            uninitialized as NULL here as
679            they're not used in the interim
680            response code. JRA. */
681
682         outvec = talloc_zero_array(newreq, struct iovec, count);
683         if (!outvec) {
684                 TALLOC_FREE(newreq);
685                 return NULL;
686         }
687         newreq->out.vector = outvec;
688         newreq->out.vector_count = count;
689
690         /* Setup the outvec's identically to req. */
691         outvec[0].iov_base = newreq->out.nbt_hdr;
692         outvec[0].iov_len = 4;
693         memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
694
695         /* Setup the vectors identically to the ones in req. */
696         for (i = 1; i < count; i += 3) {
697                 if (!dup_smb2_vec3(outvec, &outvec[i], &req->out.vector[i])) {
698                         break;
699                 }
700         }
701
702         if (i < count) {
703                 /* Alloc failed. */
704                 TALLOC_FREE(newreq);
705                 return NULL;
706         }
707
708         smb2_setup_nbt_length(newreq->out.vector,
709                 newreq->out.vector_count);
710
711         return newreq;
712 }
713
714 static void smbd_smb2_request_writev_done(struct tevent_req *subreq);
715
716 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
717 {
718         int i = 0;
719         uint8_t *outhdr = NULL;
720         struct smbd_smb2_request *nreq = NULL;
721
722         /* Create a new smb2 request we'll use
723            for the interim return. */
724         nreq = dup_smb2_req(req);
725         if (!nreq) {
726                 return NT_STATUS_NO_MEMORY;
727         }
728
729         /* Lose the last 3 out vectors. They're the
730            ones we'll be using for the async reply. */
731         nreq->out.vector_count -= 3;
732
733         smb2_setup_nbt_length(nreq->out.vector,
734                 nreq->out.vector_count);
735
736         /* Step back to the previous reply. */
737         i = nreq->current_idx - 3;
738         outhdr = (uint8_t *)nreq->out.vector[i].iov_base;
739         /* And end the chain. */
740         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
741
742         /* Calculate outgoing credits */
743         smb2_calculate_credits(req, nreq);
744
745         /* Re-sign if needed. */
746         if (nreq->do_signing) {
747                 NTSTATUS status;
748                 status = smb2_signing_sign_pdu(nreq->session->session_key,
749                                         &nreq->out.vector[i], 3);
750                 if (!NT_STATUS_IS_OK(status)) {
751                         return status;
752                 }
753         }
754         if (DEBUGLEVEL >= 10) {
755                 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
756                         (unsigned int)nreq->current_idx );
757                 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
758                         (unsigned int)nreq->out.vector_count );
759                 print_req_vectors(nreq);
760         }
761         nreq->subreq = tstream_writev_queue_send(nreq,
762                                         nreq->sconn->smb2.event_ctx,
763                                         nreq->sconn->smb2.stream,
764                                         nreq->sconn->smb2.send_queue,
765                                         nreq->out.vector,
766                                         nreq->out.vector_count);
767
768         if (nreq->subreq == NULL) {
769                 return NT_STATUS_NO_MEMORY;
770         }
771
772         tevent_req_set_callback(nreq->subreq,
773                         smbd_smb2_request_writev_done,
774                         nreq);
775
776         return NT_STATUS_OK;
777 }
778
779 struct smbd_smb2_request_pending_state {
780         struct smbd_server_connection *sconn;
781         uint8_t buf[4 + SMB2_HDR_BODY + 0x08 + 1];
782         struct iovec vector[3];
783 };
784
785 static void smbd_smb2_request_pending_writev_done(struct tevent_req *subreq)
786 {
787         struct smbd_smb2_request_pending_state *state =
788                 tevent_req_callback_data(subreq,
789                         struct smbd_smb2_request_pending_state);
790         struct smbd_server_connection *sconn = state->sconn;
791         int ret;
792         int sys_errno;
793
794         ret = tstream_writev_queue_recv(subreq, &sys_errno);
795         TALLOC_FREE(subreq);
796         if (ret == -1) {
797                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
798                 smbd_server_connection_terminate(sconn, nt_errstr(status));
799                 return;
800         }
801
802         TALLOC_FREE(state);
803 }
804
805 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
806                                          struct tevent_req *subreq)
807 {
808         NTSTATUS status;
809         struct smbd_smb2_request_pending_state *state = NULL;
810         int i = req->current_idx;
811         uint8_t *reqhdr = NULL;
812         uint8_t *hdr = NULL;
813         uint8_t *body = NULL;
814         uint32_t flags = 0;
815         uint64_t message_id = 0;
816         uint64_t async_id = 0;
817         struct iovec *outvec = NULL;
818
819         if (!tevent_req_is_in_progress(subreq)) {
820                 return NT_STATUS_OK;
821         }
822
823         req->subreq = subreq;
824         subreq = NULL;
825
826         if (req->async) {
827                 /* We're already async. */
828                 return NT_STATUS_OK;
829         }
830
831         if (req->in.vector_count > i + 3) {
832                 /*
833                  * We're trying to go async in a compound
834                  * request chain. This is not allowed.
835                  * Cancel the outstanding request.
836                  */
837                 tevent_req_cancel(req->subreq);
838                 return smbd_smb2_request_error(req,
839                         NT_STATUS_INSUFFICIENT_RESOURCES);
840         }
841
842         if (DEBUGLEVEL >= 10) {
843                 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
844                         (unsigned int)req->current_idx );
845                 print_req_vectors(req);
846         }
847
848         if (req->out.vector_count > 4) {
849                 /* This is a compound reply. We
850                  * must do an interim response
851                  * followed by the async response
852                  * to match W2K8R2.
853                  */
854                 status = smb2_send_async_interim_response(req);
855                 if (!NT_STATUS_IS_OK(status)) {
856                         return status;
857                 }
858         }
859
860         /* Don't return an intermediate packet on a pipe read/write. */
861         if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) {
862                 return NT_STATUS_OK;
863         }
864
865         reqhdr = (uint8_t *)req->out.vector[i].iov_base;
866         flags = (IVAL(reqhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
867         message_id = BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
868         async_id = message_id; /* keep it simple for now... */
869
870         /*
871          * What we send is identical to a smbd_smb2_request_error
872          * packet with an error status of STATUS_PENDING. Make use
873          * of this fact sometime when refactoring. JRA.
874          */
875
876         state = talloc_zero(req->sconn, struct smbd_smb2_request_pending_state);
877         if (state == NULL) {
878                 return NT_STATUS_NO_MEMORY;
879         }
880         state->sconn = req->sconn;
881
882         state->vector[0].iov_base = (void *)state->buf;
883         state->vector[0].iov_len = 4;
884
885         state->vector[1].iov_base = state->buf + 4;
886         state->vector[1].iov_len = SMB2_HDR_BODY;
887
888         state->vector[2].iov_base = state->buf + 4 + SMB2_HDR_BODY;
889         state->vector[2].iov_len = 9;
890
891         smb2_setup_nbt_length(state->vector, 3);
892
893         hdr = (uint8_t *)state->vector[1].iov_base;
894         body = (uint8_t *)state->vector[2].iov_base;
895
896         SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
897         SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
898         SSVAL(hdr, SMB2_HDR_EPOCH, 0);
899         SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
900         SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(reqhdr, SMB2_HDR_OPCODE));
901
902         SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
903         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
904         SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
905         SBVAL(hdr, SMB2_HDR_PID, async_id);
906         SBVAL(hdr, SMB2_HDR_SESSION_ID,
907                 BVAL(reqhdr, SMB2_HDR_SESSION_ID));
908         memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
909
910         SSVAL(body, 0x00, 0x08 + 1);
911
912         SCVAL(body, 0x02, 0);
913         SCVAL(body, 0x03, 0);
914         SIVAL(body, 0x04, 0);
915         /* Match W2K8R2... */
916         SCVAL(body, 0x08, 0x21);
917
918         /* Ensure we correctly go through crediting. Grant
919            the credits now, and zero credits on the final
920            response. */
921         smb2_set_operation_credit(req->sconn,
922                         &req->in.vector[i],
923                         &state->vector[1]);
924
925         if (req->do_signing) {
926                 status = smb2_signing_sign_pdu(req->session->session_key,
927                                         &state->vector[1], 2);
928                 if (!NT_STATUS_IS_OK(status)) {
929                         return status;
930                 }
931         }
932
933         subreq = tstream_writev_queue_send(state,
934                                         req->sconn->smb2.event_ctx,
935                                         req->sconn->smb2.stream,
936                                         req->sconn->smb2.send_queue,
937                                         state->vector,
938                                         3);
939
940         if (subreq == NULL) {
941                 return NT_STATUS_NO_MEMORY;
942         }
943
944         tevent_req_set_callback(subreq,
945                         smbd_smb2_request_pending_writev_done,
946                         state);
947
948         /* Note we're going async with this request. */
949         req->async = true;
950
951         /*
952          * Now manipulate req so that the outstanding async request
953          * is the only one left in the struct smbd_smb2_request.
954          */
955
956         if (req->current_idx == 1) {
957                 /* There was only one. */
958                 goto out;
959         }
960
961         /* Re-arrange the in.vectors. */
962         req->in.vector[1] = req->in.vector[i];
963         req->in.vector[2] = req->in.vector[i+1];
964         req->in.vector[3] = req->in.vector[i+2];
965         req->in.vector_count = 4;
966         /* Reset the new in size. */
967         smb2_setup_nbt_length(req->in.vector, 4);
968
969         /* Now recreate the out.vectors. */
970         outvec = talloc_zero_array(req, struct iovec, 4);
971         if (!outvec) {
972                 return NT_STATUS_NO_MEMORY;
973         }
974
975         /* 0 is always boilerplate and must
976          * be of size 4 for the length field. */
977
978         outvec[0].iov_base = req->out.nbt_hdr;
979         outvec[0].iov_len = 4;
980         SIVAL(req->out.nbt_hdr, 0, 0);
981
982         if (!dup_smb2_vec3(outvec, &outvec[1], &req->out.vector[i])) {
983                 return NT_STATUS_NO_MEMORY;
984         }
985
986         TALLOC_FREE(req->out.vector);
987
988         req->out.vector = outvec;
989
990         req->current_idx = 1;
991         req->out.vector_count = 4;
992
993   out:
994
995         smb2_setup_nbt_length(req->out.vector,
996                 req->out.vector_count);
997
998         /* Ensure our final reply matches the interim one. */
999         reqhdr = (uint8_t *)req->out.vector[1].iov_base;
1000         SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1001         SBVAL(reqhdr, SMB2_HDR_PID, async_id);
1002
1003         {
1004                 const uint8_t *inhdr =
1005                         (const uint8_t *)req->in.vector[1].iov_base;
1006                 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1007                         "going async\n",
1008                         smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
1009                         (unsigned long long)async_id ));
1010         }
1011         return NT_STATUS_OK;
1012 }
1013
1014 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
1015 {
1016         struct smbd_server_connection *sconn = req->sconn;
1017         struct smbd_smb2_request *cur;
1018         const uint8_t *inhdr;
1019         int i = req->current_idx;
1020         uint32_t flags;
1021         uint64_t search_message_id;
1022         uint64_t search_async_id;
1023         uint64_t found_id;
1024
1025         inhdr = (const uint8_t *)req->in.vector[i].iov_base;
1026
1027         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1028         search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1029         search_async_id = BVAL(inhdr, SMB2_HDR_PID);
1030
1031         /*
1032          * we don't need the request anymore
1033          * cancel requests never have a response
1034          */
1035         DLIST_REMOVE(req->sconn->smb2.requests, req);
1036         TALLOC_FREE(req);
1037
1038         for (cur = sconn->smb2.requests; cur; cur = cur->next) {
1039                 const uint8_t *outhdr;
1040                 uint64_t message_id;
1041                 uint64_t async_id;
1042
1043                 i = cur->current_idx;
1044
1045                 outhdr = (const uint8_t *)cur->out.vector[i].iov_base;
1046
1047                 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1048                 async_id = BVAL(outhdr, SMB2_HDR_PID);
1049
1050                 if (flags & SMB2_HDR_FLAG_ASYNC) {
1051                         if (search_async_id == async_id) {
1052                                 found_id = async_id;
1053                                 break;
1054                         }
1055                 } else {
1056                         if (search_message_id == message_id) {
1057                                 found_id = message_id;
1058                                 break;
1059                         }
1060                 }
1061         }
1062
1063         if (cur && cur->subreq) {
1064                 inhdr = (const uint8_t *)cur->in.vector[i].iov_base;
1065                 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1066                         "cancel opcode[%s] mid %llu\n",
1067                         smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
1068                         (unsigned long long)found_id ));
1069                 tevent_req_cancel(cur->subreq);
1070         }
1071
1072         return NT_STATUS_OK;
1073 }
1074
1075 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
1076 {
1077         const uint8_t *inhdr;
1078         int i = req->current_idx;
1079         uint16_t opcode;
1080         uint32_t flags;
1081         uint64_t mid;
1082         NTSTATUS status;
1083         NTSTATUS session_status;
1084         uint32_t allowed_flags;
1085         NTSTATUS return_value;
1086
1087         inhdr = (const uint8_t *)req->in.vector[i].iov_base;
1088
1089         /* TODO: verify more things */
1090
1091         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1092         opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
1093         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1094         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
1095                 smb2_opcode_name(opcode),
1096                 (unsigned long long)mid));
1097
1098         allowed_flags = SMB2_HDR_FLAG_CHAINED |
1099                         SMB2_HDR_FLAG_SIGNED |
1100                         SMB2_HDR_FLAG_DFS;
1101         if (opcode == SMB2_OP_CANCEL) {
1102                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
1103         }
1104         if ((flags & ~allowed_flags) != 0) {
1105                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
1106         }
1107
1108         session_status = smbd_smb2_request_check_session(req);
1109
1110         req->do_signing = false;
1111         if (flags & SMB2_HDR_FLAG_SIGNED) {
1112                 if (!NT_STATUS_IS_OK(session_status)) {
1113                         return smbd_smb2_request_error(req, session_status);
1114                 }
1115
1116                 req->do_signing = true;
1117                 status = smb2_signing_check_pdu(req->session->session_key,
1118                                                 &req->in.vector[i], 3);
1119                 if (!NT_STATUS_IS_OK(status)) {
1120                         return smbd_smb2_request_error(req, status);
1121                 }
1122         } else if (req->session && req->session->do_signing) {
1123                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
1124         }
1125
1126         if (flags & SMB2_HDR_FLAG_CHAINED) {
1127                 /*
1128                  * This check is mostly for giving the correct error code
1129                  * for compounded requests.
1130                  *
1131                  * TODO: we may need to move this after the session
1132                  *       and tcon checks.
1133                  */
1134                 if (!NT_STATUS_IS_OK(req->next_status)) {
1135                         return smbd_smb2_request_error(req, req->next_status);
1136                 }
1137         } else {
1138                 req->compat_chain_fsp = NULL;
1139         }
1140
1141         switch (opcode) {
1142         case SMB2_OP_NEGPROT:
1143                 /* This call needs to be run as root */
1144                 change_to_root_user();
1145
1146                 {
1147                         START_PROFILE(smb2_negprot);
1148                         return_value = smbd_smb2_request_process_negprot(req);
1149                         END_PROFILE(smb2_negprot);
1150                 }
1151                 break;
1152
1153         case SMB2_OP_SESSSETUP:
1154                 /* This call needs to be run as root */
1155                 change_to_root_user();
1156
1157                 {
1158                         START_PROFILE(smb2_sesssetup);
1159                         return_value = smbd_smb2_request_process_sesssetup(req);
1160                         END_PROFILE(smb2_sesssetup);
1161                 }
1162                 break;
1163
1164         case SMB2_OP_LOGOFF:
1165                 if (!NT_STATUS_IS_OK(session_status)) {
1166                         return_value = smbd_smb2_request_error(req, session_status);
1167                         break;
1168                 }
1169
1170                 /* This call needs to be run as root */
1171                 change_to_root_user();
1172
1173                 {
1174                         START_PROFILE(smb2_logoff);
1175                         return_value = smbd_smb2_request_process_logoff(req);
1176                         END_PROFILE(smb2_logoff);
1177                 }
1178                 break;
1179
1180         case SMB2_OP_TCON:
1181                 if (!NT_STATUS_IS_OK(session_status)) {
1182                         return_value = smbd_smb2_request_error(req, session_status);
1183                         break;
1184                 }
1185
1186                 /* This call needs to be run as root */
1187                 change_to_root_user();
1188
1189                 {
1190                         START_PROFILE(smb2_tcon);
1191                         return_value = smbd_smb2_request_process_tcon(req);
1192                         END_PROFILE(smb2_tcon);
1193                 }
1194                 break;
1195
1196         case SMB2_OP_TDIS:
1197                 if (!NT_STATUS_IS_OK(session_status)) {
1198                         return_value = smbd_smb2_request_error(req, session_status);
1199                         break;
1200                 }
1201                 status = smbd_smb2_request_check_tcon(req);
1202                 if (!NT_STATUS_IS_OK(status)) {
1203                         return_value = smbd_smb2_request_error(req, status);
1204                         break;
1205                 }
1206                 /* This call needs to be run as root */
1207                 change_to_root_user();
1208
1209
1210                 {
1211                         START_PROFILE(smb2_tdis);
1212                         return_value = smbd_smb2_request_process_tdis(req);
1213                         END_PROFILE(smb2_tdis);
1214                 }
1215                 break;
1216
1217         case SMB2_OP_CREATE:
1218                 if (!NT_STATUS_IS_OK(session_status)) {
1219                         return_value = smbd_smb2_request_error(req, session_status);
1220                         break;
1221                 }
1222                 status = smbd_smb2_request_check_tcon(req);
1223                 if (!NT_STATUS_IS_OK(status)) {
1224                         return_value = smbd_smb2_request_error(req, status);
1225                         break;
1226                 }
1227
1228                 {
1229                         START_PROFILE(smb2_create);
1230                         return_value = smbd_smb2_request_process_create(req);
1231                         END_PROFILE(smb2_create);
1232                 }
1233                 break;
1234
1235         case SMB2_OP_CLOSE:
1236                 if (!NT_STATUS_IS_OK(session_status)) {
1237                         return_value = smbd_smb2_request_error(req, session_status);
1238                         break;
1239                 }
1240                 status = smbd_smb2_request_check_tcon(req);
1241                 if (!NT_STATUS_IS_OK(status)) {
1242                         return_value = smbd_smb2_request_error(req, status);
1243                         break;
1244                 }
1245
1246                 {
1247                         START_PROFILE(smb2_close);
1248                         return_value = smbd_smb2_request_process_close(req);
1249                         END_PROFILE(smb2_close);
1250                 }
1251                 break;
1252
1253         case SMB2_OP_FLUSH:
1254                 if (!NT_STATUS_IS_OK(session_status)) {
1255                         return_value = smbd_smb2_request_error(req, session_status);
1256                         break;
1257                 }
1258                 status = smbd_smb2_request_check_tcon(req);
1259                 if (!NT_STATUS_IS_OK(status)) {
1260                         return_value = smbd_smb2_request_error(req, status);
1261                         break;
1262                 }
1263
1264                 {
1265                         START_PROFILE(smb2_flush);
1266                         return_value = smbd_smb2_request_process_flush(req);
1267                         END_PROFILE(smb2_flush);
1268                 }
1269                 break;
1270
1271         case SMB2_OP_READ:
1272                 if (!NT_STATUS_IS_OK(session_status)) {
1273                         return_value = smbd_smb2_request_error(req, session_status);
1274                         break;
1275                 }
1276                 status = smbd_smb2_request_check_tcon(req);
1277                 if (!NT_STATUS_IS_OK(status)) {
1278                         return_value = smbd_smb2_request_error(req, status);
1279                         break;
1280                 }
1281
1282                 {
1283                         START_PROFILE(smb2_read);
1284                         return_value = smbd_smb2_request_process_read(req);
1285                         END_PROFILE(smb2_read);
1286                 }
1287                 break;
1288
1289         case SMB2_OP_WRITE:
1290                 if (!NT_STATUS_IS_OK(session_status)) {
1291                         return_value = smbd_smb2_request_error(req, session_status);
1292                         break;
1293                 }
1294                 status = smbd_smb2_request_check_tcon(req);
1295                 if (!NT_STATUS_IS_OK(status)) {
1296                         return_value = smbd_smb2_request_error(req, status);
1297                         break;
1298                 }
1299
1300                 {
1301                         START_PROFILE(smb2_write);
1302                         return_value = smbd_smb2_request_process_write(req);
1303                         END_PROFILE(smb2_write);
1304                 }
1305                 break;
1306
1307         case SMB2_OP_LOCK:
1308                 if (!NT_STATUS_IS_OK(session_status)) {
1309                         /* Too ugly to live ? JRA. */
1310                         if (NT_STATUS_EQUAL(session_status,NT_STATUS_USER_SESSION_DELETED)) {
1311                                 session_status = NT_STATUS_FILE_CLOSED;
1312                         }
1313                         return_value = smbd_smb2_request_error(req, session_status);
1314                         break;
1315                 }
1316                 status = smbd_smb2_request_check_tcon(req);
1317                 if (!NT_STATUS_IS_OK(status)) {
1318                         /* Too ugly to live ? JRA. */
1319                         if (NT_STATUS_EQUAL(status,NT_STATUS_NETWORK_NAME_DELETED)) {
1320                                 status = NT_STATUS_FILE_CLOSED;
1321                         }
1322                         return_value = smbd_smb2_request_error(req, status);
1323                         break;
1324                 }
1325
1326                 {
1327                         START_PROFILE(smb2_lock);
1328                         return_value = smbd_smb2_request_process_lock(req);
1329                         END_PROFILE(smb2_lock);
1330                 }
1331                 break;
1332
1333         case SMB2_OP_IOCTL:
1334                 if (!NT_STATUS_IS_OK(session_status)) {
1335                         return_value = smbd_smb2_request_error(req, session_status);
1336                         break;
1337                 }
1338                 status = smbd_smb2_request_check_tcon(req);
1339                 if (!NT_STATUS_IS_OK(status)) {
1340                         return_value = smbd_smb2_request_error(req, status);
1341                         break;
1342                 }
1343
1344                 {
1345                         START_PROFILE(smb2_ioctl);
1346                         return_value = smbd_smb2_request_process_ioctl(req);
1347                         END_PROFILE(smb2_ioctl);
1348                 }
1349                 break;
1350
1351         case SMB2_OP_CANCEL:
1352                 /* This call needs to be run as root */
1353                 change_to_root_user();
1354
1355                 {
1356                         START_PROFILE(smb2_cancel);
1357                         return_value = smbd_smb2_request_process_cancel(req);
1358                         END_PROFILE(smb2_cancel);
1359                 }
1360                 break;
1361
1362         case SMB2_OP_KEEPALIVE:
1363                 /* This call needs to be run as root */
1364                 change_to_root_user();
1365
1366                 {
1367                         START_PROFILE(smb2_keepalive);
1368                         return_value = smbd_smb2_request_process_keepalive(req);
1369                         END_PROFILE(smb2_keepalive);
1370                 }
1371                 break;
1372
1373         case SMB2_OP_FIND:
1374                 if (!NT_STATUS_IS_OK(session_status)) {
1375                         return_value = smbd_smb2_request_error(req, session_status);
1376                         break;
1377                 }
1378                 status = smbd_smb2_request_check_tcon(req);
1379                 if (!NT_STATUS_IS_OK(status)) {
1380                         return_value = smbd_smb2_request_error(req, status);
1381                         break;
1382                 }
1383
1384                 {
1385                         START_PROFILE(smb2_find);
1386                         return_value = smbd_smb2_request_process_find(req);
1387                         END_PROFILE(smb2_find);
1388                 }
1389                 break;
1390
1391         case SMB2_OP_NOTIFY:
1392                 if (!NT_STATUS_IS_OK(session_status)) {
1393                         return_value = smbd_smb2_request_error(req, session_status);
1394                         break;
1395                 }
1396                 status = smbd_smb2_request_check_tcon(req);
1397                 if (!NT_STATUS_IS_OK(status)) {
1398                         return_value = smbd_smb2_request_error(req, status);
1399                         break;
1400                 }
1401
1402                 {
1403                         START_PROFILE(smb2_notify);
1404                         return_value = smbd_smb2_request_process_notify(req);
1405                         END_PROFILE(smb2_notify);
1406                 }
1407                 break;
1408
1409         case SMB2_OP_GETINFO:
1410                 if (!NT_STATUS_IS_OK(session_status)) {
1411                         return_value = smbd_smb2_request_error(req, session_status);
1412                         break;
1413                 }
1414                 status = smbd_smb2_request_check_tcon(req);
1415                 if (!NT_STATUS_IS_OK(status)) {
1416                         return_value = smbd_smb2_request_error(req, status);
1417                         break;
1418                 }
1419
1420                 {
1421                         START_PROFILE(smb2_getinfo);
1422                         return_value = smbd_smb2_request_process_getinfo(req);
1423                         END_PROFILE(smb2_getinfo);
1424                 }
1425                 break;
1426
1427         case SMB2_OP_SETINFO:
1428                 if (!NT_STATUS_IS_OK(session_status)) {
1429                         return_value = smbd_smb2_request_error(req, session_status);
1430                         break;
1431                 }
1432                 status = smbd_smb2_request_check_tcon(req);
1433                 if (!NT_STATUS_IS_OK(status)) {
1434                         return_value = smbd_smb2_request_error(req, status);
1435                         break;
1436                 }
1437
1438                 {
1439                         START_PROFILE(smb2_setinfo);
1440                         return_value = smbd_smb2_request_process_setinfo(req);
1441                         END_PROFILE(smb2_setinfo);
1442                 }
1443                 break;
1444
1445         case SMB2_OP_BREAK:
1446                 if (!NT_STATUS_IS_OK(session_status)) {
1447                         return_value = smbd_smb2_request_error(req, session_status);
1448                         break;
1449                 }
1450                 status = smbd_smb2_request_check_tcon(req);
1451                 if (!NT_STATUS_IS_OK(status)) {
1452                         return_value = smbd_smb2_request_error(req, status);
1453                         break;
1454                 }
1455
1456                 {
1457                         START_PROFILE(smb2_break);
1458                         return_value = smbd_smb2_request_process_break(req);
1459                         END_PROFILE(smb2_break);
1460                 }
1461                 break;
1462
1463         default:
1464                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
1465                 break;
1466         }
1467         return return_value;
1468 }
1469
1470 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
1471 {
1472         struct tevent_req *subreq;
1473         int i = req->current_idx;
1474
1475         req->subreq = NULL;
1476
1477         req->current_idx += 3;
1478
1479         if (req->current_idx < req->out.vector_count) {
1480                 /*
1481                  * We must process the remaining compound
1482                  * SMB2 requests before any new incoming SMB2
1483                  * requests. This is because incoming SMB2
1484                  * requests may include a cancel for a
1485                  * compound request we haven't processed
1486                  * yet.
1487                  */
1488                 struct tevent_immediate *im = tevent_create_immediate(req);
1489                 if (!im) {
1490                         return NT_STATUS_NO_MEMORY;
1491                 }
1492                 tevent_schedule_immediate(im,
1493                                         req->sconn->smb2.event_ctx,
1494                                         smbd_smb2_request_dispatch_immediate,
1495                                         req);
1496                 return NT_STATUS_OK;
1497         }
1498
1499         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1500
1501         /* Set credit for this operation (zero credits if this
1502            is a final reply for an async operation). */
1503         smb2_set_operation_credit(req->sconn,
1504                         req->async ? NULL : &req->in.vector[i],
1505                         &req->out.vector[i]);
1506
1507         if (req->do_signing) {
1508                 NTSTATUS status;
1509                 status = smb2_signing_sign_pdu(req->session->session_key,
1510                                                &req->out.vector[i], 3);
1511                 if (!NT_STATUS_IS_OK(status)) {
1512                         return status;
1513                 }
1514         }
1515
1516         if (DEBUGLEVEL >= 10) {
1517                 dbgtext("smbd_smb2_request_reply: sending...\n");
1518                 print_req_vectors(req);
1519         }
1520
1521         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
1522         if (req->out.vector_count == 4 &&
1523                         req->out.vector[3].iov_base == NULL &&
1524                         req->out.vector[3].iov_len != 0) {
1525                 /* Dynamic part is NULL. Chop it off,
1526                    We're going to send it via sendfile. */
1527                 req->out.vector_count -= 1;
1528         }
1529
1530         subreq = tstream_writev_queue_send(req,
1531                                            req->sconn->smb2.event_ctx,
1532                                            req->sconn->smb2.stream,
1533                                            req->sconn->smb2.send_queue,
1534                                            req->out.vector,
1535                                            req->out.vector_count);
1536         if (subreq == NULL) {
1537                 return NT_STATUS_NO_MEMORY;
1538         }
1539         tevent_req_set_callback(subreq, smbd_smb2_request_writev_done, req);
1540         /*
1541          * We're done with this request -
1542          * move it off the "being processed" queue.
1543          */
1544         DLIST_REMOVE(req->sconn->smb2.requests, req);
1545
1546         return NT_STATUS_OK;
1547 }
1548
1549 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
1550                                         struct tevent_immediate *im,
1551                                         void *private_data)
1552 {
1553         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
1554                                         struct smbd_smb2_request);
1555         struct smbd_server_connection *sconn = req->sconn;
1556         NTSTATUS status;
1557
1558         TALLOC_FREE(im);
1559
1560         if (DEBUGLEVEL >= 10) {
1561                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
1562                         req->current_idx, req->in.vector_count));
1563                 print_req_vectors(req);
1564         }
1565
1566         status = smbd_smb2_request_dispatch(req);
1567         if (!NT_STATUS_IS_OK(status)) {
1568                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1569                 return;
1570         }
1571 }
1572
1573 static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
1574 {
1575         struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
1576                                         struct smbd_smb2_request);
1577         struct smbd_server_connection *sconn = req->sconn;
1578         int ret;
1579         int sys_errno;
1580
1581         ret = tstream_writev_queue_recv(subreq, &sys_errno);
1582         TALLOC_FREE(subreq);
1583         TALLOC_FREE(req);
1584         if (ret == -1) {
1585                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
1586                 DEBUG(2,("smbd_smb2_request_writev_done: client write error %s\n",
1587                         nt_errstr(status)));
1588                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1589                 return;
1590         }
1591 }
1592
1593 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
1594                                    NTSTATUS status,
1595                                    DATA_BLOB body, DATA_BLOB *dyn,
1596                                    const char *location)
1597 {
1598         uint8_t *outhdr;
1599         int i = req->current_idx;
1600         uint32_t next_command_ofs;
1601
1602         DEBUG(10,("smbd_smb2_request_done_ex: "
1603                   "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
1604                   i, nt_errstr(status), (unsigned int)body.length,
1605                   dyn ? "yes": "no",
1606                   (unsigned int)(dyn ? dyn->length : 0),
1607                   location));
1608
1609         if (body.length < 2) {
1610                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
1611         }
1612
1613         if ((body.length % 2) != 0) {
1614                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
1615         }
1616
1617         outhdr = (uint8_t *)req->out.vector[i].iov_base;
1618
1619         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
1620         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
1621
1622         req->out.vector[i+1].iov_base = (void *)body.data;
1623         req->out.vector[i+1].iov_len = body.length;
1624
1625         if (dyn) {
1626                 req->out.vector[i+2].iov_base   = (void *)dyn->data;
1627                 req->out.vector[i+2].iov_len    = dyn->length;
1628         } else {
1629                 req->out.vector[i+2].iov_base = NULL;
1630                 req->out.vector[i+2].iov_len = 0;
1631         }
1632
1633         /* see if we need to recalculate the offset to the next response */
1634         if (next_command_ofs > 0) {
1635                 next_command_ofs  = SMB2_HDR_BODY;
1636                 next_command_ofs += req->out.vector[i+1].iov_len;
1637                 next_command_ofs += req->out.vector[i+2].iov_len;
1638         }
1639
1640         if ((next_command_ofs % 8) != 0) {
1641                 size_t pad_size = 8 - (next_command_ofs % 8);
1642                 if (req->out.vector[i+2].iov_len == 0) {
1643                         /*
1644                          * if the dyn buffer is empty
1645                          * we can use it to add padding
1646                          */
1647                         uint8_t *pad;
1648
1649                         pad = talloc_zero_array(req->out.vector,
1650                                                 uint8_t, pad_size);
1651                         if (pad == NULL) {
1652                                 return smbd_smb2_request_error(req,
1653                                                 NT_STATUS_NO_MEMORY);
1654                         }
1655
1656                         req->out.vector[i+2].iov_base = (void *)pad;
1657                         req->out.vector[i+2].iov_len = pad_size;
1658                 } else {
1659                         /*
1660                          * For now we copy the dynamic buffer
1661                          * and add the padding to the new buffer
1662                          */
1663                         size_t old_size;
1664                         uint8_t *old_dyn;
1665                         size_t new_size;
1666                         uint8_t *new_dyn;
1667
1668                         old_size = req->out.vector[i+2].iov_len;
1669                         old_dyn = (uint8_t *)req->out.vector[i+2].iov_base;
1670
1671                         new_size = old_size + pad_size;
1672                         new_dyn = talloc_zero_array(req->out.vector,
1673                                                uint8_t, new_size);
1674                         if (new_dyn == NULL) {
1675                                 return smbd_smb2_request_error(req,
1676                                                 NT_STATUS_NO_MEMORY);
1677                         }
1678
1679                         memcpy(new_dyn, old_dyn, old_size);
1680                         memset(new_dyn + old_size, 0, pad_size);
1681
1682                         req->out.vector[i+2].iov_base = (void *)new_dyn;
1683                         req->out.vector[i+2].iov_len = new_size;
1684                 }
1685                 next_command_ofs += pad_size;
1686         }
1687
1688         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1689
1690         return smbd_smb2_request_reply(req);
1691 }
1692
1693 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
1694                                     NTSTATUS status,
1695                                     DATA_BLOB *info,
1696                                     const char *location)
1697 {
1698         DATA_BLOB body;
1699         int i = req->current_idx;
1700         uint8_t *outhdr = (uint8_t *)req->out.vector[i].iov_base;
1701
1702         DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n",
1703                   i, nt_errstr(status), info ? " +info" : "",
1704                   location));
1705
1706         body.data = outhdr + SMB2_HDR_BODY;
1707         body.length = 8;
1708         SSVAL(body.data, 0, 9);
1709
1710         if (info) {
1711                 SIVAL(body.data, 0x04, info->length);
1712         } else {
1713                 /* Allocated size of req->out.vector[i].iov_base
1714                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
1715                  * 1 byte without having to do an alloc.
1716                  */
1717                 info = talloc_zero_array(req->out.vector,
1718                                         DATA_BLOB,
1719                                         1);
1720                 if (!info) {
1721                         return NT_STATUS_NO_MEMORY;
1722                 }
1723                 info->data = ((uint8_t *)outhdr) +
1724                         OUTVEC_ALLOC_SIZE - 1;
1725                 info->length = 1;
1726                 SCVAL(info->data, 0, 0);
1727         }
1728
1729         /*
1730          * if a request fails, all other remaining
1731          * compounded requests should fail too
1732          */
1733         req->next_status = NT_STATUS_INVALID_PARAMETER;
1734
1735         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
1736 }
1737
1738
1739 struct smbd_smb2_send_oplock_break_state {
1740         struct smbd_server_connection *sconn;
1741         uint8_t buf[4 + SMB2_HDR_BODY + 0x18];
1742         struct iovec vector;
1743 };
1744
1745 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq);
1746
1747 NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
1748                                      uint64_t file_id_persistent,
1749                                      uint64_t file_id_volatile,
1750                                      uint8_t oplock_level)
1751 {
1752         struct smbd_smb2_send_oplock_break_state *state;
1753         struct tevent_req *subreq;
1754         uint8_t *hdr;
1755         uint8_t *body;
1756
1757         state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
1758         if (state == NULL) {
1759                 return NT_STATUS_NO_MEMORY;
1760         }
1761         state->sconn = sconn;
1762
1763         state->vector.iov_base = (void *)state->buf;
1764         state->vector.iov_len = sizeof(state->buf);
1765
1766         _smb2_setlen(state->buf, sizeof(state->buf) - 4);
1767         hdr = state->buf + 4;
1768         body = hdr + SMB2_HDR_BODY;
1769
1770         SIVAL(hdr, 0,                           SMB2_MAGIC);
1771         SSVAL(hdr, SMB2_HDR_LENGTH,             SMB2_HDR_BODY);
1772         SSVAL(hdr, SMB2_HDR_EPOCH,              0);
1773         SIVAL(hdr, SMB2_HDR_STATUS,             0);
1774         SSVAL(hdr, SMB2_HDR_OPCODE,             SMB2_OP_BREAK);
1775         SSVAL(hdr, SMB2_HDR_CREDIT,             0);
1776         SIVAL(hdr, SMB2_HDR_FLAGS,              SMB2_HDR_FLAG_REDIRECT);
1777         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND,       0);
1778         SBVAL(hdr, SMB2_HDR_MESSAGE_ID,         UINT64_MAX);
1779         SIVAL(hdr, SMB2_HDR_PID,                0);
1780         SIVAL(hdr, SMB2_HDR_TID,                0);
1781         SBVAL(hdr, SMB2_HDR_SESSION_ID,         0);
1782         memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
1783
1784         SSVAL(body, 0x00, 0x18);
1785
1786         SCVAL(body, 0x02, oplock_level);
1787         SCVAL(body, 0x03, 0);           /* reserved */
1788         SIVAL(body, 0x04, 0);           /* reserved */
1789         SBVAL(body, 0x08, file_id_persistent);
1790         SBVAL(body, 0x10, file_id_volatile);
1791
1792         subreq = tstream_writev_queue_send(state,
1793                                            sconn->smb2.event_ctx,
1794                                            sconn->smb2.stream,
1795                                            sconn->smb2.send_queue,
1796                                            &state->vector, 1);
1797         if (subreq == NULL) {
1798                 return NT_STATUS_NO_MEMORY;
1799         }
1800         tevent_req_set_callback(subreq,
1801                                 smbd_smb2_oplock_break_writev_done,
1802                                 state);
1803
1804         return NT_STATUS_OK;
1805 }
1806
1807 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq)
1808 {
1809         struct smbd_smb2_send_oplock_break_state *state =
1810                 tevent_req_callback_data(subreq,
1811                 struct smbd_smb2_send_oplock_break_state);
1812         struct smbd_server_connection *sconn = state->sconn;
1813         int ret;
1814         int sys_errno;
1815
1816         ret = tstream_writev_queue_recv(subreq, &sys_errno);
1817         TALLOC_FREE(subreq);
1818         if (ret == -1) {
1819                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
1820                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1821                 return;
1822         }
1823
1824         TALLOC_FREE(state);
1825 }
1826
1827 struct smbd_smb2_request_read_state {
1828         size_t missing;
1829         bool asked_for_header;
1830         struct smbd_smb2_request *smb2_req;
1831 };
1832
1833 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
1834                                          void *private_data,
1835                                          TALLOC_CTX *mem_ctx,
1836                                          struct iovec **_vector,
1837                                          size_t *_count);
1838 static void smbd_smb2_request_read_done(struct tevent_req *subreq);
1839
1840 static struct tevent_req *smbd_smb2_request_read_send(TALLOC_CTX *mem_ctx,
1841                                         struct tevent_context *ev,
1842                                         struct smbd_server_connection *sconn)
1843 {
1844         struct tevent_req *req;
1845         struct smbd_smb2_request_read_state *state;
1846         struct tevent_req *subreq;
1847
1848         req = tevent_req_create(mem_ctx, &state,
1849                                 struct smbd_smb2_request_read_state);
1850         if (req == NULL) {
1851                 return NULL;
1852         }
1853         state->missing = 0;
1854         state->asked_for_header = false;
1855
1856         state->smb2_req = smbd_smb2_request_allocate(state);
1857         if (tevent_req_nomem(state->smb2_req, req)) {
1858                 return tevent_req_post(req, ev);
1859         }
1860         state->smb2_req->sconn = sconn;
1861
1862         subreq = tstream_readv_pdu_queue_send(state, ev, sconn->smb2.stream,
1863                                               sconn->smb2.recv_queue,
1864                                               smbd_smb2_request_next_vector,
1865                                               state);
1866         if (tevent_req_nomem(subreq, req)) {
1867                 return tevent_req_post(req, ev);
1868         }
1869         tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
1870
1871         return req;
1872 }
1873
1874 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
1875                                          void *private_data,
1876                                          TALLOC_CTX *mem_ctx,
1877                                          struct iovec **_vector,
1878                                          size_t *_count)
1879 {
1880         struct smbd_smb2_request_read_state *state =
1881                 talloc_get_type_abort(private_data,
1882                 struct smbd_smb2_request_read_state);
1883         struct smbd_smb2_request *req = state->smb2_req;
1884         struct iovec *vector;
1885         int idx = req->in.vector_count;
1886         size_t len = 0;
1887         uint8_t *buf = NULL;
1888
1889         if (req->in.vector_count == 0) {
1890                 /*
1891                  * first we need to get the NBT header
1892                  */
1893                 req->in.vector = talloc_array(req, struct iovec,
1894                                               req->in.vector_count + 1);
1895                 if (req->in.vector == NULL) {
1896                         return -1;
1897                 }
1898                 req->in.vector_count += 1;
1899
1900                 req->in.vector[idx].iov_base    = (void *)req->in.nbt_hdr;
1901                 req->in.vector[idx].iov_len     = 4;
1902
1903                 vector = talloc_array(mem_ctx, struct iovec, 1);
1904                 if (vector == NULL) {
1905                         return -1;
1906                 }
1907
1908                 vector[0] = req->in.vector[idx];
1909
1910                 *_vector = vector;
1911                 *_count = 1;
1912                 return 0;
1913         }
1914
1915         if (req->in.vector_count == 1) {
1916                 /*
1917                  * Now we analyze the NBT header
1918                  */
1919                 state->missing = smb2_len(req->in.vector[0].iov_base);
1920
1921                 if (state->missing == 0) {
1922                         /* if there're no remaining bytes, we're done */
1923                         *_vector = NULL;
1924                         *_count = 0;
1925                         return 0;
1926                 }
1927
1928                 req->in.vector = talloc_realloc(req, req->in.vector,
1929                                                 struct iovec,
1930                                                 req->in.vector_count + 1);
1931                 if (req->in.vector == NULL) {
1932                         return -1;
1933                 }
1934                 req->in.vector_count += 1;
1935
1936                 if (CVAL(req->in.vector[0].iov_base, 0) != 0) {
1937                         /*
1938                          * it's a special NBT message,
1939                          * so get all remaining bytes
1940                          */
1941                         len = state->missing;
1942                 } else if (state->missing < (SMB2_HDR_BODY + 2)) {
1943                         /*
1944                          * it's an invalid message, just read what we can get
1945                          * and let the caller handle the error
1946                          */
1947                         len = state->missing;
1948                 } else {
1949                         /*
1950                          * We assume it's a SMB2 request,
1951                          * and we first get the header and the
1952                          * first 2 bytes (the struct size) of the body
1953                          */
1954                         len = SMB2_HDR_BODY + 2;
1955
1956                         state->asked_for_header = true;
1957                 }
1958
1959                 state->missing -= len;
1960
1961                 buf = talloc_array(req->in.vector, uint8_t, len);
1962                 if (buf == NULL) {
1963                         return -1;
1964                 }
1965
1966                 req->in.vector[idx].iov_base    = (void *)buf;
1967                 req->in.vector[idx].iov_len     = len;
1968
1969                 vector = talloc_array(mem_ctx, struct iovec, 1);
1970                 if (vector == NULL) {
1971                         return -1;
1972                 }
1973
1974                 vector[0] = req->in.vector[idx];
1975
1976                 *_vector = vector;
1977                 *_count = 1;
1978                 return 0;
1979         }
1980
1981         if (state->missing == 0) {
1982                 /* if there're no remaining bytes, we're done */
1983                 *_vector = NULL;
1984                 *_count = 0;
1985                 return 0;
1986         }
1987
1988         if (state->asked_for_header) {
1989                 const uint8_t *hdr;
1990                 size_t full_size;
1991                 size_t next_command_ofs;
1992                 size_t body_size;
1993                 uint8_t *body;
1994                 size_t dyn_size;
1995                 uint8_t *dyn;
1996                 bool invalid = false;
1997
1998                 state->asked_for_header = false;
1999
2000                 /*
2001                  * We got the SMB2 header and the first 2 bytes
2002                  * of the body. We fix the size to just the header
2003                  * and manually copy the 2 first bytes to the body section
2004                  */
2005                 req->in.vector[idx-1].iov_len = SMB2_HDR_BODY;
2006                 hdr = (const uint8_t *)req->in.vector[idx-1].iov_base;
2007
2008                 /* allocate vectors for body and dynamic areas */
2009                 req->in.vector = talloc_realloc(req, req->in.vector,
2010                                                 struct iovec,
2011                                                 req->in.vector_count + 2);
2012                 if (req->in.vector == NULL) {
2013                         return -1;
2014                 }
2015                 req->in.vector_count += 2;
2016
2017                 full_size = state->missing + SMB2_HDR_BODY + 2;
2018                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
2019                 body_size = SVAL(hdr, SMB2_HDR_BODY);
2020
2021                 if (next_command_ofs != 0) {
2022                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
2023                                 /*
2024                                  * this is invalid, just return a zero
2025                                  * body and let the caller deal with the error
2026                                  */
2027                                 invalid = true;
2028                         } else if (next_command_ofs > full_size) {
2029                                 /*
2030                                  * this is invalid, just return a zero
2031                                  * body and let the caller deal with the error
2032                                  */
2033                                 invalid = true;
2034                         } else {
2035                                 full_size = next_command_ofs;
2036                         }
2037                 }
2038
2039                 if (!invalid) {
2040                         if (body_size < 2) {
2041                                 /*
2042                                  * this is invalid, just return a zero
2043                                  * body and let the caller deal with the error
2044                                  */
2045                                 invalid = true;
2046                         }
2047
2048                         /*
2049                          * Mask out the lowest bit, the "dynamic" part
2050                          * of body_size.
2051                          */
2052                         body_size &= ~1;
2053
2054                         if (body_size > (full_size - SMB2_HDR_BODY)) {
2055                                 /*
2056                                  * this is invalid, just return a zero
2057                                  * body and let the caller deal with the error
2058                                  */
2059                                 invalid = true;
2060                         }
2061                 }
2062
2063                 if (invalid) {
2064                         /* the caller should check this */
2065                         body_size = 2;
2066                 }
2067
2068                 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
2069
2070                 state->missing -= (body_size - 2) + dyn_size;
2071
2072                 body = talloc_array(req->in.vector, uint8_t, body_size);
2073                 if (body == NULL) {
2074                         return -1;
2075                 }
2076
2077                 dyn = talloc_array(req->in.vector, uint8_t, dyn_size);
2078                 if (dyn == NULL) {
2079                         return -1;
2080                 }
2081
2082                 req->in.vector[idx].iov_base    = (void *)body;
2083                 req->in.vector[idx].iov_len     = body_size;
2084                 req->in.vector[idx+1].iov_base  = (void *)dyn;
2085                 req->in.vector[idx+1].iov_len   = dyn_size;
2086
2087                 vector = talloc_array(mem_ctx, struct iovec, 2);
2088                 if (vector == NULL) {
2089                         return -1;
2090                 }
2091
2092                 /*
2093                  * the first 2 bytes of the body were already fetched
2094                  * together with the header
2095                  */
2096                 memcpy(body, hdr + SMB2_HDR_BODY, 2);
2097                 vector[0].iov_base = body + 2;
2098                 vector[0].iov_len = body_size - 2;
2099
2100                 vector[1] = req->in.vector[idx+1];
2101
2102                 *_vector = vector;
2103                 *_count = 2;
2104                 return 0;
2105         }
2106
2107         /*
2108          * when we endup here, we're looking for a new SMB2 request
2109          * next. And we ask for its header and the first 2 bytes of
2110          * the body (like we did for the first SMB2 request).
2111          */
2112
2113         req->in.vector = talloc_realloc(req, req->in.vector,
2114                                         struct iovec,
2115                                         req->in.vector_count + 1);
2116         if (req->in.vector == NULL) {
2117                 return -1;
2118         }
2119         req->in.vector_count += 1;
2120
2121         /*
2122          * We assume it's a SMB2 request,
2123          * and we first get the header and the
2124          * first 2 bytes (the struct size) of the body
2125          */
2126         len = SMB2_HDR_BODY + 2;
2127
2128         if (len > state->missing) {
2129                 /* let the caller handle the error */
2130                 len = state->missing;
2131         }
2132
2133         state->missing -= len;
2134         state->asked_for_header = true;
2135
2136         buf = talloc_array(req->in.vector, uint8_t, len);
2137         if (buf == NULL) {
2138                 return -1;
2139         }
2140
2141         req->in.vector[idx].iov_base    = (void *)buf;
2142         req->in.vector[idx].iov_len     = len;
2143
2144         vector = talloc_array(mem_ctx, struct iovec, 1);
2145         if (vector == NULL) {
2146                 return -1;
2147         }
2148
2149         vector[0] = req->in.vector[idx];
2150
2151         *_vector = vector;
2152         *_count = 1;
2153         return 0;
2154 }
2155
2156 static void smbd_smb2_request_read_done(struct tevent_req *subreq)
2157 {
2158         struct tevent_req *req =
2159                 tevent_req_callback_data(subreq,
2160                 struct tevent_req);
2161         int ret;
2162         int sys_errno;
2163         NTSTATUS status;
2164
2165         ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
2166         if (ret == -1) {
2167                 status = map_nt_error_from_unix(sys_errno);
2168                 tevent_req_nterror(req, status);
2169                 return;
2170         }
2171
2172         tevent_req_done(req);
2173 }
2174
2175 static NTSTATUS smbd_smb2_request_read_recv(struct tevent_req *req,
2176                                             TALLOC_CTX *mem_ctx,
2177                                             struct smbd_smb2_request **_smb2_req)
2178 {
2179         struct smbd_smb2_request_read_state *state =
2180                 tevent_req_data(req,
2181                 struct smbd_smb2_request_read_state);
2182         NTSTATUS status;
2183
2184         if (tevent_req_is_nterror(req, &status)) {
2185                 tevent_req_received(req);
2186                 return status;
2187         }
2188
2189         talloc_steal(mem_ctx, state->smb2_req->mem_pool);
2190         *_smb2_req = state->smb2_req;
2191         tevent_req_received(req);
2192         return NT_STATUS_OK;
2193 }
2194
2195 static void smbd_smb2_request_incoming(struct tevent_req *subreq);
2196
2197 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
2198                              const uint8_t *inbuf, size_t size)
2199 {
2200         NTSTATUS status;
2201         struct smbd_smb2_request *req = NULL;
2202         struct tevent_req *subreq;
2203
2204         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
2205                  (unsigned int)size));
2206
2207         status = smbd_initialize_smb2(sconn);
2208         if (!NT_STATUS_IS_OK(status)) {
2209                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2210                 return;
2211         }
2212
2213         status = smbd_smb2_request_create(sconn, inbuf, size, &req);
2214         if (!NT_STATUS_IS_OK(status)) {
2215                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2216                 return;
2217         }
2218
2219         status = smbd_smb2_request_setup_out(req);
2220         if (!NT_STATUS_IS_OK(status)) {
2221                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2222                 return;
2223         }
2224
2225         status = smbd_smb2_request_dispatch(req);
2226         if (!NT_STATUS_IS_OK(status)) {
2227                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2228                 return;
2229         }
2230
2231         /* ask for the next request */
2232         subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn);
2233         if (subreq == NULL) {
2234                 smbd_server_connection_terminate(sconn, "no memory for reading");
2235                 return;
2236         }
2237         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
2238
2239         sconn->num_requests++;
2240 }
2241
2242 static void smbd_smb2_request_incoming(struct tevent_req *subreq)
2243 {
2244         struct smbd_server_connection *sconn = tevent_req_callback_data(subreq,
2245                                                struct smbd_server_connection);
2246         NTSTATUS status;
2247         struct smbd_smb2_request *req = NULL;
2248
2249         status = smbd_smb2_request_read_recv(subreq, sconn, &req);
2250         TALLOC_FREE(subreq);
2251         if (!NT_STATUS_IS_OK(status)) {
2252                 DEBUG(2,("smbd_smb2_request_incoming: client read error %s\n",
2253                         nt_errstr(status)));
2254                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2255                 return;
2256         }
2257
2258         if (req->in.nbt_hdr[0] != 0x00) {
2259                 DEBUG(1,("smbd_smb2_request_incoming: ignore NBT[0x%02X] msg\n",
2260                          req->in.nbt_hdr[0]));
2261                 TALLOC_FREE(req);
2262                 goto next;
2263         }
2264
2265         req->current_idx = 1;
2266
2267         DEBUG(10,("smbd_smb2_request_incoming: idx[%d] of %d vectors\n",
2268                  req->current_idx, req->in.vector_count));
2269
2270         status = smbd_smb2_request_validate(req);
2271         if (!NT_STATUS_IS_OK(status)) {
2272                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2273                 return;
2274         }
2275
2276         status = smbd_smb2_request_setup_out(req);
2277         if (!NT_STATUS_IS_OK(status)) {
2278                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2279                 return;
2280         }
2281
2282         status = smbd_smb2_request_dispatch(req);
2283         if (!NT_STATUS_IS_OK(status)) {
2284                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2285                 return;
2286         }
2287
2288 next:
2289         /* ask for the next request (this constructs the main loop) */
2290         subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn);
2291         if (subreq == NULL) {
2292                 smbd_server_connection_terminate(sconn, "no memory for reading");
2293                 return;
2294         }
2295         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
2296
2297         sconn->num_requests++;
2298
2299         /* The timeout_processing function isn't run nearly
2300            often enough to implement 'max log size' without
2301            overrunning the size of the file by many megabytes.
2302            This is especially true if we are running at debug
2303            level 10.  Checking every 50 SMB2s is a nice
2304            tradeoff of performance vs log file size overrun. */
2305
2306         if ((sconn->num_requests % 50) == 0 &&
2307             need_to_check_log_size()) {
2308                 change_to_root_user();
2309                 check_log_size();
2310         }
2311 }