Remove the compound_related_in_progress state from the smb2 global state.
[metze/samba/wip.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 very high credit charge.
761          *
762          * TODO: scale up depending on 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         struct timeval defer_endtime;
1276         uint8_t *outhdr = NULL;
1277         uint32_t flags;
1278
1279         if (!tevent_req_is_in_progress(subreq)) {
1280                 return NT_STATUS_OK;
1281         }
1282
1283         req->subreq = subreq;
1284         subreq = NULL;
1285
1286         if (req->async_te) {
1287                 /* We're already async. */
1288                 return NT_STATUS_OK;
1289         }
1290
1291         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1292         flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1293         if (flags & SMB2_HDR_FLAG_ASYNC) {
1294                 /* We're already async. */
1295                 return NT_STATUS_OK;
1296         }
1297
1298         if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
1299                 /*
1300                  * We're trying to go async in a compound
1301                  * request chain.
1302                  * This is only allowed for opens that
1303                  * cause an oplock break, otherwise it
1304                  * is not allowed. See [MS-SMB2].pdf
1305                  * note <194> on Section 3.3.5.2.7.
1306                  */
1307                 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1308
1309                 if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
1310                         /*
1311                          * Cancel the outstanding request.
1312                          */
1313                         bool ok = tevent_req_cancel(req->subreq);
1314                         if (ok) {
1315                                 return NT_STATUS_OK;
1316                         }
1317                         TALLOC_FREE(req->subreq);
1318                         return smbd_smb2_request_error(req,
1319                                 NT_STATUS_INTERNAL_ERROR);
1320                 }
1321         }
1322
1323         if (DEBUGLEVEL >= 10) {
1324                 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1325                         (unsigned int)req->current_idx );
1326                 print_req_vectors(req);
1327         }
1328
1329         if (req->current_idx > 1) {
1330                 /*
1331                  * We're going async in a compound
1332                  * chain after the first request has
1333                  * already been processed. Send an
1334                  * interim response containing the
1335                  * set of replies already generated.
1336                  */
1337                 int idx = req->current_idx;
1338
1339                 status = smb2_send_async_interim_response(req);
1340                 if (!NT_STATUS_IS_OK(status)) {
1341                         return status;
1342                 }
1343                 data_blob_clear_free(&req->first_key);
1344
1345                 req->current_idx = 1;
1346
1347                 /*
1348                  * Re-arrange the in.vectors to remove what
1349                  * we just sent.
1350                  */
1351                 memmove(&req->in.vector[1],
1352                         &req->in.vector[idx],
1353                         sizeof(req->in.vector[0])*(req->in.vector_count - idx));
1354                 req->in.vector_count = 1 + (req->in.vector_count - idx);
1355
1356                 /* Re-arrange the out.vectors to match. */
1357                 memmove(&req->out.vector[1],
1358                         &req->out.vector[idx],
1359                         sizeof(req->out.vector[0])*(req->out.vector_count - idx));
1360                 req->out.vector_count = 1 + (req->out.vector_count - idx);
1361
1362                 if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
1363                         /*
1364                          * We only have one remaining request as
1365                          * we've processed everything else.
1366                          * This is no longer a compound request.
1367                          */
1368                         req->compound_related = false;
1369                         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1370                         flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
1371                         SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
1372                 }
1373         }
1374         data_blob_clear_free(&req->last_key);
1375
1376         defer_endtime = timeval_current_ofs_usec(defer_time);
1377         req->async_te = tevent_add_timer(req->sconn->ev_ctx,
1378                                          req, defer_endtime,
1379                                          smbd_smb2_request_pending_timer,
1380                                          req);
1381         if (req->async_te == NULL) {
1382                 return NT_STATUS_NO_MEMORY;
1383         }
1384
1385         return NT_STATUS_OK;
1386 }
1387
1388 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1389                                             struct tevent_timer *te,
1390                                             struct timeval current_time,
1391                                             void *private_data)
1392 {
1393         struct smbd_smb2_request *req =
1394                 talloc_get_type_abort(private_data,
1395                 struct smbd_smb2_request);
1396         struct smbd_smb2_request_pending_state *state = NULL;
1397         uint8_t *outhdr = NULL;
1398         const uint8_t *inhdr = NULL;
1399         uint8_t *tf = NULL;
1400         size_t tf_len = 0;
1401         uint8_t *hdr = NULL;
1402         uint8_t *body = NULL;
1403         uint8_t *dyn = NULL;
1404         uint32_t flags = 0;
1405         uint64_t session_id = 0;
1406         uint64_t message_id = 0;
1407         uint64_t nonce_high = 0;
1408         uint64_t nonce_low = 0;
1409         uint64_t async_id = 0;
1410         struct tevent_req *subreq = NULL;
1411
1412         TALLOC_FREE(req->async_te);
1413
1414         /* Ensure our final reply matches the interim one. */
1415         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1416         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1417         flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1418         message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1419         session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
1420
1421         async_id = message_id; /* keep it simple for now... */
1422
1423         SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1424         SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
1425
1426         DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1427                 "going async\n",
1428                 smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
1429                 (unsigned long long)async_id ));
1430
1431         /*
1432          * What we send is identical to a smbd_smb2_request_error
1433          * packet with an error status of STATUS_PENDING. Make use
1434          * of this fact sometime when refactoring. JRA.
1435          */
1436
1437         state = talloc_zero(req->sconn, struct smbd_smb2_request_pending_state);
1438         if (state == NULL) {
1439                 smbd_server_connection_terminate(req->sconn,
1440                                                  nt_errstr(NT_STATUS_NO_MEMORY));
1441                 return;
1442         }
1443         state->sconn = req->sconn;
1444
1445         tf = state->buf + NBT_HDR_SIZE;
1446         tf_len = SMB2_TF_HDR_SIZE;
1447
1448         hdr = tf + SMB2_TF_HDR_SIZE;
1449         body = hdr + SMB2_HDR_BODY;
1450         dyn = body + 8;
1451
1452         if (req->do_encryption) {
1453                 struct smbXsrv_session *x = req->session;
1454
1455                 nonce_high = x->nonce_high;
1456                 nonce_low = x->nonce_low;
1457
1458                 x->nonce_low += 1;
1459                 if (x->nonce_low == 0) {
1460                         x->nonce_low += 1;
1461                         x->nonce_high += 1;
1462                 }
1463         }
1464
1465         SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
1466         SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
1467         SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
1468         SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
1469
1470         SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1471         SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1472         SSVAL(hdr, SMB2_HDR_EPOCH, 0);
1473         SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
1474         SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
1475
1476         SIVAL(hdr, SMB2_HDR_FLAGS, flags);
1477         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
1478         SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
1479         SBVAL(hdr, SMB2_HDR_PID, async_id);
1480         SBVAL(hdr, SMB2_HDR_SESSION_ID,
1481                 BVAL(outhdr, SMB2_HDR_SESSION_ID));
1482         memcpy(hdr+SMB2_HDR_SIGNATURE,
1483                outhdr+SMB2_HDR_SIGNATURE, 16);
1484
1485         SSVAL(body, 0x00, 0x08 + 1);
1486
1487         SCVAL(body, 0x02, 0);
1488         SCVAL(body, 0x03, 0);
1489         SIVAL(body, 0x04, 0);
1490         /* Match W2K8R2... */
1491         SCVAL(dyn,  0x00, 0x21);
1492
1493         state->vector[0].iov_base = (void *)state->buf;
1494         state->vector[0].iov_len = NBT_HDR_SIZE;
1495
1496         if (req->do_encryption) {
1497                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
1498                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
1499         } else {
1500                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
1501                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
1502         }
1503
1504         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
1505         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
1506
1507         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
1508         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
1509
1510         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
1511         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = 1;
1512
1513         smb2_setup_nbt_length(state->vector, 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
1514
1515         /* Ensure we correctly go through crediting. Grant
1516            the credits now, and zero credits on the final
1517            response. */
1518         smb2_set_operation_credit(req->sconn,
1519                         SMBD_SMB2_IN_HDR_IOV(req),
1520                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
1521
1522         SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1523
1524         if (DEBUGLVL(10)) {
1525                 int i;
1526
1527                 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
1528                         dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1529                                 (unsigned int)i,
1530                                 (unsigned int)ARRAY_SIZE(state->vector),
1531                                 (unsigned int)state->vector[i].iov_len);
1532                 }
1533         }
1534
1535         if (req->do_encryption) {
1536                 NTSTATUS status;
1537                 struct smbXsrv_session *x = req->session;
1538                 struct smbXsrv_connection *conn = x->connection;
1539                 DATA_BLOB encryption_key = x->global->encryption_key;
1540
1541                 status = smb2_signing_encrypt_pdu(encryption_key,
1542                                         conn->protocol,
1543                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
1544                                         SMBD_SMB2_NUM_IOV_PER_REQ);
1545                 if (!NT_STATUS_IS_OK(status)) {
1546                         smbd_server_connection_terminate(req->sconn,
1547                                                 nt_errstr(status));
1548                         return;
1549                 }
1550         } else if (req->do_signing) {
1551                 NTSTATUS status;
1552                 struct smbXsrv_session *x = req->session;
1553                 struct smbXsrv_connection *conn = x->connection;
1554                 DATA_BLOB signing_key = x->global->channels[0].signing_key;
1555
1556                 status = smb2_signing_sign_pdu(signing_key,
1557                                         conn->protocol,
1558                                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS],
1559                                         SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1560                 if (!NT_STATUS_IS_OK(status)) {
1561                         smbd_server_connection_terminate(req->sconn,
1562                                                 nt_errstr(status));
1563                         return;
1564                 }
1565         }
1566
1567         subreq = tstream_writev_queue_send(state,
1568                                         state->sconn->ev_ctx,
1569                                         state->sconn->smb2.stream,
1570                                         state->sconn->smb2.send_queue,
1571                                         state->vector,
1572                                         ARRAY_SIZE(state->vector));
1573         if (subreq == NULL) {
1574                 smbd_server_connection_terminate(state->sconn,
1575                                                  nt_errstr(NT_STATUS_NO_MEMORY));
1576                 return;
1577         }
1578         tevent_req_set_callback(subreq,
1579                         smbd_smb2_request_pending_writev_done,
1580                         state);
1581 }
1582
1583 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
1584 {
1585         struct smbd_server_connection *sconn = req->sconn;
1586         struct smbd_smb2_request *cur;
1587         const uint8_t *inhdr;
1588         uint32_t flags;
1589         uint64_t search_message_id;
1590         uint64_t search_async_id;
1591         uint64_t found_id;
1592
1593         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1594
1595         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1596         search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1597         search_async_id = BVAL(inhdr, SMB2_HDR_PID);
1598
1599         /*
1600          * we don't need the request anymore
1601          * cancel requests never have a response
1602          */
1603         DLIST_REMOVE(req->sconn->smb2.requests, req);
1604         TALLOC_FREE(req);
1605
1606         for (cur = sconn->smb2.requests; cur; cur = cur->next) {
1607                 const uint8_t *outhdr;
1608                 uint64_t message_id;
1609                 uint64_t async_id;
1610
1611                 if (cur->compound_related) {
1612                         /*
1613                          * Never cancel anything in a compound request.
1614                          * Way too hard to deal with the result.
1615                          */
1616                         continue;
1617                 }
1618
1619                 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
1620
1621                 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1622                 async_id = BVAL(outhdr, SMB2_HDR_PID);
1623
1624                 if (flags & SMB2_HDR_FLAG_ASYNC) {
1625                         if (search_async_id == async_id) {
1626                                 found_id = async_id;
1627                                 break;
1628                         }
1629                 } else {
1630                         if (search_message_id == message_id) {
1631                                 found_id = message_id;
1632                                 break;
1633                         }
1634                 }
1635         }
1636
1637         if (cur && cur->subreq) {
1638                 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
1639                 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1640                         "cancel opcode[%s] mid %llu\n",
1641                         smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
1642                         (unsigned long long)found_id ));
1643                 tevent_req_cancel(cur->subreq);
1644         }
1645
1646         return NT_STATUS_OK;
1647 }
1648
1649 /*************************************************************
1650  Ensure an incoming tid is a valid one for us to access.
1651  Change to the associated uid credentials and chdir to the
1652  valid tid directory.
1653 *************************************************************/
1654
1655 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
1656 {
1657         const uint8_t *inhdr;
1658         uint32_t in_flags;
1659         uint32_t in_tid;
1660         struct smbXsrv_tcon *tcon;
1661         NTSTATUS status;
1662         NTTIME now = timeval_to_nttime(&req->request_time);
1663
1664         req->tcon = NULL;
1665
1666         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1667
1668         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1669         in_tid = IVAL(inhdr, SMB2_HDR_TID);
1670
1671         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1672                 in_tid = req->last_tid;
1673         }
1674
1675         req->last_tid = 0;
1676
1677         status = smb2srv_tcon_lookup(req->session,
1678                                      in_tid, now, &tcon);
1679         if (!NT_STATUS_IS_OK(status)) {
1680                 return status;
1681         }
1682
1683         if (!change_to_user(tcon->compat, req->session->compat->vuid)) {
1684                 return NT_STATUS_ACCESS_DENIED;
1685         }
1686
1687         /* should we pass FLAG_CASELESS_PATHNAMES here? */
1688         if (!set_current_service(tcon->compat, 0, true)) {
1689                 return NT_STATUS_ACCESS_DENIED;
1690         }
1691
1692         req->tcon = tcon;
1693         req->last_tid = in_tid;
1694
1695         return NT_STATUS_OK;
1696 }
1697
1698 /*************************************************************
1699  Ensure an incoming session_id is a valid one for us to access.
1700 *************************************************************/
1701
1702 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
1703 {
1704         const uint8_t *inhdr;
1705         uint32_t in_flags;
1706         uint16_t in_opcode;
1707         uint64_t in_session_id;
1708         struct smbXsrv_session *session = NULL;
1709         struct auth_session_info *session_info;
1710         NTSTATUS status;
1711         NTTIME now = timeval_to_nttime(&req->request_time);
1712
1713         req->session = NULL;
1714         req->tcon = NULL;
1715
1716         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1717
1718         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1719         in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
1720         in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
1721
1722         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1723                 in_session_id = req->last_session_id;
1724         }
1725
1726         req->last_session_id = 0;
1727
1728         /* lookup an existing session */
1729         status = smb2srv_session_lookup(req->sconn->conn,
1730                                         in_session_id, now,
1731                                         &session);
1732         if (session) {
1733                 req->session = session;
1734                 req->last_session_id = in_session_id;
1735         }
1736         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1737                 switch (in_opcode) {
1738                 case SMB2_OP_SESSSETUP:
1739                         status = NT_STATUS_OK;
1740                         break;
1741                 default:
1742                         break;
1743                 }
1744         }
1745         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1746                 switch (in_opcode) {
1747                 case SMB2_OP_TCON:
1748                 case SMB2_OP_CREATE:
1749                 case SMB2_OP_GETINFO:
1750                 case SMB2_OP_SETINFO:
1751                         return NT_STATUS_INVALID_HANDLE;
1752                 default:
1753                         /*
1754                          * Notice the check for
1755                          * (session_info == NULL)
1756                          * below.
1757                          */
1758                         status = NT_STATUS_OK;
1759                         break;
1760                 }
1761         }
1762         if (!NT_STATUS_IS_OK(status)) {
1763                 return status;
1764         }
1765
1766         session_info = session->global->auth_session_info;
1767         if (session_info == NULL) {
1768                 return NT_STATUS_INVALID_HANDLE;
1769         }
1770
1771         set_current_user_info(session_info->unix_info->sanitized_username,
1772                               session_info->unix_info->unix_name,
1773                               session_info->info->domain_name);
1774
1775         return NT_STATUS_OK;
1776 }
1777
1778 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
1779                                                 uint32_t data_length)
1780 {
1781         uint16_t needed_charge;
1782         uint16_t credit_charge = 1;
1783         const uint8_t *inhdr;
1784
1785         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1786
1787         if (req->sconn->smb2.supports_multicredit) {
1788                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
1789                 credit_charge = MAX(credit_charge, 1);
1790         }
1791
1792         needed_charge = (data_length - 1)/ 65536 + 1;
1793
1794         DEBUG(10, ("mid %llu, CreditCharge: %d, NeededCharge: %d\n",
1795                    (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
1796                    credit_charge, needed_charge));
1797
1798         if (needed_charge > credit_charge) {
1799                 DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
1800                           credit_charge, needed_charge));
1801                 return NT_STATUS_INVALID_PARAMETER;
1802         }
1803
1804         return NT_STATUS_OK;
1805 }
1806
1807 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
1808                                         size_t expected_body_size)
1809 {
1810         struct iovec *inhdr_v;
1811         const uint8_t *inhdr;
1812         uint16_t opcode;
1813         const uint8_t *inbody;
1814         size_t body_size;
1815         size_t min_dyn_size = expected_body_size & 0x00000001;
1816         int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
1817
1818         /*
1819          * The following should be checked already.
1820          */
1821         if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
1822                 return NT_STATUS_INTERNAL_ERROR;
1823         }
1824         if (req->current_idx > max_idx) {
1825                 return NT_STATUS_INTERNAL_ERROR;
1826         }
1827
1828         inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
1829         if (inhdr_v->iov_len != SMB2_HDR_BODY) {
1830                 return NT_STATUS_INTERNAL_ERROR;
1831         }
1832         if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
1833                 return NT_STATUS_INTERNAL_ERROR;
1834         }
1835
1836         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1837         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
1838
1839         switch (opcode) {
1840         case SMB2_OP_IOCTL:
1841         case SMB2_OP_GETINFO:
1842                 min_dyn_size = 0;
1843                 break;
1844         }
1845
1846         /*
1847          * Now check the expected body size,
1848          * where the last byte might be in the
1849          * dynamic section..
1850          */
1851         if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
1852                 return NT_STATUS_INVALID_PARAMETER;
1853         }
1854         if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
1855                 return NT_STATUS_INVALID_PARAMETER;
1856         }
1857
1858         inbody = SMBD_SMB2_IN_BODY_PTR(req);
1859
1860         body_size = SVAL(inbody, 0x00);
1861         if (body_size != expected_body_size) {
1862                 return NT_STATUS_INVALID_PARAMETER;
1863         }
1864
1865         return NT_STATUS_OK;
1866 }
1867
1868 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
1869 {
1870         struct smbXsrv_connection *conn = req->sconn->conn;
1871         const struct smbd_smb2_dispatch_table *call = NULL;
1872         const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
1873         const uint8_t *inhdr;
1874         uint16_t opcode;
1875         uint32_t flags;
1876         uint64_t mid;
1877         NTSTATUS status;
1878         NTSTATUS session_status;
1879         uint32_t allowed_flags;
1880         NTSTATUS return_value;
1881         struct smbXsrv_session *x = NULL;
1882         bool signing_required = false;
1883         bool encryption_required = false;
1884
1885         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1886
1887         /* TODO: verify more things */
1888
1889         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1890         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
1891         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1892         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
1893                 smb2_opcode_name(opcode),
1894                 (unsigned long long)mid));
1895
1896         if (conn->protocol >= PROTOCOL_SMB2_02) {
1897                 /*
1898                  * once the protocol is negotiated
1899                  * SMB2_OP_NEGPROT is not allowed anymore
1900                  */
1901                 if (opcode == SMB2_OP_NEGPROT) {
1902                         /* drop the connection */
1903                         return NT_STATUS_INVALID_PARAMETER;
1904                 }
1905         } else {
1906                 /*
1907                  * if the protocol is not negotiated yet
1908                  * only SMB2_OP_NEGPROT is allowed.
1909                  */
1910                 if (opcode != SMB2_OP_NEGPROT) {
1911                         /* drop the connection */
1912                         return NT_STATUS_INVALID_PARAMETER;
1913                 }
1914         }
1915
1916         /*
1917          * Check if the client provided a valid session id,
1918          * if so smbd_smb2_request_check_session() calls
1919          * set_current_user_info().
1920          *
1921          * As some command don't require a valid session id
1922          * we defer the check of the session_status
1923          */
1924         session_status = smbd_smb2_request_check_session(req);
1925         x = req->session;
1926         if (x != NULL) {
1927                 signing_required = x->global->signing_required;
1928                 encryption_required = x->global->encryption_required;
1929
1930                 if (opcode == SMB2_OP_SESSSETUP &&
1931                     x->global->channels[0].signing_key.length) {
1932                         signing_required = true;
1933                 }
1934         }
1935
1936         req->do_signing = false;
1937         req->do_encryption = false;
1938         if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
1939                 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
1940                 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
1941
1942                 if (x != NULL && x->global->session_wire_id != tf_session_id) {
1943                         DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
1944                                  "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
1945                                  (unsigned long long)x->global->session_wire_id,
1946                                  (unsigned long long)tf_session_id));
1947                         /*
1948                          * TODO: windows allows this...
1949                          * should we drop the connection?
1950                          *
1951                          * For now we just return ACCESS_DENIED
1952                          * (Windows clients never trigger this)
1953                          * and wait for an update of [MS-SMB2].
1954                          */
1955                         return smbd_smb2_request_error(req,
1956                                         NT_STATUS_ACCESS_DENIED);
1957                 }
1958
1959                 req->do_encryption = true;
1960         }
1961
1962         if (encryption_required && !req->do_encryption) {
1963                 return smbd_smb2_request_error(req,
1964                                 NT_STATUS_ACCESS_DENIED);
1965         }
1966
1967         call = smbd_smb2_call(opcode);
1968         if (call == NULL) {
1969                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
1970         }
1971
1972         allowed_flags = SMB2_HDR_FLAG_CHAINED |
1973                         SMB2_HDR_FLAG_SIGNED |
1974                         SMB2_HDR_FLAG_DFS;
1975         if (opcode == SMB2_OP_CANCEL) {
1976                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
1977         }
1978         if ((flags & ~allowed_flags) != 0) {
1979                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
1980         }
1981
1982         if (flags & SMB2_HDR_FLAG_CHAINED) {
1983                 /*
1984                  * This check is mostly for giving the correct error code
1985                  * for compounded requests.
1986                  */
1987                 if (!NT_STATUS_IS_OK(session_status)) {
1988                         return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
1989                 }
1990         } else {
1991                 req->compat_chain_fsp = NULL;
1992         }
1993
1994         if (req->do_encryption) {
1995                 signing_required = false;
1996         } else if (flags & SMB2_HDR_FLAG_SIGNED) {
1997                 DATA_BLOB signing_key;
1998
1999                 if (x == NULL) {
2000                         return smbd_smb2_request_error(
2001                                 req, NT_STATUS_ACCESS_DENIED);
2002                 }
2003
2004                 signing_key = x->global->channels[0].signing_key;
2005
2006                 /*
2007                  * If we have a signing key, we should
2008                  * sign the response
2009                  */
2010                 if (signing_key.length > 0) {
2011                         req->do_signing = true;
2012                 }
2013
2014                 status = smb2_signing_check_pdu(signing_key,
2015                                                 conn->protocol,
2016                                                 SMBD_SMB2_IN_HDR_IOV(req),
2017                                                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2018                 if (!NT_STATUS_IS_OK(status)) {
2019                         return smbd_smb2_request_error(req, status);
2020                 }
2021
2022                 /*
2023                  * Now that we know the request was correctly signed
2024                  * we have to sign the response too.
2025                  */
2026                 req->do_signing = true;
2027
2028                 if (!NT_STATUS_IS_OK(session_status)) {
2029                         return smbd_smb2_request_error(req, session_status);
2030                 }
2031         } else if (opcode == SMB2_OP_CANCEL) {
2032                 /* Cancel requests are allowed to skip the signing */
2033         } else if (signing_required) {
2034                 /*
2035                  * If signing is required we try to sign
2036                  * a possible error response
2037                  */
2038                 req->do_signing = true;
2039                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
2040         }
2041
2042         if (flags & SMB2_HDR_FLAG_CHAINED) {
2043                 req->compound_related = true;
2044         }
2045
2046         if (call->need_session) {
2047                 if (!NT_STATUS_IS_OK(session_status)) {
2048                         return smbd_smb2_request_error(req, session_status);
2049                 }
2050         }
2051
2052         if (call->need_tcon) {
2053                 SMB_ASSERT(call->need_session);
2054
2055                 /*
2056                  * This call needs to be run as user.
2057                  *
2058                  * smbd_smb2_request_check_tcon()
2059                  * calls change_to_user() on success.
2060                  */
2061                 status = smbd_smb2_request_check_tcon(req);
2062                 if (!NT_STATUS_IS_OK(status)) {
2063                         return smbd_smb2_request_error(req, status);
2064                 }
2065                 if (req->tcon->global->encryption_required) {
2066                         encryption_required = true;
2067                 }
2068                 if (encryption_required && !req->do_encryption) {
2069                         return smbd_smb2_request_error(req,
2070                                 NT_STATUS_ACCESS_DENIED);
2071                 }
2072         }
2073
2074         if (call->fileid_ofs != 0) {
2075                 size_t needed = call->fileid_ofs + 16;
2076                 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2077                 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2078                 uint64_t file_id_persistent;
2079                 uint64_t file_id_volatile;
2080                 struct files_struct *fsp;
2081
2082                 SMB_ASSERT(call->need_tcon);
2083
2084                 if (needed > body_size) {
2085                         return smbd_smb2_request_error(req,
2086                                         NT_STATUS_INVALID_PARAMETER);
2087                 }
2088
2089                 file_id_persistent      = BVAL(body, call->fileid_ofs + 0);
2090                 file_id_volatile        = BVAL(body, call->fileid_ofs + 8);
2091
2092                 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2093                 if (fsp == NULL) {
2094                         if (!call->allow_invalid_fileid) {
2095                                 return smbd_smb2_request_error(req,
2096                                                 NT_STATUS_FILE_CLOSED);
2097                         }
2098
2099                         if (file_id_persistent != UINT64_MAX) {
2100                                 return smbd_smb2_request_error(req,
2101                                                 NT_STATUS_FILE_CLOSED);
2102                         }
2103                         if (file_id_volatile != UINT64_MAX) {
2104                                 return smbd_smb2_request_error(req,
2105                                                 NT_STATUS_FILE_CLOSED);
2106                         }
2107                 }
2108         }
2109
2110         if (call->as_root) {
2111                 SMB_ASSERT(call->fileid_ofs == 0);
2112                 /* This call needs to be run as root */
2113                 change_to_root_user();
2114         } else {
2115                 SMB_ASSERT(call->need_tcon);
2116         }
2117
2118         switch (opcode) {
2119         case SMB2_OP_NEGPROT:
2120                 {
2121                         START_PROFILE(smb2_negprot);
2122                         return_value = smbd_smb2_request_process_negprot(req);
2123                         END_PROFILE(smb2_negprot);
2124                 }
2125                 break;
2126
2127         case SMB2_OP_SESSSETUP:
2128                 {
2129                         START_PROFILE(smb2_sesssetup);
2130                         return_value = smbd_smb2_request_process_sesssetup(req);
2131                         END_PROFILE(smb2_sesssetup);
2132                 }
2133                 break;
2134
2135         case SMB2_OP_LOGOFF:
2136                 {
2137                         START_PROFILE(smb2_logoff);
2138                         return_value = smbd_smb2_request_process_logoff(req);
2139                         END_PROFILE(smb2_logoff);
2140                 }
2141                 break;
2142
2143         case SMB2_OP_TCON:
2144                 {
2145                         START_PROFILE(smb2_tcon);
2146                         return_value = smbd_smb2_request_process_tcon(req);
2147                         END_PROFILE(smb2_tcon);
2148                 }
2149                 break;
2150
2151         case SMB2_OP_TDIS:
2152                 {
2153                         START_PROFILE(smb2_tdis);
2154                         return_value = smbd_smb2_request_process_tdis(req);
2155                         END_PROFILE(smb2_tdis);
2156                 }
2157                 break;
2158
2159         case SMB2_OP_CREATE:
2160                 {
2161                         START_PROFILE(smb2_create);
2162                         return_value = smbd_smb2_request_process_create(req);
2163                         END_PROFILE(smb2_create);
2164                 }
2165                 break;
2166
2167         case SMB2_OP_CLOSE:
2168                 {
2169                         START_PROFILE(smb2_close);
2170                         return_value = smbd_smb2_request_process_close(req);
2171                         END_PROFILE(smb2_close);
2172                 }
2173                 break;
2174
2175         case SMB2_OP_FLUSH:
2176                 {
2177                         START_PROFILE(smb2_flush);
2178                         return_value = smbd_smb2_request_process_flush(req);
2179                         END_PROFILE(smb2_flush);
2180                 }
2181                 break;
2182
2183         case SMB2_OP_READ:
2184                 {
2185                         START_PROFILE(smb2_read);
2186                         return_value = smbd_smb2_request_process_read(req);
2187                         END_PROFILE(smb2_read);
2188                 }
2189                 break;
2190
2191         case SMB2_OP_WRITE:
2192                 {
2193                         START_PROFILE(smb2_write);
2194                         return_value = smbd_smb2_request_process_write(req);
2195                         END_PROFILE(smb2_write);
2196                 }
2197                 break;
2198
2199         case SMB2_OP_LOCK:
2200                 {
2201                         START_PROFILE(smb2_lock);
2202                         return_value = smbd_smb2_request_process_lock(req);
2203                         END_PROFILE(smb2_lock);
2204                 }
2205                 break;
2206
2207         case SMB2_OP_IOCTL:
2208                 {
2209                         START_PROFILE(smb2_ioctl);
2210                         return_value = smbd_smb2_request_process_ioctl(req);
2211                         END_PROFILE(smb2_ioctl);
2212                 }
2213                 break;
2214
2215         case SMB2_OP_CANCEL:
2216                 {
2217                         START_PROFILE(smb2_cancel);
2218                         return_value = smbd_smb2_request_process_cancel(req);
2219                         END_PROFILE(smb2_cancel);
2220                 }
2221                 break;
2222
2223         case SMB2_OP_KEEPALIVE:
2224                 {
2225                         START_PROFILE(smb2_keepalive);
2226                         return_value = smbd_smb2_request_process_keepalive(req);
2227                         END_PROFILE(smb2_keepalive);
2228                 }
2229                 break;
2230
2231         case SMB2_OP_FIND:
2232                 {
2233                         START_PROFILE(smb2_find);
2234                         return_value = smbd_smb2_request_process_find(req);
2235                         END_PROFILE(smb2_find);
2236                 }
2237                 break;
2238
2239         case SMB2_OP_NOTIFY:
2240                 {
2241                         START_PROFILE(smb2_notify);
2242                         return_value = smbd_smb2_request_process_notify(req);
2243                         END_PROFILE(smb2_notify);
2244                 }
2245                 break;
2246
2247         case SMB2_OP_GETINFO:
2248                 {
2249                         START_PROFILE(smb2_getinfo);
2250                         return_value = smbd_smb2_request_process_getinfo(req);
2251                         END_PROFILE(smb2_getinfo);
2252                 }
2253                 break;
2254
2255         case SMB2_OP_SETINFO:
2256                 {
2257                         START_PROFILE(smb2_setinfo);
2258                         return_value = smbd_smb2_request_process_setinfo(req);
2259                         END_PROFILE(smb2_setinfo);
2260                 }
2261                 break;
2262
2263         case SMB2_OP_BREAK:
2264                 {
2265                         START_PROFILE(smb2_break);
2266                         return_value = smbd_smb2_request_process_break(req);
2267                         END_PROFILE(smb2_break);
2268                 }
2269                 break;
2270
2271         default:
2272                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2273                 break;
2274         }
2275         return return_value;
2276 }
2277
2278 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
2279 {
2280         struct smbXsrv_connection *conn = req->sconn->conn;
2281         struct tevent_req *subreq;
2282         int first_idx = 1;
2283         struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
2284         struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
2285         struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
2286
2287         req->subreq = NULL;
2288         TALLOC_FREE(req->async_te);
2289
2290         if (req->do_encryption &&
2291             (firsttf->iov_len == 0) &&
2292             (req->first_key.length == 0) &&
2293             (req->session != NULL) &&
2294             (req->session->global->encryption_key.length != 0))
2295         {
2296                 DATA_BLOB encryption_key = req->session->global->encryption_key;
2297                 uint8_t *tf;
2298                 uint64_t session_id = req->session->global->session_wire_id;
2299                 struct smbXsrv_session *x = req->session;
2300                 uint64_t nonce_high;
2301                 uint64_t nonce_low;
2302
2303                 nonce_high = x->nonce_high;
2304                 nonce_low = x->nonce_low;
2305
2306                 x->nonce_low += 1;
2307                 if (x->nonce_low == 0) {
2308                         x->nonce_low += 1;
2309                         x->nonce_high += 1;
2310                 }
2311
2312                 /*
2313                  * We need to place the SMB2_TRANSFORM header before the
2314                  * first SMB2 header
2315                  */
2316
2317                 /*
2318                  * we need to remember the encryption key
2319                  * and defer the signing/encryption until
2320                  * we are sure that we do not change
2321                  * the header again.
2322                  */
2323                 req->first_key = data_blob_dup_talloc(req, encryption_key);
2324                 if (req->first_key.data == NULL) {
2325                         return NT_STATUS_NO_MEMORY;
2326                 }
2327
2328                 tf = talloc_zero_array(req->out.vector, uint8_t,
2329                                        SMB2_TF_HDR_SIZE);
2330                 if (tf == NULL) {
2331                         return NT_STATUS_NO_MEMORY;
2332                 }
2333
2334                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2335                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2336                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2337                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2338
2339                 firsttf->iov_base = (void *)tf;
2340                 firsttf->iov_len = SMB2_TF_HDR_SIZE;
2341         }
2342
2343         if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
2344             (req->last_key.length > 0) &&
2345             (firsttf->iov_len == 0))
2346         {
2347                 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
2348                 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
2349                 NTSTATUS status;
2350
2351                 /*
2352                  * As we are sure the header of the last request in the
2353                  * compound chain will not change, we can to sign here
2354                  * with the last signing key we remembered.
2355                  */
2356                 status = smb2_signing_sign_pdu(req->last_key,
2357                                                conn->protocol,
2358                                                lasthdr,
2359                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2360                 if (!NT_STATUS_IS_OK(status)) {
2361                         return status;
2362                 }
2363         }
2364         data_blob_clear_free(&req->last_key);
2365
2366         req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
2367
2368         if (req->current_idx < req->out.vector_count) {
2369                 /*
2370                  * We must process the remaining compound
2371                  * SMB2 requests before any new incoming SMB2
2372                  * requests. This is because incoming SMB2
2373                  * requests may include a cancel for a
2374                  * compound request we haven't processed
2375                  * yet.
2376                  */
2377                 struct tevent_immediate *im = tevent_create_immediate(req);
2378                 if (!im) {
2379                         return NT_STATUS_NO_MEMORY;
2380                 }
2381
2382                 if (req->do_signing && firsttf->iov_len == 0) {
2383                         struct smbXsrv_session *x = req->session;
2384                         DATA_BLOB signing_key = x->global->channels[0].signing_key;
2385
2386                         /*
2387                          * we need to remember the signing key
2388                          * and defer the signing until
2389                          * we are sure that we do not change
2390                          * the header again.
2391                          */
2392                         req->last_key = data_blob_dup_talloc(req, signing_key);
2393                         if (req->last_key.data == NULL) {
2394                                 return NT_STATUS_NO_MEMORY;
2395                         }
2396                 }
2397
2398                 tevent_schedule_immediate(im,
2399                                         req->sconn->ev_ctx,
2400                                         smbd_smb2_request_dispatch_immediate,
2401                                         req);
2402                 return NT_STATUS_OK;
2403         }
2404
2405         if (req->compound_related) {
2406                 req->compound_related = false;
2407         }
2408
2409         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
2410
2411         /* Set credit for these operations (zero credits if this
2412            is a final reply for an async operation). */
2413         smb2_calculate_credits(req, req);
2414
2415         /*
2416          * now check if we need to sign the current response
2417          */
2418         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
2419                 NTSTATUS status;
2420
2421                 status = smb2_signing_encrypt_pdu(req->first_key,
2422                                         conn->protocol,
2423                                         firsttf,
2424                                         req->out.vector_count - first_idx);
2425                 if (!NT_STATUS_IS_OK(status)) {
2426                         return status;
2427                 }
2428         } else if (req->do_signing) {
2429                 NTSTATUS status;
2430                 struct smbXsrv_session *x = req->session;
2431                 DATA_BLOB signing_key = x->global->channels[0].signing_key;
2432
2433                 status = smb2_signing_sign_pdu(signing_key,
2434                                                conn->protocol,
2435                                                outhdr,
2436                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2437                 if (!NT_STATUS_IS_OK(status)) {
2438                         return status;
2439                 }
2440         }
2441         data_blob_clear_free(&req->first_key);
2442
2443         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2444         if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
2445             outdyn->iov_base == NULL && outdyn->iov_len != 0) {
2446                 /* Dynamic part is NULL. Chop it off,
2447                    We're going to send it via sendfile. */
2448                 req->out.vector_count -= 1;
2449         }
2450
2451         subreq = tstream_writev_queue_send(req,
2452                                            req->sconn->ev_ctx,
2453                                            req->sconn->smb2.stream,
2454                                            req->sconn->smb2.send_queue,
2455                                            req->out.vector,
2456                                            req->out.vector_count);
2457         if (subreq == NULL) {
2458                 return NT_STATUS_NO_MEMORY;
2459         }
2460         tevent_req_set_callback(subreq, smbd_smb2_request_writev_done, req);
2461         /*
2462          * We're done with this request -
2463          * move it off the "being processed" queue.
2464          */
2465         DLIST_REMOVE(req->sconn->smb2.requests, req);
2466
2467         return NT_STATUS_OK;
2468 }
2469
2470 static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn);
2471
2472 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
2473                                         struct tevent_immediate *im,
2474                                         void *private_data)
2475 {
2476         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
2477                                         struct smbd_smb2_request);
2478         struct smbd_server_connection *sconn = req->sconn;
2479         NTSTATUS status;
2480
2481         TALLOC_FREE(im);
2482
2483         if (DEBUGLEVEL >= 10) {
2484                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2485                         req->current_idx, req->in.vector_count));
2486                 print_req_vectors(req);
2487         }
2488
2489         status = smbd_smb2_request_dispatch(req);
2490         if (!NT_STATUS_IS_OK(status)) {
2491                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2492                 return;
2493         }
2494
2495         status = smbd_smb2_request_next_incoming(sconn);
2496         if (!NT_STATUS_IS_OK(status)) {
2497                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2498                 return;
2499         }
2500 }
2501
2502 static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
2503 {
2504         struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
2505                                         struct smbd_smb2_request);
2506         struct smbd_server_connection *sconn = req->sconn;
2507         int ret;
2508         int sys_errno;
2509         NTSTATUS status;
2510
2511         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2512         TALLOC_FREE(subreq);
2513         TALLOC_FREE(req);
2514         if (ret == -1) {
2515                 status = map_nt_error_from_unix(sys_errno);
2516                 DEBUG(2,("smbd_smb2_request_writev_done: client write error %s\n",
2517                         nt_errstr(status)));
2518                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2519                 return;
2520         }
2521
2522         status = smbd_smb2_request_next_incoming(sconn);
2523         if (!NT_STATUS_IS_OK(status)) {
2524                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2525                 return;
2526         }
2527 }
2528
2529 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
2530                                    NTSTATUS status,
2531                                    DATA_BLOB body, DATA_BLOB *dyn,
2532                                    const char *location)
2533 {
2534         uint8_t *outhdr;
2535         struct iovec *outbody_v;
2536         struct iovec *outdyn_v;
2537         uint32_t next_command_ofs;
2538
2539         DEBUG(10,("smbd_smb2_request_done_ex: "
2540                   "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
2541                   req->current_idx, nt_errstr(status), (unsigned int)body.length,
2542                   dyn ? "yes": "no",
2543                   (unsigned int)(dyn ? dyn->length : 0),
2544                   location));
2545
2546         if (body.length < 2) {
2547                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2548         }
2549
2550         if ((body.length % 2) != 0) {
2551                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2552         }
2553
2554         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2555         outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
2556         outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
2557
2558         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
2559         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
2560
2561         outbody_v->iov_base = (void *)body.data;
2562         outbody_v->iov_len = body.length;
2563
2564         if (dyn) {
2565                 outdyn_v->iov_base = (void *)dyn->data;
2566                 outdyn_v->iov_len = dyn->length;
2567         } else {
2568                 outdyn_v->iov_base = NULL;
2569                 outdyn_v->iov_len = 0;
2570         }
2571
2572         /* see if we need to recalculate the offset to the next response */
2573         if (next_command_ofs > 0) {
2574                 next_command_ofs  = SMB2_HDR_BODY;
2575                 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
2576                 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
2577         }
2578
2579         if ((next_command_ofs % 8) != 0) {
2580                 size_t pad_size = 8 - (next_command_ofs % 8);
2581                 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
2582                         /*
2583                          * if the dyn buffer is empty
2584                          * we can use it to add padding
2585                          */
2586                         uint8_t *pad;
2587
2588                         pad = talloc_zero_array(req->out.vector,
2589                                                 uint8_t, pad_size);
2590                         if (pad == NULL) {
2591                                 return smbd_smb2_request_error(req,
2592                                                 NT_STATUS_NO_MEMORY);
2593                         }
2594
2595                         outdyn_v->iov_base = (void *)pad;
2596                         outdyn_v->iov_len = pad_size;
2597                 } else {
2598                         /*
2599                          * For now we copy the dynamic buffer
2600                          * and add the padding to the new buffer
2601                          */
2602                         size_t old_size;
2603                         uint8_t *old_dyn;
2604                         size_t new_size;
2605                         uint8_t *new_dyn;
2606
2607                         old_size = SMBD_SMB2_OUT_DYN_LEN(req);
2608                         old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
2609
2610                         new_size = old_size + pad_size;
2611                         new_dyn = talloc_zero_array(req->out.vector,
2612                                                uint8_t, new_size);
2613                         if (new_dyn == NULL) {
2614                                 return smbd_smb2_request_error(req,
2615                                                 NT_STATUS_NO_MEMORY);
2616                         }
2617
2618                         memcpy(new_dyn, old_dyn, old_size);
2619                         memset(new_dyn + old_size, 0, pad_size);
2620
2621                         outdyn_v->iov_base = (void *)new_dyn;
2622                         outdyn_v->iov_len = new_size;
2623                 }
2624                 next_command_ofs += pad_size;
2625         }
2626
2627         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
2628
2629         return smbd_smb2_request_reply(req);
2630 }
2631
2632 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
2633                                     NTSTATUS status,
2634                                     DATA_BLOB *info,
2635                                     const char *location)
2636 {
2637         DATA_BLOB body;
2638         uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2639         size_t unread_bytes = smbd_smb2_unread_bytes(req);
2640
2641         DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n",
2642                   req->current_idx, nt_errstr(status), info ? " +info" : "",
2643                   location));
2644
2645         if (unread_bytes) {
2646                 /* Recvfile error. Drain incoming socket. */
2647                 size_t ret = drain_socket(req->sconn->sock, unread_bytes);
2648                 if (ret != unread_bytes) {
2649                         smbd_server_connection_terminate(req->sconn,
2650                                 "Failed to drain SMB2 socket\n");
2651                 }
2652         }
2653
2654         body.data = outhdr + SMB2_HDR_BODY;
2655         body.length = 8;
2656         SSVAL(body.data, 0, 9);
2657
2658         if (info) {
2659                 SIVAL(body.data, 0x04, info->length);
2660         } else {
2661                 /* Allocated size of req->out.vector[i].iov_base
2662                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
2663                  * 1 byte without having to do an alloc.
2664                  */
2665                 info = talloc_zero_array(req->out.vector,
2666                                         DATA_BLOB,
2667                                         1);
2668                 if (!info) {
2669                         return NT_STATUS_NO_MEMORY;
2670                 }
2671                 info->data = ((uint8_t *)outhdr) +
2672                         OUTVEC_ALLOC_SIZE - 1;
2673                 info->length = 1;
2674                 SCVAL(info->data, 0, 0);
2675         }
2676
2677         /*
2678          * Note: Even if there is an error, continue to process the request.
2679          * per MS-SMB2.
2680          */
2681
2682         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
2683 }
2684
2685
2686 struct smbd_smb2_send_oplock_break_state {
2687         struct smbd_server_connection *sconn;
2688         uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x18];
2689         struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
2690 };
2691
2692 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq);
2693
2694 NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
2695                                      struct smbXsrv_session *session,
2696                                      struct smbXsrv_tcon *tcon,
2697                                      struct smbXsrv_open *op,
2698                                      uint8_t oplock_level)
2699 {
2700         struct smbd_smb2_send_oplock_break_state *state;
2701         struct smbXsrv_connection *conn = sconn->conn;
2702         struct tevent_req *subreq;
2703         uint8_t *tf;
2704         size_t tf_len;
2705         uint8_t *hdr;
2706         uint8_t *body;
2707         size_t body_len;
2708         uint8_t *dyn;
2709         size_t dyn_len;
2710         bool do_encryption = session->global->encryption_required;
2711         uint64_t nonce_high = 0;
2712         uint64_t nonce_low = 0;
2713
2714         if (tcon->global->encryption_required) {
2715                 do_encryption = true;
2716         }
2717
2718         state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
2719         if (state == NULL) {
2720                 return NT_STATUS_NO_MEMORY;
2721         }
2722         state->sconn = sconn;
2723
2724         tf = state->buf + NBT_HDR_SIZE;
2725         tf_len = SMB2_TF_HDR_SIZE;
2726         hdr = tf + tf_len;
2727         body = hdr + SMB2_HDR_BODY;
2728         body_len = 0x18;
2729         dyn = body + body_len;
2730         dyn_len = 0;
2731
2732         if (do_encryption) {
2733                 nonce_high = session->nonce_high;
2734                 nonce_low = session->nonce_low;
2735
2736                 session->nonce_low += 1;
2737                 if (session->nonce_low == 0) {
2738                         session->nonce_low += 1;
2739                         session->nonce_high += 1;
2740                 }
2741         }
2742
2743         SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2744         SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2745         SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2746         SBVAL(tf, SMB2_TF_SESSION_ID, session->global->session_wire_id);
2747
2748         SIVAL(hdr, 0,                           SMB2_MAGIC);
2749         SSVAL(hdr, SMB2_HDR_LENGTH,             SMB2_HDR_BODY);
2750         SSVAL(hdr, SMB2_HDR_EPOCH,              0);
2751         SIVAL(hdr, SMB2_HDR_STATUS,             0);
2752         SSVAL(hdr, SMB2_HDR_OPCODE,             SMB2_OP_BREAK);
2753         SSVAL(hdr, SMB2_HDR_CREDIT,             0);
2754         SIVAL(hdr, SMB2_HDR_FLAGS,              SMB2_HDR_FLAG_REDIRECT);
2755         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND,       0);
2756         SBVAL(hdr, SMB2_HDR_MESSAGE_ID,         UINT64_MAX);
2757         SIVAL(hdr, SMB2_HDR_PID,                0);
2758         SIVAL(hdr, SMB2_HDR_TID,                0);
2759         SBVAL(hdr, SMB2_HDR_SESSION_ID,         0);
2760         memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
2761
2762         SSVAL(body, 0x00, body_len);
2763
2764         SCVAL(body, 0x02, oplock_level);
2765         SCVAL(body, 0x03, 0);           /* reserved */
2766         SIVAL(body, 0x04, 0);           /* reserved */
2767         SBVAL(body, 0x08, op->global->open_persistent_id);
2768         SBVAL(body, 0x10, op->global->open_volatile_id);
2769
2770         state->vector[0].iov_base = (void *)state->buf;
2771         state->vector[0].iov_len = NBT_HDR_SIZE;
2772
2773         if (do_encryption) {
2774                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
2775                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
2776         } else {
2777                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
2778                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
2779         }
2780
2781         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
2782         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
2783
2784         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
2785         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = body_len;
2786
2787         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
2788         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = dyn_len;
2789
2790         smb2_setup_nbt_length(state->vector, 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2791
2792         if (do_encryption) {
2793                 NTSTATUS status;
2794                 DATA_BLOB encryption_key = session->global->encryption_key;
2795
2796                 status = smb2_signing_encrypt_pdu(encryption_key,
2797                                         conn->protocol,
2798                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2799                                         SMBD_SMB2_NUM_IOV_PER_REQ);
2800                 if (!NT_STATUS_IS_OK(status)) {
2801                         return status;
2802                 }
2803         }
2804
2805         subreq = tstream_writev_queue_send(state,
2806                                            sconn->ev_ctx,
2807                                            sconn->smb2.stream,
2808                                            sconn->smb2.send_queue,
2809                                            state->vector,
2810                                            ARRAY_SIZE(state->vector));
2811         if (subreq == NULL) {
2812                 return NT_STATUS_NO_MEMORY;
2813         }
2814         tevent_req_set_callback(subreq,
2815                                 smbd_smb2_oplock_break_writev_done,
2816                                 state);
2817
2818         return NT_STATUS_OK;
2819 }
2820
2821 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq)
2822 {
2823         struct smbd_smb2_send_oplock_break_state *state =
2824                 tevent_req_callback_data(subreq,
2825                 struct smbd_smb2_send_oplock_break_state);
2826         struct smbd_server_connection *sconn = state->sconn;
2827         int ret;
2828         int sys_errno;
2829
2830         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2831         TALLOC_FREE(subreq);
2832         if (ret == -1) {
2833                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
2834                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2835                 return;
2836         }
2837
2838         TALLOC_FREE(state);
2839 }
2840
2841 struct smbd_smb2_request_read_state {
2842         struct tevent_context *ev;
2843         struct smbd_server_connection *sconn;
2844         struct smbd_smb2_request *smb2_req;
2845         struct {
2846                 uint8_t nbt[NBT_HDR_SIZE];
2847                 bool done;
2848         } hdr;
2849         bool doing_receivefile;
2850         size_t min_recv_size;
2851         size_t pktlen;
2852         uint8_t *pktbuf;
2853 };
2854
2855 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
2856                                          void *private_data,
2857                                          TALLOC_CTX *mem_ctx,
2858                                          struct iovec **_vector,
2859                                          size_t *_count);
2860 static void smbd_smb2_request_read_done(struct tevent_req *subreq);
2861
2862 static size_t get_min_receive_file_size(struct smbd_smb2_request *smb2_req)
2863 {
2864         if (smb2_req->do_signing) {
2865                 return 0;
2866         }
2867         if (smb2_req->do_encryption) {
2868                 return 0;
2869         }
2870         return (size_t)lp_min_receive_file_size();
2871 }
2872
2873 static struct tevent_req *smbd_smb2_request_read_send(TALLOC_CTX *mem_ctx,
2874                                         struct tevent_context *ev,
2875                                         struct smbd_server_connection *sconn)
2876 {
2877         struct tevent_req *req;
2878         struct smbd_smb2_request_read_state *state;
2879         struct tevent_req *subreq;
2880
2881         req = tevent_req_create(mem_ctx, &state,
2882                                 struct smbd_smb2_request_read_state);
2883         if (req == NULL) {
2884                 return NULL;
2885         }
2886         state->ev = ev;
2887         state->sconn = sconn;
2888
2889         state->smb2_req = smbd_smb2_request_allocate(state);
2890         if (tevent_req_nomem(state->smb2_req, req)) {
2891                 return tevent_req_post(req, ev);
2892         }
2893         state->smb2_req->sconn = sconn;
2894         state->min_recv_size = get_min_receive_file_size(state->smb2_req);
2895
2896         subreq = tstream_readv_pdu_queue_send(state->smb2_req,
2897                                         state->ev,
2898                                         state->sconn->smb2.stream,
2899                                         state->sconn->smb2.recv_queue,
2900                                         smbd_smb2_request_next_vector,
2901                                         state);
2902         if (tevent_req_nomem(subreq, req)) {
2903                 return tevent_req_post(req, ev);
2904         }
2905         tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
2906
2907         return req;
2908 }
2909
2910 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
2911 {
2912         uint32_t flags;
2913
2914         if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
2915                 /* Transform header. Cannot recvfile. */
2916                 return false;
2917         }
2918         if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
2919                 /* Not SMB2. Normal error path will cope. */
2920                 return false;
2921         }
2922         if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
2923                 /* Not SMB2. Normal error path will cope. */
2924                 return false;
2925         }
2926         if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
2927                 /* Needs to be a WRITE. */
2928                 return false;
2929         }
2930         if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
2931                 /* Chained. Cannot recvfile. */
2932                 return false;
2933         }
2934         flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
2935         if (flags & SMB2_HDR_FLAG_CHAINED) {
2936                 /* Chained. Cannot recvfile. */
2937                 return false;
2938         }
2939         if (flags & SMB2_HDR_FLAG_SIGNED) {
2940                 /* Signed. Cannot recvfile. */
2941                 return false;
2942         }
2943
2944         DEBUG(10,("Doing recvfile write len = %u\n",
2945                 (unsigned int)(state->pktlen -
2946                 SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN)));
2947
2948         return true;
2949 }
2950
2951 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
2952                                          void *private_data,
2953                                          TALLOC_CTX *mem_ctx,
2954                                          struct iovec **_vector,
2955                                          size_t *_count)
2956 {
2957         struct smbd_smb2_request_read_state *state =
2958                 talloc_get_type_abort(private_data,
2959                 struct smbd_smb2_request_read_state);
2960         struct iovec *vector = NULL;
2961         size_t min_recvfile_size = UINT32_MAX;
2962
2963         if (state->pktlen > 0) {
2964                 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
2965                         /*
2966                          * Not a possible receivefile write.
2967                          * Read the rest of the data.
2968                          */
2969                         state->doing_receivefile = false;
2970                         vector = talloc_array(mem_ctx, struct iovec, 1);
2971                         if (vector == NULL) {
2972                                 return -1;
2973                         }
2974                         vector[0].iov_base = (void *)(state->pktbuf +
2975                                 SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
2976                         vector[0].iov_len = (state->pktlen -
2977                                 SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
2978                         *_vector = vector;
2979                         *_count = 1;
2980                 } else {
2981                         /*
2982                          * Either this is a receivefile write so we've
2983                          * done a short read, or if not we have all the data.
2984                          * Either way, we're done and
2985                          * smbd_smb2_request_read_done() will handle
2986                          * and short read case by looking at the
2987                          * state->doing_receivefile value.
2988                          */
2989                         *_vector = NULL;
2990                         *_count = 0;
2991                 }
2992                 return 0;
2993         }
2994
2995         if (!state->hdr.done) {
2996                 /*
2997                  * first we need to get the NBT header
2998                  */
2999                 vector = talloc_array(mem_ctx, struct iovec, 1);
3000                 if (vector == NULL) {
3001                         return -1;
3002                 }
3003
3004                 vector[0].iov_base = (void *)state->hdr.nbt;
3005                 vector[0].iov_len = NBT_HDR_SIZE;
3006
3007                 *_vector = vector;
3008                 *_count = 1;
3009
3010                 state->hdr.done = true;
3011                 return 0;
3012         }
3013
3014         /*
3015          * Now we analyze the NBT header
3016          */
3017         state->pktlen = smb2_len(state->hdr.nbt);
3018
3019         if (state->pktlen == 0) {
3020                 /* if there're no remaining bytes, we're done */
3021                 *_vector = NULL;
3022                 *_count = 0;
3023                 return 0;
3024         }
3025
3026         state->pktbuf = talloc_array(state->smb2_req, uint8_t, state->pktlen);
3027         if (state->pktbuf == NULL) {
3028                 return -1;
3029         }
3030
3031         vector = talloc_array(mem_ctx, struct iovec, 1);
3032         if (vector == NULL) {
3033                 return -1;
3034         }
3035
3036         vector[0].iov_base = (void *)state->pktbuf;
3037
3038         if (state->min_recv_size != 0) {
3039                 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3040                 min_recvfile_size += state->min_recv_size;
3041         }
3042
3043         if (state->pktlen > min_recvfile_size) {
3044                 /*
3045                  * Might be a receivefile write. Read the SMB2 HEADER +
3046                  * SMB2_WRITE header first. Set 'doing_receivefile'
3047                  * as we're *attempting* receivefile write. If this
3048                  * turns out not to be a SMB2_WRITE request or otherwise
3049                  * not suitable then we'll just read the rest of the data
3050                  * the next time this function is called.
3051                  */
3052                 vector[0].iov_len = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3053                 state->doing_receivefile = true;
3054         } else {
3055                 vector[0].iov_len = state->pktlen;
3056         }
3057
3058         *_vector = vector;
3059         *_count = 1;
3060         return 0;
3061 }
3062
3063 static void smbd_smb2_request_read_done(struct tevent_req *subreq)
3064 {
3065         struct tevent_req *req =
3066                 tevent_req_callback_data(subreq,
3067                 struct tevent_req);
3068         struct smbd_smb2_request_read_state *state =
3069                 tevent_req_data(req,
3070                 struct smbd_smb2_request_read_state);
3071         int ret;
3072         int sys_errno;
3073         NTSTATUS status;
3074         NTTIME now;
3075
3076         ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
3077         TALLOC_FREE(subreq);
3078         if (ret == -1) {
3079                 status = map_nt_error_from_unix(sys_errno);
3080                 tevent_req_nterror(req, status);
3081                 return;
3082         }
3083
3084         if (state->hdr.nbt[0] != 0x00) {
3085                 DEBUG(1,("smbd_smb2_request_read_done: ignore NBT[0x%02X] msg\n",
3086                          state->hdr.nbt[0]));
3087
3088                 ZERO_STRUCT(state->hdr);
3089                 TALLOC_FREE(state->pktbuf);
3090                 state->pktlen = 0;
3091
3092                 subreq = tstream_readv_pdu_queue_send(state->smb2_req,
3093                                                 state->ev,
3094                                                 state->sconn->smb2.stream,
3095                                                 state->sconn->smb2.recv_queue,
3096                                                 smbd_smb2_request_next_vector,
3097                                                 state);
3098                 if (tevent_req_nomem(subreq, req)) {
3099                         return;
3100                 }
3101                 tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
3102                 return;
3103         }
3104
3105         state->smb2_req->request_time = timeval_current();
3106         now = timeval_to_nttime(&state->smb2_req->request_time);
3107
3108         status = smbd_smb2_inbuf_parse_compound(state->smb2_req->sconn->conn,
3109                                                 now,
3110                                                 state->pktbuf,
3111                                                 state->pktlen,
3112                                                 state->smb2_req,
3113                                                 &state->smb2_req->in.vector,
3114                                                 &state->smb2_req->in.vector_count);
3115         if (tevent_req_nterror(req, status)) {
3116                 return;
3117         }
3118
3119         if (state->doing_receivefile) {
3120                 state->smb2_req->smb1req = talloc_zero(state->smb2_req,
3121                                                 struct smb_request);
3122                 if (tevent_req_nomem(state->smb2_req->smb1req, req)) {
3123                         return;
3124                 }
3125                 state->smb2_req->smb1req->unread_bytes =
3126                         state->pktlen - SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3127         }
3128
3129         state->smb2_req->current_idx = 1;
3130
3131         tevent_req_done(req);
3132 }
3133
3134 static NTSTATUS smbd_smb2_request_read_recv(struct tevent_req *req,
3135                                             TALLOC_CTX *mem_ctx,
3136                                             struct smbd_smb2_request **_smb2_req)
3137 {
3138         struct smbd_smb2_request_read_state *state =
3139                 tevent_req_data(req,
3140                 struct smbd_smb2_request_read_state);
3141         NTSTATUS status;
3142
3143         if (tevent_req_is_nterror(req, &status)) {
3144                 tevent_req_received(req);
3145                 return status;
3146         }
3147
3148         *_smb2_req = talloc_move(mem_ctx, &state->smb2_req);
3149         tevent_req_received(req);
3150         return NT_STATUS_OK;
3151 }
3152
3153 static void smbd_smb2_request_incoming(struct tevent_req *subreq);
3154
3155 static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn)
3156 {
3157         size_t max_send_queue_len;
3158         size_t cur_send_queue_len;
3159         struct tevent_req *subreq;
3160
3161         if (tevent_queue_length(sconn->smb2.recv_queue) > 0) {
3162                 /*
3163                  * if there is already a smbd_smb2_request_read
3164                  * pending, we are done.
3165                  */
3166                 return NT_STATUS_OK;
3167         }
3168
3169         max_send_queue_len = MAX(1, sconn->smb2.max_credits/16);
3170         cur_send_queue_len = tevent_queue_length(sconn->smb2.send_queue);
3171
3172         if (cur_send_queue_len > max_send_queue_len) {
3173                 /*
3174                  * if we have a lot of requests to send,
3175                  * we wait until they are on the wire until we
3176                  * ask for the next request.
3177                  */
3178                 return NT_STATUS_OK;
3179         }
3180
3181         /* ask for the next request */
3182         subreq = smbd_smb2_request_read_send(sconn, sconn->ev_ctx, sconn);
3183         if (subreq == NULL) {
3184                 return NT_STATUS_NO_MEMORY;
3185         }
3186         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
3187
3188         return NT_STATUS_OK;
3189 }
3190
3191 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
3192                              uint8_t *inbuf, size_t size)
3193 {
3194         NTSTATUS status;
3195         struct smbd_smb2_request *req = NULL;
3196
3197         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3198                  (unsigned int)size));
3199
3200         status = smbd_initialize_smb2(sconn);
3201         if (!NT_STATUS_IS_OK(status)) {
3202                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3203                 return;
3204         }
3205
3206         status = smbd_smb2_request_create(sconn, inbuf, size, &req);
3207         if (!NT_STATUS_IS_OK(status)) {
3208                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3209                 return;
3210         }
3211
3212         status = smbd_smb2_request_validate(req);
3213         if (!NT_STATUS_IS_OK(status)) {
3214                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3215                 return;
3216         }
3217
3218         status = smbd_smb2_request_setup_out(req);
3219         if (!NT_STATUS_IS_OK(status)) {
3220                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3221                 return;
3222         }
3223
3224         status = smbd_smb2_request_dispatch(req);
3225         if (!NT_STATUS_IS_OK(status)) {
3226                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3227                 return;
3228         }
3229
3230         status = smbd_smb2_request_next_incoming(sconn);
3231         if (!NT_STATUS_IS_OK(status)) {
3232                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3233                 return;
3234         }
3235
3236         sconn->num_requests++;
3237 }
3238
3239 static void smbd_smb2_request_incoming(struct tevent_req *subreq)
3240 {
3241         struct smbd_server_connection *sconn = tevent_req_callback_data(subreq,
3242                                                struct smbd_server_connection);
3243         NTSTATUS status;
3244         struct smbd_smb2_request *req = NULL;
3245
3246         status = smbd_smb2_request_read_recv(subreq, sconn, &req);
3247         TALLOC_FREE(subreq);
3248         if (!NT_STATUS_IS_OK(status)) {
3249                 DEBUG(2,("smbd_smb2_request_incoming: client read error %s\n",
3250                         nt_errstr(status)));
3251                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3252                 return;
3253         }
3254
3255         DEBUG(10,("smbd_smb2_request_incoming: idx[%d] of %d vectors\n",
3256                  req->current_idx, req->in.vector_count));
3257
3258         status = smbd_smb2_request_validate(req);
3259         if (!NT_STATUS_IS_OK(status)) {
3260                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3261                 return;
3262         }
3263
3264         status = smbd_smb2_request_setup_out(req);
3265         if (!NT_STATUS_IS_OK(status)) {
3266                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3267                 return;
3268         }
3269
3270         status = smbd_smb2_request_dispatch(req);
3271         if (!NT_STATUS_IS_OK(status)) {
3272                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3273                 return;
3274         }
3275
3276         status = smbd_smb2_request_next_incoming(sconn);
3277         if (!NT_STATUS_IS_OK(status)) {
3278                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3279                 return;
3280         }
3281
3282         sconn->num_requests++;
3283
3284         /* The timeout_processing function isn't run nearly
3285            often enough to implement 'max log size' without
3286            overrunning the size of the file by many megabytes.
3287            This is especially true if we are running at debug
3288            level 10.  Checking every 50 SMB2s is a nice
3289            tradeoff of performance vs log file size overrun. */
3290
3291         if ((sconn->num_requests % 50) == 0 &&
3292             need_to_check_log_size()) {
3293                 change_to_root_user();
3294                 check_log_size();
3295         }
3296 }