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