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