106e6acd0b21ae3846f03ddb18123c1f20e18eb2
[kai/samba.git] / source3 / smbd / smb2_server.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "smbprofile.h"
29 #include "../lib/util/bitmap.h"
30 #include "../librpc/gen_ndr/krb5pac.h"
31 #include "auth.h"
32
33 #define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
34
35 static const struct smbd_smb2_dispatch_table {
36         uint16_t opcode;
37         const char *name;
38         bool need_session;
39         bool need_tcon;
40         bool as_root;
41         uint16_t fileid_ofs;
42         bool allow_invalid_fileid;
43 } smbd_smb2_table[] = {
44 #define _OP(o) .opcode = o, .name = #o
45         {
46                 _OP(SMB2_OP_NEGPROT),
47                 .as_root = true,
48         },{
49                 _OP(SMB2_OP_SESSSETUP),
50                 .as_root = true,
51         },{
52                 _OP(SMB2_OP_LOGOFF),
53                 .need_session = true,
54                 .as_root = true,
55         },{
56                 _OP(SMB2_OP_TCON),
57                 .need_session = true,
58                 /*
59                  * This call needs to be run as root.
60                  *
61                  * smbd_smb2_request_process_tcon()
62                  * calls make_connection_snum(), which will call
63                  * change_to_user(), when needed.
64                  */
65                 .as_root = true,
66         },{
67                 _OP(SMB2_OP_TDIS),
68                 .need_session = true,
69                 .need_tcon = true,
70                 .as_root = true,
71         },{
72                 _OP(SMB2_OP_CREATE),
73                 .need_session = true,
74                 .need_tcon = true,
75         },{
76                 _OP(SMB2_OP_CLOSE),
77                 .need_session = true,
78                 .need_tcon = true,
79                 .fileid_ofs = 0x08,
80         },{
81                 _OP(SMB2_OP_FLUSH),
82                 .need_session = true,
83                 .need_tcon = true,
84                 .fileid_ofs = 0x08,
85         },{
86                 _OP(SMB2_OP_READ),
87                 .need_session = true,
88                 .need_tcon = true,
89                 .fileid_ofs = 0x10,
90         },{
91                 _OP(SMB2_OP_WRITE),
92                 .need_session = true,
93                 .need_tcon = true,
94                 .fileid_ofs = 0x10,
95         },{
96                 _OP(SMB2_OP_LOCK),
97                 .need_session = true,
98                 .need_tcon = true,
99                 .fileid_ofs = 0x08,
100         },{
101                 _OP(SMB2_OP_IOCTL),
102                 .need_session = true,
103                 .need_tcon = true,
104                 .fileid_ofs = 0x08,
105                 .allow_invalid_fileid = true,
106         },{
107                 _OP(SMB2_OP_CANCEL),
108                 .as_root = true,
109         },{
110                 _OP(SMB2_OP_KEEPALIVE),
111                 .as_root = true,
112         },{
113                 _OP(SMB2_OP_FIND),
114                 .need_session = true,
115                 .need_tcon = true,
116                 .fileid_ofs = 0x08,
117         },{
118                 _OP(SMB2_OP_NOTIFY),
119                 .need_session = true,
120                 .need_tcon = true,
121                 .fileid_ofs = 0x08,
122         },{
123                 _OP(SMB2_OP_GETINFO),
124                 .need_session = true,
125                 .need_tcon = true,
126                 .fileid_ofs = 0x18,
127         },{
128                 _OP(SMB2_OP_SETINFO),
129                 .need_session = true,
130                 .need_tcon = true,
131                 .fileid_ofs = 0x10,
132         },{
133                 _OP(SMB2_OP_BREAK),
134                 .need_session = true,
135                 .need_tcon = true,
136                 /*
137                  * we do not set
138                  * .fileid_ofs here
139                  * as LEASE breaks does not
140                  * have a file id
141                  */
142         }
143 };
144
145 const char *smb2_opcode_name(uint16_t opcode)
146 {
147         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
148                 return "Bad SMB2 opcode";
149         }
150         return smbd_smb2_table[opcode].name;
151 }
152
153 static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
154 {
155         const struct smbd_smb2_dispatch_table *ret = NULL;
156
157         if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
158                 return NULL;
159         }
160
161         ret = &smbd_smb2_table[opcode];
162
163         SMB_ASSERT(ret->opcode == opcode);
164
165         return ret;
166 }
167
168 static void print_req_vectors(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 = IVAL(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                 uint32_t flags;
717
718                 if (hdr->iov_len != SMB2_HDR_BODY) {
719                         return NT_STATUS_INVALID_PARAMETER;
720                 }
721
722                 if (body->iov_len < 2) {
723                         return NT_STATUS_INVALID_PARAMETER;
724                 }
725
726                 inhdr = (const uint8_t *)hdr->iov_base;
727
728                 /* Check the SMB2 header */
729                 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
730                         return NT_STATUS_INVALID_PARAMETER;
731                 }
732
733                 if (!smb2_validate_message_id(req->sconn, inhdr)) {
734                         return NT_STATUS_INVALID_PARAMETER;
735                 }
736
737                 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
738                 if (idx < SMBD_SMB2_NUM_IOV_PER_REQ) {
739                         /*
740                          * the 1st request should never have the
741                          * SMB2_HDR_FLAG_CHAINED flag set
742                          */
743                         if (flags & SMB2_HDR_FLAG_CHAINED) {
744                                 req->next_status = NT_STATUS_INVALID_PARAMETER;
745                                 return NT_STATUS_OK;
746                         }
747                 } else if (idx < 2*SMBD_SMB2_NUM_IOV_PER_REQ) {
748                         /*
749                          * the 2nd request triggers related vs. unrelated
750                          * compounded requests
751                          */
752                         if (flags & SMB2_HDR_FLAG_CHAINED) {
753                                 req->compound_related = true;
754                         }
755                 } else {
756 #if 0
757                         /*
758                          * It seems the this tests are wrong
759                          * see the SMB2-COMPOUND test
760                          */
761
762                         /*
763                          * all other requests should match the 2nd one
764                          */
765                         if (flags & SMB2_HDR_FLAG_CHAINED) {
766                                 if (!req->compound_related) {
767                                         req->next_status =
768                                                 NT_STATUS_INVALID_PARAMETER;
769                                         return NT_STATUS_OK;
770                                 }
771                         } else {
772                                 if (req->compound_related) {
773                                         req->next_status =
774                                                 NT_STATUS_INVALID_PARAMETER;
775                                         return NT_STATUS_OK;
776                                 }
777                         }
778 #endif
779                 }
780         }
781
782         return NT_STATUS_OK;
783 }
784
785 static void smb2_set_operation_credit(struct smbd_server_connection *sconn,
786                         const struct iovec *in_vector,
787                         struct iovec *out_vector)
788 {
789         const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
790         uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
791         uint16_t credit_charge = 1;
792         uint16_t credits_requested;
793         uint32_t out_flags;
794         uint16_t cmd;
795         NTSTATUS out_status;
796         uint16_t credits_granted = 0;
797         uint64_t credits_possible;
798         uint16_t current_max_credits;
799
800         /*
801          * first we grant only 1/16th of the max range.
802          *
803          * Windows also starts with the 1/16th and then grants
804          * more later. I was only able to trigger higher
805          * values, when using a verify high credit charge.
806          *
807          * TODO: scale up depending one load, free memory
808          *       or other stuff.
809          *       Maybe also on the relationship between number
810          *       of requests and the used sequence number.
811          *       Which means we would grant more credits
812          *       for client which use multi credit requests.
813          */
814         current_max_credits = sconn->smb2.max_credits / 16;
815         current_max_credits = MAX(current_max_credits, 1);
816
817         if (sconn->smb2.supports_multicredit) {
818                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
819                 credit_charge = MAX(credit_charge, 1);
820         }
821
822         cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
823         credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
824         out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
825         out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
826
827         SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
828         SMB_ASSERT(sconn->smb2.max_credits >= credit_charge);
829
830         if (out_flags & SMB2_HDR_FLAG_ASYNC) {
831                 /*
832                  * In case we already send an async interim
833                  * response, we should not grant
834                  * credits on the final response.
835                  */
836                 credits_granted = 0;
837         } else if (credits_requested > 0) {
838                 uint16_t additional_max = 0;
839                 uint16_t additional_credits = credits_requested - 1;
840
841                 switch (cmd) {
842                 case SMB2_OP_NEGPROT:
843                         break;
844                 case SMB2_OP_SESSSETUP:
845                         /*
846                          * Windows 2012 RC1 starts to grant
847                          * additional credits
848                          * with a successful session setup
849                          */
850                         if (NT_STATUS_IS_OK(out_status)) {
851                                 additional_max = 32;
852                         }
853                         break;
854                 default:
855                         /*
856                          * We match windows and only grant additional credits
857                          * in chunks of 32.
858                          */
859                         additional_max = 32;
860                         break;
861                 }
862
863                 additional_credits = MIN(additional_credits, additional_max);
864
865                 credits_granted = credit_charge + additional_credits;
866         } else if (sconn->smb2.credits_granted == 0) {
867                 /*
868                  * Make sure the client has always at least one credit
869                  */
870                 credits_granted = 1;
871         }
872
873         /*
874          * sequence numbers should not wrap
875          *
876          * 1. calculate the possible credits until
877          *    the sequence numbers start to wrap on 64-bit.
878          *
879          * 2. UINT64_MAX is used for Break Notifications.
880          *
881          * 2. truncate the possible credits to the maximum
882          *    credits we want to grant to the client in total.
883          *
884          * 3. remove the range we'll already granted to the client
885          *    this makes sure the client consumes the lowest sequence
886          *    number, before we can grant additional credits.
887          */
888         credits_possible = UINT64_MAX - sconn->smb2.seqnum_low;
889         if (credits_possible > 0) {
890                 /* remove UINT64_MAX */
891                 credits_possible -= 1;
892         }
893         credits_possible = MIN(credits_possible, current_max_credits);
894         credits_possible -= sconn->smb2.seqnum_range;
895
896         credits_granted = MIN(credits_granted, credits_possible);
897
898         SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
899         sconn->smb2.credits_granted += credits_granted;
900         sconn->smb2.seqnum_range += credits_granted;
901
902         DEBUG(10,("smb2_set_operation_credit: requested %u, charge %u, "
903                 "granted %u, current possible/max %u/%u, "
904                 "total granted/max/low/range %u/%u/%llu/%u\n",
905                 (unsigned int)credits_requested,
906                 (unsigned int)credit_charge,
907                 (unsigned int)credits_granted,
908                 (unsigned int)credits_possible,
909                 (unsigned int)current_max_credits,
910                 (unsigned int)sconn->smb2.credits_granted,
911                 (unsigned int)sconn->smb2.max_credits,
912                 (unsigned long long)sconn->smb2.seqnum_low,
913                 (unsigned int)sconn->smb2.seqnum_range));
914 }
915
916 static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
917                                 struct smbd_smb2_request *outreq)
918 {
919         int count, idx;
920         uint16_t total_credits = 0;
921
922         count = outreq->out.vector_count;
923
924         for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
925                 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
926                 struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
927                 uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
928
929                 smb2_set_operation_credit(outreq->sconn, inhdr_v, outhdr_v);
930
931                 /* To match Windows, count up what we
932                    just granted. */
933                 total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
934                 /* Set to zero in all but the last reply. */
935                 if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
936                         SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
937                 } else {
938                         SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
939                 }
940         }
941 }
942
943 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
944 {
945         struct iovec *vector;
946         int count;
947         int idx;
948
949         count = req->in.vector_count;
950         vector = talloc_zero_array(req, struct iovec, count);
951         if (vector == NULL) {
952                 return NT_STATUS_NO_MEMORY;
953         }
954
955         vector[0].iov_base      = req->out.nbt_hdr;
956         vector[0].iov_len       = 4;
957         SIVAL(req->out.nbt_hdr, 0, 0);
958
959         for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
960                 struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
961                 const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
962                 uint8_t *outhdr = NULL;
963                 uint8_t *outbody = NULL;
964                 uint32_t next_command_ofs = 0;
965                 struct iovec *current = &vector[idx];
966
967                 if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
968                         /* we have a next command -
969                          * setup for the error case. */
970                         next_command_ofs = SMB2_HDR_BODY + 9;
971                 }
972
973                 outhdr = talloc_zero_array(vector, uint8_t,
974                                       OUTVEC_ALLOC_SIZE);
975                 if (outhdr == NULL) {
976                         return NT_STATUS_NO_MEMORY;
977                 }
978
979                 outbody = outhdr + SMB2_HDR_BODY;
980
981                 /*
982                  * SMBD_SMB2_TF_IOV_OFS might be used later
983                  */
984                 current[SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
985                 current[SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
986
987                 current[SMBD_SMB2_HDR_IOV_OFS].iov_base  = (void *)outhdr;
988                 current[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
989
990                 current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
991                 current[SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
992
993                 current[SMBD_SMB2_DYN_IOV_OFS].iov_base  = NULL;
994                 current[SMBD_SMB2_DYN_IOV_OFS].iov_len   = 0;
995
996                 /* setup the SMB2 header */
997                 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID,     SMB2_MAGIC);
998                 SSVAL(outhdr, SMB2_HDR_LENGTH,          SMB2_HDR_BODY);
999                 SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1000                       SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1001                 SIVAL(outhdr, SMB2_HDR_STATUS,
1002                       NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1003                 SSVAL(outhdr, SMB2_HDR_OPCODE,
1004                       SVAL(inhdr, SMB2_HDR_OPCODE));
1005                 SIVAL(outhdr, SMB2_HDR_FLAGS,
1006                       IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1007                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND,    next_command_ofs);
1008                 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1009                       BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1010                 SIVAL(outhdr, SMB2_HDR_PID,
1011                       IVAL(inhdr, SMB2_HDR_PID));
1012                 SIVAL(outhdr, SMB2_HDR_TID,
1013                       IVAL(inhdr, SMB2_HDR_TID));
1014                 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1015                       BVAL(inhdr, SMB2_HDR_SESSION_ID));
1016                 memcpy(outhdr + SMB2_HDR_SIGNATURE,
1017                        inhdr + SMB2_HDR_SIGNATURE, 16);
1018
1019                 /* setup error body header */
1020                 SSVAL(outbody, 0x00, 0x08 + 1);
1021                 SSVAL(outbody, 0x02, 0);
1022                 SIVAL(outbody, 0x04, 0);
1023         }
1024
1025         req->out.vector = vector;
1026         req->out.vector_count = count;
1027
1028         /* setup the length of the NBT packet */
1029         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1030
1031         DLIST_ADD_END(req->sconn->smb2.requests, req, struct smbd_smb2_request *);
1032
1033         return NT_STATUS_OK;
1034 }
1035
1036 void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
1037                                          const char *reason,
1038                                          const char *location)
1039 {
1040         DEBUG(10,("smbd_server_connection_terminate_ex: reason[%s] at %s\n",
1041                   reason, location));
1042         exit_server_cleanly(reason);
1043 }
1044
1045 static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1046                         struct iovec *outvec,
1047                         const struct iovec *srcvec)
1048 {
1049         const uint8_t *srctf;
1050         size_t srctf_len;
1051         const uint8_t *srchdr;
1052         size_t srchdr_len;
1053         const uint8_t *srcbody;
1054         size_t srcbody_len;
1055         const uint8_t *expected_srcbody;
1056         const uint8_t *srcdyn;
1057         size_t srcdyn_len;
1058         const uint8_t *expected_srcdyn;
1059         uint8_t *dsttf;
1060         uint8_t *dsthdr;
1061         uint8_t *dstbody;
1062         uint8_t *dstdyn;
1063
1064         srctf  = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1065         srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1066         srchdr  = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1067         srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1068         srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1069         srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1070         expected_srcbody = srchdr + SMB2_HDR_BODY;
1071         srcdyn  = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1072         srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1073         expected_srcdyn = srcbody + 8;
1074
1075         if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1076                 return false;
1077         }
1078
1079         if (srchdr_len != SMB2_HDR_BODY) {
1080                 return false;
1081         }
1082
1083         if (srctf_len == SMB2_TF_HDR_SIZE) {
1084                 dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1085                 if (dsttf == NULL) {
1086                         return false;
1087                 }
1088         } else {
1089                 dsttf = NULL;
1090         }
1091         outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1092         outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1093
1094         /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1095          * be allocated with size OUTVEC_ALLOC_SIZE. */
1096
1097         dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1098         if (dsthdr == NULL) {
1099                 return false;
1100         }
1101         outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1102         outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1103
1104         /*
1105          * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1106          * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1107          * then duplicate this. Else use talloc_memdup().
1108          */
1109
1110         if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1111                 dstbody = dsthdr + SMB2_HDR_BODY;
1112         } else {
1113                 dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1114                 if (dstbody == NULL) {
1115                         return false;
1116                 }
1117         }
1118         outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1119         outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1120
1121         /*
1122          * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1123          * pointing to
1124          * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1125          * then duplicate this. Else use talloc_memdup().
1126          */
1127
1128         if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1129                 dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1130         } else if (srcdyn == NULL) {
1131                 dstdyn = NULL;
1132         } else {
1133                 dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1134                 if (dstdyn == NULL) {
1135                         return false;
1136                 }
1137         }
1138         outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1139         outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1140
1141         return true;
1142 }
1143
1144 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1145 {
1146         struct smbd_smb2_request *newreq = NULL;
1147         struct iovec *outvec = NULL;
1148         int count = req->out.vector_count;
1149         int i;
1150
1151         newreq = smbd_smb2_request_allocate(req->sconn);
1152         if (!newreq) {
1153                 return NULL;
1154         }
1155
1156         newreq->sconn = req->sconn;
1157         newreq->session = req->session;
1158         newreq->do_encryption = req->do_encryption;
1159         newreq->do_signing = req->do_signing;
1160         newreq->current_idx = req->current_idx;
1161
1162         outvec = talloc_zero_array(newreq, struct iovec, count);
1163         if (!outvec) {
1164                 TALLOC_FREE(newreq);
1165                 return NULL;
1166         }
1167         newreq->out.vector = outvec;
1168         newreq->out.vector_count = count;
1169
1170         /* Setup the outvec's identically to req. */
1171         outvec[0].iov_base = newreq->out.nbt_hdr;
1172         outvec[0].iov_len = 4;
1173         memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1174
1175         /* Setup the vectors identically to the ones in req. */
1176         for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1177                 if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1178                         break;
1179                 }
1180         }
1181
1182         if (i < count) {
1183                 /* Alloc failed. */
1184                 TALLOC_FREE(newreq);
1185                 return NULL;
1186         }
1187
1188         smb2_setup_nbt_length(newreq->out.vector,
1189                 newreq->out.vector_count);
1190
1191         return newreq;
1192 }
1193
1194 static void smbd_smb2_request_writev_done(struct tevent_req *subreq);
1195
1196 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
1197 {
1198         struct smbXsrv_connection *conn = req->sconn->conn;
1199         int first_idx = 1;
1200         struct iovec *firsttf = NULL;
1201         struct iovec *outhdr_v = NULL;
1202         uint8_t *outhdr = NULL;
1203         struct smbd_smb2_request *nreq = NULL;
1204         NTSTATUS status;
1205
1206         /* Create a new smb2 request we'll use
1207            for the interim return. */
1208         nreq = dup_smb2_req(req);
1209         if (!nreq) {
1210                 return NT_STATUS_NO_MEMORY;
1211         }
1212
1213         /* Lose the last X out vectors. They're the
1214            ones we'll be using for the async reply. */
1215         nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
1216
1217         smb2_setup_nbt_length(nreq->out.vector,
1218                 nreq->out.vector_count);
1219
1220         /* Step back to the previous reply. */
1221         nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
1222         firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
1223         outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
1224         outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
1225         /* And end the chain. */
1226         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
1227
1228         /* Calculate outgoing credits */
1229         smb2_calculate_credits(req, nreq);
1230
1231         if (DEBUGLEVEL >= 10) {
1232                 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1233                         (unsigned int)nreq->current_idx );
1234                 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1235                         (unsigned int)nreq->out.vector_count );
1236                 print_req_vectors(nreq);
1237         }
1238
1239         /*
1240          * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1241          * we need to sign/encrypt here with the last/first key we remembered
1242          */
1243         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
1244                 status = smb2_signing_encrypt_pdu(req->first_key,
1245                                         conn->protocol,
1246                                         firsttf,
1247                                         nreq->out.vector_count - first_idx);
1248                 if (!NT_STATUS_IS_OK(status)) {
1249                         return status;
1250                 }
1251         } else if (req->last_key.length > 0) {
1252                 status = smb2_signing_sign_pdu(req->last_key,
1253                                                conn->protocol,
1254                                                outhdr_v,
1255                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1256                 if (!NT_STATUS_IS_OK(status)) {
1257                         return status;
1258                 }
1259         }
1260
1261         nreq->subreq = tstream_writev_queue_send(nreq,
1262                                         nreq->sconn->ev_ctx,
1263                                         nreq->sconn->smb2.stream,
1264                                         nreq->sconn->smb2.send_queue,
1265                                         nreq->out.vector,
1266                                         nreq->out.vector_count);
1267
1268         if (nreq->subreq == NULL) {
1269                 return NT_STATUS_NO_MEMORY;
1270         }
1271
1272         tevent_req_set_callback(nreq->subreq,
1273                         smbd_smb2_request_writev_done,
1274                         nreq);
1275
1276         return NT_STATUS_OK;
1277 }
1278
1279 struct smbd_smb2_request_pending_state {
1280         struct smbd_server_connection *sconn;
1281         uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1282         struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1283 };
1284
1285 static void smbd_smb2_request_pending_writev_done(struct tevent_req *subreq)
1286 {
1287         struct smbd_smb2_request_pending_state *state =
1288                 tevent_req_callback_data(subreq,
1289                         struct smbd_smb2_request_pending_state);
1290         struct smbd_server_connection *sconn = state->sconn;
1291         int ret;
1292         int sys_errno;
1293
1294         ret = tstream_writev_queue_recv(subreq, &sys_errno);
1295         TALLOC_FREE(subreq);
1296         if (ret == -1) {
1297                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
1298                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1299                 return;
1300         }
1301
1302         TALLOC_FREE(state);
1303 }
1304
1305 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1306                                             struct tevent_timer *te,
1307                                             struct timeval current_time,
1308                                             void *private_data);
1309
1310 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1311                                          struct tevent_req *subreq,
1312                                          uint32_t defer_time)
1313 {
1314         NTSTATUS status;
1315         int idx = req->current_idx;
1316         struct timeval defer_endtime;
1317         uint8_t *outhdr = NULL;
1318         uint32_t flags;
1319
1320         if (!tevent_req_is_in_progress(subreq)) {
1321                 return NT_STATUS_OK;
1322         }
1323
1324         req->subreq = subreq;
1325         subreq = NULL;
1326
1327         if (req->async_te) {
1328                 /* We're already async. */
1329                 return NT_STATUS_OK;
1330         }
1331
1332         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1333         flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1334         if (flags & SMB2_HDR_FLAG_ASYNC) {
1335                 /* We're already async. */
1336                 return NT_STATUS_OK;
1337         }
1338
1339         if (req->in.vector_count > idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
1340                 /*
1341                  * We're trying to go async in a compound
1342                  * request chain. This is not allowed.
1343                  * Cancel the outstanding request.
1344                  */
1345                 tevent_req_cancel(req->subreq);
1346                 return smbd_smb2_request_error(req,
1347                         NT_STATUS_INSUFFICIENT_RESOURCES);
1348         }
1349
1350         if (DEBUGLEVEL >= 10) {
1351                 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
1352                         (unsigned int)req->current_idx );
1353                 print_req_vectors(req);
1354         }
1355
1356         if (req->out.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ)) {
1357                 /*
1358                  * This is a compound reply. We
1359                  * must do an interim response
1360                  * followed by the async response
1361                  * to match W2K8R2.
1362                  */
1363                 status = smb2_send_async_interim_response(req);
1364                 if (!NT_STATUS_IS_OK(status)) {
1365                         return status;
1366                 }
1367                 data_blob_clear_free(&req->first_key);
1368
1369                 /*
1370                  * We're splitting off the last SMB2
1371                  * request in a compound set, and the
1372                  * smb2_send_async_interim_response()
1373                  * call above just sent all the replies
1374                  * for the previous SMB2 requests in
1375                  * this compound set. So we're no longer
1376                  * in the "compound_related_in_progress"
1377                  * state, and this is no longer a compound
1378                  * request.
1379                  */
1380                 req->compound_related = false;
1381                 req->sconn->smb2.compound_related_in_progress = false;
1382
1383                 req->current_idx = 1;
1384
1385                 /* Re-arrange the in.vectors. */
1386                 memmove(&req->in.vector[req->current_idx],
1387                         &req->in.vector[idx],
1388                         sizeof(req->in.vector[0])*SMBD_SMB2_NUM_IOV_PER_REQ);
1389                 req->in.vector_count = req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ;
1390
1391                 /* Re-arrange the out.vectors. */
1392                 memmove(&req->out.vector[req->current_idx],
1393                         &req->out.vector[idx],
1394                         sizeof(req->out.vector[0])*SMBD_SMB2_NUM_IOV_PER_REQ);
1395                 req->out.vector_count = req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ;
1396
1397                 outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1398                 flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
1399                 SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
1400         }
1401         data_blob_clear_free(&req->last_key);
1402
1403         defer_endtime = timeval_current_ofs_usec(defer_time);
1404         req->async_te = tevent_add_timer(req->sconn->ev_ctx,
1405                                          req, defer_endtime,
1406                                          smbd_smb2_request_pending_timer,
1407                                          req);
1408         if (req->async_te == NULL) {
1409                 return NT_STATUS_NO_MEMORY;
1410         }
1411
1412         return NT_STATUS_OK;
1413 }
1414
1415 static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1416                                             struct tevent_timer *te,
1417                                             struct timeval current_time,
1418                                             void *private_data)
1419 {
1420         struct smbd_smb2_request *req =
1421                 talloc_get_type_abort(private_data,
1422                 struct smbd_smb2_request);
1423         struct smbd_smb2_request_pending_state *state = NULL;
1424         uint8_t *outhdr = NULL;
1425         const uint8_t *inhdr = NULL;
1426         uint8_t *tf = NULL;
1427         size_t tf_len = 0;
1428         uint8_t *hdr = NULL;
1429         uint8_t *body = NULL;
1430         uint8_t *dyn = NULL;
1431         uint32_t flags = 0;
1432         uint64_t session_id = 0;
1433         uint64_t message_id = 0;
1434         uint64_t nonce_high;
1435         uint64_t nonce_low;
1436         uint64_t async_id = 0;
1437         struct tevent_req *subreq = NULL;
1438
1439         TALLOC_FREE(req->async_te);
1440
1441         /* Ensure our final reply matches the interim one. */
1442         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1443         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
1444         flags = IVAL(outhdr, SMB2_HDR_FLAGS);
1445         message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1446         session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
1447
1448         async_id = message_id; /* keep it simple for now... */
1449
1450         SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1451         SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
1452
1453         DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
1454                 "going async\n",
1455                 smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
1456                 (unsigned long long)async_id ));
1457
1458         /*
1459          * What we send is identical to a smbd_smb2_request_error
1460          * packet with an error status of STATUS_PENDING. Make use
1461          * of this fact sometime when refactoring. JRA.
1462          */
1463
1464         state = talloc_zero(req->sconn, struct smbd_smb2_request_pending_state);
1465         if (state == NULL) {
1466                 smbd_server_connection_terminate(req->sconn,
1467                                                  nt_errstr(NT_STATUS_NO_MEMORY));
1468                 return;
1469         }
1470         state->sconn = req->sconn;
1471
1472         tf = state->buf + NBT_HDR_SIZE;
1473         tf_len = SMB2_TF_HDR_SIZE;
1474
1475         hdr = tf + SMB2_TF_HDR_SIZE;
1476         body = hdr + SMB2_HDR_BODY;
1477         dyn = body + 8;
1478
1479         /*
1480          * We may have 2 responses (PENDING, FINAL),
1481          * so alter the nonce.
1482          *
1483          * The PENDING response has the SMB2_HDR_FLAG_ASYNC bit
1484          * set.
1485          */
1486         nonce_high = session_id | SMB2_HDR_FLAG_ASYNC;
1487         nonce_low = message_id;
1488
1489         SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
1490         SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
1491         SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
1492         SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
1493
1494         SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1495         SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1496         SSVAL(hdr, SMB2_HDR_EPOCH, 0);
1497         SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
1498         SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
1499
1500         SIVAL(hdr, SMB2_HDR_FLAGS, flags);
1501         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
1502         SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
1503         SBVAL(hdr, SMB2_HDR_PID, async_id);
1504         SBVAL(hdr, SMB2_HDR_SESSION_ID,
1505                 BVAL(outhdr, SMB2_HDR_SESSION_ID));
1506         memcpy(hdr+SMB2_HDR_SIGNATURE,
1507                outhdr+SMB2_HDR_SIGNATURE, 16);
1508
1509         SSVAL(body, 0x00, 0x08 + 1);
1510
1511         SCVAL(body, 0x02, 0);
1512         SCVAL(body, 0x03, 0);
1513         SIVAL(body, 0x04, 0);
1514         /* Match W2K8R2... */
1515         SCVAL(dyn,  0x00, 0x21);
1516
1517         state->vector[0].iov_base = (void *)state->buf;
1518         state->vector[0].iov_len = NBT_HDR_SIZE;
1519
1520         if (req->do_encryption) {
1521                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
1522                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
1523         } else {
1524                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
1525                 state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
1526         }
1527
1528         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
1529         state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
1530
1531         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
1532         state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
1533
1534         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
1535         state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = 1;
1536
1537         smb2_setup_nbt_length(state->vector, 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
1538
1539         /* Ensure we correctly go through crediting. Grant
1540            the credits now, and zero credits on the final
1541            response. */
1542         smb2_set_operation_credit(req->sconn,
1543                         SMBD_SMB2_IN_HDR_IOV(req),
1544                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
1545
1546         SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
1547
1548         if (DEBUGLVL(10)) {
1549                 int i;
1550
1551                 for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
1552                         dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
1553                                 (unsigned int)i,
1554                                 (unsigned int)ARRAY_SIZE(state->vector),
1555                                 (unsigned int)state->vector[i].iov_len);
1556                         dump_data(0, state->vector[i].iov_base, state->vector[i].iov_len);
1557                 }
1558         }
1559
1560         if (req->do_encryption) {
1561                 NTSTATUS status;
1562                 struct smbXsrv_session *x = req->session;
1563                 struct smbXsrv_connection *conn = x->connection;
1564                 DATA_BLOB encryption_key = x->global->encryption_key;
1565
1566                 status = smb2_signing_encrypt_pdu(encryption_key,
1567                                         conn->protocol,
1568                                         &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
1569                                         SMBD_SMB2_NUM_IOV_PER_REQ);
1570                 if (!NT_STATUS_IS_OK(status)) {
1571                         smbd_server_connection_terminate(req->sconn,
1572                                                 nt_errstr(status));
1573                         return;
1574                 }
1575         } else if (req->do_signing) {
1576                 NTSTATUS status;
1577                 struct smbXsrv_session *x = req->session;
1578                 struct smbXsrv_connection *conn = x->connection;
1579                 DATA_BLOB signing_key = x->global->channels[0].signing_key;
1580
1581                 status = smb2_signing_sign_pdu(signing_key,
1582                                         conn->protocol,
1583                                         &state->vector[1+SMBD_SMB2_HDR_IOV_OFS],
1584                                         SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1585                 if (!NT_STATUS_IS_OK(status)) {
1586                         smbd_server_connection_terminate(req->sconn,
1587                                                 nt_errstr(status));
1588                         return;
1589                 }
1590         }
1591
1592         subreq = tstream_writev_queue_send(state,
1593                                         state->sconn->ev_ctx,
1594                                         state->sconn->smb2.stream,
1595                                         state->sconn->smb2.send_queue,
1596                                         state->vector,
1597                                         ARRAY_SIZE(state->vector));
1598         if (subreq == NULL) {
1599                 smbd_server_connection_terminate(state->sconn,
1600                                                  nt_errstr(NT_STATUS_NO_MEMORY));
1601                 return;
1602         }
1603         tevent_req_set_callback(subreq,
1604                         smbd_smb2_request_pending_writev_done,
1605                         state);
1606 }
1607
1608 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
1609 {
1610         struct smbd_server_connection *sconn = req->sconn;
1611         struct smbd_smb2_request *cur;
1612         const uint8_t *inhdr;
1613         uint32_t flags;
1614         uint64_t search_message_id;
1615         uint64_t search_async_id;
1616         uint64_t found_id;
1617
1618         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1619
1620         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1621         search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1622         search_async_id = BVAL(inhdr, SMB2_HDR_PID);
1623
1624         /*
1625          * we don't need the request anymore
1626          * cancel requests never have a response
1627          */
1628         DLIST_REMOVE(req->sconn->smb2.requests, req);
1629         TALLOC_FREE(req);
1630
1631         for (cur = sconn->smb2.requests; cur; cur = cur->next) {
1632                 const uint8_t *outhdr;
1633                 uint64_t message_id;
1634                 uint64_t async_id;
1635
1636                 outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
1637
1638                 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
1639                 async_id = BVAL(outhdr, SMB2_HDR_PID);
1640
1641                 if (flags & SMB2_HDR_FLAG_ASYNC) {
1642                         if (search_async_id == async_id) {
1643                                 found_id = async_id;
1644                                 break;
1645                         }
1646                 } else {
1647                         if (search_message_id == message_id) {
1648                                 found_id = message_id;
1649                                 break;
1650                         }
1651                 }
1652         }
1653
1654         if (cur && cur->subreq) {
1655                 inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
1656                 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
1657                         "cancel opcode[%s] mid %llu\n",
1658                         smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
1659                         (unsigned long long)found_id ));
1660                 tevent_req_cancel(cur->subreq);
1661         }
1662
1663         return NT_STATUS_OK;
1664 }
1665
1666 /*************************************************************
1667  Ensure an incoming tid is a valid one for us to access.
1668  Change to the associated uid credentials and chdir to the
1669  valid tid directory.
1670 *************************************************************/
1671
1672 static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
1673 {
1674         const uint8_t *inhdr;
1675         uint32_t in_flags;
1676         uint32_t in_tid;
1677         struct smbXsrv_tcon *tcon;
1678         NTSTATUS status;
1679         NTTIME now = timeval_to_nttime(&req->request_time);
1680
1681         req->tcon = NULL;
1682
1683         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1684
1685         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1686         in_tid = IVAL(inhdr, SMB2_HDR_TID);
1687
1688         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1689                 in_tid = req->last_tid;
1690         }
1691
1692         status = smb2srv_tcon_lookup(req->session,
1693                                      in_tid, now, &tcon);
1694         if (!NT_STATUS_IS_OK(status)) {
1695                 return status;
1696         }
1697
1698         if (!change_to_user(tcon->compat, req->session->compat->vuid)) {
1699                 return NT_STATUS_ACCESS_DENIED;
1700         }
1701
1702         /* should we pass FLAG_CASELESS_PATHNAMES here? */
1703         if (!set_current_service(tcon->compat, 0, true)) {
1704                 return NT_STATUS_ACCESS_DENIED;
1705         }
1706
1707         req->tcon = tcon;
1708         req->last_tid = in_tid;
1709
1710         return NT_STATUS_OK;
1711 }
1712
1713 /*************************************************************
1714  Ensure an incoming session_id is a valid one for us to access.
1715 *************************************************************/
1716
1717 static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
1718 {
1719         const uint8_t *inhdr;
1720         uint32_t in_flags;
1721         uint16_t in_opcode;
1722         uint64_t in_session_id;
1723         struct smbXsrv_session *session = NULL;
1724         struct auth_session_info *session_info;
1725         NTSTATUS status;
1726         NTTIME now = timeval_to_nttime(&req->request_time);
1727
1728         req->session = NULL;
1729         req->tcon = NULL;
1730
1731         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1732
1733         in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1734         in_opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
1735         in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
1736
1737         if (in_flags & SMB2_HDR_FLAG_CHAINED) {
1738                 in_session_id = req->last_session_id;
1739         }
1740
1741         /* lookup an existing session */
1742         status = smb2srv_session_lookup(req->sconn->conn,
1743                                         in_session_id, now,
1744                                         &session);
1745         if (session) {
1746                 req->session = session;
1747                 req->last_session_id = in_session_id;
1748         }
1749         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1750                 switch (in_opcode) {
1751                 case SMB2_OP_SESSSETUP:
1752                         status = NT_STATUS_OK;
1753                         break;
1754                 default:
1755                         break;
1756                 }
1757         }
1758         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1759                 switch (in_opcode) {
1760                 case SMB2_OP_TCON:
1761                 case SMB2_OP_CREATE:
1762                 case SMB2_OP_GETINFO:
1763                 case SMB2_OP_SETINFO:
1764                         return NT_STATUS_INVALID_HANDLE;
1765                 default:
1766                         /*
1767                          * Notice the check for
1768                          * (session_info == NULL)
1769                          * below.
1770                          */
1771                         status = NT_STATUS_OK;
1772                         break;
1773                 }
1774         }
1775         if (!NT_STATUS_IS_OK(status)) {
1776                 return status;
1777         }
1778
1779         session_info = session->global->auth_session_info;
1780         if (session_info == NULL) {
1781                 return NT_STATUS_INVALID_HANDLE;
1782         }
1783
1784         set_current_user_info(session_info->unix_info->sanitized_username,
1785                               session_info->unix_info->unix_name,
1786                               session_info->info->domain_name);
1787
1788         return NT_STATUS_OK;
1789 }
1790
1791 NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
1792                                                 uint32_t data_length)
1793 {
1794         uint16_t needed_charge;
1795         uint16_t credit_charge = 1;
1796         const uint8_t *inhdr;
1797
1798         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1799
1800         if (req->sconn->smb2.supports_multicredit) {
1801                 credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
1802                 credit_charge = MAX(credit_charge, 1);
1803         }
1804
1805         needed_charge = (data_length - 1)/ 65536 + 1;
1806
1807         DEBUG(10, ("mid %llu, CreditCharge: %d, NeededCharge: %d\n",
1808                    (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
1809                    credit_charge, needed_charge));
1810
1811         if (needed_charge > credit_charge) {
1812                 DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
1813                           credit_charge, needed_charge));
1814                 return NT_STATUS_INVALID_PARAMETER;
1815         }
1816
1817         return NT_STATUS_OK;
1818 }
1819
1820 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
1821                                         size_t expected_body_size)
1822 {
1823         struct iovec *inhdr_v;
1824         const uint8_t *inhdr;
1825         uint16_t opcode;
1826         const uint8_t *inbody;
1827         size_t body_size;
1828         size_t min_dyn_size = expected_body_size & 0x00000001;
1829         int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
1830
1831         /*
1832          * The following should be checked already.
1833          */
1834         if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
1835                 return NT_STATUS_INTERNAL_ERROR;
1836         }
1837         if (req->current_idx > max_idx) {
1838                 return NT_STATUS_INTERNAL_ERROR;
1839         }
1840
1841         inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
1842         if (inhdr_v->iov_len != SMB2_HDR_BODY) {
1843                 return NT_STATUS_INTERNAL_ERROR;
1844         }
1845         if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
1846                 return NT_STATUS_INTERNAL_ERROR;
1847         }
1848
1849         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1850         opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
1851
1852         switch (opcode) {
1853         case SMB2_OP_IOCTL:
1854         case SMB2_OP_GETINFO:
1855                 min_dyn_size = 0;
1856                 break;
1857         }
1858
1859         /*
1860          * Now check the expected body size,
1861          * where the last byte might be in the
1862          * dynamic section..
1863          */
1864         if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
1865                 return NT_STATUS_INVALID_PARAMETER;
1866         }
1867         if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
1868                 return NT_STATUS_INVALID_PARAMETER;
1869         }
1870
1871         inbody = SMBD_SMB2_IN_BODY_PTR(req);
1872
1873         body_size = SVAL(inbody, 0x00);
1874         if (body_size != expected_body_size) {
1875                 return NT_STATUS_INVALID_PARAMETER;
1876         }
1877
1878         return NT_STATUS_OK;
1879 }
1880
1881 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
1882 {
1883         struct smbXsrv_connection *conn = req->sconn->conn;
1884         const struct smbd_smb2_dispatch_table *call = NULL;
1885         const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
1886         const uint8_t *inhdr;
1887         uint16_t opcode;
1888         uint32_t flags;
1889         uint64_t mid;
1890         NTSTATUS status;
1891         NTSTATUS session_status;
1892         uint32_t allowed_flags;
1893         NTSTATUS return_value;
1894         struct smbXsrv_session *x = NULL;
1895         bool signing_required = false;
1896         bool encryption_required = false;
1897
1898         inhdr = SMBD_SMB2_IN_HDR_PTR(req);
1899
1900         /* TODO: verify more things */
1901
1902         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
1903         opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
1904         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
1905         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
1906                 smb2_opcode_name(opcode),
1907                 (unsigned long long)mid));
1908
1909         if (conn->protocol >= PROTOCOL_SMB2_02) {
1910                 /*
1911                  * once the protocol is negotiated
1912                  * SMB2_OP_NEGPROT is not allowed anymore
1913                  */
1914                 if (opcode == SMB2_OP_NEGPROT) {
1915                         /* drop the connection */
1916                         return NT_STATUS_INVALID_PARAMETER;
1917                 }
1918         } else {
1919                 /*
1920                  * if the protocol is not negotiated yet
1921                  * only SMB2_OP_NEGPROT is allowed.
1922                  */
1923                 if (opcode != SMB2_OP_NEGPROT) {
1924                         /* drop the connection */
1925                         return NT_STATUS_INVALID_PARAMETER;
1926                 }
1927         }
1928
1929         /*
1930          * Check if the client provided a valid session id,
1931          * if so smbd_smb2_request_check_session() calls
1932          * set_current_user_info().
1933          *
1934          * As some command don't require a valid session id
1935          * we defer the check of the session_status
1936          */
1937         session_status = smbd_smb2_request_check_session(req);
1938         x = req->session;
1939         if (x != NULL) {
1940                 signing_required = x->global->signing_required;
1941                 encryption_required = x->global->encryption_required;
1942
1943                 if (opcode == SMB2_OP_SESSSETUP &&
1944                     x->global->channels[0].signing_key.length) {
1945                         signing_required = true;
1946                 }
1947         }
1948
1949         req->do_signing = false;
1950         req->do_encryption = false;
1951         if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
1952                 const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
1953                 uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
1954
1955                 if (x != NULL && x->global->session_wire_id != tf_session_id) {
1956                         DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
1957                                  "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
1958                                  (unsigned long long)x->global->session_wire_id,
1959                                  (unsigned long long)tf_session_id));
1960                         /*
1961                          * TODO: windows allows this...
1962                          * should we drop the connection?
1963                          *
1964                          * For now we just return ACCESS_DENIED
1965                          * (Windows clients never trigger this)
1966                          * and wait for an update of [MS-SMB2].
1967                          */
1968                         return smbd_smb2_request_error(req,
1969                                         NT_STATUS_ACCESS_DENIED);
1970                 }
1971
1972                 req->do_encryption = true;
1973         }
1974
1975         if (encryption_required && !req->do_encryption) {
1976                 return smbd_smb2_request_error(req,
1977                                 NT_STATUS_ACCESS_DENIED);
1978         }
1979
1980         call = smbd_smb2_call(opcode);
1981         if (call == NULL) {
1982                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
1983         }
1984
1985         allowed_flags = SMB2_HDR_FLAG_CHAINED |
1986                         SMB2_HDR_FLAG_SIGNED |
1987                         SMB2_HDR_FLAG_DFS;
1988         if (opcode == SMB2_OP_CANCEL) {
1989                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
1990         }
1991         if ((flags & ~allowed_flags) != 0) {
1992                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
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);
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                 /*
2045                  * This check is mostly for giving the correct error code
2046                  * for compounded requests.
2047                  *
2048                  * TODO: we may need to move this after the session
2049                  *       and tcon checks.
2050                  */
2051                 if (!NT_STATUS_IS_OK(req->next_status)) {
2052                         return smbd_smb2_request_error(req, req->next_status);
2053                 }
2054         } else {
2055                 req->compat_chain_fsp = NULL;
2056         }
2057
2058         if (req->compound_related) {
2059                 req->sconn->smb2.compound_related_in_progress = true;
2060         }
2061
2062         if (call->need_session) {
2063                 if (!NT_STATUS_IS_OK(session_status)) {
2064                         return smbd_smb2_request_error(req, session_status);
2065                 }
2066         }
2067
2068         if (call->need_tcon) {
2069                 SMB_ASSERT(call->need_session);
2070
2071                 /*
2072                  * This call needs to be run as user.
2073                  *
2074                  * smbd_smb2_request_check_tcon()
2075                  * calls change_to_user() on success.
2076                  */
2077                 status = smbd_smb2_request_check_tcon(req);
2078                 if (!NT_STATUS_IS_OK(status)) {
2079                         return smbd_smb2_request_error(req, status);
2080                 }
2081                 if (req->tcon->global->encryption_required) {
2082                         encryption_required = true;
2083                 }
2084                 if (encryption_required && !req->do_encryption) {
2085                         return smbd_smb2_request_error(req,
2086                                 NT_STATUS_ACCESS_DENIED);
2087                 }
2088         }
2089
2090         if (call->fileid_ofs != 0) {
2091                 size_t needed = call->fileid_ofs + 16;
2092                 const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
2093                 size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
2094                 uint64_t file_id_persistent;
2095                 uint64_t file_id_volatile;
2096                 struct files_struct *fsp;
2097
2098                 SMB_ASSERT(call->need_tcon);
2099
2100                 if (needed > body_size) {
2101                         return smbd_smb2_request_error(req,
2102                                         NT_STATUS_INVALID_PARAMETER);
2103                 }
2104
2105                 file_id_persistent      = BVAL(body, call->fileid_ofs + 0);
2106                 file_id_volatile        = BVAL(body, call->fileid_ofs + 8);
2107
2108                 fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
2109                 if (fsp == NULL) {
2110                         if (!call->allow_invalid_fileid) {
2111                                 return smbd_smb2_request_error(req,
2112                                                 NT_STATUS_FILE_CLOSED);
2113                         }
2114
2115                         if (file_id_persistent != UINT64_MAX) {
2116                                 return smbd_smb2_request_error(req,
2117                                                 NT_STATUS_FILE_CLOSED);
2118                         }
2119                         if (file_id_volatile != UINT64_MAX) {
2120                                 return smbd_smb2_request_error(req,
2121                                                 NT_STATUS_FILE_CLOSED);
2122                         }
2123                 }
2124         }
2125
2126         if (call->as_root) {
2127                 SMB_ASSERT(call->fileid_ofs == 0);
2128                 /* This call needs to be run as root */
2129                 change_to_root_user();
2130         } else {
2131                 SMB_ASSERT(call->need_tcon);
2132         }
2133
2134         switch (opcode) {
2135         case SMB2_OP_NEGPROT:
2136                 {
2137                         START_PROFILE(smb2_negprot);
2138                         return_value = smbd_smb2_request_process_negprot(req);
2139                         END_PROFILE(smb2_negprot);
2140                 }
2141                 break;
2142
2143         case SMB2_OP_SESSSETUP:
2144                 {
2145                         START_PROFILE(smb2_sesssetup);
2146                         return_value = smbd_smb2_request_process_sesssetup(req);
2147                         END_PROFILE(smb2_sesssetup);
2148                 }
2149                 break;
2150
2151         case SMB2_OP_LOGOFF:
2152                 {
2153                         START_PROFILE(smb2_logoff);
2154                         return_value = smbd_smb2_request_process_logoff(req);
2155                         END_PROFILE(smb2_logoff);
2156                 }
2157                 break;
2158
2159         case SMB2_OP_TCON:
2160                 {
2161                         START_PROFILE(smb2_tcon);
2162                         return_value = smbd_smb2_request_process_tcon(req);
2163                         END_PROFILE(smb2_tcon);
2164                 }
2165                 break;
2166
2167         case SMB2_OP_TDIS:
2168                 {
2169                         START_PROFILE(smb2_tdis);
2170                         return_value = smbd_smb2_request_process_tdis(req);
2171                         END_PROFILE(smb2_tdis);
2172                 }
2173                 break;
2174
2175         case SMB2_OP_CREATE:
2176                 {
2177                         START_PROFILE(smb2_create);
2178                         return_value = smbd_smb2_request_process_create(req);
2179                         END_PROFILE(smb2_create);
2180                 }
2181                 break;
2182
2183         case SMB2_OP_CLOSE:
2184                 {
2185                         START_PROFILE(smb2_close);
2186                         return_value = smbd_smb2_request_process_close(req);
2187                         END_PROFILE(smb2_close);
2188                 }
2189                 break;
2190
2191         case SMB2_OP_FLUSH:
2192                 {
2193                         START_PROFILE(smb2_flush);
2194                         return_value = smbd_smb2_request_process_flush(req);
2195                         END_PROFILE(smb2_flush);
2196                 }
2197                 break;
2198
2199         case SMB2_OP_READ:
2200                 {
2201                         START_PROFILE(smb2_read);
2202                         return_value = smbd_smb2_request_process_read(req);
2203                         END_PROFILE(smb2_read);
2204                 }
2205                 break;
2206
2207         case SMB2_OP_WRITE:
2208                 {
2209                         START_PROFILE(smb2_write);
2210                         return_value = smbd_smb2_request_process_write(req);
2211                         END_PROFILE(smb2_write);
2212                 }
2213                 break;
2214
2215         case SMB2_OP_LOCK:
2216                 {
2217                         START_PROFILE(smb2_lock);
2218                         return_value = smbd_smb2_request_process_lock(req);
2219                         END_PROFILE(smb2_lock);
2220                 }
2221                 break;
2222
2223         case SMB2_OP_IOCTL:
2224                 {
2225                         START_PROFILE(smb2_ioctl);
2226                         return_value = smbd_smb2_request_process_ioctl(req);
2227                         END_PROFILE(smb2_ioctl);
2228                 }
2229                 break;
2230
2231         case SMB2_OP_CANCEL:
2232                 {
2233                         START_PROFILE(smb2_cancel);
2234                         return_value = smbd_smb2_request_process_cancel(req);
2235                         END_PROFILE(smb2_cancel);
2236                 }
2237                 break;
2238
2239         case SMB2_OP_KEEPALIVE:
2240                 {
2241                         START_PROFILE(smb2_keepalive);
2242                         return_value = smbd_smb2_request_process_keepalive(req);
2243                         END_PROFILE(smb2_keepalive);
2244                 }
2245                 break;
2246
2247         case SMB2_OP_FIND:
2248                 {
2249                         START_PROFILE(smb2_find);
2250                         return_value = smbd_smb2_request_process_find(req);
2251                         END_PROFILE(smb2_find);
2252                 }
2253                 break;
2254
2255         case SMB2_OP_NOTIFY:
2256                 {
2257                         START_PROFILE(smb2_notify);
2258                         return_value = smbd_smb2_request_process_notify(req);
2259                         END_PROFILE(smb2_notify);
2260                 }
2261                 break;
2262
2263         case SMB2_OP_GETINFO:
2264                 {
2265                         START_PROFILE(smb2_getinfo);
2266                         return_value = smbd_smb2_request_process_getinfo(req);
2267                         END_PROFILE(smb2_getinfo);
2268                 }
2269                 break;
2270
2271         case SMB2_OP_SETINFO:
2272                 {
2273                         START_PROFILE(smb2_setinfo);
2274                         return_value = smbd_smb2_request_process_setinfo(req);
2275                         END_PROFILE(smb2_setinfo);
2276                 }
2277                 break;
2278
2279         case SMB2_OP_BREAK:
2280                 {
2281                         START_PROFILE(smb2_break);
2282                         return_value = smbd_smb2_request_process_break(req);
2283                         END_PROFILE(smb2_break);
2284                 }
2285                 break;
2286
2287         default:
2288                 return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
2289                 break;
2290         }
2291         return return_value;
2292 }
2293
2294 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
2295 {
2296         struct smbXsrv_connection *conn = req->sconn->conn;
2297         struct tevent_req *subreq;
2298         int first_idx = 1;
2299         struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
2300         struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
2301         struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
2302
2303         req->subreq = NULL;
2304         TALLOC_FREE(req->async_te);
2305
2306         if (req->do_encryption &&
2307             (firsttf->iov_len == 0) &&
2308             (req->first_key.length == 0) &&
2309             (req->session != NULL) &&
2310             (req->session->global->encryption_key.length != 0))
2311         {
2312                 DATA_BLOB encryption_key = req->session->global->encryption_key;
2313                 uint8_t *tf;
2314                 const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2315                 uint64_t session_id = req->session->global->session_wire_id;
2316                 uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2317                 uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
2318                 /*
2319                  * We may have 2 responses (PENDING, FINAL),
2320                  * so alter the nonce.
2321                  *
2322                  * The FINAL response has the SMB2_HDR_FLAG_ASYNC bit
2323                  * cleared.
2324                  */
2325                 uint64_t nonce_high = session_id & ~SMB2_HDR_FLAG_ASYNC;
2326                 uint64_t nonce_low = message_id;
2327
2328                 if (nonce_low == 0) {
2329                         nonce_low = async_id;
2330                 }
2331
2332                 /*
2333                  * We need to place the SMB2_TRANSFORM header before the
2334                  * first SMB2 header
2335                  */
2336
2337                 /*
2338                  * we need to remember the encryption key
2339                  * and defer the signing/encryption until
2340                  * we are sure that we do not change
2341                  * the header again.
2342                  */
2343                 req->first_key = data_blob_dup_talloc(req, encryption_key);
2344                 if (req->first_key.data == NULL) {
2345                         return NT_STATUS_NO_MEMORY;
2346                 }
2347
2348                 tf = talloc_zero_array(req->out.vector, uint8_t,
2349                                        SMB2_TF_HDR_SIZE);
2350                 if (tf == NULL) {
2351                         return NT_STATUS_NO_MEMORY;
2352                 }
2353
2354                 SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2355                 SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2356                 SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2357                 SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2358
2359                 firsttf->iov_base = (void *)tf;
2360                 firsttf->iov_len = SMB2_TF_HDR_SIZE;
2361         }
2362
2363         if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
2364             (req->last_key.length > 0) &&
2365             (firsttf->iov_len == 0))
2366         {
2367                 int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
2368                 struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
2369                 NTSTATUS status;
2370
2371                 /*
2372                  * As we are sure the header of the last request in the
2373                  * compound chain will not change, we can to sign here
2374                  * with the last signing key we remembered.
2375                  */
2376                 status = smb2_signing_sign_pdu(req->last_key,
2377                                                conn->protocol,
2378                                                lasthdr,
2379                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2380                 if (!NT_STATUS_IS_OK(status)) {
2381                         return status;
2382                 }
2383         }
2384         data_blob_clear_free(&req->last_key);
2385
2386         req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
2387
2388         if (req->current_idx < req->out.vector_count) {
2389                 /*
2390                  * We must process the remaining compound
2391                  * SMB2 requests before any new incoming SMB2
2392                  * requests. This is because incoming SMB2
2393                  * requests may include a cancel for a
2394                  * compound request we haven't processed
2395                  * yet.
2396                  */
2397                 struct tevent_immediate *im = tevent_create_immediate(req);
2398                 if (!im) {
2399                         return NT_STATUS_NO_MEMORY;
2400                 }
2401
2402                 if (req->do_signing && firsttf->iov_len == 0) {
2403                         struct smbXsrv_session *x = req->session;
2404                         DATA_BLOB signing_key = x->global->channels[0].signing_key;
2405
2406                         /*
2407                          * we need to remember the signing key
2408                          * and defer the signing until
2409                          * we are sure that we do not change
2410                          * the header again.
2411                          */
2412                         req->last_key = data_blob_dup_talloc(req, signing_key);
2413                         if (req->last_key.data == NULL) {
2414                                 return NT_STATUS_NO_MEMORY;
2415                         }
2416                 }
2417
2418                 tevent_schedule_immediate(im,
2419                                         req->sconn->ev_ctx,
2420                                         smbd_smb2_request_dispatch_immediate,
2421                                         req);
2422                 return NT_STATUS_OK;
2423         }
2424
2425         if (req->compound_related) {
2426                 req->sconn->smb2.compound_related_in_progress = false;
2427         }
2428
2429         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
2430
2431         /* Set credit for these operations (zero credits if this
2432            is a final reply for an async operation). */
2433         smb2_calculate_credits(req, req);
2434
2435         /*
2436          * now check if we need to sign the current response
2437          */
2438         if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
2439                 NTSTATUS status;
2440
2441                 status = smb2_signing_encrypt_pdu(req->first_key,
2442                                         conn->protocol,
2443                                         firsttf,
2444                                         req->out.vector_count - first_idx);
2445                 if (!NT_STATUS_IS_OK(status)) {
2446                         return status;
2447                 }
2448         } else if (req->do_signing) {
2449                 NTSTATUS status;
2450                 struct smbXsrv_session *x = req->session;
2451                 DATA_BLOB signing_key = x->global->channels[0].signing_key;
2452
2453                 status = smb2_signing_sign_pdu(signing_key,
2454                                                conn->protocol,
2455                                                outhdr,
2456                                                SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2457                 if (!NT_STATUS_IS_OK(status)) {
2458                         return status;
2459                 }
2460         }
2461         data_blob_clear_free(&req->first_key);
2462
2463         /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
2464         if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
2465             outdyn->iov_base == NULL && outdyn->iov_len != 0) {
2466                 /* Dynamic part is NULL. Chop it off,
2467                    We're going to send it via sendfile. */
2468                 req->out.vector_count -= 1;
2469         }
2470
2471         subreq = tstream_writev_queue_send(req,
2472                                            req->sconn->ev_ctx,
2473                                            req->sconn->smb2.stream,
2474                                            req->sconn->smb2.send_queue,
2475                                            req->out.vector,
2476                                            req->out.vector_count);
2477         if (subreq == NULL) {
2478                 return NT_STATUS_NO_MEMORY;
2479         }
2480         tevent_req_set_callback(subreq, smbd_smb2_request_writev_done, req);
2481         /*
2482          * We're done with this request -
2483          * move it off the "being processed" queue.
2484          */
2485         DLIST_REMOVE(req->sconn->smb2.requests, req);
2486
2487         return NT_STATUS_OK;
2488 }
2489
2490 static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn);
2491
2492 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
2493                                         struct tevent_immediate *im,
2494                                         void *private_data)
2495 {
2496         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
2497                                         struct smbd_smb2_request);
2498         struct smbd_server_connection *sconn = req->sconn;
2499         NTSTATUS status;
2500
2501         TALLOC_FREE(im);
2502
2503         if (DEBUGLEVEL >= 10) {
2504                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
2505                         req->current_idx, req->in.vector_count));
2506                 print_req_vectors(req);
2507         }
2508
2509         status = smbd_smb2_request_dispatch(req);
2510         if (!NT_STATUS_IS_OK(status)) {
2511                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2512                 return;
2513         }
2514
2515         status = smbd_smb2_request_next_incoming(sconn);
2516         if (!NT_STATUS_IS_OK(status)) {
2517                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2518                 return;
2519         }
2520 }
2521
2522 static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
2523 {
2524         struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
2525                                         struct smbd_smb2_request);
2526         struct smbd_server_connection *sconn = req->sconn;
2527         int ret;
2528         int sys_errno;
2529         NTSTATUS status;
2530
2531         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2532         TALLOC_FREE(subreq);
2533         TALLOC_FREE(req);
2534         if (ret == -1) {
2535                 status = map_nt_error_from_unix(sys_errno);
2536                 DEBUG(2,("smbd_smb2_request_writev_done: client write error %s\n",
2537                         nt_errstr(status)));
2538                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2539                 return;
2540         }
2541
2542         status = smbd_smb2_request_next_incoming(sconn);
2543         if (!NT_STATUS_IS_OK(status)) {
2544                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2545                 return;
2546         }
2547 }
2548
2549 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
2550                                    NTSTATUS status,
2551                                    DATA_BLOB body, DATA_BLOB *dyn,
2552                                    const char *location)
2553 {
2554         uint8_t *outhdr;
2555         struct iovec *outbody_v;
2556         struct iovec *outdyn_v;
2557         uint32_t next_command_ofs;
2558
2559         DEBUG(10,("smbd_smb2_request_done_ex: "
2560                   "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
2561                   req->current_idx, nt_errstr(status), (unsigned int)body.length,
2562                   dyn ? "yes": "no",
2563                   (unsigned int)(dyn ? dyn->length : 0),
2564                   location));
2565
2566         if (body.length < 2) {
2567                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2568         }
2569
2570         if ((body.length % 2) != 0) {
2571                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
2572         }
2573
2574         outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2575         outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
2576         outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
2577
2578         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
2579         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
2580
2581         outbody_v->iov_base = (void *)body.data;
2582         outbody_v->iov_len = body.length;
2583
2584         if (dyn) {
2585                 outdyn_v->iov_base = (void *)dyn->data;
2586                 outdyn_v->iov_len = dyn->length;
2587         } else {
2588                 outdyn_v->iov_base = NULL;
2589                 outdyn_v->iov_len = 0;
2590         }
2591
2592         /* see if we need to recalculate the offset to the next response */
2593         if (next_command_ofs > 0) {
2594                 next_command_ofs  = SMB2_HDR_BODY;
2595                 next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
2596                 next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
2597         }
2598
2599         if ((next_command_ofs % 8) != 0) {
2600                 size_t pad_size = 8 - (next_command_ofs % 8);
2601                 if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
2602                         /*
2603                          * if the dyn buffer is empty
2604                          * we can use it to add padding
2605                          */
2606                         uint8_t *pad;
2607
2608                         pad = talloc_zero_array(req->out.vector,
2609                                                 uint8_t, pad_size);
2610                         if (pad == NULL) {
2611                                 return smbd_smb2_request_error(req,
2612                                                 NT_STATUS_NO_MEMORY);
2613                         }
2614
2615                         outdyn_v->iov_base = (void *)pad;
2616                         outdyn_v->iov_len = pad_size;
2617                 } else {
2618                         /*
2619                          * For now we copy the dynamic buffer
2620                          * and add the padding to the new buffer
2621                          */
2622                         size_t old_size;
2623                         uint8_t *old_dyn;
2624                         size_t new_size;
2625                         uint8_t *new_dyn;
2626
2627                         old_size = SMBD_SMB2_OUT_DYN_LEN(req);
2628                         old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
2629
2630                         new_size = old_size + pad_size;
2631                         new_dyn = talloc_zero_array(req->out.vector,
2632                                                uint8_t, new_size);
2633                         if (new_dyn == NULL) {
2634                                 return smbd_smb2_request_error(req,
2635                                                 NT_STATUS_NO_MEMORY);
2636                         }
2637
2638                         memcpy(new_dyn, old_dyn, old_size);
2639                         memset(new_dyn + old_size, 0, pad_size);
2640
2641                         outdyn_v->iov_base = (void *)new_dyn;
2642                         outdyn_v->iov_len = new_size;
2643                 }
2644                 next_command_ofs += pad_size;
2645         }
2646
2647         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
2648
2649         return smbd_smb2_request_reply(req);
2650 }
2651
2652 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
2653                                     NTSTATUS status,
2654                                     DATA_BLOB *info,
2655                                     const char *location)
2656 {
2657         DATA_BLOB body;
2658         uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2659
2660         DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n",
2661                   req->current_idx, nt_errstr(status), info ? " +info" : "",
2662                   location));
2663
2664         body.data = outhdr + SMB2_HDR_BODY;
2665         body.length = 8;
2666         SSVAL(body.data, 0, 9);
2667
2668         if (info) {
2669                 SIVAL(body.data, 0x04, info->length);
2670         } else {
2671                 /* Allocated size of req->out.vector[i].iov_base
2672                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
2673                  * 1 byte without having to do an alloc.
2674                  */
2675                 info = talloc_zero_array(req->out.vector,
2676                                         DATA_BLOB,
2677                                         1);
2678                 if (!info) {
2679                         return NT_STATUS_NO_MEMORY;
2680                 }
2681                 info->data = ((uint8_t *)outhdr) +
2682                         OUTVEC_ALLOC_SIZE - 1;
2683                 info->length = 1;
2684                 SCVAL(info->data, 0, 0);
2685         }
2686
2687         /*
2688          * if a request fails, all other remaining
2689          * compounded requests should fail too
2690          */
2691         req->next_status = NT_STATUS_INVALID_PARAMETER;
2692
2693         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
2694 }
2695
2696
2697 struct smbd_smb2_send_oplock_break_state {
2698         struct smbd_server_connection *sconn;
2699         uint8_t buf[4 + SMB2_HDR_BODY + 0x18];
2700         struct iovec vector;
2701 };
2702
2703 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq);
2704
2705 NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
2706                                      uint64_t file_id_persistent,
2707                                      uint64_t file_id_volatile,
2708                                      uint8_t oplock_level)
2709 {
2710         struct smbd_smb2_send_oplock_break_state *state;
2711         struct tevent_req *subreq;
2712         uint8_t *hdr;
2713         uint8_t *body;
2714
2715         state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
2716         if (state == NULL) {
2717                 return NT_STATUS_NO_MEMORY;
2718         }
2719         state->sconn = sconn;
2720
2721         state->vector.iov_base = (void *)state->buf;
2722         state->vector.iov_len = sizeof(state->buf);
2723
2724         _smb2_setlen(state->buf, sizeof(state->buf) - 4);
2725         hdr = state->buf + 4;
2726         body = hdr + SMB2_HDR_BODY;
2727
2728         SIVAL(hdr, 0,                           SMB2_MAGIC);
2729         SSVAL(hdr, SMB2_HDR_LENGTH,             SMB2_HDR_BODY);
2730         SSVAL(hdr, SMB2_HDR_EPOCH,              0);
2731         SIVAL(hdr, SMB2_HDR_STATUS,             0);
2732         SSVAL(hdr, SMB2_HDR_OPCODE,             SMB2_OP_BREAK);
2733         SSVAL(hdr, SMB2_HDR_CREDIT,             0);
2734         SIVAL(hdr, SMB2_HDR_FLAGS,              SMB2_HDR_FLAG_REDIRECT);
2735         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND,       0);
2736         SBVAL(hdr, SMB2_HDR_MESSAGE_ID,         UINT64_MAX);
2737         SIVAL(hdr, SMB2_HDR_PID,                0);
2738         SIVAL(hdr, SMB2_HDR_TID,                0);
2739         SBVAL(hdr, SMB2_HDR_SESSION_ID,         0);
2740         memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
2741
2742         SSVAL(body, 0x00, 0x18);
2743
2744         SCVAL(body, 0x02, oplock_level);
2745         SCVAL(body, 0x03, 0);           /* reserved */
2746         SIVAL(body, 0x04, 0);           /* reserved */
2747         SBVAL(body, 0x08, file_id_persistent);
2748         SBVAL(body, 0x10, file_id_volatile);
2749
2750         subreq = tstream_writev_queue_send(state,
2751                                            sconn->ev_ctx,
2752                                            sconn->smb2.stream,
2753                                            sconn->smb2.send_queue,
2754                                            &state->vector, 1);
2755         if (subreq == NULL) {
2756                 return NT_STATUS_NO_MEMORY;
2757         }
2758         tevent_req_set_callback(subreq,
2759                                 smbd_smb2_oplock_break_writev_done,
2760                                 state);
2761
2762         return NT_STATUS_OK;
2763 }
2764
2765 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq)
2766 {
2767         struct smbd_smb2_send_oplock_break_state *state =
2768                 tevent_req_callback_data(subreq,
2769                 struct smbd_smb2_send_oplock_break_state);
2770         struct smbd_server_connection *sconn = state->sconn;
2771         int ret;
2772         int sys_errno;
2773
2774         ret = tstream_writev_queue_recv(subreq, &sys_errno);
2775         TALLOC_FREE(subreq);
2776         if (ret == -1) {
2777                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
2778                 smbd_server_connection_terminate(sconn, nt_errstr(status));
2779                 return;
2780         }
2781
2782         TALLOC_FREE(state);
2783 }
2784
2785 struct smbd_smb2_request_read_state {
2786         struct tevent_context *ev;
2787         struct smbd_server_connection *sconn;
2788         struct smbd_smb2_request *smb2_req;
2789         struct {
2790                 uint8_t nbt[NBT_HDR_SIZE];
2791                 bool done;
2792         } hdr;
2793         size_t pktlen;
2794         uint8_t *pktbuf;
2795 };
2796
2797 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
2798                                          void *private_data,
2799                                          TALLOC_CTX *mem_ctx,
2800                                          struct iovec **_vector,
2801                                          size_t *_count);
2802 static void smbd_smb2_request_read_done(struct tevent_req *subreq);
2803
2804 static struct tevent_req *smbd_smb2_request_read_send(TALLOC_CTX *mem_ctx,
2805                                         struct tevent_context *ev,
2806                                         struct smbd_server_connection *sconn)
2807 {
2808         struct tevent_req *req;
2809         struct smbd_smb2_request_read_state *state;
2810         struct tevent_req *subreq;
2811
2812         req = tevent_req_create(mem_ctx, &state,
2813                                 struct smbd_smb2_request_read_state);
2814         if (req == NULL) {
2815                 return NULL;
2816         }
2817         state->ev = ev;
2818         state->sconn = sconn;
2819
2820         state->smb2_req = smbd_smb2_request_allocate(state);
2821         if (tevent_req_nomem(state->smb2_req, req)) {
2822                 return tevent_req_post(req, ev);
2823         }
2824         state->smb2_req->sconn = sconn;
2825
2826         subreq = tstream_readv_pdu_queue_send(state->smb2_req,
2827                                         state->ev,
2828                                         state->sconn->smb2.stream,
2829                                         state->sconn->smb2.recv_queue,
2830                                         smbd_smb2_request_next_vector,
2831                                         state);
2832         if (tevent_req_nomem(subreq, req)) {
2833                 return tevent_req_post(req, ev);
2834         }
2835         tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
2836
2837         return req;
2838 }
2839
2840 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
2841                                          void *private_data,
2842                                          TALLOC_CTX *mem_ctx,
2843                                          struct iovec **_vector,
2844                                          size_t *_count)
2845 {
2846         struct smbd_smb2_request_read_state *state =
2847                 talloc_get_type_abort(private_data,
2848                 struct smbd_smb2_request_read_state);
2849         struct iovec *vector;
2850
2851         if (state->pktlen > 0) {
2852                 /* if there're no remaining bytes, we're done */
2853                 *_vector = NULL;
2854                 *_count = 0;
2855                 return 0;
2856         }
2857
2858         if (!state->hdr.done) {
2859                 /*
2860                  * first we need to get the NBT header
2861                  */
2862                 vector = talloc_array(mem_ctx, struct iovec, 1);
2863                 if (vector == NULL) {
2864                         return -1;
2865                 }
2866
2867                 vector[0].iov_base = (void *)state->hdr.nbt;
2868                 vector[0].iov_len = NBT_HDR_SIZE;
2869
2870                 *_vector = vector;
2871                 *_count = 1;
2872
2873                 state->hdr.done = true;
2874                 return 0;
2875         }
2876
2877         /*
2878          * Now we analyze the NBT header
2879          */
2880         state->pktlen = smb2_len(state->hdr.nbt);
2881
2882         if (state->pktlen == 0) {
2883                 /* if there're no remaining bytes, we're done */
2884                 *_vector = NULL;
2885                 *_count = 0;
2886                 return 0;
2887         }
2888
2889         state->pktbuf = talloc_array(state->smb2_req, uint8_t, state->pktlen);
2890         if (state->pktbuf == NULL) {
2891                 return -1;
2892         }
2893
2894         vector = talloc_array(mem_ctx, struct iovec, 1);
2895         if (vector == NULL) {
2896                 return -1;
2897         }
2898
2899         vector[0].iov_base = (void *)state->pktbuf;
2900         vector[0].iov_len = state->pktlen;
2901
2902         *_vector = vector;
2903         *_count = 1;
2904         return 0;
2905 }
2906
2907 static void smbd_smb2_request_read_done(struct tevent_req *subreq)
2908 {
2909         struct tevent_req *req =
2910                 tevent_req_callback_data(subreq,
2911                 struct tevent_req);
2912         struct smbd_smb2_request_read_state *state =
2913                 tevent_req_data(req,
2914                 struct smbd_smb2_request_read_state);
2915         int ret;
2916         int sys_errno;
2917         NTSTATUS status;
2918         NTTIME now;
2919
2920         ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
2921         TALLOC_FREE(subreq);
2922         if (ret == -1) {
2923                 status = map_nt_error_from_unix(sys_errno);
2924                 tevent_req_nterror(req, status);
2925                 return;
2926         }
2927
2928         if (state->hdr.nbt[0] != 0x00) {
2929                 DEBUG(1,("smbd_smb2_request_read_done: ignore NBT[0x%02X] msg\n",
2930                          state->hdr.nbt[0]));
2931
2932                 ZERO_STRUCT(state->hdr);
2933                 TALLOC_FREE(state->pktbuf);
2934                 state->pktlen = 0;
2935
2936                 subreq = tstream_readv_pdu_queue_send(state->smb2_req,
2937                                                 state->ev,
2938                                                 state->sconn->smb2.stream,
2939                                                 state->sconn->smb2.recv_queue,
2940                                                 smbd_smb2_request_next_vector,
2941                                                 state);
2942                 if (tevent_req_nomem(subreq, req)) {
2943                         return;
2944                 }
2945                 tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
2946                 return;
2947         }
2948
2949         state->smb2_req->request_time = timeval_current();
2950         now = timeval_to_nttime(&state->smb2_req->request_time);
2951
2952         status = smbd_smb2_inbuf_parse_compound(state->smb2_req->sconn->conn,
2953                                                 now,
2954                                                 state->pktbuf,
2955                                                 state->pktlen,
2956                                                 state->smb2_req,
2957                                                 &state->smb2_req->in.vector,
2958                                                 &state->smb2_req->in.vector_count);
2959         if (tevent_req_nterror(req, status)) {
2960                 return;
2961         }
2962
2963         state->smb2_req->current_idx = 1;
2964
2965         tevent_req_done(req);
2966 }
2967
2968 static NTSTATUS smbd_smb2_request_read_recv(struct tevent_req *req,
2969                                             TALLOC_CTX *mem_ctx,
2970                                             struct smbd_smb2_request **_smb2_req)
2971 {
2972         struct smbd_smb2_request_read_state *state =
2973                 tevent_req_data(req,
2974                 struct smbd_smb2_request_read_state);
2975         NTSTATUS status;
2976
2977         if (tevent_req_is_nterror(req, &status)) {
2978                 tevent_req_received(req);
2979                 return status;
2980         }
2981
2982         *_smb2_req = talloc_move(mem_ctx, &state->smb2_req);
2983         tevent_req_received(req);
2984         return NT_STATUS_OK;
2985 }
2986
2987 static void smbd_smb2_request_incoming(struct tevent_req *subreq);
2988
2989 static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn)
2990 {
2991         size_t max_send_queue_len;
2992         size_t cur_send_queue_len;
2993         struct tevent_req *subreq;
2994
2995         if (sconn->smb2.compound_related_in_progress) {
2996                 /*
2997                  * Can't read another until the related
2998                  * compound is done.
2999                  */
3000                 return NT_STATUS_OK;
3001         }
3002
3003         if (tevent_queue_length(sconn->smb2.recv_queue) > 0) {
3004                 /*
3005                  * if there is already a smbd_smb2_request_read
3006                  * pending, we are done.
3007                  */
3008                 return NT_STATUS_OK;
3009         }
3010
3011         max_send_queue_len = MAX(1, sconn->smb2.max_credits/16);
3012         cur_send_queue_len = tevent_queue_length(sconn->smb2.send_queue);
3013
3014         if (cur_send_queue_len > max_send_queue_len) {
3015                 /*
3016                  * if we have a lot of requests to send,
3017                  * we wait until they are on the wire until we
3018                  * ask for the next request.
3019                  */
3020                 return NT_STATUS_OK;
3021         }
3022
3023         /* ask for the next request */
3024         subreq = smbd_smb2_request_read_send(sconn, sconn->ev_ctx, sconn);
3025         if (subreq == NULL) {
3026                 return NT_STATUS_NO_MEMORY;
3027         }
3028         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
3029
3030         return NT_STATUS_OK;
3031 }
3032
3033 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
3034                              uint8_t *inbuf, size_t size)
3035 {
3036         NTSTATUS status;
3037         struct smbd_smb2_request *req = NULL;
3038
3039         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
3040                  (unsigned int)size));
3041
3042         status = smbd_initialize_smb2(sconn);
3043         if (!NT_STATUS_IS_OK(status)) {
3044                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3045                 return;
3046         }
3047
3048         status = smbd_smb2_request_create(sconn, inbuf, size, &req);
3049         if (!NT_STATUS_IS_OK(status)) {
3050                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3051                 return;
3052         }
3053
3054         status = smbd_smb2_request_validate(req);
3055         if (!NT_STATUS_IS_OK(status)) {
3056                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3057                 return;
3058         }
3059
3060         status = smbd_smb2_request_setup_out(req);
3061         if (!NT_STATUS_IS_OK(status)) {
3062                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3063                 return;
3064         }
3065
3066         status = smbd_smb2_request_dispatch(req);
3067         if (!NT_STATUS_IS_OK(status)) {
3068                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3069                 return;
3070         }
3071
3072         status = smbd_smb2_request_next_incoming(sconn);
3073         if (!NT_STATUS_IS_OK(status)) {
3074                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3075                 return;
3076         }
3077
3078         sconn->num_requests++;
3079 }
3080
3081 static void smbd_smb2_request_incoming(struct tevent_req *subreq)
3082 {
3083         struct smbd_server_connection *sconn = tevent_req_callback_data(subreq,
3084                                                struct smbd_server_connection);
3085         NTSTATUS status;
3086         struct smbd_smb2_request *req = NULL;
3087
3088         status = smbd_smb2_request_read_recv(subreq, sconn, &req);
3089         TALLOC_FREE(subreq);
3090         if (!NT_STATUS_IS_OK(status)) {
3091                 DEBUG(2,("smbd_smb2_request_incoming: client read error %s\n",
3092                         nt_errstr(status)));
3093                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3094                 return;
3095         }
3096
3097         DEBUG(10,("smbd_smb2_request_incoming: idx[%d] of %d vectors\n",
3098                  req->current_idx, req->in.vector_count));
3099
3100         status = smbd_smb2_request_validate(req);
3101         if (!NT_STATUS_IS_OK(status)) {
3102                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3103                 return;
3104         }
3105
3106         status = smbd_smb2_request_setup_out(req);
3107         if (!NT_STATUS_IS_OK(status)) {
3108                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3109                 return;
3110         }
3111
3112         status = smbd_smb2_request_dispatch(req);
3113         if (!NT_STATUS_IS_OK(status)) {
3114                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3115                 return;
3116         }
3117
3118         status = smbd_smb2_request_next_incoming(sconn);
3119         if (!NT_STATUS_IS_OK(status)) {
3120                 smbd_server_connection_terminate(sconn, nt_errstr(status));
3121                 return;
3122         }
3123
3124         sconn->num_requests++;
3125
3126         /* The timeout_processing function isn't run nearly
3127            often enough to implement 'max log size' without
3128            overrunning the size of the file by many megabytes.
3129            This is especially true if we are running at debug
3130            level 10.  Checking every 50 SMB2s is a nice
3131            tradeoff of performance vs log file size overrun. */
3132
3133         if ((sconn->num_requests % 50) == 0 &&
3134             need_to_check_log_size()) {
3135                 change_to_root_user();
3136                 check_log_size();
3137         }
3138 }