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