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