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