Make us pass all SMB2 lock tests except MULTIPLE-UNLOCK and CONTEXT. Them next :-).
[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/globals.h"
24 #include "../libcli/smb/smb_common.h"
25 #include "../lib/tsocket/tsocket.h"
26
27 #define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
28
29 static const char *smb2_names[] = {
30         "SMB2_NEGPROT",
31         "SMB2_SESSSETUP",
32         "SMB2_LOGOFF",
33         "SMB2_TCON",
34         "SMB2_TDIS",
35         "SMB2_CREATE",
36         "SMB2_CLOSE",
37         "SMB2_FLUSH",
38         "SMB2_READ",
39         "SMB2_WRITE",
40         "SMB2_LOCK",
41         "SMB2_IOCTL",
42         "SMB2_CANCEL",
43         "SMB2_KEEPALIVE",
44         "SMB2_FIND",
45         "SMB2_NOTIFY",
46         "SMB2_GETINFO",
47         "SMB2_SETINFO",
48         "SMB2_BREAK"
49 };
50
51 const char *smb2_opcode_name(uint16_t opcode)
52 {
53         if (opcode > 0x12) {
54                 return "Bad SMB2 opcode";
55         }
56         return smb2_names[opcode];
57 }
58
59 static void print_req_vectors(struct smbd_smb2_request *req)
60 {
61         int i;
62
63         for (i = 0; i < req->in.vector_count; i++) {
64                 dbgtext("\treq->in.vector[%u].iov_len = %u\n",
65                         (unsigned int)i,
66                         (unsigned int)req->in.vector[i].iov_len);
67         }
68         for (i = 0; i < req->out.vector_count; i++) {
69                 dbgtext("\treq->out.vector[%u].iov_len = %u\n",
70                         (unsigned int)i,
71                         (unsigned int)req->out.vector[i].iov_len);
72         }
73 }
74
75 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
76 {
77         if (size < (4 + SMB2_HDR_BODY)) {
78                 return false;
79         }
80
81         if (IVAL(inbuf, 4) != SMB2_MAGIC) {
82                 return false;
83         }
84
85         return true;
86 }
87
88 static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *sconn)
89 {
90         NTSTATUS status;
91         int ret;
92
93         TALLOC_FREE(sconn->smb1.fde);
94
95         sconn->smb2.event_ctx = smbd_event_context();
96
97         sconn->smb2.recv_queue = tevent_queue_create(sconn, "smb2 recv queue");
98         if (sconn->smb2.recv_queue == NULL) {
99                 return NT_STATUS_NO_MEMORY;
100         }
101
102         sconn->smb2.send_queue = tevent_queue_create(sconn, "smb2 send queue");
103         if (sconn->smb2.send_queue == NULL) {
104                 return NT_STATUS_NO_MEMORY;
105         }
106
107         sconn->smb2.sessions.idtree = idr_init(sconn);
108         if (sconn->smb2.sessions.idtree == NULL) {
109                 return NT_STATUS_NO_MEMORY;
110         }
111         sconn->smb2.sessions.limit = 0x0000FFFE;
112         sconn->smb2.sessions.list = NULL;
113
114         ret = tstream_bsd_existing_socket(sconn, smbd_server_fd(),
115                                           &sconn->smb2.stream);
116         if (ret == -1) {
117                 status = map_nt_error_from_unix(errno);
118                 return status;
119         }
120
121         /* Ensure child is set to non-blocking mode */
122         set_blocking(smbd_server_fd(),false);
123         return NT_STATUS_OK;
124 }
125
126 #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
127 #define _smb2_setlen(_buf,len) do { \
128         uint8_t *buf = (uint8_t *)_buf; \
129         buf[0] = 0; \
130         buf[1] = ((len)&0xFF0000)>>16; \
131         buf[2] = ((len)&0xFF00)>>8; \
132         buf[3] = (len)&0xFF; \
133 } while (0)
134
135 static void smb2_setup_nbt_length(struct iovec *vector, int count)
136 {
137         size_t len = 0;
138         int i;
139
140         for (i=1; i < count; i++) {
141                 len += vector[i].iov_len;
142         }
143
144         _smb2_setlen(vector[0].iov_base, len);
145 }
146
147 static int smbd_smb2_request_parent_destructor(struct smbd_smb2_request **req)
148 {
149         if (*req) {
150                 (*req)->parent = NULL;
151                 (*req)->mem_pool = NULL;
152         }
153
154         return 0;
155 }
156
157 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
158 {
159         if (req->out.vector) {
160                 DLIST_REMOVE(req->sconn->smb2.requests, req);
161         }
162
163         if (req->parent) {
164                 *req->parent = NULL;
165                 talloc_free(req->mem_pool);
166         }
167
168         return 0;
169 }
170
171 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
172 {
173         TALLOC_CTX *mem_pool;
174         struct smbd_smb2_request **parent;
175         struct smbd_smb2_request *req;
176
177 #if 0
178         /* Enable this to find subtle valgrind errors. */
179         mem_pool = talloc_init("smbd_smb2_request_allocate");
180 #else
181         mem_pool = talloc_pool(mem_ctx, 8192);
182 #endif
183         if (mem_pool == NULL) {
184                 return NULL;
185         }
186
187         parent = talloc(mem_pool, struct smbd_smb2_request *);
188         if (parent == NULL) {
189                 talloc_free(mem_pool);
190                 return NULL;
191         }
192
193         req = talloc_zero(parent, struct smbd_smb2_request);
194         if (req == NULL) {
195                 talloc_free(mem_pool);
196                 return NULL;
197         }
198         *parent         = req;
199         req->mem_pool   = mem_pool;
200         req->parent     = parent;
201
202         talloc_set_destructor(parent, smbd_smb2_request_parent_destructor);
203         talloc_set_destructor(req, smbd_smb2_request_destructor);
204
205         return req;
206 }
207
208 static NTSTATUS smbd_smb2_request_create(struct smbd_server_connection *sconn,
209                                          const uint8_t *inbuf, size_t size,
210                                          struct smbd_smb2_request **_req)
211 {
212         struct smbd_smb2_request *req;
213         uint32_t protocol_version;
214         const uint8_t *inhdr = NULL;
215         off_t ofs = 0;
216         uint16_t cmd;
217         uint32_t next_command_ofs;
218
219         if (size < (4 + SMB2_HDR_BODY + 2)) {
220                 DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
221                 return NT_STATUS_INVALID_PARAMETER;
222         }
223
224         inhdr = inbuf + 4;
225
226         protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
227         if (protocol_version != SMB2_MAGIC) {
228                 DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
229                          protocol_version));
230                 return NT_STATUS_INVALID_PARAMETER;
231         }
232
233         cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
234         if (cmd != SMB2_OP_NEGPROT) {
235                 DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
236                          cmd));
237                 return NT_STATUS_INVALID_PARAMETER;
238         }
239
240         next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
241         if (next_command_ofs != 0) {
242                 DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
243                          next_command_ofs));
244                 return NT_STATUS_INVALID_PARAMETER;
245         }
246
247         req = smbd_smb2_request_allocate(sconn);
248         if (req == NULL) {
249                 return NT_STATUS_NO_MEMORY;
250         }
251         req->sconn = sconn;
252
253         talloc_steal(req, inbuf);
254
255         req->in.vector = talloc_array(req, struct iovec, 4);
256         if (req->in.vector == NULL) {
257                 TALLOC_FREE(req);
258                 return NT_STATUS_NO_MEMORY;
259         }
260         req->in.vector_count = 4;
261
262         memcpy(req->in.nbt_hdr, inbuf, 4);
263
264         ofs = 0;
265         req->in.vector[0].iov_base      = (void *)req->in.nbt_hdr;
266         req->in.vector[0].iov_len       = 4;
267         ofs += req->in.vector[0].iov_len;
268
269         req->in.vector[1].iov_base      = (void *)(inbuf + ofs);
270         req->in.vector[1].iov_len       = SMB2_HDR_BODY;
271         ofs += req->in.vector[1].iov_len;
272
273         req->in.vector[2].iov_base      = (void *)(inbuf + ofs);
274         req->in.vector[2].iov_len       = SVAL(inbuf, ofs) & 0xFFFE;
275         ofs += req->in.vector[2].iov_len;
276
277         if (ofs > size) {
278                 return NT_STATUS_INVALID_PARAMETER;
279         }
280
281         req->in.vector[3].iov_base      = (void *)(inbuf + ofs);
282         req->in.vector[3].iov_len       = size - ofs;
283         ofs += req->in.vector[3].iov_len;
284
285         req->current_idx = 1;
286
287         *_req = req;
288         return NT_STATUS_OK;
289 }
290
291 static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req,
292                                 uint16_t *p_creds_requested)
293 {
294         int count;
295         int idx;
296         bool compound_related = false;
297
298         *p_creds_requested = 0;
299         count = req->in.vector_count;
300
301         if (count < 4) {
302                 /* It's not a SMB2 request */
303                 return NT_STATUS_INVALID_PARAMETER;
304         }
305
306         for (idx=1; idx < count; idx += 3) {
307                 uint16_t creds_requested = 0;
308                 const uint8_t *inhdr = NULL;
309                 uint32_t flags;
310
311                 if (req->in.vector[idx].iov_len != SMB2_HDR_BODY) {
312                         return NT_STATUS_INVALID_PARAMETER;
313                 }
314
315                 if (req->in.vector[idx+1].iov_len < 2) {
316                         return NT_STATUS_INVALID_PARAMETER;
317                 }
318
319                 inhdr = (const uint8_t *)req->in.vector[idx].iov_base;
320
321                 /* setup the SMB2 header */
322                 if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
323                         return NT_STATUS_INVALID_PARAMETER;
324                 }
325
326                 creds_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
327                 if (*p_creds_requested + creds_requested < creds_requested) {
328                         *p_creds_requested = 65535;
329                 } else {
330                         *p_creds_requested += creds_requested;
331                 }
332
333                 flags = IVAL(inhdr, SMB2_HDR_FLAGS);
334                 if (idx == 1) {
335                         /*
336                          * the 1st request should never have the
337                          * SMB2_HDR_FLAG_CHAINED flag set
338                          */
339                         if (flags & SMB2_HDR_FLAG_CHAINED) {
340                                 req->next_status = NT_STATUS_INVALID_PARAMETER;
341                                 return NT_STATUS_OK;
342                         }
343                 } else if (idx == 4) {
344                         /*
345                          * the 2nd request triggers related vs. unrelated
346                          * compounded requests
347                          */
348                         if (flags & SMB2_HDR_FLAG_CHAINED) {
349                                 compound_related = true;
350                         }
351                 } else if (idx > 4) {
352 #if 0
353                         /*
354                          * It seems the this tests are wrong
355                          * see the SMB2-COMPOUND test
356                          */
357
358                         /*
359                          * all other requests should match the 2nd one
360                          */
361                         if (flags & SMB2_HDR_FLAG_CHAINED) {
362                                 if (!compound_related) {
363                                         req->next_status =
364                                                 NT_STATUS_INVALID_PARAMETER;
365                                         return NT_STATUS_OK;
366                                 }
367                         } else {
368                                 if (compound_related) {
369                                         req->next_status =
370                                                 NT_STATUS_INVALID_PARAMETER;
371                                         return NT_STATUS_OK;
372                                 }
373                         }
374 #endif
375                 }
376         }
377
378         return NT_STATUS_OK;
379 }
380
381 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req, uint16_t creds)
382 {
383         struct iovec *vector;
384         int count;
385         int idx;
386
387         count = req->in.vector_count;
388         vector = talloc_zero_array(req, struct iovec, count);
389         if (vector == NULL) {
390                 return NT_STATUS_NO_MEMORY;
391         }
392
393         vector[0].iov_base      = req->out.nbt_hdr;
394         vector[0].iov_len       = 4;
395         SIVAL(req->out.nbt_hdr, 0, 0);
396
397         for (idx=1; idx < count; idx += 3) {
398                 const uint8_t *inhdr = NULL;
399                 uint32_t in_flags;
400                 uint8_t *outhdr = NULL;
401                 uint8_t *outbody = NULL;
402                 uint32_t next_command_ofs = 0;
403                 struct iovec *current = &vector[idx];
404
405                 if ((idx + 3) < count) {
406                         /* we have a next command -
407                          * setup for the error case. */
408                         next_command_ofs = SMB2_HDR_BODY + 9;
409                 }
410
411                 inhdr = (const uint8_t *)req->in.vector[idx].iov_base;
412                 in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
413
414                 outhdr = talloc_zero_array(vector, uint8_t,
415                                       OUTVEC_ALLOC_SIZE);
416                 if (outhdr == NULL) {
417                         return NT_STATUS_NO_MEMORY;
418                 }
419
420                 outbody = outhdr + SMB2_HDR_BODY;
421
422                 current[0].iov_base     = (void *)outhdr;
423                 current[0].iov_len      = SMB2_HDR_BODY;
424
425                 current[1].iov_base     = (void *)outbody;
426                 current[1].iov_len      = 8;
427
428                 current[2].iov_base     = NULL;
429                 current[2].iov_len      = 0;
430
431                 /* setup the SMB2 header */
432                 SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID,     SMB2_MAGIC);
433                 SSVAL(outhdr, SMB2_HDR_LENGTH,          SMB2_HDR_BODY);
434                 SSVAL(outhdr, SMB2_HDR_EPOCH,           0);
435                 SIVAL(outhdr, SMB2_HDR_STATUS,
436                       NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
437                 SSVAL(outhdr, SMB2_HDR_OPCODE,
438                       SVAL(inhdr, SMB2_HDR_OPCODE));
439                 SSVAL(outhdr, SMB2_HDR_CREDIT,          creds);
440                 SIVAL(outhdr, SMB2_HDR_FLAGS,
441                       IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
442                 SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND,    next_command_ofs);
443                 SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
444                       BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
445                 SIVAL(outhdr, SMB2_HDR_PID,
446                       IVAL(inhdr, SMB2_HDR_PID));
447                 SIVAL(outhdr, SMB2_HDR_TID,
448                       IVAL(inhdr, SMB2_HDR_TID));
449                 SBVAL(outhdr, SMB2_HDR_SESSION_ID,
450                       BVAL(inhdr, SMB2_HDR_SESSION_ID));
451                 memset(outhdr + SMB2_HDR_SIGNATURE, 0, 16);
452
453                 /* setup error body header */
454                 SSVAL(outbody, 0x00, 0x08 + 1);
455                 SSVAL(outbody, 0x02, 0);
456                 SIVAL(outbody, 0x04, 0);
457         }
458
459         req->out.vector = vector;
460         req->out.vector_count = count;
461
462         /* setup the length of the NBT packet */
463         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
464
465         DLIST_ADD_END(req->sconn->smb2.requests, req, struct smbd_smb2_request *);
466
467         return NT_STATUS_OK;
468 }
469
470 void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
471                                          const char *reason,
472                                          const char *location)
473 {
474         DEBUG(10,("smbd_server_connection_terminate_ex: reason[%s] at %s\n",
475                   reason, location));
476         exit_server_cleanly(reason);
477 }
478
479 static bool dup_smb2_vec(struct iovec *dstvec,
480                         const struct iovec *srcvec,
481                         int offset)
482 {
483
484         if (srcvec[offset].iov_len &&
485                         srcvec[offset].iov_base) {
486                 dstvec[offset].iov_base = talloc_memdup(dstvec,
487                                         srcvec[offset].iov_base,
488                                         srcvec[offset].iov_len);
489                 if (!dstvec[offset].iov_base) {
490                         return false;
491                 }
492                 dstvec[offset].iov_len = srcvec[offset].iov_len;
493         } else {
494                 dstvec[offset].iov_base = NULL;
495                 dstvec[offset].iov_len = 0;
496         }
497         return true;
498 }
499
500 static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
501 {
502         struct smbd_smb2_request *newreq = NULL;
503         struct iovec *outvec = NULL;
504         int count = req->out.vector_count;
505         int i;
506
507         newreq = smbd_smb2_request_allocate(req->sconn);
508         if (!newreq) {
509                 return NULL;
510         }
511
512         newreq->sconn = req->sconn;
513         newreq->do_signing = req->do_signing;
514         newreq->current_idx = req->current_idx;
515         newreq->async = false;
516         newreq->cancelled = false;
517
518         outvec = talloc_zero_array(newreq, struct iovec, count);
519         if (!outvec) {
520                 TALLOC_FREE(newreq);
521                 return NULL;
522         }
523         newreq->out.vector = outvec;
524         newreq->out.vector_count = count;
525
526         /* Setup the outvec's identically to req. */
527         outvec[0].iov_base = newreq->out.nbt_hdr;
528         outvec[0].iov_len = 4;
529         memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
530
531         for (i = 1; i < count; i += 3) {
532                 /* i + 0 and i + 1 are always
533                  * boilerplate. */
534                 outvec[i].iov_base = talloc_memdup(outvec,
535                                                 req->out.vector[i].iov_base,
536                                                 OUTVEC_ALLOC_SIZE);
537                 if (!outvec[i].iov_base) {
538                         break;
539                 }
540                 outvec[i].iov_len = SMB2_HDR_BODY;
541
542                 outvec[i+1].iov_base = ((uint8_t *)outvec[i].iov_base) +
543                                                 SMB2_HDR_BODY;
544                 outvec[i+1].iov_len = 8;
545
546                 if (req->out.vector[i+2].iov_base ==
547                                 ((uint8_t *)req->out.vector[i].iov_base) +
548                                         (OUTVEC_ALLOC_SIZE - 1) &&
549                                 req->out.vector[i+2].iov_len == 1) {
550                         /* Common SMB2 error packet case. */
551                         outvec[i+2].iov_base = ((uint8_t *)outvec[i].iov_base) +
552                                 (OUTVEC_ALLOC_SIZE - 1);
553                         outvec[i+2].iov_len = 1;
554                 } else if (!dup_smb2_vec(outvec,
555                                 req->out.vector,
556                                 i)) {
557                         break;
558                 }
559         }
560
561         if (i < count) {
562                 /* Alloc failed. */
563                 TALLOC_FREE(newreq);
564                 return NULL;
565         }
566
567         smb2_setup_nbt_length(newreq->out.vector,
568                 newreq->out.vector_count);
569
570         return newreq;
571 }
572
573 static void smbd_smb2_request_writev_done(struct tevent_req *subreq);
574
575 static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
576 {
577         int i = 0;
578         uint8_t *outhdr = NULL;
579         struct smbd_smb2_request *nreq = NULL;
580
581         /* Create a new smb2 request we'll use
582            for the interim return. */
583         nreq = dup_smb2_req(req);
584         if (!nreq) {
585                 return NT_STATUS_NO_MEMORY;
586         }
587
588         /* Lose the last 3 out vectors. They're the
589            ones we'll be using for the async reply. */
590         nreq->out.vector_count -= 3;
591
592         smb2_setup_nbt_length(nreq->out.vector,
593                 nreq->out.vector_count);
594
595         /* Step back to the previous reply. */
596         i = nreq->current_idx - 3;
597         outhdr = (uint8_t *)nreq->out.vector[i].iov_base;
598         /* And end the chain. */
599         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
600
601         /* Re-sign if needed. */
602         if (nreq->do_signing) {
603                 NTSTATUS status;
604                 status = smb2_signing_sign_pdu(nreq->session->session_key,
605                                         &nreq->out.vector[i], 3);
606                 if (!NT_STATUS_IS_OK(status)) {
607                         return status;
608                 }
609         }
610         if (DEBUGLEVEL >= 10) {
611                 dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
612                         (unsigned int)nreq->current_idx );
613                 dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
614                         (unsigned int)nreq->out.vector_count );
615                 print_req_vectors(nreq);
616         }
617         nreq->subreq = tstream_writev_queue_send(nreq,
618                                         nreq->sconn->smb2.event_ctx,
619                                         nreq->sconn->smb2.stream,
620                                         nreq->sconn->smb2.send_queue,
621                                         nreq->out.vector,
622                                         nreq->out.vector_count);
623
624         if (nreq->subreq == NULL) {
625                 return NT_STATUS_NO_MEMORY;
626         }
627
628         tevent_req_set_callback(nreq->subreq,
629                         smbd_smb2_request_writev_done,
630                         nreq);
631
632         return NT_STATUS_OK;
633 }
634
635 struct smbd_smb2_request_pending_state {
636         struct smbd_server_connection *sconn;
637         uint8_t buf[4 + SMB2_HDR_BODY + 0x08 + 1];
638         struct iovec vector[3];
639 };
640
641 static void smbd_smb2_request_pending_writev_done(struct tevent_req *subreq)
642 {
643         struct smbd_smb2_request_pending_state *state =
644                 tevent_req_callback_data(subreq,
645                         struct smbd_smb2_request_pending_state);
646         struct smbd_server_connection *sconn = state->sconn;
647         int ret;
648         int sys_errno;
649
650         ret = tstream_writev_queue_recv(subreq, &sys_errno);
651         TALLOC_FREE(subreq);
652         if (ret == -1) {
653                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
654                 smbd_server_connection_terminate(sconn, nt_errstr(status));
655                 return;
656         }
657
658         TALLOC_FREE(state);
659 }
660
661 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
662                                          struct tevent_req *subreq)
663 {
664         NTSTATUS status;
665         struct smbd_smb2_request_pending_state *state = NULL;
666         int i = req->current_idx;
667         uint8_t *reqhdr = NULL;
668         uint8_t *hdr = NULL;
669         uint8_t *body = NULL;
670         uint32_t flags = 0;
671         uint64_t message_id = 0;
672         uint64_t async_id = 0;
673         struct iovec *outvec = NULL;
674
675         if (!tevent_req_is_in_progress(subreq)) {
676                 return NT_STATUS_OK;
677         }
678
679         if (req->async) {
680                 /* We're already async. */
681                 return NT_STATUS_OK;
682         }
683
684         if (req->in.vector_count > i + 3) {
685                 /*
686                  * We're trying to go async in a compound
687                  * request chain. This is not allowed.
688                  * Cancel the outstanding request.
689                  */
690                 tevent_req_cancel(subreq);
691                 return smbd_smb2_request_error(req,
692                         NT_STATUS_INSUFFICIENT_RESOURCES);
693         }
694
695         req->subreq = subreq;
696         subreq = NULL;
697
698         if (DEBUGLEVEL >= 10) {
699                 dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
700                         (unsigned int)req->current_idx );
701                 print_req_vectors(req);
702         }
703
704         if (req->out.vector_count > 4) {
705                 /* This is a compound reply. We
706                  * must do an interim response
707                  * followed by the async response
708                  * to match W2K8R2.
709                  */
710                 status = smb2_send_async_interim_response(req);
711                 if (!NT_STATUS_IS_OK(status)) {
712                         return status;
713                 }
714         }
715
716         /* Don't return an intermediate packet on a pipe read/write. */
717         if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) {
718                 return NT_STATUS_OK;
719         }
720
721         reqhdr = (uint8_t *)req->out.vector[i].iov_base;
722         flags = (IVAL(reqhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
723         message_id = BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
724         async_id = message_id; /* keep it simple for now... */
725
726         /*
727          * What we send is identical to a smbd_smb2_request_error
728          * packet with an error status of STATUS_PENDING. Make use
729          * of this fact sometime when refactoring. JRA.
730          */
731
732         state = talloc_zero(req->sconn, struct smbd_smb2_request_pending_state);
733         if (state == NULL) {
734                 return NT_STATUS_NO_MEMORY;
735         }
736         state->sconn = req->sconn;
737
738         state->vector[0].iov_base = (void *)state->buf;
739         state->vector[0].iov_len = 4;
740
741         state->vector[1].iov_base = state->buf + 4;
742         state->vector[1].iov_len = SMB2_HDR_BODY;
743
744         state->vector[2].iov_base = state->buf + 4 + SMB2_HDR_BODY;
745         state->vector[2].iov_len = 9;
746
747         smb2_setup_nbt_length(state->vector, 3);
748
749         hdr = (uint8_t *)state->vector[1].iov_base;
750         body = (uint8_t *)state->vector[2].iov_base;
751
752         SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
753         SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
754         SSVAL(hdr, SMB2_HDR_EPOCH, 0);
755         SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
756         SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(reqhdr, SMB2_HDR_OPCODE));
757         SSVAL(hdr, SMB2_HDR_CREDIT, 5);
758         SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
759         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
760         SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
761         SBVAL(hdr, SMB2_HDR_PID, async_id);
762         SBVAL(hdr, SMB2_HDR_SESSION_ID,
763                 BVAL(reqhdr, SMB2_HDR_SESSION_ID));
764         memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
765
766         SSVAL(body, 0x00, 0x08 + 1);
767
768         SCVAL(body, 0x02, 0);
769         SCVAL(body, 0x03, 0);
770         SIVAL(body, 0x04, 0);
771         /* Match W2K8R2... */
772         SCVAL(body, 0x08, 0x21);
773
774         if (req->do_signing) {
775                 status = smb2_signing_sign_pdu(req->session->session_key,
776                                         state->vector, 3);
777                 if (!NT_STATUS_IS_OK(status)) {
778                         return status;
779                 }
780         }
781
782         subreq = tstream_writev_queue_send(state,
783                                         req->sconn->smb2.event_ctx,
784                                         req->sconn->smb2.stream,
785                                         req->sconn->smb2.send_queue,
786                                         state->vector,
787                                         3);
788
789         if (subreq == NULL) {
790                 return NT_STATUS_NO_MEMORY;
791         }
792
793         tevent_req_set_callback(subreq,
794                         smbd_smb2_request_pending_writev_done,
795                         state);
796
797         /* Note we're going async with this request. */
798         req->async = true;
799
800         /*
801          * Now manipulate req so that the outstanding async request
802          * is the only one left in the struct smbd_smb2_request.
803          */
804
805         if (req->current_idx == 1) {
806                 /* There was only one. */
807                 goto out;
808         }
809
810         /* Re-arrange the in.vectors. */
811         req->in.vector[1] = req->in.vector[i];
812         req->in.vector[2] = req->in.vector[i+1];
813         req->in.vector[3] = req->in.vector[i+2];
814         req->in.vector_count = 4;
815         /* Reset the new in size. */
816         smb2_setup_nbt_length(req->in.vector, 4);
817
818         /* Now recreate the out.vectors. */
819         outvec = talloc_zero_array(req, struct iovec, 4);
820         if (!outvec) {
821                 return NT_STATUS_NO_MEMORY;
822         }
823         outvec[0].iov_base = req->out.nbt_hdr;
824         outvec[0].iov_len = 4;
825         SIVAL(req->out.nbt_hdr, 0, 0);
826
827         outvec[1].iov_base = talloc_memdup(outvec,
828                                 req->out.vector[i].iov_base,
829                                 OUTVEC_ALLOC_SIZE);
830         if (!outvec[1].iov_base) {
831                 return NT_STATUS_NO_MEMORY;
832         }
833         outvec[1].iov_len = SMB2_HDR_BODY;
834
835         outvec[2].iov_base = ((uint8_t *)outvec[1].iov_base) +
836                                 SMB2_HDR_BODY;
837         outvec[2].iov_len = 8;
838
839         if (req->out.vector[i+2].iov_base &&
840                         req->out.vector[i+2].iov_len) {
841                 if (req->out.vector[i+2].iov_base ==
842                                 ((uint8_t *)req->out.vector[i].iov_base) +
843                                         (OUTVEC_ALLOC_SIZE - 1) &&
844                                 req->out.vector[i].iov_len == 1) {
845                         /* Common SMB2 error packet case. */
846                         outvec[3].iov_base = ((uint8_t *)outvec[1].iov_base) +
847                                 (OUTVEC_ALLOC_SIZE - 1);
848                 } else {
849                         outvec[3].iov_base = talloc_memdup(outvec,
850                                         req->out.vector[i+2].iov_base,
851                                         req->out.vector[i+2].iov_len);
852                         if (!outvec[3].iov_base) {
853                                 return NT_STATUS_NO_MEMORY;
854                         }
855                 }
856                 outvec[3].iov_len = req->out.vector[i+2].iov_len;
857         } else {
858                 outvec[3].iov_base = NULL;
859                 outvec[3].iov_len = 0;
860         }
861
862         TALLOC_FREE(req->out.vector);
863
864         req->out.vector = outvec;
865
866         req->current_idx = 1;
867         req->out.vector_count = 4;
868
869   out:
870
871         smb2_setup_nbt_length(req->out.vector,
872                 req->out.vector_count);
873
874         /* Ensure our final reply matches the interim one. */
875         reqhdr = (uint8_t *)req->out.vector[1].iov_base;
876         SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
877         SBVAL(reqhdr, SMB2_HDR_PID, async_id);
878
879         {
880                 const uint8_t *inhdr =
881                         (const uint8_t *)req->in.vector[1].iov_base;
882                 DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
883                         "going async\n",
884                         smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
885                         (unsigned long long)async_id ));
886         }
887         return NT_STATUS_OK;
888 }
889
890 static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
891 {
892         struct smbd_server_connection *sconn = req->sconn;
893         struct smbd_smb2_request *cur;
894         const uint8_t *inhdr;
895         int i = req->current_idx;
896         uint32_t flags;
897         uint64_t search_message_id;
898         uint64_t search_async_id;
899         uint64_t found_id;
900
901         inhdr = (const uint8_t *)req->in.vector[i].iov_base;
902
903         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
904         search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
905         search_async_id = BVAL(inhdr, SMB2_HDR_PID);
906
907         /*
908          * we don't need the request anymore
909          * cancel requests never have a response
910          */
911         TALLOC_FREE(req);
912
913         for (cur = sconn->smb2.requests; cur; cur = cur->next) {
914                 const uint8_t *outhdr;
915                 uint64_t message_id;
916                 uint64_t async_id;
917
918                 i = cur->current_idx;
919
920                 outhdr = (const uint8_t *)cur->out.vector[i].iov_base;
921
922                 message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
923                 async_id = BVAL(outhdr, SMB2_HDR_PID);
924
925                 if (flags & SMB2_HDR_FLAG_ASYNC) {
926                         if (search_async_id == async_id) {
927                                 found_id = async_id;
928                                 break;
929                         }
930                 } else {
931                         if (search_message_id == message_id) {
932                                 found_id = message_id;
933                                 break;
934                         }
935                 }
936         }
937
938         if (cur && cur->subreq) {
939                 inhdr = (const uint8_t *)cur->in.vector[i].iov_base;
940                 DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
941                         "cancel opcode[%s] mid %llu\n",
942                         smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
943                         (unsigned long long)found_id ));
944                 tevent_req_cancel(cur->subreq);
945         }
946
947         return NT_STATUS_OK;
948 }
949
950 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
951 {
952         const uint8_t *inhdr;
953         int i = req->current_idx;
954         uint16_t opcode;
955         uint32_t flags;
956         uint64_t mid;
957         NTSTATUS status;
958         NTSTATUS session_status;
959         uint32_t allowed_flags;
960
961         inhdr = (const uint8_t *)req->in.vector[i].iov_base;
962
963         /* TODO: verify more things */
964
965         flags = IVAL(inhdr, SMB2_HDR_FLAGS);
966         opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
967         mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
968         DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
969                 smb2_opcode_name(opcode),
970                 (unsigned long long)mid));
971
972         allowed_flags = SMB2_HDR_FLAG_CHAINED |
973                         SMB2_HDR_FLAG_SIGNED |
974                         SMB2_HDR_FLAG_DFS;
975         if (opcode == SMB2_OP_CANCEL) {
976                 allowed_flags |= SMB2_HDR_FLAG_ASYNC;
977         }
978         if ((flags & ~allowed_flags) != 0) {
979                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
980         }
981
982         session_status = smbd_smb2_request_check_session(req);
983
984         req->do_signing = false;
985         if (flags & SMB2_HDR_FLAG_SIGNED) {
986                 if (!NT_STATUS_IS_OK(session_status)) {
987                         return smbd_smb2_request_error(req, session_status);
988                 }
989
990                 req->do_signing = true;
991                 status = smb2_signing_check_pdu(req->session->session_key,
992                                                 &req->in.vector[i], 3);
993                 if (!NT_STATUS_IS_OK(status)) {
994                         return smbd_smb2_request_error(req, status);
995                 }
996         } else if (req->session && req->session->do_signing) {
997                 return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
998         }
999
1000         if (flags & SMB2_HDR_FLAG_CHAINED) {
1001                 /*
1002                  * This check is mostly for giving the correct error code
1003                  * for compounded requests.
1004                  *
1005                  * TODO: we may need to move this after the session
1006                  *       and tcon checks.
1007                  */
1008                 if (!NT_STATUS_IS_OK(req->next_status)) {
1009                         return smbd_smb2_request_error(req, req->next_status);
1010                 }
1011         } else {
1012                 req->compat_chain_fsp = NULL;
1013         }
1014
1015         switch (opcode) {
1016         case SMB2_OP_NEGPROT:
1017                 return smbd_smb2_request_process_negprot(req);
1018
1019         case SMB2_OP_SESSSETUP:
1020                 return smbd_smb2_request_process_sesssetup(req);
1021
1022         case SMB2_OP_LOGOFF:
1023                 if (!NT_STATUS_IS_OK(session_status)) {
1024                         return smbd_smb2_request_error(req, session_status);
1025                 }
1026                 return smbd_smb2_request_process_logoff(req);
1027
1028         case SMB2_OP_TCON:
1029                 if (!NT_STATUS_IS_OK(session_status)) {
1030                         return smbd_smb2_request_error(req, session_status);
1031                 }
1032                 status = smbd_smb2_request_check_session(req);
1033                 if (!NT_STATUS_IS_OK(status)) {
1034                         return smbd_smb2_request_error(req, status);
1035                 }
1036                 return smbd_smb2_request_process_tcon(req);
1037
1038         case SMB2_OP_TDIS:
1039                 if (!NT_STATUS_IS_OK(session_status)) {
1040                         return smbd_smb2_request_error(req, session_status);
1041                 }
1042                 status = smbd_smb2_request_check_tcon(req);
1043                 if (!NT_STATUS_IS_OK(status)) {
1044                         return smbd_smb2_request_error(req, status);
1045                 }
1046                 return smbd_smb2_request_process_tdis(req);
1047
1048         case SMB2_OP_CREATE:
1049                 if (!NT_STATUS_IS_OK(session_status)) {
1050                         return smbd_smb2_request_error(req, session_status);
1051                 }
1052                 status = smbd_smb2_request_check_tcon(req);
1053                 if (!NT_STATUS_IS_OK(status)) {
1054                         return smbd_smb2_request_error(req, status);
1055                 }
1056                 return smbd_smb2_request_process_create(req);
1057
1058         case SMB2_OP_CLOSE:
1059                 if (!NT_STATUS_IS_OK(session_status)) {
1060                         return smbd_smb2_request_error(req, session_status);
1061                 }
1062                 status = smbd_smb2_request_check_tcon(req);
1063                 if (!NT_STATUS_IS_OK(status)) {
1064                         return smbd_smb2_request_error(req, status);
1065                 }
1066                 return smbd_smb2_request_process_close(req);
1067
1068         case SMB2_OP_FLUSH:
1069                 if (!NT_STATUS_IS_OK(session_status)) {
1070                         return smbd_smb2_request_error(req, session_status);
1071                 }
1072                 status = smbd_smb2_request_check_tcon(req);
1073                 if (!NT_STATUS_IS_OK(status)) {
1074                         return smbd_smb2_request_error(req, status);
1075                 }
1076                 return smbd_smb2_request_process_flush(req);
1077
1078         case SMB2_OP_READ:
1079                 if (!NT_STATUS_IS_OK(session_status)) {
1080                         return smbd_smb2_request_error(req, session_status);
1081                 }
1082                 status = smbd_smb2_request_check_tcon(req);
1083                 if (!NT_STATUS_IS_OK(status)) {
1084                         return smbd_smb2_request_error(req, status);
1085                 }
1086                 return smbd_smb2_request_process_read(req);
1087
1088         case SMB2_OP_WRITE:
1089                 if (!NT_STATUS_IS_OK(session_status)) {
1090                         return smbd_smb2_request_error(req, session_status);
1091                 }
1092                 status = smbd_smb2_request_check_tcon(req);
1093                 if (!NT_STATUS_IS_OK(status)) {
1094                         return smbd_smb2_request_error(req, status);
1095                 }
1096                 return smbd_smb2_request_process_write(req);
1097
1098         case SMB2_OP_LOCK:
1099                 if (!NT_STATUS_IS_OK(session_status)) {
1100                         /* Too ugly to live ? JRA. */
1101                         if (NT_STATUS_EQUAL(session_status,NT_STATUS_USER_SESSION_DELETED)) {
1102                                 session_status = NT_STATUS_FILE_CLOSED;
1103                         }
1104                         return smbd_smb2_request_error(req, session_status);
1105                 }
1106                 status = smbd_smb2_request_check_tcon(req);
1107                 if (!NT_STATUS_IS_OK(status)) {
1108                         /* Too ugly to live ? JRA. */
1109                         if (NT_STATUS_EQUAL(status,NT_STATUS_NETWORK_NAME_DELETED)) {
1110                                 status = NT_STATUS_FILE_CLOSED;
1111                         }
1112                         return smbd_smb2_request_error(req, status);
1113                 }
1114                 return smbd_smb2_request_process_lock(req);
1115
1116         case SMB2_OP_IOCTL:
1117                 if (!NT_STATUS_IS_OK(session_status)) {
1118                         return smbd_smb2_request_error(req, session_status);
1119                 }
1120                 status = smbd_smb2_request_check_tcon(req);
1121                 if (!NT_STATUS_IS_OK(status)) {
1122                         return smbd_smb2_request_error(req, status);
1123                 }
1124                 return smbd_smb2_request_process_ioctl(req);
1125
1126         case SMB2_OP_CANCEL:
1127                 return smbd_smb2_request_process_cancel(req);
1128
1129         case SMB2_OP_KEEPALIVE:
1130                 return smbd_smb2_request_process_keepalive(req);
1131
1132         case SMB2_OP_FIND:
1133                 if (!NT_STATUS_IS_OK(session_status)) {
1134                         return smbd_smb2_request_error(req, session_status);
1135                 }
1136                 status = smbd_smb2_request_check_tcon(req);
1137                 if (!NT_STATUS_IS_OK(status)) {
1138                         return smbd_smb2_request_error(req, status);
1139                 }
1140                 return smbd_smb2_request_process_find(req);
1141
1142         case SMB2_OP_NOTIFY:
1143                 if (!NT_STATUS_IS_OK(session_status)) {
1144                         return smbd_smb2_request_error(req, session_status);
1145                 }
1146                 status = smbd_smb2_request_check_tcon(req);
1147                 if (!NT_STATUS_IS_OK(status)) {
1148                         return smbd_smb2_request_error(req, status);
1149                 }
1150                 return smbd_smb2_request_process_notify(req);
1151
1152         case SMB2_OP_GETINFO:
1153                 if (!NT_STATUS_IS_OK(session_status)) {
1154                         return smbd_smb2_request_error(req, session_status);
1155                 }
1156                 status = smbd_smb2_request_check_tcon(req);
1157                 if (!NT_STATUS_IS_OK(status)) {
1158                         return smbd_smb2_request_error(req, status);
1159                 }
1160                 return smbd_smb2_request_process_getinfo(req);
1161
1162         case SMB2_OP_SETINFO:
1163                 if (!NT_STATUS_IS_OK(session_status)) {
1164                         return smbd_smb2_request_error(req, session_status);
1165                 }
1166                 status = smbd_smb2_request_check_tcon(req);
1167                 if (!NT_STATUS_IS_OK(status)) {
1168                         return smbd_smb2_request_error(req, status);
1169                 }
1170                 return smbd_smb2_request_process_setinfo(req);
1171
1172         case SMB2_OP_BREAK:
1173                 if (!NT_STATUS_IS_OK(session_status)) {
1174                         return smbd_smb2_request_error(req, session_status);
1175                 }
1176                 status = smbd_smb2_request_check_tcon(req);
1177                 if (!NT_STATUS_IS_OK(status)) {
1178                         return smbd_smb2_request_error(req, status);
1179                 }
1180                 return smbd_smb2_request_process_break(req);
1181         }
1182
1183         return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
1184 }
1185
1186 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
1187 {
1188         struct tevent_req *subreq;
1189
1190         req->subreq = NULL;
1191
1192         smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1193
1194         if (req->do_signing) {
1195                 int i = req->current_idx;
1196                 NTSTATUS status;
1197                 status = smb2_signing_sign_pdu(req->session->session_key,
1198                                                &req->out.vector[i], 3);
1199                 if (!NT_STATUS_IS_OK(status)) {
1200                         return status;
1201                 }
1202         }
1203
1204         req->current_idx += 3;
1205
1206         if (req->current_idx < req->out.vector_count) {
1207                 /*
1208                  * We must process the remaining compound
1209                  * SMB2 requests before any new incoming SMB2
1210                  * requests. This is because incoming SMB2
1211                  * requests may include a cancel for a
1212                  * compound request we haven't processed
1213                  * yet.
1214                  */
1215                 struct tevent_immediate *im = tevent_create_immediate(req);
1216                 if (!im) {
1217                         return NT_STATUS_NO_MEMORY;
1218                 }
1219                 tevent_schedule_immediate(im,
1220                                         req->sconn->smb2.event_ctx,
1221                                         smbd_smb2_request_dispatch_immediate,
1222                                         req);
1223                 return NT_STATUS_OK;
1224         }
1225
1226         if (DEBUGLEVEL >= 10) {
1227                 dbgtext("smbd_smb2_request_reply: sending...\n");
1228                 print_req_vectors(req);
1229         }
1230
1231         subreq = tstream_writev_queue_send(req,
1232                                            req->sconn->smb2.event_ctx,
1233                                            req->sconn->smb2.stream,
1234                                            req->sconn->smb2.send_queue,
1235                                            req->out.vector,
1236                                            req->out.vector_count);
1237         if (subreq == NULL) {
1238                 return NT_STATUS_NO_MEMORY;
1239         }
1240         tevent_req_set_callback(subreq, smbd_smb2_request_writev_done, req);
1241
1242         return NT_STATUS_OK;
1243 }
1244
1245 void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
1246                                         struct tevent_immediate *im,
1247                                         void *private_data)
1248 {
1249         struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
1250                                         struct smbd_smb2_request);
1251         struct smbd_server_connection *sconn = req->sconn;
1252         NTSTATUS status;
1253
1254         TALLOC_FREE(im);
1255
1256         if (DEBUGLEVEL >= 10) {
1257                 DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
1258                         req->current_idx, req->in.vector_count));
1259                 print_req_vectors(req);
1260         }
1261
1262         status = smbd_smb2_request_dispatch(req);
1263         if (!NT_STATUS_IS_OK(status)) {
1264                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1265                 return;
1266         }
1267 }
1268
1269 static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
1270 {
1271         struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
1272                                         struct smbd_smb2_request);
1273         struct smbd_server_connection *sconn = req->sconn;
1274         int ret;
1275         int sys_errno;
1276
1277         ret = tstream_writev_queue_recv(subreq, &sys_errno);
1278         TALLOC_FREE(subreq);
1279         TALLOC_FREE(req);
1280         if (ret == -1) {
1281                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
1282                 DEBUG(2,("smbd_smb2_request_writev_done: client write error %s\n",
1283                         nt_errstr(status)));
1284                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1285                 return;
1286         }
1287 }
1288
1289 NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
1290                                    NTSTATUS status,
1291                                    DATA_BLOB body, DATA_BLOB *dyn,
1292                                    const char *location)
1293 {
1294         uint8_t *outhdr;
1295         int i = req->current_idx;
1296         uint32_t next_command_ofs;
1297
1298         DEBUG(10,("smbd_smb2_request_done_ex: "
1299                   "idx[%d] status[%s] body[%u] dyn[%s:%u] at %s\n",
1300                   i, nt_errstr(status), (unsigned int)body.length,
1301                   dyn ? "yes": "no",
1302                   (unsigned int)(dyn ? dyn->length : 0),
1303                   location));
1304
1305         if (body.length < 2) {
1306                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
1307         }
1308
1309         if ((body.length % 2) != 0) {
1310                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
1311         }
1312
1313         outhdr = (uint8_t *)req->out.vector[i].iov_base;
1314
1315         next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
1316         SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
1317
1318         req->out.vector[i+1].iov_base = (void *)body.data;
1319         req->out.vector[i+1].iov_len = body.length;
1320
1321         if (dyn) {
1322                 req->out.vector[i+2].iov_base   = (void *)dyn->data;
1323                 req->out.vector[i+2].iov_len    = dyn->length;
1324         } else {
1325                 req->out.vector[i+2].iov_base = NULL;
1326                 req->out.vector[i+2].iov_len = 0;
1327         }
1328
1329         /* see if we need to recalculate the offset to the next response */
1330         if (next_command_ofs > 0) {
1331                 next_command_ofs  = SMB2_HDR_BODY;
1332                 next_command_ofs += req->out.vector[i+1].iov_len;
1333                 next_command_ofs += req->out.vector[i+2].iov_len;
1334         }
1335
1336         if ((next_command_ofs % 8) != 0) {
1337                 size_t pad_size = 8 - (next_command_ofs % 8);
1338                 if (req->out.vector[i+2].iov_len == 0) {
1339                         /*
1340                          * if the dyn buffer is empty
1341                          * we can use it to add padding
1342                          */
1343                         uint8_t *pad;
1344
1345                         pad = talloc_zero_array(req->out.vector,
1346                                                 uint8_t, pad_size);
1347                         if (pad == NULL) {
1348                                 return smbd_smb2_request_error(req,
1349                                                 NT_STATUS_NO_MEMORY);
1350                         }
1351
1352                         req->out.vector[i+2].iov_base = (void *)pad;
1353                         req->out.vector[i+2].iov_len = pad_size;
1354                 } else {
1355                         /*
1356                          * For now we copy the dynamic buffer
1357                          * and add the padding to the new buffer
1358                          */
1359                         size_t old_size;
1360                         uint8_t *old_dyn;
1361                         size_t new_size;
1362                         uint8_t *new_dyn;
1363
1364                         old_size = req->out.vector[i+2].iov_len;
1365                         old_dyn = (uint8_t *)req->out.vector[i+2].iov_base;
1366
1367                         new_size = old_size + pad_size;
1368                         new_dyn = talloc_zero_array(req->out.vector,
1369                                                uint8_t, new_size);
1370                         if (new_dyn == NULL) {
1371                                 return smbd_smb2_request_error(req,
1372                                                 NT_STATUS_NO_MEMORY);
1373                         }
1374
1375                         memcpy(new_dyn, old_dyn, old_size);
1376                         memset(new_dyn + old_size, 0, pad_size);
1377
1378                         req->out.vector[i+2].iov_base = (void *)new_dyn;
1379                         req->out.vector[i+2].iov_len = new_size;
1380                 }
1381                 next_command_ofs += pad_size;
1382         }
1383
1384         SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1385
1386         return smbd_smb2_request_reply(req);
1387 }
1388
1389 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
1390                                     NTSTATUS status,
1391                                     DATA_BLOB *info,
1392                                     const char *location)
1393 {
1394         DATA_BLOB body;
1395         int i = req->current_idx;
1396         uint8_t *outhdr = (uint8_t *)req->out.vector[i].iov_base;
1397
1398         DEBUG(10,("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| at %s\n",
1399                   i, nt_errstr(status), info ? " +info" : "",
1400                   location));
1401
1402         body.data = outhdr + SMB2_HDR_BODY;
1403         body.length = 8;
1404         SSVAL(body.data, 0, 9);
1405
1406         if (info) {
1407                 SIVAL(body.data, 0x04, info->length);
1408         } else {
1409                 /* Allocated size of req->out.vector[i].iov_base
1410                  * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
1411                  * 1 byte without having to do an alloc.
1412                  */
1413                 info = talloc_zero_array(req->out.vector,
1414                                         DATA_BLOB,
1415                                         1);
1416                 if (!info) {
1417                         return NT_STATUS_NO_MEMORY;
1418                 }
1419                 info->data = ((uint8_t *)outhdr) +
1420                         OUTVEC_ALLOC_SIZE - 1;
1421                 info->length = 1;
1422                 SCVAL(info->data, 0, 0);
1423         }
1424
1425         /*
1426          * if a request fails, all other remaining
1427          * compounded requests should fail too
1428          */
1429         req->next_status = NT_STATUS_INVALID_PARAMETER;
1430
1431         return smbd_smb2_request_done_ex(req, status, body, info, __location__);
1432 }
1433
1434
1435 struct smbd_smb2_send_oplock_break_state {
1436         struct smbd_server_connection *sconn;
1437         uint8_t buf[4 + SMB2_HDR_BODY + 0x18];
1438         struct iovec vector;
1439 };
1440
1441 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq);
1442
1443 NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
1444                                      uint64_t file_id_volatile,
1445                                      uint8_t oplock_level)
1446 {
1447         struct smbd_smb2_send_oplock_break_state *state;
1448         struct tevent_req *subreq;
1449         uint8_t *hdr;
1450         uint8_t *body;
1451
1452         state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
1453         if (state == NULL) {
1454                 return NT_STATUS_NO_MEMORY;
1455         }
1456         state->sconn = sconn;
1457
1458         state->vector.iov_base = (void *)state->buf;
1459         state->vector.iov_len = sizeof(state->buf);
1460
1461         _smb2_setlen(state->buf, sizeof(state->buf) - 4);
1462         hdr = state->buf + 4;
1463         body = hdr + SMB2_HDR_BODY;
1464
1465         SIVAL(hdr, 0,                           SMB2_MAGIC);
1466         SSVAL(hdr, SMB2_HDR_LENGTH,             SMB2_HDR_BODY);
1467         SSVAL(hdr, SMB2_HDR_EPOCH,              0);
1468         SIVAL(hdr, SMB2_HDR_STATUS,             0);
1469         SSVAL(hdr, SMB2_HDR_OPCODE,             SMB2_OP_BREAK);
1470         SSVAL(hdr, SMB2_HDR_CREDIT,             0);
1471         SIVAL(hdr, SMB2_HDR_FLAGS,              SMB2_HDR_FLAG_REDIRECT);
1472         SIVAL(hdr, SMB2_HDR_NEXT_COMMAND,       0);
1473         SBVAL(hdr, SMB2_HDR_MESSAGE_ID,         UINT64_MAX);
1474         SIVAL(hdr, SMB2_HDR_PID,                0);
1475         SIVAL(hdr, SMB2_HDR_TID,                0);
1476         SBVAL(hdr, SMB2_HDR_SESSION_ID,         0);
1477         memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
1478
1479         SSVAL(body, 0x00, 0x18);
1480
1481         SCVAL(body, 0x02, oplock_level);
1482         SCVAL(body, 0x03, 0);           /* reserved */
1483         SIVAL(body, 0x04, 0);           /* reserved */
1484         SBVAL(body, 0x08, 0);           /* file_id_persistent */
1485         SBVAL(body, 0x10, file_id_volatile);
1486
1487         subreq = tstream_writev_queue_send(state,
1488                                            sconn->smb2.event_ctx,
1489                                            sconn->smb2.stream,
1490                                            sconn->smb2.send_queue,
1491                                            &state->vector, 1);
1492         if (subreq == NULL) {
1493                 return NT_STATUS_NO_MEMORY;
1494         }
1495         tevent_req_set_callback(subreq,
1496                                 smbd_smb2_oplock_break_writev_done,
1497                                 state);
1498
1499         return NT_STATUS_OK;
1500 }
1501
1502 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq)
1503 {
1504         struct smbd_smb2_send_oplock_break_state *state =
1505                 tevent_req_callback_data(subreq,
1506                 struct smbd_smb2_send_oplock_break_state);
1507         struct smbd_server_connection *sconn = state->sconn;
1508         int ret;
1509         int sys_errno;
1510
1511         ret = tstream_writev_queue_recv(subreq, &sys_errno);
1512         TALLOC_FREE(subreq);
1513         if (ret == -1) {
1514                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
1515                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1516                 return;
1517         }
1518
1519         TALLOC_FREE(state);
1520 }
1521
1522 struct smbd_smb2_request_read_state {
1523         size_t missing;
1524         bool asked_for_header;
1525         struct smbd_smb2_request *smb2_req;
1526 };
1527
1528 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
1529                                          void *private_data,
1530                                          TALLOC_CTX *mem_ctx,
1531                                          struct iovec **_vector,
1532                                          size_t *_count);
1533 static void smbd_smb2_request_read_done(struct tevent_req *subreq);
1534
1535 static struct tevent_req *smbd_smb2_request_read_send(TALLOC_CTX *mem_ctx,
1536                                         struct tevent_context *ev,
1537                                         struct smbd_server_connection *sconn)
1538 {
1539         struct tevent_req *req;
1540         struct smbd_smb2_request_read_state *state;
1541         struct tevent_req *subreq;
1542
1543         req = tevent_req_create(mem_ctx, &state,
1544                                 struct smbd_smb2_request_read_state);
1545         if (req == NULL) {
1546                 return NULL;
1547         }
1548         state->missing = 0;
1549         state->asked_for_header = false;
1550
1551         state->smb2_req = smbd_smb2_request_allocate(state);
1552         if (tevent_req_nomem(state->smb2_req, req)) {
1553                 return tevent_req_post(req, ev);
1554         }
1555         state->smb2_req->sconn = sconn;
1556
1557         subreq = tstream_readv_pdu_queue_send(state, ev, sconn->smb2.stream,
1558                                               sconn->smb2.recv_queue,
1559                                               smbd_smb2_request_next_vector,
1560                                               state);
1561         if (tevent_req_nomem(subreq, req)) {
1562                 return tevent_req_post(req, ev);
1563         }
1564         tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
1565
1566         return req;
1567 }
1568
1569 static int smbd_smb2_request_next_vector(struct tstream_context *stream,
1570                                          void *private_data,
1571                                          TALLOC_CTX *mem_ctx,
1572                                          struct iovec **_vector,
1573                                          size_t *_count)
1574 {
1575         struct smbd_smb2_request_read_state *state =
1576                 talloc_get_type_abort(private_data,
1577                 struct smbd_smb2_request_read_state);
1578         struct smbd_smb2_request *req = state->smb2_req;
1579         struct iovec *vector;
1580         int idx = req->in.vector_count;
1581         size_t len = 0;
1582         uint8_t *buf = NULL;
1583
1584         if (req->in.vector_count == 0) {
1585                 /*
1586                  * first we need to get the NBT header
1587                  */
1588                 req->in.vector = talloc_array(req, struct iovec,
1589                                               req->in.vector_count + 1);
1590                 if (req->in.vector == NULL) {
1591                         return -1;
1592                 }
1593                 req->in.vector_count += 1;
1594
1595                 req->in.vector[idx].iov_base    = (void *)req->in.nbt_hdr;
1596                 req->in.vector[idx].iov_len     = 4;
1597
1598                 vector = talloc_array(mem_ctx, struct iovec, 1);
1599                 if (vector == NULL) {
1600                         return -1;
1601                 }
1602
1603                 vector[0] = req->in.vector[idx];
1604
1605                 *_vector = vector;
1606                 *_count = 1;
1607                 return 0;
1608         }
1609
1610         if (req->in.vector_count == 1) {
1611                 /*
1612                  * Now we analyze the NBT header
1613                  */
1614                 state->missing = smb2_len(req->in.vector[0].iov_base);
1615
1616                 if (state->missing == 0) {
1617                         /* if there're no remaining bytes, we're done */
1618                         *_vector = NULL;
1619                         *_count = 0;
1620                         return 0;
1621                 }
1622
1623                 req->in.vector = talloc_realloc(req, req->in.vector,
1624                                                 struct iovec,
1625                                                 req->in.vector_count + 1);
1626                 if (req->in.vector == NULL) {
1627                         return -1;
1628                 }
1629                 req->in.vector_count += 1;
1630
1631                 if (CVAL(req->in.vector[0].iov_base, 0) != 0) {
1632                         /*
1633                          * it's a special NBT message,
1634                          * so get all remaining bytes
1635                          */
1636                         len = state->missing;
1637                 } else if (state->missing < (SMB2_HDR_BODY + 2)) {
1638                         /*
1639                          * it's an invalid message, just read what we can get
1640                          * and let the caller handle the error
1641                          */
1642                         len = state->missing;
1643                 } else {
1644                         /*
1645                          * We assume it's a SMB2 request,
1646                          * and we first get the header and the
1647                          * first 2 bytes (the struct size) of the body
1648                          */
1649                         len = SMB2_HDR_BODY + 2;
1650
1651                         state->asked_for_header = true;
1652                 }
1653
1654                 state->missing -= len;
1655
1656                 buf = talloc_array(req->in.vector, uint8_t, len);
1657                 if (buf == NULL) {
1658                         return -1;
1659                 }
1660
1661                 req->in.vector[idx].iov_base    = (void *)buf;
1662                 req->in.vector[idx].iov_len     = len;
1663
1664                 vector = talloc_array(mem_ctx, struct iovec, 1);
1665                 if (vector == NULL) {
1666                         return -1;
1667                 }
1668
1669                 vector[0] = req->in.vector[idx];
1670
1671                 *_vector = vector;
1672                 *_count = 1;
1673                 return 0;
1674         }
1675
1676         if (state->missing == 0) {
1677                 /* if there're no remaining bytes, we're done */
1678                 *_vector = NULL;
1679                 *_count = 0;
1680                 return 0;
1681         }
1682
1683         if (state->asked_for_header) {
1684                 const uint8_t *hdr;
1685                 size_t full_size;
1686                 size_t next_command_ofs;
1687                 size_t body_size;
1688                 uint8_t *body;
1689                 size_t dyn_size;
1690                 uint8_t *dyn;
1691                 bool invalid = false;
1692
1693                 state->asked_for_header = false;
1694
1695                 /*
1696                  * We got the SMB2 header and the first 2 bytes
1697                  * of the body. We fix the size to just the header
1698                  * and manually copy the 2 first bytes to the body section
1699                  */
1700                 req->in.vector[idx-1].iov_len = SMB2_HDR_BODY;
1701                 hdr = (const uint8_t *)req->in.vector[idx-1].iov_base;
1702
1703                 /* allocate vectors for body and dynamic areas */
1704                 req->in.vector = talloc_realloc(req, req->in.vector,
1705                                                 struct iovec,
1706                                                 req->in.vector_count + 2);
1707                 if (req->in.vector == NULL) {
1708                         return -1;
1709                 }
1710                 req->in.vector_count += 2;
1711
1712                 full_size = state->missing + SMB2_HDR_BODY + 2;
1713                 next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
1714                 body_size = SVAL(hdr, SMB2_HDR_BODY);
1715
1716                 if (next_command_ofs != 0) {
1717                         if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
1718                                 /*
1719                                  * this is invalid, just return a zero
1720                                  * body and let the caller deal with the error
1721                                  */
1722                                 invalid = true;
1723                         } else if (next_command_ofs > full_size) {
1724                                 /*
1725                                  * this is invalid, just return a zero
1726                                  * body and let the caller deal with the error
1727                                  */
1728                                 invalid = true;
1729                         } else {
1730                                 full_size = next_command_ofs;
1731                         }
1732                 }
1733
1734                 if (!invalid) {
1735                         if (body_size < 2) {
1736                                 /*
1737                                  * this is invalid, just return a zero
1738                                  * body and let the caller deal with the error
1739                                  */
1740                                 invalid = true;
1741                         }
1742
1743                         if ((body_size % 2) != 0) {
1744                                 body_size -= 1;
1745                         }
1746
1747                         if (body_size > (full_size - SMB2_HDR_BODY)) {
1748                                 /*
1749                                  * this is invalid, just return a zero
1750                                  * body and let the caller deal with the error
1751                                  */
1752                                 invalid = true;
1753                         }
1754                 }
1755
1756                 if (invalid) {
1757                         /* the caller should check this */
1758                         body_size = 2;
1759                 }
1760
1761                 dyn_size = full_size - (SMB2_HDR_BODY + body_size);
1762
1763                 state->missing -= (body_size - 2) + dyn_size;
1764
1765                 body = talloc_array(req->in.vector, uint8_t, body_size);
1766                 if (body == NULL) {
1767                         return -1;
1768                 }
1769
1770                 dyn = talloc_array(req->in.vector, uint8_t, dyn_size);
1771                 if (dyn == NULL) {
1772                         return -1;
1773                 }
1774
1775                 req->in.vector[idx].iov_base    = (void *)body;
1776                 req->in.vector[idx].iov_len     = body_size;
1777                 req->in.vector[idx+1].iov_base  = (void *)dyn;
1778                 req->in.vector[idx+1].iov_len   = dyn_size;
1779
1780                 vector = talloc_array(mem_ctx, struct iovec, 2);
1781                 if (vector == NULL) {
1782                         return -1;
1783                 }
1784
1785                 /*
1786                  * the first 2 bytes of the body were already fetched
1787                  * together with the header
1788                  */
1789                 memcpy(body, hdr + SMB2_HDR_BODY, 2);
1790                 vector[0].iov_base = body + 2;
1791                 vector[0].iov_len = body_size - 2;
1792
1793                 vector[1] = req->in.vector[idx+1];
1794
1795                 *_vector = vector;
1796                 *_count = 2;
1797                 return 0;
1798         }
1799
1800         /*
1801          * when we endup here, we're looking for a new SMB2 request
1802          * next. And we ask for its header and the first 2 bytes of
1803          * the body (like we did for the first SMB2 request).
1804          */
1805
1806         req->in.vector = talloc_realloc(req, req->in.vector,
1807                                         struct iovec,
1808                                         req->in.vector_count + 1);
1809         if (req->in.vector == NULL) {
1810                 return -1;
1811         }
1812         req->in.vector_count += 1;
1813
1814         /*
1815          * We assume it's a SMB2 request,
1816          * and we first get the header and the
1817          * first 2 bytes (the struct size) of the body
1818          */
1819         len = SMB2_HDR_BODY + 2;
1820
1821         if (len > state->missing) {
1822                 /* let the caller handle the error */
1823                 len = state->missing;
1824         }
1825
1826         state->missing -= len;
1827         state->asked_for_header = true;
1828
1829         buf = talloc_array(req->in.vector, uint8_t, len);
1830         if (buf == NULL) {
1831                 return -1;
1832         }
1833
1834         req->in.vector[idx].iov_base    = (void *)buf;
1835         req->in.vector[idx].iov_len     = len;
1836
1837         vector = talloc_array(mem_ctx, struct iovec, 1);
1838         if (vector == NULL) {
1839                 return -1;
1840         }
1841
1842         vector[0] = req->in.vector[idx];
1843
1844         *_vector = vector;
1845         *_count = 1;
1846         return 0;
1847 }
1848
1849 static void smbd_smb2_request_read_done(struct tevent_req *subreq)
1850 {
1851         struct tevent_req *req =
1852                 tevent_req_callback_data(subreq,
1853                 struct tevent_req);
1854         int ret;
1855         int sys_errno;
1856         NTSTATUS status;
1857
1858         ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
1859         if (ret == -1) {
1860                 status = map_nt_error_from_unix(sys_errno);
1861                 tevent_req_nterror(req, status);
1862                 return;
1863         }
1864
1865         tevent_req_done(req);
1866 }
1867
1868 static NTSTATUS smbd_smb2_request_read_recv(struct tevent_req *req,
1869                                             TALLOC_CTX *mem_ctx,
1870                                             struct smbd_smb2_request **_smb2_req)
1871 {
1872         struct smbd_smb2_request_read_state *state =
1873                 tevent_req_data(req,
1874                 struct smbd_smb2_request_read_state);
1875         NTSTATUS status;
1876
1877         if (tevent_req_is_nterror(req, &status)) {
1878                 tevent_req_received(req);
1879                 return status;
1880         }
1881
1882         talloc_steal(mem_ctx, state->smb2_req->mem_pool);
1883         *_smb2_req = state->smb2_req;
1884         tevent_req_received(req);
1885         return NT_STATUS_OK;
1886 }
1887
1888 static void smbd_smb2_request_incoming(struct tevent_req *subreq);
1889
1890 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
1891                              const uint8_t *inbuf, size_t size)
1892 {
1893         NTSTATUS status;
1894         struct smbd_smb2_request *req;
1895         struct tevent_req *subreq;
1896
1897         DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
1898                  (unsigned int)size));
1899
1900         status = smbd_initialize_smb2(sconn);
1901         if (!NT_STATUS_IS_OK(status)) {
1902                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1903                 return;
1904         }
1905
1906         status = smbd_smb2_request_create(sconn, inbuf, size, &req);
1907         if (!NT_STATUS_IS_OK(status)) {
1908                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1909                 return;
1910         }
1911
1912         status = smbd_smb2_request_setup_out(req, (uint16_t)lp_maxmux());
1913         if (!NT_STATUS_IS_OK(status)) {
1914                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1915                 return;
1916         }
1917
1918         status = smbd_smb2_request_dispatch(req);
1919         if (!NT_STATUS_IS_OK(status)) {
1920                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1921                 return;
1922         }
1923
1924         /* ask for the next request */
1925         subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn);
1926         if (subreq == NULL) {
1927                 smbd_server_connection_terminate(sconn, "no memory for reading");
1928                 return;
1929         }
1930         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
1931 }
1932
1933 static void smbd_smb2_request_incoming(struct tevent_req *subreq)
1934 {
1935         uint16_t creds_requested = 0;
1936         struct smbd_server_connection *sconn = tevent_req_callback_data(subreq,
1937                                                struct smbd_server_connection);
1938         NTSTATUS status;
1939         struct smbd_smb2_request *req = NULL;
1940
1941         status = smbd_smb2_request_read_recv(subreq, sconn, &req);
1942         TALLOC_FREE(subreq);
1943         if (!NT_STATUS_IS_OK(status)) {
1944                 DEBUG(2,("smbd_smb2_request_incoming: client read error %s\n",
1945                         nt_errstr(status)));
1946                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1947                 return;
1948         }
1949
1950         if (req->in.nbt_hdr[0] != 0x00) {
1951                 DEBUG(1,("smbd_smb2_request_incoming: ignore NBT[0x%02X] msg\n",
1952                          req->in.nbt_hdr[0]));
1953                 TALLOC_FREE(req);
1954                 goto next;
1955         }
1956
1957         req->current_idx = 1;
1958
1959         DEBUG(10,("smbd_smb2_request_incoming: idx[%d] of %d vectors\n",
1960                  req->current_idx, req->in.vector_count));
1961
1962         status = smbd_smb2_request_validate(req, &creds_requested);
1963         if (!NT_STATUS_IS_OK(status)) {
1964                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1965                 return;
1966         }
1967
1968         status = smbd_smb2_request_setup_out(req, 5);
1969         if (!NT_STATUS_IS_OK(status)) {
1970                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1971                 return;
1972         }
1973
1974         status = smbd_smb2_request_dispatch(req);
1975         if (!NT_STATUS_IS_OK(status)) {
1976                 smbd_server_connection_terminate(sconn, nt_errstr(status));
1977                 return;
1978         }
1979
1980 next:
1981         /* ask for the next request (this constructs the main loop) */
1982         subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn);
1983         if (subreq == NULL) {
1984                 smbd_server_connection_terminate(sconn, "no memory for reading");
1985                 return;
1986         }
1987         tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
1988 }