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