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