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