s3:smb2_server: fix drain_socket error handling
[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 (signing_required || (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_USER_SESSION_DELETED);
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;
2648
2649                 errno = 0;
2650                 ret = drain_socket(req->sconn->sock, unread_bytes);
2651                 if (ret != unread_bytes) {
2652                         NTSTATUS error;
2653
2654                         if (errno == 0) {
2655                                 error = NT_STATUS_IO_DEVICE_ERROR;
2656                         } else {
2657                                 error = map_nt_error_from_unix_common(errno);
2658                         }
2659
2660                         DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
2661                                   "ret[%u] errno[%d] => %s\n",
2662                                   (unsigned)unread_bytes,
2663                                   (unsigned)ret, errno, nt_errstr(error)));
2664                         return error;
2665                 }
2666         }
2667
2668         body.data = outhdr + SMB2_HDR_BODY;
2669         body.length = 8;
2670         SSVAL(body.data, 0, 9);
2671
2672         if (info) {
2673                 SIVAL(body.data, 0x04, info->length);
2674         } else {
2675                 /* Allocated size of req->out.vector[i].iov_base
2676                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
2677                  * 1 byte without having to do an alloc.
2678                  */
2679                 info = talloc_zero_array(req->out.vector,
2680                                         DATA_BLOB,
2681                                         1);
2682                 if (!info) {
2683                         return NT_STATUS_NO_MEMORY;
2684                 }
2685                 info->data = ((uint8_t *)outhdr) +
2686                         OUTVEC_ALLOC_SIZE - 1;
2687                 info->length = 1;
2688                 SCVAL(info->data, 0, 0);
2689         }
2690
2691         /*
2692          * Note: Even if there is an error, continue to process the request.
2693          * per MS-SMB2.
2694          */
2695
2696         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
2697 }
2698
2699
2700 struct smbd_smb2_send_oplock_break_state {
2701         struct smbd_server_connection *sconn;
2702         uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x18];
2703         struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
2704 };
2705
2706 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq);
2707
2708 NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
2709                                      struct smbXsrv_session *session,
2710                                      struct smbXsrv_tcon *tcon,
2711                                      struct smbXsrv_open *op,
2712                                      uint8_t oplock_level)
2713 {
2714         struct smbd_smb2_send_oplock_break_state *state;
2715         struct smbXsrv_connection *conn = sconn->conn;
2716         struct tevent_req *subreq;
2717         uint8_t *tf;
2718         size_t tf_len;
2719         uint8_t *hdr;
2720         uint8_t *body;
2721         size_t body_len;
2722         uint8_t *dyn;
2723         size_t dyn_len;
2724         bool do_encryption = session->global->encryption_required;
2725         uint64_t nonce_high = 0;
2726         uint64_t nonce_low = 0;
2727
2728         if (tcon->global->encryption_required) {
2729                 do_encryption = true;
2730         }
2731
2732         state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
2733         if (state == NULL) {
2734                 return NT_STATUS_NO_MEMORY;
2735         }
2736         state->sconn = sconn;
2737
2738         tf = state->buf + NBT_HDR_SIZE;
2739         tf_len = SMB2_TF_HDR_SIZE;
2740         hdr = tf + tf_len;
2741         body = hdr + SMB2_HDR_BODY;
2742         body_len = 0x18;
2743         dyn = body + body_len;
2744         dyn_len = 0;
2745
2746         if (do_encryption) {
2747                 nonce_high = session->nonce_high;
2748                 nonce_low = session->nonce_low;
2749
2750                 session->nonce_low += 1;
2751                 if (session->nonce_low == 0) {
2752                         session->nonce_low += 1;
2753                         session->nonce_high += 1;
2754                 }
2755         }
2756
2757         SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2758         SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2759         SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2760         SBVAL(tf, SMB2_TF_SESSION_ID, session->global->session_wire_id);
2761
2762         SIVAL(hdr, 0,                           SMB2_MAGIC);
2763         SSVAL(hdr, SMB2_HDR_LENGTH,             SMB2_HDR_BODY);
2764         SSVAL(hdr, SMB2_HDR_EPOCH,              0);
2765         SIVAL(hdr, SMB2_HDR_STATUS,             0);
2766         SSVAL(hdr, SMB2_HDR_OPCODE,             SMB2_OP_BREAK);
2767         SSVAL(hdr, SMB2_HDR_CREDIT,             0);
2768         SIVAL(hdr, SMB2_HDR_FLAGS,              SMB2_HDR_FLAG_REDIRECT);
2769         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND,       0);
2770         SBVAL(hdr, SMB2_HDR_MESSAGE_ID,         UINT64_MAX);
2771         SIVAL(hdr, SMB2_HDR_PID,                0);
2772         SIVAL(hdr, SMB2_HDR_TID,                0);
2773         SBVAL(hdr, SMB2_HDR_SESSION_ID,         0);
2774         memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
2775
2776         SSVAL(body, 0x00, body_len);
2777
2778         SCVAL(body, 0x02, oplock_level);
2779         SCVAL(body, 0x03, 0);           /* reserved */
2780         SIVAL(body, 0x04, 0);           /* reserved */
2781         SBVAL(body, 0x08, op->global->open_persistent_id);
2782         SBVAL(body, 0x10, op->global->open_volatile_id);
2783
2784         state->vector[0].iov_base = (void *)state->buf;
2785         state->vector[0].iov_len = NBT_HDR_SIZE;
2786
2787         if (do_encryption) {
2788                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
2789                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
2790         } else {
2791                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
2792                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
2793         }
2794
2795         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
2796         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
2797
2798         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
2799         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = body_len;
2800
2801         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
2802         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = dyn_len;
2803
2804         smb2_setup_nbt_length(state->vector, 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2805
2806         if (do_encryption) {
2807                 NTSTATUS status;
2808                 DATA_BLOB encryption_key = session->global->encryption_key;
2809
2810                 status = smb2_signing_encrypt_pdu(encryption_key,
2811                                         conn->protocol,
2812                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2813                                         SMBD_SMB2_NUM_IOV_PER_REQ);
2814                 if (!NT_STATUS_IS_OK(status)) {
2815                         return status;
2816                 }
2817         }
2818
2819         subreq = tstream_writev_queue_send(state,
2820                                            sconn->ev_ctx,
2821                                            sconn->smb2.stream,
2822                                            sconn->smb2.send_queue,
2823                                            state->vector,
2824                                            ARRAY_SIZE(state->vector));
2825         if (subreq == NULL) {
2826                 return NT_STATUS_NO_MEMORY;
2827         }
2828         tevent_req_set_callback(subreq,
2829                                 smbd_smb2_oplock_break_writev_done,
2830                                 state);
2831
2832         return NT_STATUS_OK;
2833 }
2834
2835 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq)
2836 {
2837         struct smbd_smb2_send_oplock_break_state *state =
2838                 tevent_req_callback_data(subreq,
2839                 struct smbd_smb2_send_oplock_break_state);
2840         struct smbd_server_connection *sconn = state->sconn;
2841         int ret;
2842         int sys_errno;
2843
2844         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2845         TALLOC_FREE(subreq);
2846         if (ret == -1) {
2847                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
2848                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2849                 return;
2850         }
2851
2852         TALLOC_FREE(state);
2853 }
2854
2855 struct smbd_smb2_request_read_state {
2856         struct tevent_context *ev;
2857         struct smbd_server_connection *sconn;
2858         struct smbd_smb2_request *smb2_req;
2859         struct {
2860                 uint8_t nbt[NBT_HDR_SIZE];
2861                 bool done;
2862         } hdr;
2863         bool doing_receivefile;
2864         size_t min_recv_size;
2865         size_t pktlen;
2866         uint8_t *pktbuf;
2867 };
2868
2869 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
2870                                          void *private_data,
2871                                          TALLOC_CTX *mem_ctx,
2872                                          struct iovec **_vector,
2873                                          size_t *_count);
2874 static void smbd_smb2_request_read_done(struct tevent_req *subreq);
2875
2876 static size_t get_min_receive_file_size(struct smbd_smb2_request *smb2_req)
2877 {
2878         if (smb2_req->do_signing) {
2879                 return 0;
2880         }
2881         if (smb2_req->do_encryption) {
2882                 return 0;
2883         }
2884         return (size_t)lp_min_receive_file_size();
2885 }
2886
2887 static struct tevent_req *smbd_smb2_request_read_send(TALLOC_CTX *mem_ctx,
2888                                         struct tevent_context *ev,
2889                                         struct smbd_server_connection *sconn)
2890 {
2891         struct tevent_req *req;
2892         struct smbd_smb2_request_read_state *state;
2893         struct tevent_req *subreq;
2894
2895         req = tevent_req_create(mem_ctx, &state,
2896                                 struct smbd_smb2_request_read_state);
2897         if (req == NULL) {
2898                 return NULL;
2899         }
2900         state->ev = ev;
2901         state->sconn = sconn;
2902
2903         state->smb2_req = smbd_smb2_request_allocate(state);
2904         if (tevent_req_nomem(state->smb2_req, req)) {
2905                 return tevent_req_post(req, ev);
2906         }
2907         state->smb2_req->sconn = sconn;
2908         state->min_recv_size = get_min_receive_file_size(state->smb2_req);
2909
2910         subreq = tstream_readv_pdu_queue_send(state->smb2_req,
2911                                         state->ev,
2912                                         state->sconn->smb2.stream,
2913                                         state->sconn->smb2.recv_queue,
2914                                         smbd_smb2_request_next_vector,
2915                                         state);
2916         if (tevent_req_nomem(subreq, req)) {
2917                 return tevent_req_post(req, ev);
2918         }
2919         tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
2920
2921         return req;
2922 }
2923
2924 static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
2925 {
2926         uint32_t flags;
2927
2928         if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
2929                 /* Transform header. Cannot recvfile. */
2930                 return false;
2931         }
2932         if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
2933                 /* Not SMB2. Normal error path will cope. */
2934                 return false;
2935         }
2936         if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
2937                 /* Not SMB2. Normal error path will cope. */
2938                 return false;
2939         }
2940         if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
2941                 /* Needs to be a WRITE. */
2942                 return false;
2943         }
2944         if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
2945                 /* Chained. Cannot recvfile. */
2946                 return false;
2947         }
2948         flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
2949         if (flags & SMB2_HDR_FLAG_CHAINED) {
2950                 /* Chained. Cannot recvfile. */
2951                 return false;
2952         }
2953         if (flags & SMB2_HDR_FLAG_SIGNED) {
2954                 /* Signed. Cannot recvfile. */
2955                 return false;
2956         }
2957
2958         DEBUG(10,("Doing recvfile write len = %u\n",
2959                 (unsigned int)(state->pktlen -
2960                 SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN)));
2961
2962         return true;
2963 }
2964
2965 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
2966                                          void *private_data,
2967                                          TALLOC_CTX *mem_ctx,
2968                                          struct iovec **_vector,
2969                                          size_t *_count)
2970 {
2971         struct smbd_smb2_request_read_state *state =
2972                 talloc_get_type_abort(private_data,
2973                 struct smbd_smb2_request_read_state);
2974         struct iovec *vector = NULL;
2975         size_t min_recvfile_size = UINT32_MAX;
2976
2977         if (state->pktlen > 0) {
2978                 if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
2979                         /*
2980                          * Not a possible receivefile write.
2981                          * Read the rest of the data.
2982                          */
2983                         state->doing_receivefile = false;
2984                         vector = talloc_array(mem_ctx, struct iovec, 1);
2985                         if (vector == NULL) {
2986                                 return -1;
2987                         }
2988                         vector[0].iov_base = (void *)(state->pktbuf +
2989                                 SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
2990                         vector[0].iov_len = (state->pktlen -
2991                                 SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
2992                         *_vector = vector;
2993                         *_count = 1;
2994                 } else {
2995                         /*
2996                          * Either this is a receivefile write so we've
2997                          * done a short read, or if not we have all the data.
2998                          * Either way, we're done and
2999                          * smbd_smb2_request_read_done() will handle
3000                          * and short read case by looking at the
3001                          * state->doing_receivefile value.
3002                          */
3003                         *_vector = NULL;
3004                         *_count = 0;
3005                 }
3006                 return 0;
3007         }
3008
3009         if (!state->hdr.done) {
3010                 /*
3011                  * first we need to get the NBT header
3012                  */
3013                 vector = talloc_array(mem_ctx, struct iovec, 1);
3014                 if (vector == NULL) {
3015                         return -1;
3016                 }
3017
3018                 vector[0].iov_base = (void *)state->hdr.nbt;
3019                 vector[0].iov_len = NBT_HDR_SIZE;
3020
3021                 *_vector = vector;
3022                 *_count = 1;
3023
3024                 state->hdr.done = true;
3025                 return 0;
3026         }
3027
3028         /*
3029          * Now we analyze the NBT header
3030          */
3031         state->pktlen = smb2_len(state->hdr.nbt);
3032
3033         if (state->pktlen == 0) {
3034                 /* if there're no remaining bytes, we're done */
3035                 *_vector = NULL;
3036                 *_count = 0;
3037                 return 0;
3038         }
3039
3040         state->pktbuf = talloc_array(state->smb2_req, uint8_t, state->pktlen);
3041         if (state->pktbuf == NULL) {
3042                 return -1;
3043         }
3044
3045         vector = talloc_array(mem_ctx, struct iovec, 1);
3046         if (vector == NULL) {
3047                 return -1;
3048         }
3049
3050         vector[0].iov_base = (void *)state->pktbuf;
3051
3052         if (state->min_recv_size != 0) {
3053                 min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3054                 min_recvfile_size += state->min_recv_size;
3055         }
3056
3057         if (state->pktlen > min_recvfile_size) {
3058                 /*
3059                  * Might be a receivefile write. Read the SMB2 HEADER +
3060                  * SMB2_WRITE header first. Set 'doing_receivefile'
3061                  * as we're *attempting* receivefile write. If this
3062                  * turns out not to be a SMB2_WRITE request or otherwise
3063                  * not suitable then we'll just read the rest of the data
3064                  * the next time this function is called.
3065                  */
3066                 vector[0].iov_len = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3067                 state->doing_receivefile = true;
3068         } else {
3069                 vector[0].iov_len = state->pktlen;
3070         }
3071
3072         *_vector = vector;
3073         *_count = 1;
3074         return 0;
3075 }
3076
3077 static void smbd_smb2_request_read_done(struct tevent_req *subreq)
3078 {
3079         struct tevent_req *req =
3080                 tevent_req_callback_data(subreq,
3081                 struct tevent_req);
3082         struct smbd_smb2_request_read_state *state =
3083                 tevent_req_data(req,
3084                 struct smbd_smb2_request_read_state);
3085         int ret;
3086         int sys_errno;
3087         NTSTATUS status;
3088         NTTIME now;
3089
3090         ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
3091         TALLOC_FREE(subreq);
3092         if (ret == -1) {
3093                 status = map_nt_error_from_unix(sys_errno);
3094                 tevent_req_nterror(req, status);
3095                 return;
3096         }
3097
3098         if (state->hdr.nbt[0] != 0x00) {
3099                 DEBUG(1,("smbd_smb2_request_read_done: ignore NBT[0x%02X] msg\n",
3100                          state->hdr.nbt[0]));
3101
3102                 ZERO_STRUCT(state->hdr);
3103                 TALLOC_FREE(state->pktbuf);
3104                 state->pktlen = 0;
3105
3106                 subreq = tstream_readv_pdu_queue_send(state->smb2_req,
3107                                                 state->ev,
3108                                                 state->sconn->smb2.stream,
3109                                                 state->sconn->smb2.recv_queue,
3110                                                 smbd_smb2_request_next_vector,
3111                                                 state);
3112                 if (tevent_req_nomem(subreq, req)) {
3113                         return;
3114                 }
3115                 tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
3116                 return;
3117         }
3118
3119         state->smb2_req->request_time = timeval_current();
3120         now = timeval_to_nttime(&state->smb2_req->request_time);
3121
3122         status = smbd_smb2_inbuf_parse_compound(state->smb2_req->sconn->conn,
3123                                                 now,
3124                                                 state->pktbuf,
3125                                                 state->pktlen,
3126                                                 state->smb2_req,
3127                                                 &state->smb2_req->in.vector,
3128                                                 &state->smb2_req->in.vector_count);
3129         if (tevent_req_nterror(req, status)) {
3130                 return;
3131         }
3132
3133         if (state->doing_receivefile) {
3134                 state->smb2_req->smb1req = talloc_zero(state->smb2_req,
3135                                                 struct smb_request);
3136                 if (tevent_req_nomem(state->smb2_req->smb1req, req)) {
3137                         return;
3138                 }
3139                 state->smb2_req->smb1req->unread_bytes =
3140                         state->pktlen - SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
3141         }
3142
3143         state->smb2_req->current_idx = 1;
3144
3145         tevent_req_done(req);
3146 }
3147
3148 static NTSTATUS smbd_smb2_request_read_recv(struct tevent_req *req,
3149                                             TALLOC_CTX *mem_ctx,
3150                                             struct smbd_smb2_request **_smb2_req)
3151 {
3152         struct smbd_smb2_request_read_state *state =
3153                 tevent_req_data(req,
3154                 struct smbd_smb2_request_read_state);
3155         NTSTATUS status;
3156
3157         if (tevent_req_is_nterror(req, &status)) {
3158                 tevent_req_received(req);
3159                 return status;
3160         }
3161
3162         *_smb2_req = talloc_move(mem_ctx, &state->smb2_req);
3163         tevent_req_received(req);
3164         return NT_STATUS_OK;
3165 }
3166
3167 static void smbd_smb2_request_incoming(struct tevent_req *subreq);
3168
3169 static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn)
3170 {
3171         size_t max_send_queue_len;
3172         size_t cur_send_queue_len;
3173         struct tevent_req *subreq;
3174
3175         if (tevent_queue_length(sconn->smb2.recv_queue) > 0) {
3176                 /*
3177                  * if there is already a smbd_smb2_request_read
3178                  * pending, we are done.
3179                  */
3180                 return NT_STATUS_OK;
3181         }
3182
3183         max_send_queue_len = MAX(1, sconn->smb2.max_credits/16);
3184         cur_send_queue_len = tevent_queue_length(sconn->smb2.send_queue);
3185
3186         if (cur_send_queue_len > max_send_queue_len) {
3187                 /*
3188                  * if we have a lot of requests to send,
3189                  * we wait until they are on the wire until we
3190                  * ask for the next request.
3191                  */
3192                 return NT_STATUS_OK;
3193         }
3194
3195         /* ask for the next request */
3196         subreq = smbd_smb2_request_read_send(sconn, sconn->ev_ctx, sconn);
3197         if (subreq == NULL) {
3198                 return NT_STATUS_NO_MEMORY;
3199         }
3200         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
3201
3202         return NT_STATUS_OK;
3203 }
3204
3205 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
3206                              uint8_t *inbuf, size_t size)
3207 {
3208         NTSTATUS status;
3209         struct smbd_smb2_request *req = NULL;
3210
3211         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3212                  (unsigned int)size));
3213
3214         status = smbd_initialize_smb2(sconn);
3215         if (!NT_STATUS_IS_OK(status)) {
3216                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3217                 return;
3218         }
3219
3220         status = smbd_smb2_request_create(sconn, inbuf, size, &req);
3221         if (!NT_STATUS_IS_OK(status)) {
3222                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3223                 return;
3224         }
3225
3226         status = smbd_smb2_request_validate(req);
3227         if (!NT_STATUS_IS_OK(status)) {
3228                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3229                 return;
3230         }
3231
3232         status = smbd_smb2_request_setup_out(req);
3233         if (!NT_STATUS_IS_OK(status)) {
3234                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3235                 return;
3236         }
3237
3238         status = smbd_smb2_request_dispatch(req);
3239         if (!NT_STATUS_IS_OK(status)) {
3240                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3241                 return;
3242         }
3243
3244         status = smbd_smb2_request_next_incoming(sconn);
3245         if (!NT_STATUS_IS_OK(status)) {
3246                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3247                 return;
3248         }
3249
3250         sconn->num_requests++;
3251 }
3252
3253 static void smbd_smb2_request_incoming(struct tevent_req *subreq)
3254 {
3255         struct smbd_server_connection *sconn = tevent_req_callback_data(subreq,
3256                                                struct smbd_server_connection);
3257         NTSTATUS status;
3258         struct smbd_smb2_request *req = NULL;
3259
3260         status = smbd_smb2_request_read_recv(subreq, sconn, &req);
3261         TALLOC_FREE(subreq);
3262         if (!NT_STATUS_IS_OK(status)) {
3263                 DEBUG(2,("smbd_smb2_request_incoming: client read error %s\n",
3264                         nt_errstr(status)));
3265                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3266                 return;
3267         }
3268
3269         DEBUG(10,("smbd_smb2_request_incoming: idx[%d] of %d vectors\n",
3270                  req->current_idx, req->in.vector_count));
3271
3272         status = smbd_smb2_request_validate(req);
3273         if (!NT_STATUS_IS_OK(status)) {
3274                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3275                 return;
3276         }
3277
3278         status = smbd_smb2_request_setup_out(req);
3279         if (!NT_STATUS_IS_OK(status)) {
3280                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3281                 return;
3282         }
3283
3284         status = smbd_smb2_request_dispatch(req);
3285         if (!NT_STATUS_IS_OK(status)) {
3286                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3287                 return;
3288         }
3289
3290         status = smbd_smb2_request_next_incoming(sconn);
3291         if (!NT_STATUS_IS_OK(status)) {
3292                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3293                 return;
3294         }
3295
3296         sconn->num_requests++;
3297
3298         /* The timeout_processing function isn't run nearly
3299            often enough to implement 'max log size' without
3300            overrunning the size of the file by many megabytes.
3301            This is especially true if we are running at debug
3302            level 10.  Checking every 50 SMB2s is a nice
3303            tradeoff of performance vs log file size overrun. */
3304
3305         if ((sconn->num_requests % 50) == 0 &&
3306             need_to_check_log_size()) {
3307                 change_to_root_user();
3308                 check_log_size();
3309         }
3310 }