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