Line data Source code
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 "system/network.h"
24 : #include "smbd/smbd.h"
25 : #include "smbd/globals.h"
26 : #include "smbd/smbXsrv_open.h"
27 : #include "lib/param/param.h"
28 : #include "../libcli/smb/smb_common.h"
29 : #include "../lib/tsocket/tsocket.h"
30 : #include "../lib/util/tevent_ntstatus.h"
31 : #include "smbprofile.h"
32 : #include "../lib/util/bitmap.h"
33 : #include "../librpc/gen_ndr/krb5pac.h"
34 : #include "lib/util/iov_buf.h"
35 : #include "auth.h"
36 : #include "libcli/smb/smbXcli_base.h"
37 : #include "source3/lib/substitute.h"
38 :
39 : #if defined(LINUX)
40 : /* SIOCOUTQ TIOCOUTQ are the same */
41 : #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
42 : #define __HAVE_TCP_INFO_RTO 1
43 : #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
44 : #elif defined(FREEBSD)
45 : #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
46 : #define __HAVE_TCP_INFO_RTO 1
47 : #define __ALLOW_MULTI_CHANNEL_SUPPORT 1
48 : #endif
49 :
50 : #include "lib/crypto/gnutls_helpers.h"
51 : #include <gnutls/gnutls.h>
52 : #include <gnutls/crypto.h>
53 :
54 : #undef DBGC_CLASS
55 : #define DBGC_CLASS DBGC_SMB2
56 :
57 : static void smbd_smb2_connection_handler(struct tevent_context *ev,
58 : struct tevent_fd *fde,
59 : uint16_t flags,
60 : void *private_data);
61 : static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
62 :
63 : static const struct smbd_smb2_dispatch_table {
64 : uint16_t opcode;
65 : const char *name;
66 : bool need_session;
67 : bool need_tcon;
68 : bool as_root;
69 : uint16_t fileid_ofs;
70 : bool modify;
71 : } smbd_smb2_table[] = {
72 : #define _OP(o) .opcode = o, .name = #o
73 : {
74 : _OP(SMB2_OP_NEGPROT),
75 : .as_root = true,
76 : },{
77 : _OP(SMB2_OP_SESSSETUP),
78 : .as_root = true,
79 : },{
80 : _OP(SMB2_OP_LOGOFF),
81 : .need_session = true,
82 : .as_root = true,
83 : },{
84 : _OP(SMB2_OP_TCON),
85 : .need_session = true,
86 : /*
87 : * This call needs to be run as root.
88 : *
89 : * smbd_smb2_request_process_tcon()
90 : * calls make_connection_snum(), which will call
91 : * change_to_user(), when needed.
92 : */
93 : .as_root = true,
94 : },{
95 : _OP(SMB2_OP_TDIS),
96 : .need_session = true,
97 : .need_tcon = true,
98 : .as_root = true,
99 : },{
100 : _OP(SMB2_OP_CREATE),
101 : .need_session = true,
102 : .need_tcon = true,
103 : },{
104 : _OP(SMB2_OP_CLOSE),
105 : .need_session = true,
106 : .need_tcon = true,
107 : .fileid_ofs = 0x08,
108 : },{
109 : _OP(SMB2_OP_FLUSH),
110 : .need_session = true,
111 : .need_tcon = true,
112 : .fileid_ofs = 0x08,
113 : },{
114 : _OP(SMB2_OP_READ),
115 : .need_session = true,
116 : .need_tcon = true,
117 : .fileid_ofs = 0x10,
118 : },{
119 : _OP(SMB2_OP_WRITE),
120 : .need_session = true,
121 : .need_tcon = true,
122 : .fileid_ofs = 0x10,
123 : .modify = true,
124 : },{
125 : _OP(SMB2_OP_LOCK),
126 : .need_session = true,
127 : .need_tcon = true,
128 : .fileid_ofs = 0x08,
129 : },{
130 : _OP(SMB2_OP_IOCTL),
131 : .need_session = true,
132 : .need_tcon = true,
133 : .fileid_ofs = 0x08,
134 : .modify = true,
135 : },{
136 : _OP(SMB2_OP_CANCEL),
137 : .as_root = true,
138 : },{
139 : _OP(SMB2_OP_KEEPALIVE),
140 : .as_root = true,
141 : },{
142 : _OP(SMB2_OP_QUERY_DIRECTORY),
143 : .need_session = true,
144 : .need_tcon = true,
145 : .fileid_ofs = 0x08,
146 : },{
147 : _OP(SMB2_OP_NOTIFY),
148 : .need_session = true,
149 : .need_tcon = true,
150 : .fileid_ofs = 0x08,
151 : },{
152 : _OP(SMB2_OP_GETINFO),
153 : .need_session = true,
154 : .need_tcon = true,
155 : .fileid_ofs = 0x18,
156 : },{
157 : _OP(SMB2_OP_SETINFO),
158 : .need_session = true,
159 : .need_tcon = true,
160 : .fileid_ofs = 0x10,
161 : .modify = true,
162 : },{
163 : _OP(SMB2_OP_BREAK),
164 : .need_session = true,
165 : .need_tcon = true,
166 : /*
167 : * we do not set
168 : * .fileid_ofs here
169 : * as LEASE breaks does not
170 : * have a file id
171 : */
172 : }
173 : };
174 :
175 0 : const char *smb2_opcode_name(uint16_t opcode)
176 : {
177 0 : if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
178 0 : return "Bad SMB2 opcode";
179 : }
180 0 : return smbd_smb2_table[opcode].name;
181 : }
182 :
183 157044 : static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
184 : {
185 157044 : const struct smbd_smb2_dispatch_table *ret = NULL;
186 :
187 157044 : if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
188 0 : return NULL;
189 : }
190 :
191 157044 : ret = &smbd_smb2_table[opcode];
192 :
193 157044 : SMB_ASSERT(ret->opcode == opcode);
194 :
195 157044 : return ret;
196 : }
197 :
198 0 : static void print_req_vectors(const struct smbd_smb2_request *req)
199 : {
200 : int i;
201 :
202 0 : for (i = 0; i < req->in.vector_count; i++) {
203 0 : dbgtext("\treq->in.vector[%u].iov_len = %u\n",
204 : (unsigned int)i,
205 0 : (unsigned int)req->in.vector[i].iov_len);
206 : }
207 0 : for (i = 0; i < req->out.vector_count; i++) {
208 0 : dbgtext("\treq->out.vector[%u].iov_len = %u\n",
209 : (unsigned int)i,
210 0 : (unsigned int)req->out.vector[i].iov_len);
211 : }
212 0 : }
213 :
214 1817 : bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
215 : {
216 1817 : if (size < (4 + SMB2_HDR_BODY)) {
217 18 : return false;
218 : }
219 :
220 1799 : if (IVAL(inbuf, 4) != SMB2_MAGIC) {
221 118 : return false;
222 : }
223 :
224 1681 : return true;
225 : }
226 :
227 2577 : bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
228 : {
229 2577 : return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
230 : }
231 :
232 0 : bool smbd_smb2_is_last_in_compound(const struct smbd_smb2_request *req)
233 : {
234 0 : return (req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ ==
235 0 : req->in.vector_count);
236 : }
237 :
238 5052 : static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
239 : uint64_t expected_seq_low)
240 : {
241 : int rc;
242 :
243 5052 : xconn->smb2.credits.seq_low = expected_seq_low;
244 5052 : xconn->smb2.credits.seq_range = 1;
245 5052 : xconn->smb2.credits.granted = 1;
246 5052 : xconn->smb2.credits.max = lp_smb2_max_credits();
247 6601 : xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
248 5052 : xconn->smb2.credits.max);
249 5052 : if (xconn->smb2.credits.bitmap == NULL) {
250 0 : return NT_STATUS_NO_MEMORY;
251 : }
252 :
253 5052 : tevent_fd_set_close_fn(xconn->transport.fde, NULL);
254 5052 : TALLOC_FREE(xconn->transport.fde);
255 :
256 5052 : xconn->transport.fde = tevent_add_fd(
257 : xconn->client->raw_ev_ctx,
258 : xconn,
259 : xconn->transport.sock,
260 : TEVENT_FD_READ,
261 : smbd_smb2_connection_handler,
262 : xconn);
263 5052 : if (xconn->transport.fde == NULL) {
264 0 : close(xconn->transport.sock);
265 0 : xconn->transport.sock = -1;
266 0 : return NT_STATUS_NO_MEMORY;
267 : }
268 5052 : tevent_fd_set_auto_close(xconn->transport.fde);
269 :
270 : /* Ensure child is set to non-blocking mode */
271 5052 : rc = set_blocking(xconn->transport.sock, false);
272 5052 : if (rc < 0) {
273 0 : return NT_STATUS_INTERNAL_ERROR;
274 : }
275 :
276 5052 : return NT_STATUS_OK;
277 : }
278 :
279 : #define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
280 : #define _smb2_setlen(_buf,len) do { \
281 : uint8_t *buf = (uint8_t *)_buf; \
282 : buf[0] = 0; \
283 : buf[1] = ((len)&0xFF0000)>>16; \
284 : buf[2] = ((len)&0xFF00)>>8; \
285 : buf[3] = (len)&0xFF; \
286 : } while (0)
287 :
288 335666 : static bool smb2_setup_nbt_length(struct iovec *vector, int count)
289 : {
290 : ssize_t len;
291 :
292 335666 : if (count == 0) {
293 0 : return false;
294 : }
295 :
296 335666 : len = iov_buflen(vector+1, count-1);
297 :
298 335666 : if ((len == -1) || (len > 0xFFFFFF)) {
299 0 : return false;
300 : }
301 :
302 335666 : _smb2_setlen(vector[0].iov_base, len);
303 335666 : return true;
304 : }
305 :
306 159604 : static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
307 : {
308 159604 : TALLOC_FREE(req->first_enc_key);
309 159604 : TALLOC_FREE(req->last_sign_key);
310 159604 : return 0;
311 : }
312 :
313 0 : void smb2_request_set_async_internal(struct smbd_smb2_request *req,
314 : bool async_internal)
315 : {
316 0 : req->async_internal = async_internal;
317 0 : }
318 :
319 159604 : static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
320 : {
321 : TALLOC_CTX *mem_pool;
322 : struct smbd_smb2_request *req;
323 :
324 : #if 0
325 : /* Enable this to find subtle valgrind errors. */
326 : mem_pool = talloc_init("smbd_smb2_request_allocate");
327 : #else
328 159604 : mem_pool = talloc_tos();
329 : #endif
330 159604 : if (mem_pool == NULL) {
331 0 : return NULL;
332 : }
333 :
334 159604 : req = talloc_zero(mem_pool, struct smbd_smb2_request);
335 159604 : if (req == NULL) {
336 0 : talloc_free(mem_pool);
337 0 : return NULL;
338 : }
339 159604 : talloc_reparent(mem_pool, mem_ctx, req);
340 : #if 0
341 : TALLOC_FREE(mem_pool);
342 : #endif
343 :
344 159604 : req->last_session_id = UINT64_MAX;
345 159604 : req->last_tid = UINT32_MAX;
346 :
347 159604 : talloc_set_destructor(req, smbd_smb2_request_destructor);
348 :
349 159604 : return req;
350 : }
351 :
352 157044 : static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
353 : NTTIME now,
354 : uint8_t *buf,
355 : size_t buflen,
356 : struct smbd_smb2_request *req,
357 : struct iovec **piov,
358 : int *pnum_iov)
359 : {
360 157044 : TALLOC_CTX *mem_ctx = req;
361 : struct iovec *iov;
362 157044 : int num_iov = 1;
363 157044 : size_t taken = 0;
364 157044 : uint8_t *first_hdr = buf;
365 157044 : size_t verified_buflen = 0;
366 157044 : uint8_t *tf = NULL;
367 157044 : size_t tf_len = 0;
368 :
369 : /*
370 : * Note: index '0' is reserved for the transport protocol
371 : */
372 157044 : iov = req->in._vector;
373 :
374 434197 : while (taken < buflen) {
375 157044 : size_t len = buflen - taken;
376 157044 : uint8_t *hdr = first_hdr + taken;
377 : struct iovec *cur;
378 : size_t full_size;
379 : size_t next_command_ofs;
380 : uint16_t body_size;
381 157044 : uint8_t *body = NULL;
382 : uint32_t dyn_size;
383 157044 : uint8_t *dyn = NULL;
384 157044 : struct iovec *iov_alloc = NULL;
385 :
386 157044 : if (iov != req->in._vector) {
387 0 : iov_alloc = iov;
388 : }
389 :
390 157044 : if (verified_buflen > taken) {
391 0 : len = verified_buflen - taken;
392 : } else {
393 157044 : tf = NULL;
394 157044 : tf_len = 0;
395 : }
396 :
397 157044 : if (len < 4) {
398 0 : DEBUG(10, ("%d bytes left, expected at least %d\n",
399 : (int)len, 4));
400 0 : goto inval;
401 : }
402 157044 : if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
403 624 : struct smbXsrv_session *s = NULL;
404 : uint64_t uid;
405 : struct iovec tf_iov[2];
406 : NTSTATUS status;
407 : size_t enc_len;
408 :
409 624 : if (xconn->protocol < PROTOCOL_SMB3_00) {
410 0 : DEBUG(10, ("Got SMB2_TRANSFORM header, "
411 : "but dialect[0x%04X] is used\n",
412 : xconn->smb2.server.dialect));
413 0 : goto inval;
414 : }
415 :
416 624 : if (xconn->smb2.server.cipher == 0) {
417 0 : DEBUG(10, ("Got SMB2_TRANSFORM header, "
418 : "but not negotiated "
419 : "client[0x%08X] server[0x%08X]\n",
420 : xconn->smb2.client.capabilities,
421 : xconn->smb2.server.capabilities));
422 0 : goto inval;
423 : }
424 :
425 624 : if (len < SMB2_TF_HDR_SIZE) {
426 0 : DEBUG(1, ("%d bytes left, expected at least %d\n",
427 : (int)len, SMB2_TF_HDR_SIZE));
428 0 : goto inval;
429 : }
430 624 : tf = hdr;
431 624 : tf_len = SMB2_TF_HDR_SIZE;
432 624 : taken += tf_len;
433 :
434 624 : hdr = first_hdr + taken;
435 624 : enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
436 624 : uid = BVAL(tf, SMB2_TF_SESSION_ID);
437 :
438 624 : if (len < SMB2_TF_HDR_SIZE + enc_len) {
439 0 : DEBUG(1, ("%d bytes left, expected at least %d\n",
440 : (int)len,
441 : (int)(SMB2_TF_HDR_SIZE + enc_len)));
442 0 : goto inval;
443 : }
444 :
445 624 : status = smb2srv_session_lookup_conn(xconn, uid, now,
446 : &s);
447 624 : if (s == NULL) {
448 0 : status = smb2srv_session_lookup_global(xconn->client,
449 : uid, req, &s);
450 : }
451 624 : if (s == NULL) {
452 0 : DEBUG(1, ("invalid session[%llu] in "
453 : "SMB2_TRANSFORM header\n",
454 : (unsigned long long)uid));
455 0 : TALLOC_FREE(iov_alloc);
456 0 : return NT_STATUS_USER_SESSION_DELETED;
457 : }
458 :
459 624 : tf_iov[0].iov_base = (void *)tf;
460 624 : tf_iov[0].iov_len = tf_len;
461 624 : tf_iov[1].iov_base = (void *)hdr;
462 624 : tf_iov[1].iov_len = enc_len;
463 :
464 624 : status = smb2_signing_decrypt_pdu(s->global->decryption_key,
465 : tf_iov, 2);
466 624 : if (!NT_STATUS_IS_OK(status)) {
467 0 : TALLOC_FREE(iov_alloc);
468 0 : return status;
469 : }
470 :
471 624 : verified_buflen = taken + enc_len;
472 624 : len = enc_len;
473 : }
474 :
475 : /*
476 : * We need the header plus the body length field
477 : */
478 :
479 157044 : if (len < SMB2_HDR_BODY + 2) {
480 :
481 0 : if ((len == 5) &&
482 0 : (IVAL(hdr, 0) == SMB_SUICIDE_PACKET) &&
483 0 : lp_parm_bool(-1, "smbd", "suicide mode", false)) {
484 0 : uint8_t exitcode = CVAL(hdr, 4);
485 0 : DBG_WARNING("SUICIDE: Exiting immediately "
486 : "with code %"PRIu8"\n",
487 : exitcode);
488 0 : exit(exitcode);
489 : }
490 :
491 0 : DEBUG(10, ("%d bytes left, expected at least %d\n",
492 : (int)len, SMB2_HDR_BODY));
493 0 : goto inval;
494 : }
495 157044 : if (IVAL(hdr, 0) != SMB2_MAGIC) {
496 0 : DEBUG(10, ("Got non-SMB2 PDU: %x\n",
497 : IVAL(hdr, 0)));
498 0 : goto inval;
499 : }
500 157044 : if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
501 0 : DEBUG(10, ("Got HDR len %d, expected %d\n",
502 : SVAL(hdr, 4), SMB2_HDR_BODY));
503 0 : goto inval;
504 : }
505 :
506 157044 : full_size = len;
507 157044 : next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
508 157044 : body_size = SVAL(hdr, SMB2_HDR_BODY);
509 :
510 157044 : if (next_command_ofs != 0) {
511 0 : if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
512 0 : goto inval;
513 : }
514 0 : if (next_command_ofs > full_size) {
515 0 : goto inval;
516 : }
517 0 : full_size = next_command_ofs;
518 : }
519 157044 : if (body_size < 2) {
520 0 : goto inval;
521 : }
522 157044 : body_size &= 0xfffe;
523 :
524 157044 : if (body_size > (full_size - SMB2_HDR_BODY)) {
525 : /*
526 : * let the caller handle the error
527 : */
528 0 : body_size = full_size - SMB2_HDR_BODY;
529 : }
530 157044 : body = hdr + SMB2_HDR_BODY;
531 157044 : dyn = body + body_size;
532 157044 : dyn_size = full_size - (SMB2_HDR_BODY + body_size);
533 :
534 157044 : if (num_iov >= ARRAY_SIZE(req->in._vector)) {
535 0 : struct iovec *iov_tmp = NULL;
536 :
537 0 : iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
538 : struct iovec,
539 : num_iov +
540 : SMBD_SMB2_NUM_IOV_PER_REQ);
541 0 : if (iov_tmp == NULL) {
542 0 : TALLOC_FREE(iov_alloc);
543 0 : return NT_STATUS_NO_MEMORY;
544 : }
545 :
546 0 : if (iov_alloc == NULL) {
547 0 : memcpy(iov_tmp,
548 0 : req->in._vector,
549 : sizeof(req->in._vector));
550 : }
551 :
552 0 : iov = iov_tmp;
553 : }
554 157044 : cur = &iov[num_iov];
555 157044 : num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
556 :
557 157044 : cur[SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
558 157044 : cur[SMBD_SMB2_TF_IOV_OFS].iov_len = tf_len;
559 157044 : cur[SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
560 157044 : cur[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
561 157044 : cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
562 157044 : cur[SMBD_SMB2_BODY_IOV_OFS].iov_len = body_size;
563 157044 : cur[SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
564 157044 : cur[SMBD_SMB2_DYN_IOV_OFS].iov_len = dyn_size;
565 :
566 157044 : taken += full_size;
567 : }
568 :
569 157044 : *piov = iov;
570 157044 : *pnum_iov = num_iov;
571 157044 : return NT_STATUS_OK;
572 :
573 0 : inval:
574 0 : if (iov != req->in._vector) {
575 0 : TALLOC_FREE(iov);
576 : }
577 0 : return NT_STATUS_INVALID_PARAMETER;
578 : }
579 :
580 5052 : static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
581 : const uint8_t *_inpdu, size_t size,
582 : struct smbd_smb2_request **_req)
583 : {
584 5052 : struct smbd_server_connection *sconn = xconn->client->sconn;
585 : struct smbd_smb2_request *req;
586 : uint32_t protocol_version;
587 5052 : uint8_t *inpdu = NULL;
588 5052 : const uint8_t *inhdr = NULL;
589 : uint16_t cmd;
590 : uint32_t next_command_ofs;
591 : NTSTATUS status;
592 : NTTIME now;
593 :
594 5052 : if (size < (SMB2_HDR_BODY + 2)) {
595 0 : DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
596 0 : return NT_STATUS_INVALID_PARAMETER;
597 : }
598 :
599 5052 : inhdr = _inpdu;
600 :
601 5052 : protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
602 5052 : if (protocol_version != SMB2_MAGIC) {
603 0 : DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
604 : protocol_version));
605 0 : return NT_STATUS_INVALID_PARAMETER;
606 : }
607 :
608 5052 : cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
609 5052 : if (cmd != SMB2_OP_NEGPROT) {
610 0 : DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
611 : cmd));
612 0 : return NT_STATUS_INVALID_PARAMETER;
613 : }
614 :
615 5052 : next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
616 5052 : if (next_command_ofs != 0) {
617 0 : DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
618 : next_command_ofs));
619 0 : return NT_STATUS_INVALID_PARAMETER;
620 : }
621 :
622 5052 : req = smbd_smb2_request_allocate(xconn);
623 5052 : if (req == NULL) {
624 0 : return NT_STATUS_NO_MEMORY;
625 : }
626 5052 : req->sconn = sconn;
627 5052 : req->xconn = xconn;
628 :
629 5052 : inpdu = talloc_memdup(req, _inpdu, size);
630 5052 : if (inpdu == NULL) {
631 0 : return NT_STATUS_NO_MEMORY;
632 : }
633 :
634 5052 : req->request_time = timeval_current();
635 5052 : now = timeval_to_nttime(&req->request_time);
636 :
637 5052 : status = smbd_smb2_inbuf_parse_compound(xconn,
638 : now,
639 : inpdu,
640 : size,
641 : req, &req->in.vector,
642 : &req->in.vector_count);
643 5052 : if (!NT_STATUS_IS_OK(status)) {
644 0 : TALLOC_FREE(req);
645 0 : return status;
646 : }
647 :
648 5052 : req->current_idx = 1;
649 :
650 5052 : *_req = req;
651 5052 : return NT_STATUS_OK;
652 : }
653 :
654 703910 : static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
655 : uint64_t message_id, uint64_t seq_id)
656 : {
657 703910 : struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
658 : unsigned int offset;
659 : uint64_t seq_tmp;
660 :
661 703910 : seq_tmp = xconn->smb2.credits.seq_low;
662 703910 : if (seq_id < seq_tmp) {
663 0 : DBGC_ERR(DBGC_SMB2_CREDITS,
664 : "smb2_validate_sequence_number: bad message_id "
665 : "%llu (sequence id %llu) "
666 : "(granted = %u, low = %llu, range = %u)\n",
667 : (unsigned long long)message_id,
668 : (unsigned long long)seq_id,
669 : (unsigned int)xconn->smb2.credits.granted,
670 : (unsigned long long)xconn->smb2.credits.seq_low,
671 : (unsigned int)xconn->smb2.credits.seq_range);
672 0 : return false;
673 : }
674 :
675 703910 : seq_tmp += xconn->smb2.credits.seq_range;
676 703910 : if (seq_id >= seq_tmp) {
677 0 : DBGC_ERR(DBGC_SMB2_CREDITS,
678 : "smb2_validate_sequence_number: bad message_id "
679 : "%llu (sequence id %llu) "
680 : "(granted = %u, low = %llu, range = %u)\n",
681 : (unsigned long long)message_id,
682 : (unsigned long long)seq_id,
683 : (unsigned int)xconn->smb2.credits.granted,
684 : (unsigned long long)xconn->smb2.credits.seq_low,
685 : (unsigned int)xconn->smb2.credits.seq_range);
686 0 : return false;
687 : }
688 :
689 703910 : offset = seq_id % xconn->smb2.credits.max;
690 :
691 703910 : if (bitmap_query(credits_bm, offset)) {
692 0 : DBGC_ERR(DBGC_SMB2_CREDITS,
693 : "smb2_validate_sequence_number: duplicate message_id "
694 : "%llu (sequence id %llu) "
695 : "(granted = %u, low = %llu, range = %u) "
696 : "(bm offset %u)\n",
697 : (unsigned long long)message_id,
698 : (unsigned long long)seq_id,
699 : (unsigned int)xconn->smb2.credits.granted,
700 : (unsigned long long)xconn->smb2.credits.seq_low,
701 : (unsigned int)xconn->smb2.credits.seq_range,
702 : offset);
703 0 : return false;
704 : }
705 :
706 : /* Mark the message_ids as seen in the bitmap. */
707 703910 : bitmap_set(credits_bm, offset);
708 :
709 703910 : if (seq_id != xconn->smb2.credits.seq_low) {
710 0 : return true;
711 : }
712 :
713 : /*
714 : * Move the window forward by all the message_id's
715 : * already seen.
716 : */
717 1960200 : while (bitmap_query(credits_bm, offset)) {
718 703910 : DBGC_DEBUG(DBGC_SMB2_CREDITS,
719 : "smb2_validate_sequence_number: clearing "
720 : "id %llu (position %u) from bitmap\n",
721 : (unsigned long long)(xconn->smb2.credits.seq_low),
722 : offset);
723 703910 : bitmap_clear(credits_bm, offset);
724 :
725 703910 : xconn->smb2.credits.seq_low += 1;
726 703910 : xconn->smb2.credits.seq_range -= 1;
727 703910 : offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
728 : }
729 :
730 703910 : return true;
731 : }
732 :
733 157044 : static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
734 : const uint8_t *inhdr)
735 : {
736 157044 : uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
737 157044 : uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
738 157044 : uint16_t credit_charge = 1;
739 : uint64_t i;
740 :
741 157044 : if (opcode == SMB2_OP_CANCEL) {
742 : /* SMB2_CANCEL requests by definition resend messageids. */
743 18 : return true;
744 : }
745 :
746 157026 : if (xconn->smb2.credits.multicredit) {
747 149602 : credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
748 149602 : credit_charge = MAX(credit_charge, 1);
749 : }
750 :
751 157026 : DEBUGC(11,
752 : DBGC_SMB2_CREDITS,
753 : ("smb2_validate_message_id: mid %llu (charge %llu), "
754 : "credits_granted %llu, "
755 : "seqnum low/range: %llu/%llu\n",
756 : (unsigned long long) message_id,
757 : (unsigned long long) credit_charge,
758 : (unsigned long long) xconn->smb2.credits.granted,
759 : (unsigned long long) xconn->smb2.credits.seq_low,
760 : (unsigned long long) xconn->smb2.credits.seq_range));
761 :
762 157026 : if (xconn->smb2.credits.granted < credit_charge) {
763 0 : DBGC_ERR(DBGC_SMB2_CREDITS,
764 : "smb2_validate_message_id: client used more "
765 : "credits than granted, mid %llu, charge %llu, "
766 : "credits_granted %llu, "
767 : "seqnum low/range: %llu/%llu\n",
768 : (unsigned long long) message_id,
769 : (unsigned long long) credit_charge,
770 : (unsigned long long) xconn->smb2.credits.granted,
771 : (unsigned long long) xconn->smb2.credits.seq_low,
772 : (unsigned long long) xconn->smb2.credits.seq_range);
773 0 : return false;
774 : }
775 :
776 : /*
777 : * now check the message ids
778 : *
779 : * for multi-credit requests we need to check all current mid plus
780 : * the implicit mids caused by the credit charge
781 : * e.g. current mid = 15, charge 5 => mark 15-19 as used
782 : */
783 :
784 860936 : for (i = 0; i <= (credit_charge-1); i++) {
785 703910 : uint64_t id = message_id + i;
786 : bool ok;
787 :
788 703910 : DEBUGC(11,
789 : DBGC_SMB2_CREDITS,
790 : ("Iterating mid %llu charge %u (sequence %llu)\n",
791 : (unsigned long long)message_id,
792 : credit_charge,
793 : (unsigned long long)id));
794 :
795 703910 : ok = smb2_validate_sequence_number(xconn, message_id, id);
796 703910 : if (!ok) {
797 0 : return false;
798 : }
799 : }
800 :
801 : /* substract used credits */
802 157026 : xconn->smb2.credits.granted -= credit_charge;
803 :
804 157026 : return true;
805 : }
806 :
807 157044 : static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
808 : {
809 : int count;
810 : int idx;
811 :
812 157044 : count = req->in.vector_count;
813 :
814 157044 : if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
815 : /* It's not a SMB2 request */
816 0 : return NT_STATUS_INVALID_PARAMETER;
817 : }
818 :
819 314088 : for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
820 157044 : struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
821 157044 : struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
822 157044 : const uint8_t *inhdr = NULL;
823 :
824 157044 : if (hdr->iov_len != SMB2_HDR_BODY) {
825 0 : return NT_STATUS_INVALID_PARAMETER;
826 : }
827 :
828 157044 : if (body->iov_len < 2) {
829 0 : return NT_STATUS_INVALID_PARAMETER;
830 : }
831 :
832 157044 : inhdr = (const uint8_t *)hdr->iov_base;
833 :
834 : /* Check the SMB2 header */
835 157044 : if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
836 0 : return NT_STATUS_INVALID_PARAMETER;
837 : }
838 :
839 157044 : if (!smb2_validate_message_id(req->xconn, inhdr)) {
840 0 : return NT_STATUS_INVALID_PARAMETER;
841 : }
842 : }
843 :
844 157044 : return NT_STATUS_OK;
845 : }
846 :
847 178622 : static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
848 : const struct iovec *in_vector,
849 : struct iovec *out_vector)
850 : {
851 178622 : const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
852 178622 : uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
853 178622 : uint16_t credit_charge = 1;
854 : uint16_t credits_requested;
855 : uint32_t out_flags;
856 : uint16_t cmd;
857 : NTSTATUS out_status;
858 178622 : uint16_t credits_granted = 0;
859 : uint64_t credits_possible;
860 : uint16_t current_max_credits;
861 :
862 : /*
863 : * first we grant only 1/16th of the max range.
864 : *
865 : * Windows also starts with the 1/16th and then grants
866 : * more later. I was only able to trigger higher
867 : * values, when using a very high credit charge.
868 : *
869 : * TODO: scale up depending on load, free memory
870 : * or other stuff.
871 : * Maybe also on the relationship between number
872 : * of requests and the used sequence number.
873 : * Which means we would grant more credits
874 : * for client which use multi credit requests.
875 : *
876 : * The above is what Windows Server < 2016 is doing,
877 : * but new servers use all credits (8192 by default).
878 : */
879 178622 : current_max_credits = xconn->smb2.credits.max;
880 178622 : current_max_credits = MAX(current_max_credits, 1);
881 :
882 178622 : if (xconn->smb2.credits.multicredit) {
883 175859 : credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
884 175859 : credit_charge = MAX(credit_charge, 1);
885 : }
886 :
887 178622 : cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
888 178622 : credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
889 178622 : credits_requested = MAX(credits_requested, 1);
890 178622 : out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
891 178622 : out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
892 :
893 178622 : SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
894 :
895 178622 : if (xconn->smb2.credits.max < credit_charge) {
896 0 : smbd_server_connection_terminate(xconn,
897 : "client error: credit charge > max credits\n");
898 0 : return;
899 : }
900 :
901 178622 : if (out_flags & SMB2_HDR_FLAG_ASYNC) {
902 : /*
903 : * In case we already send an async interim
904 : * response, we should not grant
905 : * credits on the final response.
906 : */
907 21646 : credits_granted = 0;
908 : } else {
909 156976 : uint16_t additional_possible =
910 156976 : xconn->smb2.credits.max - credit_charge;
911 156976 : uint16_t additional_max = 0;
912 156976 : uint16_t additional_credits = credits_requested - 1;
913 :
914 156976 : switch (cmd) {
915 8323 : case SMB2_OP_NEGPROT:
916 8323 : break;
917 6774 : case SMB2_OP_SESSSETUP:
918 : /*
919 : * Windows 2012 RC1 starts to grant
920 : * additional credits
921 : * with a successful session setup
922 : */
923 6774 : if (NT_STATUS_IS_OK(out_status)) {
924 4832 : additional_max = xconn->smb2.credits.max;
925 : }
926 6774 : break;
927 141879 : default:
928 : /*
929 : * Windows Server < 2016 and older Samba versions
930 : * used to only grant additional credits in
931 : * chunks of 32 credits.
932 : *
933 : * But we match Windows Server 2016 and grant
934 : * all credits as requested.
935 : */
936 141879 : additional_max = xconn->smb2.credits.max;
937 141879 : break;
938 : }
939 :
940 156976 : additional_max = MIN(additional_max, additional_possible);
941 156976 : additional_credits = MIN(additional_credits, additional_max);
942 :
943 156976 : credits_granted = credit_charge + additional_credits;
944 : }
945 :
946 : /*
947 : * sequence numbers should not wrap
948 : *
949 : * 1. calculate the possible credits until
950 : * the sequence numbers start to wrap on 64-bit.
951 : *
952 : * 2. UINT64_MAX is used for Break Notifications.
953 : *
954 : * 2. truncate the possible credits to the maximum
955 : * credits we want to grant to the client in total.
956 : *
957 : * 3. remove the range we'll already granted to the client
958 : * this makes sure the client consumes the lowest sequence
959 : * number, before we can grant additional credits.
960 : */
961 178622 : credits_possible = UINT64_MAX - xconn->smb2.credits.seq_low;
962 178622 : if (credits_possible > 0) {
963 : /* remove UINT64_MAX */
964 178622 : credits_possible -= 1;
965 : }
966 178622 : credits_possible = MIN(credits_possible, current_max_credits);
967 178622 : credits_possible -= xconn->smb2.credits.seq_range;
968 :
969 178622 : credits_granted = MIN(credits_granted, credits_possible);
970 :
971 178622 : SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
972 178622 : xconn->smb2.credits.granted += credits_granted;
973 178622 : xconn->smb2.credits.seq_range += credits_granted;
974 :
975 178622 : DBGC_DEBUG(DBGC_SMB2_CREDITS,
976 : "smb2_set_operation_credit: requested %u, charge %u, "
977 : "granted %u, current possible/max %u/%u, "
978 : "total granted/max/low/range %u/%u/%llu/%u\n",
979 : (unsigned int)credits_requested,
980 : (unsigned int)credit_charge,
981 : (unsigned int)credits_granted,
982 : (unsigned int)credits_possible,
983 : (unsigned int)current_max_credits,
984 : (unsigned int)xconn->smb2.credits.granted,
985 : (unsigned int)xconn->smb2.credits.max,
986 : (unsigned long long)xconn->smb2.credits.seq_low,
987 : (unsigned int)xconn->smb2.credits.seq_range);
988 : }
989 :
990 156976 : static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
991 : struct smbd_smb2_request *outreq)
992 : {
993 : int count, idx;
994 156976 : uint16_t total_credits = 0;
995 :
996 156976 : count = outreq->out.vector_count;
997 :
998 313952 : for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
999 156976 : struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
1000 156976 : struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
1001 156976 : uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
1002 :
1003 156976 : smb2_set_operation_credit(outreq->xconn, inhdr_v, outhdr_v);
1004 :
1005 : /* To match Windows, count up what we
1006 : just granted. */
1007 156976 : total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
1008 : /* Set to zero in all but the last reply. */
1009 156976 : if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
1010 0 : SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
1011 : } else {
1012 156976 : SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
1013 : }
1014 : }
1015 156976 : }
1016 :
1017 151594 : DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size)
1018 : {
1019 151594 : if (req->current_idx <= 1) {
1020 151594 : if (size <= sizeof(req->out._body)) {
1021 151594 : return data_blob_const(req->out._body, size);
1022 : }
1023 : }
1024 :
1025 0 : return data_blob_talloc(req, NULL, size);
1026 : }
1027 :
1028 157044 : static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
1029 : {
1030 157044 : struct smbXsrv_connection *xconn = req->xconn;
1031 : TALLOC_CTX *mem_ctx;
1032 : struct iovec *vector;
1033 : int count;
1034 : int idx;
1035 : bool ok;
1036 :
1037 157044 : count = req->in.vector_count;
1038 157044 : if (count <= ARRAY_SIZE(req->out._vector)) {
1039 157044 : mem_ctx = req;
1040 157044 : vector = req->out._vector;
1041 : } else {
1042 0 : vector = talloc_zero_array(req, struct iovec, count);
1043 0 : if (vector == NULL) {
1044 0 : return NT_STATUS_NO_MEMORY;
1045 : }
1046 0 : mem_ctx = vector;
1047 : }
1048 :
1049 157044 : vector[0].iov_base = req->out.nbt_hdr;
1050 157044 : vector[0].iov_len = 4;
1051 157044 : SIVAL(req->out.nbt_hdr, 0, 0);
1052 :
1053 314088 : for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
1054 157044 : struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
1055 157044 : const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
1056 157044 : uint8_t *outhdr = NULL;
1057 157044 : uint8_t *outbody = NULL;
1058 157044 : uint32_t next_command_ofs = 0;
1059 157044 : struct iovec *current = &vector[idx];
1060 :
1061 157044 : if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
1062 : /* we have a next command -
1063 : * setup for the error case. */
1064 0 : next_command_ofs = SMB2_HDR_BODY + 9;
1065 : }
1066 :
1067 157044 : if (idx == 1) {
1068 157044 : outhdr = req->out._hdr;
1069 : } else {
1070 0 : outhdr = talloc_zero_array(mem_ctx, uint8_t,
1071 : OUTVEC_ALLOC_SIZE);
1072 0 : if (outhdr == NULL) {
1073 0 : return NT_STATUS_NO_MEMORY;
1074 : }
1075 : }
1076 :
1077 157044 : outbody = outhdr + SMB2_HDR_BODY;
1078 :
1079 : /*
1080 : * SMBD_SMB2_TF_IOV_OFS might be used later
1081 : */
1082 157044 : current[SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
1083 157044 : current[SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
1084 :
1085 157044 : current[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)outhdr;
1086 157044 : current[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1087 :
1088 157044 : current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
1089 157044 : current[SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
1090 :
1091 157044 : current[SMBD_SMB2_DYN_IOV_OFS].iov_base = NULL;
1092 157044 : current[SMBD_SMB2_DYN_IOV_OFS].iov_len = 0;
1093 :
1094 : /* setup the SMB2 header */
1095 157044 : SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
1096 157044 : SSVAL(outhdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
1097 157044 : SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1098 : SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1099 157044 : SIVAL(outhdr, SMB2_HDR_STATUS,
1100 : NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1101 157044 : SSVAL(outhdr, SMB2_HDR_OPCODE,
1102 : SVAL(inhdr, SMB2_HDR_OPCODE));
1103 157044 : SIVAL(outhdr, SMB2_HDR_FLAGS,
1104 : IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1105 157044 : SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1106 157044 : SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1107 : BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1108 157044 : SIVAL(outhdr, SMB2_HDR_PID,
1109 : IVAL(inhdr, SMB2_HDR_PID));
1110 157044 : SIVAL(outhdr, SMB2_HDR_TID,
1111 : IVAL(inhdr, SMB2_HDR_TID));
1112 157044 : SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1113 : BVAL(inhdr, SMB2_HDR_SESSION_ID));
1114 157044 : memcpy(outhdr + SMB2_HDR_SIGNATURE,
1115 157044 : inhdr + SMB2_HDR_SIGNATURE, 16);
1116 :
1117 : /* setup error body header */
1118 157044 : SSVAL(outbody, 0x00, 0x08 + 1);
1119 157044 : SSVAL(outbody, 0x02, 0);
1120 157044 : SIVAL(outbody, 0x04, 0);
1121 : }
1122 :
1123 157044 : req->out.vector = vector;
1124 157044 : req->out.vector_count = count;
1125 :
1126 : /* setup the length of the NBT packet */
1127 157044 : ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1128 157044 : if (!ok) {
1129 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1130 : }
1131 :
1132 157044 : DLIST_ADD_END(xconn->smb2.requests, req);
1133 :
1134 157044 : return NT_STATUS_OK;
1135 : }
1136 :
1137 5270 : bool smbXsrv_server_multi_channel_enabled(void)
1138 : {
1139 5270 : bool enabled = lp_server_multi_channel_support();
1140 : #ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1141 : bool forced = false;
1142 : struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
1143 : bool unspecified = lpcfg_parm_is_unspecified(lp_ctx, "server multi channel support");
1144 : if (unspecified) {
1145 : enabled = false;
1146 : }
1147 : /*
1148 : * If we don't have support from the kernel
1149 : * to ask for the un-acked number of bytes
1150 : * in the socket send queue, we better
1151 : * don't support multi-channel.
1152 : */
1153 : forced = lp_parm_bool(-1, "force", "server multi channel support", false);
1154 : if (enabled && !forced) {
1155 : D_NOTICE("'server multi channel support' enabled "
1156 : "but not supported on %s (%s)\n",
1157 : SYSTEM_UNAME_SYSNAME, SYSTEM_UNAME_RELEASE);
1158 : DEBUGADD(DBGLVL_NOTICE, ("Please report this on "
1159 : "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1160 : enabled = false;
1161 : }
1162 : TALLOC_FREE(lp_ctx);
1163 : #endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1164 5270 : return enabled;
1165 : }
1166 :
1167 0 : static NTSTATUS smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection *xconn,
1168 : uint32_t *_rto_usecs)
1169 : {
1170 : /*
1171 : * Define an Retransmission Timeout
1172 : * of 1 second, if there's no way for the
1173 : * kernel to tell us the current value.
1174 : */
1175 0 : uint32_t rto_usecs = 1000000;
1176 :
1177 : #ifdef __HAVE_TCP_INFO_RTO
1178 : {
1179 : struct tcp_info info;
1180 0 : socklen_t ilen = sizeof(info);
1181 : int ret;
1182 :
1183 0 : ZERO_STRUCT(info);
1184 0 : ret = getsockopt(xconn->transport.sock,
1185 : IPPROTO_TCP, TCP_INFO,
1186 : (void *)&info, &ilen);
1187 0 : if (ret != 0) {
1188 0 : int saved_errno = errno;
1189 0 : NTSTATUS status = map_nt_error_from_unix(errno);
1190 0 : DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1191 : saved_errno, strerror(saved_errno),
1192 : nt_errstr(status));
1193 0 : return status;
1194 : }
1195 :
1196 0 : DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1197 : (unsigned)info.tcpi_rto,
1198 : (unsigned)info.tcpi_rtt,
1199 : (unsigned)info.tcpi_rttvar);
1200 0 : rto_usecs = info.tcpi_rto;
1201 : }
1202 : #endif /* __HAVE_TCP_INFO_RTO */
1203 :
1204 0 : rto_usecs = MAX(rto_usecs, 200000); /* at least 0.2s */
1205 0 : rto_usecs = MIN(rto_usecs, 1000000); /* at max 1.0s */
1206 0 : *_rto_usecs = rto_usecs;
1207 0 : return NT_STATUS_OK;
1208 : }
1209 :
1210 0 : static NTSTATUS smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection *xconn,
1211 : uint64_t *_acked_bytes)
1212 : {
1213 : /*
1214 : * Unless the kernel has an interface
1215 : * to reveal the number of un-acked bytes
1216 : * in the socket send queue, we'll assume
1217 : * everything is already acked.
1218 : *
1219 : * But that would mean that we better don't
1220 : * pretent to support multi-channel.
1221 : */
1222 0 : uint64_t unacked_bytes = 0;
1223 :
1224 0 : *_acked_bytes = 0;
1225 :
1226 0 : if (xconn->ack.force_unacked_timeout) {
1227 : /*
1228 : * Smbtorture tries to test channel failures...
1229 : * Just pretend nothing was acked...
1230 : */
1231 0 : DBG_INFO("Simulating channel failure: "
1232 : "xconn->ack.unacked_bytes[%llu]\n",
1233 : (unsigned long long)xconn->ack.unacked_bytes);
1234 0 : return NT_STATUS_OK;
1235 : }
1236 :
1237 : #ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1238 : {
1239 0 : int value = 0;
1240 : int ret;
1241 :
1242 : /*
1243 : * If we have kernel support to get
1244 : * the number of bytes waiting in
1245 : * the socket's send queue, we
1246 : * use that in order to find out
1247 : * the number of unacked bytes.
1248 : */
1249 0 : ret = ioctl(xconn->transport.sock,
1250 : __IOCTL_SEND_QUEUE_SIZE_OPCODE,
1251 : &value);
1252 0 : if (ret != 0) {
1253 0 : int saved_errno = errno;
1254 0 : NTSTATUS status = map_nt_error_from_unix(saved_errno);
1255 0 : DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1256 : "errno %d (%s) - %s\n",
1257 : saved_errno, strerror(saved_errno),
1258 : nt_errstr(status));
1259 0 : return status;
1260 : }
1261 :
1262 0 : if (value < 0) {
1263 0 : DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1264 : (unsigned long long)xconn->ack.unacked_bytes,
1265 : value);
1266 0 : return NT_STATUS_INTERNAL_ERROR;
1267 : }
1268 0 : unacked_bytes = value;
1269 : }
1270 : #endif
1271 0 : if (xconn->ack.unacked_bytes == 0) {
1272 0 : xconn->ack.unacked_bytes = unacked_bytes;
1273 0 : return NT_STATUS_OK;
1274 : }
1275 :
1276 0 : if (xconn->ack.unacked_bytes < unacked_bytes) {
1277 0 : DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1278 : (unsigned long long)xconn->ack.unacked_bytes,
1279 : (unsigned long long)unacked_bytes);
1280 0 : return NT_STATUS_INTERNAL_ERROR;
1281 : }
1282 :
1283 0 : *_acked_bytes = xconn->ack.unacked_bytes - unacked_bytes;
1284 0 : xconn->ack.unacked_bytes = unacked_bytes;
1285 0 : return NT_STATUS_OK;
1286 : }
1287 :
1288 10640 : static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue **queue,
1289 : NTSTATUS status)
1290 : {
1291 10640 : struct smbd_smb2_send_queue *e = NULL;
1292 10640 : struct smbd_smb2_send_queue *n = NULL;
1293 :
1294 13132 : for (e = *queue; e != NULL; e = n) {
1295 2492 : n = e->next;
1296 :
1297 2492 : DLIST_REMOVE(*queue, e);
1298 2492 : if (e->ack.req != NULL) {
1299 0 : tevent_req_nterror(e->ack.req, status);
1300 : }
1301 : }
1302 10640 : }
1303 :
1304 0 : static NTSTATUS smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue **queue,
1305 : uint64_t acked_bytes)
1306 : {
1307 0 : struct smbd_smb2_send_queue *e = NULL;
1308 0 : struct smbd_smb2_send_queue *n = NULL;
1309 :
1310 0 : for (e = *queue; e != NULL; e = n) {
1311 : bool expired;
1312 :
1313 0 : n = e->next;
1314 :
1315 0 : if (e->ack.req == NULL) {
1316 0 : continue;
1317 : }
1318 :
1319 0 : if (e->ack.required_acked_bytes <= acked_bytes) {
1320 0 : e->ack.required_acked_bytes = 0;
1321 0 : DLIST_REMOVE(*queue, e);
1322 0 : tevent_req_done(e->ack.req);
1323 0 : continue;
1324 : }
1325 0 : e->ack.required_acked_bytes -= acked_bytes;
1326 :
1327 0 : expired = timeval_expired(&e->ack.timeout);
1328 0 : if (expired) {
1329 0 : return NT_STATUS_IO_TIMEOUT;
1330 : }
1331 : }
1332 :
1333 0 : return NT_STATUS_OK;
1334 : }
1335 :
1336 0 : static NTSTATUS smbd_smb2_check_ack_queue(struct smbXsrv_connection *xconn)
1337 : {
1338 0 : uint64_t acked_bytes = 0;
1339 : NTSTATUS status;
1340 :
1341 0 : status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1342 0 : if (!NT_STATUS_IS_OK(status)) {
1343 0 : return status;
1344 : }
1345 :
1346 0 : status = smbd_smb2_send_queue_ack_bytes(&xconn->ack.queue, acked_bytes);
1347 0 : if (!NT_STATUS_IS_OK(status)) {
1348 0 : return status;
1349 : }
1350 :
1351 0 : status = smbd_smb2_send_queue_ack_bytes(&xconn->smb2.send_queue, 0);
1352 0 : if (!NT_STATUS_IS_OK(status)) {
1353 0 : return status;
1354 : }
1355 :
1356 0 : return NT_STATUS_OK;
1357 : }
1358 :
1359 0 : static void smbXsrv_connection_ack_checker(struct tevent_req *subreq)
1360 : {
1361 0 : struct smbXsrv_connection *xconn =
1362 0 : tevent_req_callback_data(subreq,
1363 : struct smbXsrv_connection);
1364 0 : struct smbXsrv_client *client = xconn->client;
1365 : struct timeval next_check;
1366 : NTSTATUS status;
1367 : bool ok;
1368 :
1369 0 : xconn->ack.checker_subreq = NULL;
1370 :
1371 0 : ok = tevent_wakeup_recv(subreq);
1372 0 : TALLOC_FREE(subreq);
1373 0 : if (!ok) {
1374 0 : smbd_server_connection_terminate(xconn,
1375 : "tevent_wakeup_recv() failed");
1376 0 : return;
1377 : }
1378 :
1379 0 : status = smbd_smb2_check_ack_queue(xconn);
1380 0 : if (!NT_STATUS_IS_OK(status)) {
1381 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
1382 0 : return;
1383 : }
1384 :
1385 0 : next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1386 0 : xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1387 : client->raw_ev_ctx,
1388 : next_check);
1389 0 : if (xconn->ack.checker_subreq == NULL) {
1390 0 : smbd_server_connection_terminate(xconn,
1391 : "tevent_wakeup_send() failed");
1392 0 : return;
1393 : }
1394 0 : tevent_req_set_callback(xconn->ack.checker_subreq,
1395 : smbXsrv_connection_ack_checker,
1396 : xconn);
1397 : }
1398 :
1399 5052 : static NTSTATUS smbXsrv_client_pending_breaks_updated(struct smbXsrv_client *client)
1400 : {
1401 5052 : struct smbXsrv_connection *xconn = NULL;
1402 :
1403 10156 : for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1404 : struct timeval next_check;
1405 5104 : uint64_t acked_bytes = 0;
1406 : NTSTATUS status;
1407 :
1408 : /*
1409 : * A new 'pending break cycle' starts
1410 : * with a first pending break and lasts until
1411 : * all pending breaks are finished.
1412 : *
1413 : * This is typically a very short time,
1414 : * the value of one retransmission timeout.
1415 : */
1416 :
1417 5104 : if (client->pending_breaks == NULL) {
1418 : /*
1419 : * No more pending breaks, remove a pending
1420 : * checker timer
1421 : */
1422 5104 : TALLOC_FREE(xconn->ack.checker_subreq);
1423 8633 : continue;
1424 : }
1425 :
1426 0 : if (xconn->ack.checker_subreq != NULL) {
1427 : /*
1428 : * The cycle already started =>
1429 : * nothing todo
1430 : */
1431 0 : continue;
1432 : }
1433 :
1434 : /*
1435 : * Get the current retransmission timeout value.
1436 : *
1437 : * It may change over time, but fetching it once
1438 : * per 'pending break' cycled should be enough.
1439 : */
1440 0 : status = smbXsrv_connection_get_rto_usecs(xconn,
1441 : &xconn->ack.rto_usecs);
1442 0 : if (!NT_STATUS_IS_OK(status)) {
1443 0 : return status;
1444 : }
1445 :
1446 : /*
1447 : * At the start of the cycle we reset the
1448 : * unacked_bytes counter (first to 0 and
1449 : * within smbXsrv_connection_get_acked_bytes()
1450 : * to the current value in the kernel
1451 : * send queue.
1452 : */
1453 0 : xconn->ack.unacked_bytes = 0;
1454 0 : status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1455 0 : if (!NT_STATUS_IS_OK(status)) {
1456 0 : return status;
1457 : }
1458 :
1459 : /*
1460 : * We setup a timer in order to check for
1461 : * acked bytes after one retransmission timeout.
1462 : *
1463 : * The code that sets up the send_queue.ack.timeout
1464 : * uses a multiple of the retransmission timeout.
1465 : */
1466 0 : next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1467 0 : xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1468 : client->raw_ev_ctx,
1469 : next_check);
1470 0 : if (xconn->ack.checker_subreq == NULL) {
1471 0 : return NT_STATUS_NO_MEMORY;
1472 : }
1473 0 : tevent_req_set_callback(xconn->ack.checker_subreq,
1474 : smbXsrv_connection_ack_checker,
1475 : xconn);
1476 : }
1477 :
1478 5052 : return NT_STATUS_OK;
1479 : }
1480 :
1481 15304 : void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
1482 : NTSTATUS status)
1483 : {
1484 15304 : if (!NT_STATUS_IS_OK(xconn->transport.status)) {
1485 9984 : return;
1486 : }
1487 :
1488 5320 : xconn->transport.status = status;
1489 5320 : TALLOC_FREE(xconn->transport.fde);
1490 5320 : if (xconn->transport.sock != -1) {
1491 5320 : xconn->transport.sock = -1;
1492 : }
1493 5320 : smbd_smb2_send_queue_ack_fail(&xconn->ack.queue, status);
1494 5320 : smbd_smb2_send_queue_ack_fail(&xconn->smb2.send_queue, status);
1495 5320 : xconn->smb2.send_queue_len = 0;
1496 5320 : DO_PROFILE_INC(disconnect);
1497 : }
1498 :
1499 5042 : size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
1500 : {
1501 5042 : struct smbXsrv_connection *xconn = NULL;
1502 5042 : size_t num_ok = 0;
1503 :
1504 10136 : for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1505 5094 : if (NT_STATUS_IS_OK(xconn->transport.status)) {
1506 52 : num_ok++;
1507 : }
1508 : }
1509 :
1510 5042 : return num_ok;
1511 : }
1512 :
1513 : struct smbXsrv_connection_shutdown_state {
1514 : struct smbXsrv_connection *xconn;
1515 : };
1516 :
1517 : static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
1518 :
1519 50 : static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
1520 : struct tevent_context *ev,
1521 : struct smbXsrv_connection *xconn)
1522 : {
1523 50 : struct tevent_req *req = NULL;
1524 50 : struct smbXsrv_connection_shutdown_state *state = NULL;
1525 50 : struct tevent_req *subreq = NULL;
1526 50 : size_t len = 0;
1527 50 : struct smbd_smb2_request *preq = NULL;
1528 : NTSTATUS status;
1529 :
1530 : /*
1531 : * The caller should have called
1532 : * smbXsrv_connection_disconnect_transport() before.
1533 : */
1534 50 : SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
1535 50 : SMB_ASSERT(xconn->transport.terminating);
1536 50 : SMB_ASSERT(xconn->transport.shutdown_wait_queue == NULL);
1537 :
1538 50 : req = tevent_req_create(mem_ctx, &state,
1539 : struct smbXsrv_connection_shutdown_state);
1540 50 : if (req == NULL) {
1541 0 : return NULL;
1542 : }
1543 :
1544 50 : state->xconn = xconn;
1545 50 : tevent_req_defer_callback(req, ev);
1546 :
1547 50 : xconn->transport.shutdown_wait_queue =
1548 50 : tevent_queue_create(state, "smbXsrv_connection_shutdown_queue");
1549 50 : if (tevent_req_nomem(xconn->transport.shutdown_wait_queue, req)) {
1550 0 : return tevent_req_post(req, ev);
1551 : }
1552 :
1553 50 : for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next) {
1554 : /*
1555 : * Now wait until the request is finished.
1556 : *
1557 : * We don't set a callback, as we just want to block the
1558 : * wait queue and the talloc_free() of the request will
1559 : * remove the item from the wait queue.
1560 : *
1561 : * Note that we don't cancel the requests here
1562 : * in order to keep the replay detection logic correct.
1563 : *
1564 : * However if we teardown the last channel of
1565 : * a connection, we'll call some logic via
1566 : * smbXsrv_session_disconnect_xconn()
1567 : * -> smbXsrv_session_disconnect_xconn_callback()
1568 : * -> smbXsrv_session_remove_channel()
1569 : * -> smb2srv_session_shutdown_send()
1570 : * will indeed cancel the request.
1571 : */
1572 0 : subreq = tevent_queue_wait_send(preq, ev,
1573 : xconn->transport.shutdown_wait_queue);
1574 0 : if (tevent_req_nomem(subreq, req)) {
1575 0 : return tevent_req_post(req, ev);
1576 : }
1577 : }
1578 :
1579 : /*
1580 : * This may attach sessions with num_channels == 0
1581 : * to xconn->transport.shutdown_wait_queue.
1582 : */
1583 50 : status = smbXsrv_session_disconnect_xconn(xconn);
1584 50 : if (tevent_req_nterror(req, status)) {
1585 0 : return tevent_req_post(req, ev);
1586 : }
1587 :
1588 50 : len = tevent_queue_length(xconn->transport.shutdown_wait_queue);
1589 50 : if (len == 0) {
1590 48 : tevent_req_done(req);
1591 48 : return tevent_req_post(req, ev);
1592 : }
1593 :
1594 : /*
1595 : * Now we add our own waiter to the end of the queue,
1596 : * this way we get notified when all pending requests are finished
1597 : * and send to the socket.
1598 : */
1599 2 : subreq = tevent_queue_wait_send(state, ev, xconn->transport.shutdown_wait_queue);
1600 2 : if (tevent_req_nomem(subreq, req)) {
1601 0 : return tevent_req_post(req, ev);
1602 : }
1603 2 : tevent_req_set_callback(subreq, smbXsrv_connection_shutdown_wait_done, req);
1604 :
1605 2 : return req;
1606 : }
1607 :
1608 2 : static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
1609 : {
1610 1 : struct tevent_req *req =
1611 2 : tevent_req_callback_data(subreq,
1612 : struct tevent_req);
1613 1 : struct smbXsrv_connection_shutdown_state *state =
1614 2 : tevent_req_data(req,
1615 : struct smbXsrv_connection_shutdown_state);
1616 2 : struct smbXsrv_connection *xconn = state->xconn;
1617 :
1618 2 : tevent_queue_wait_recv(subreq);
1619 2 : TALLOC_FREE(subreq);
1620 :
1621 2 : tevent_req_done(req);
1622 : /*
1623 : * make sure the xconn pointer is still valid,
1624 : * it should as we used tevent_req_defer_callback()
1625 : */
1626 2 : SMB_ASSERT(xconn->transport.terminating);
1627 2 : }
1628 :
1629 50 : static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
1630 : {
1631 25 : struct smbXsrv_connection_shutdown_state *state =
1632 50 : tevent_req_data(req,
1633 : struct smbXsrv_connection_shutdown_state);
1634 50 : struct smbXsrv_connection *xconn = state->xconn;
1635 : /*
1636 : * make sure the xconn pointer is still valid,
1637 : * it should as we used tevent_req_defer_callback()
1638 : */
1639 50 : SMB_ASSERT(xconn->transport.terminating);
1640 50 : return tevent_req_simple_recv_ntstatus(req);
1641 : }
1642 :
1643 50 : static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
1644 : {
1645 25 : struct smbXsrv_connection *xconn =
1646 50 : tevent_req_callback_data(subreq,
1647 : struct smbXsrv_connection);
1648 50 : struct smbXsrv_client *client = xconn->client;
1649 : NTSTATUS status;
1650 :
1651 50 : status = smbXsrv_connection_shutdown_recv(subreq);
1652 50 : TALLOC_FREE(subreq);
1653 50 : if (!NT_STATUS_IS_OK(status)) {
1654 0 : exit_server("smbXsrv_connection_shutdown_recv failed");
1655 : }
1656 :
1657 50 : DLIST_REMOVE(client->connections, xconn);
1658 50 : TALLOC_FREE(xconn);
1659 50 : }
1660 :
1661 5042 : void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
1662 : const char *reason,
1663 : const char *location)
1664 : {
1665 5042 : struct smbXsrv_client *client = xconn->client;
1666 5042 : size_t num_ok = 0;
1667 :
1668 : /*
1669 : * Make sure that no new request will be able to use this session.
1670 : *
1671 : * smbXsrv_connection_disconnect_transport() might be called already,
1672 : * but calling it again is a no-op.
1673 : */
1674 5042 : smbXsrv_connection_disconnect_transport(xconn,
1675 5042 : NT_STATUS_CONNECTION_DISCONNECTED);
1676 :
1677 5042 : num_ok = smbXsrv_client_valid_connections(client);
1678 :
1679 5042 : if (xconn->transport.terminating) {
1680 0 : DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1681 : smbXsrv_connection_dbg(xconn), num_ok,
1682 : reason, location);
1683 0 : return;
1684 : }
1685 5042 : xconn->transport.terminating = true;
1686 :
1687 5042 : DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1688 : smbXsrv_connection_dbg(xconn), num_ok,
1689 : reason, location);
1690 :
1691 5042 : if (xconn->has_cluster_movable_ip) {
1692 : /*
1693 : * If the connection has a movable cluster public address
1694 : * we disconnect all client connections,
1695 : * as the public address might be moved to
1696 : * a different node.
1697 : *
1698 : * In future we may recheck which node currently
1699 : * holds this address, but for now we keep it simple.
1700 : */
1701 0 : smbd_server_disconnect_client_ex(xconn->client,
1702 : reason,
1703 : location);
1704 0 : return;
1705 : }
1706 :
1707 5042 : if (num_ok != 0) {
1708 50 : struct tevent_req *subreq = NULL;
1709 :
1710 50 : subreq = smbXsrv_connection_shutdown_send(client,
1711 : client->raw_ev_ctx,
1712 : xconn);
1713 50 : if (subreq == NULL) {
1714 0 : exit_server("smbXsrv_connection_shutdown_send failed");
1715 : }
1716 50 : tevent_req_set_callback(subreq,
1717 : smbd_server_connection_terminate_done,
1718 : xconn);
1719 50 : return;
1720 : }
1721 :
1722 : /*
1723 : * The last connection was disconnected
1724 : */
1725 4992 : exit_server_cleanly(reason);
1726 : }
1727 :
1728 0 : void smbd_server_disconnect_client_ex(struct smbXsrv_client *client,
1729 : const char *reason,
1730 : const char *location)
1731 : {
1732 0 : size_t num_ok = 0;
1733 :
1734 0 : num_ok = smbXsrv_client_valid_connections(client);
1735 :
1736 0 : DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1737 : client->global->remote_address, num_ok,
1738 : reason, location);
1739 :
1740 : /*
1741 : * Something bad happened we need to disconnect all connections.
1742 : */
1743 0 : exit_server_cleanly(reason);
1744 : }
1745 :
1746 0 : static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1747 : struct iovec *outvec,
1748 : const struct iovec *srcvec)
1749 : {
1750 : const uint8_t *srctf;
1751 : size_t srctf_len;
1752 : const uint8_t *srchdr;
1753 : size_t srchdr_len;
1754 : const uint8_t *srcbody;
1755 : size_t srcbody_len;
1756 : const uint8_t *expected_srcbody;
1757 : const uint8_t *srcdyn;
1758 : size_t srcdyn_len;
1759 : const uint8_t *expected_srcdyn;
1760 : uint8_t *dsttf;
1761 : uint8_t *dsthdr;
1762 : uint8_t *dstbody;
1763 : uint8_t *dstdyn;
1764 :
1765 0 : srctf = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1766 0 : srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1767 0 : srchdr = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1768 0 : srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1769 0 : srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1770 0 : srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1771 0 : expected_srcbody = srchdr + SMB2_HDR_BODY;
1772 0 : srcdyn = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1773 0 : srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1774 0 : expected_srcdyn = srcbody + 8;
1775 :
1776 0 : if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1777 0 : return false;
1778 : }
1779 :
1780 0 : if (srchdr_len != SMB2_HDR_BODY) {
1781 0 : return false;
1782 : }
1783 :
1784 0 : if (srctf_len == SMB2_TF_HDR_SIZE) {
1785 0 : dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1786 0 : if (dsttf == NULL) {
1787 0 : return false;
1788 : }
1789 : } else {
1790 0 : dsttf = NULL;
1791 : }
1792 0 : outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1793 0 : outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1794 :
1795 : /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1796 : * be allocated with size OUTVEC_ALLOC_SIZE. */
1797 :
1798 0 : dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1799 0 : if (dsthdr == NULL) {
1800 0 : return false;
1801 : }
1802 0 : outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1803 0 : outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1804 :
1805 : /*
1806 : * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1807 : * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1808 : * then duplicate this. Else use talloc_memdup().
1809 : */
1810 :
1811 0 : if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1812 0 : dstbody = dsthdr + SMB2_HDR_BODY;
1813 : } else {
1814 0 : dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1815 0 : if (dstbody == NULL) {
1816 0 : return false;
1817 : }
1818 : }
1819 0 : outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1820 0 : outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1821 :
1822 : /*
1823 : * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1824 : * pointing to
1825 : * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1826 : * then duplicate this. Else use talloc_memdup().
1827 : */
1828 :
1829 0 : if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1830 0 : dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1831 0 : } else if (srcdyn == NULL) {
1832 0 : dstdyn = NULL;
1833 : } else {
1834 0 : dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1835 0 : if (dstdyn == NULL) {
1836 0 : return false;
1837 : }
1838 : }
1839 0 : outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1840 0 : outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1841 :
1842 0 : return true;
1843 : }
1844 :
1845 0 : static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1846 : {
1847 0 : struct smbd_smb2_request *newreq = NULL;
1848 0 : struct iovec *outvec = NULL;
1849 0 : int count = req->out.vector_count;
1850 : int i;
1851 : bool ok;
1852 :
1853 0 : newreq = smbd_smb2_request_allocate(req->xconn);
1854 0 : if (!newreq) {
1855 0 : return NULL;
1856 : }
1857 :
1858 0 : newreq->sconn = req->sconn;
1859 0 : newreq->xconn = req->xconn;
1860 0 : newreq->session = req->session;
1861 0 : newreq->do_encryption = req->do_encryption;
1862 0 : newreq->do_signing = req->do_signing;
1863 0 : newreq->current_idx = req->current_idx;
1864 :
1865 0 : outvec = talloc_zero_array(newreq, struct iovec, count);
1866 0 : if (!outvec) {
1867 0 : TALLOC_FREE(newreq);
1868 0 : return NULL;
1869 : }
1870 0 : newreq->out.vector = outvec;
1871 0 : newreq->out.vector_count = count;
1872 :
1873 : /* Setup the outvec's identically to req. */
1874 0 : outvec[0].iov_base = newreq->out.nbt_hdr;
1875 0 : outvec[0].iov_len = 4;
1876 0 : memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1877 :
1878 : /* Setup the vectors identically to the ones in req. */
1879 0 : for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1880 0 : if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1881 0 : break;
1882 : }
1883 : }
1884 :
1885 0 : if (i < count) {
1886 : /* Alloc failed. */
1887 0 : TALLOC_FREE(newreq);
1888 0 : return NULL;
1889 : }
1890 :
1891 0 : ok = smb2_setup_nbt_length(newreq->out.vector,
1892 : newreq->out.vector_count);
1893 0 : if (!ok) {
1894 0 : TALLOC_FREE(newreq);
1895 0 : return NULL;
1896 : }
1897 :
1898 0 : return newreq;
1899 : }
1900 :
1901 0 : static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
1902 : {
1903 0 : struct smbXsrv_connection *xconn = req->xconn;
1904 0 : int first_idx = 1;
1905 0 : struct iovec *firsttf = NULL;
1906 0 : struct iovec *outhdr_v = NULL;
1907 0 : uint8_t *outhdr = NULL;
1908 0 : struct smbd_smb2_request *nreq = NULL;
1909 : NTSTATUS status;
1910 : bool ok;
1911 :
1912 : /* Create a new smb2 request we'll use
1913 : for the interim return. */
1914 0 : nreq = dup_smb2_req(req);
1915 0 : if (!nreq) {
1916 0 : return NT_STATUS_NO_MEMORY;
1917 : }
1918 :
1919 : /* Lose the last X out vectors. They're the
1920 : ones we'll be using for the async reply. */
1921 0 : nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
1922 :
1923 0 : ok = smb2_setup_nbt_length(nreq->out.vector,
1924 : nreq->out.vector_count);
1925 0 : if (!ok) {
1926 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1927 : }
1928 :
1929 : /* Step back to the previous reply. */
1930 0 : nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
1931 0 : firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
1932 0 : outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
1933 0 : outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
1934 : /* And end the chain. */
1935 0 : SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
1936 :
1937 : /* Calculate outgoing credits */
1938 0 : smb2_calculate_credits(req, nreq);
1939 :
1940 0 : if (DEBUGLEVEL >= 10) {
1941 0 : dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
1942 0 : (unsigned int)nreq->current_idx );
1943 0 : dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
1944 0 : (unsigned int)nreq->out.vector_count );
1945 0 : print_req_vectors(nreq);
1946 : }
1947 :
1948 : /*
1949 : * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
1950 : * we need to sign/encrypt here with the last/first key we remembered
1951 : */
1952 0 : if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
1953 0 : status = smb2_signing_encrypt_pdu(req->first_enc_key,
1954 : firsttf,
1955 0 : nreq->out.vector_count - first_idx);
1956 0 : if (!NT_STATUS_IS_OK(status)) {
1957 0 : return status;
1958 : }
1959 0 : } else if (smb2_signing_key_valid(req->last_sign_key)) {
1960 0 : status = smb2_signing_sign_pdu(req->last_sign_key,
1961 : outhdr_v,
1962 : SMBD_SMB2_NUM_IOV_PER_REQ - 1);
1963 0 : if (!NT_STATUS_IS_OK(status)) {
1964 0 : return status;
1965 : }
1966 : }
1967 :
1968 0 : nreq->queue_entry.mem_ctx = nreq;
1969 0 : nreq->queue_entry.vector = nreq->out.vector;
1970 0 : nreq->queue_entry.count = nreq->out.vector_count;
1971 0 : DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
1972 0 : xconn->smb2.send_queue_len++;
1973 :
1974 0 : status = smbd_smb2_flush_send_queue(xconn);
1975 0 : if (!NT_STATUS_IS_OK(status)) {
1976 0 : return status;
1977 : }
1978 :
1979 0 : return NT_STATUS_OK;
1980 : }
1981 :
1982 : struct smbd_smb2_request_pending_state {
1983 : struct smbd_smb2_send_queue queue_entry;
1984 : uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
1985 : struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
1986 : };
1987 :
1988 : static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
1989 : struct tevent_timer *te,
1990 : struct timeval current_time,
1991 : void *private_data);
1992 :
1993 148445 : NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
1994 : struct tevent_req *subreq,
1995 : uint32_t defer_time)
1996 : {
1997 : NTSTATUS status;
1998 : struct timeval defer_endtime;
1999 148445 : uint8_t *outhdr = NULL;
2000 : uint32_t flags;
2001 :
2002 148445 : if (!tevent_req_is_in_progress(subreq)) {
2003 : /*
2004 : * This is a performance optimization,
2005 : * it avoids one tevent_loop iteration,
2006 : * which means we avoid one
2007 : * talloc_stackframe_pool/talloc_free pair.
2008 : */
2009 48960 : tevent_req_notify_callback(subreq);
2010 46468 : return NT_STATUS_OK;
2011 : }
2012 :
2013 99485 : req->subreq = subreq;
2014 99485 : subreq = NULL;
2015 :
2016 99485 : if (req->async_te) {
2017 : /* We're already async. */
2018 0 : return NT_STATUS_OK;
2019 : }
2020 :
2021 99485 : outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2022 99485 : flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2023 99485 : if (flags & SMB2_HDR_FLAG_ASYNC) {
2024 : /* We're already async. */
2025 0 : return NT_STATUS_OK;
2026 : }
2027 :
2028 99485 : if (req->async_internal || defer_time == 0) {
2029 : /*
2030 : * An SMB2 request implementation wants to handle the request
2031 : * asynchronously "internally" while keeping synchronous
2032 : * behaviour for the SMB2 request. This means we don't send an
2033 : * interim response and we can allow processing of compound SMB2
2034 : * requests (cf the subsequent check) for all cases.
2035 : */
2036 9172 : return NT_STATUS_OK;
2037 : }
2038 :
2039 90313 : if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
2040 : /*
2041 : * We're trying to go async in a compound request
2042 : * chain. This is only allowed for opens that cause an
2043 : * oplock break or for the last operation in the
2044 : * chain, otherwise it is not allowed. See
2045 : * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2046 : */
2047 0 : const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2048 :
2049 0 : if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
2050 : /*
2051 : * Cancel the outstanding request.
2052 : */
2053 0 : bool ok = tevent_req_cancel(req->subreq);
2054 0 : if (ok) {
2055 0 : return NT_STATUS_OK;
2056 : }
2057 0 : TALLOC_FREE(req->subreq);
2058 0 : return smbd_smb2_request_error(req,
2059 : NT_STATUS_INTERNAL_ERROR);
2060 : }
2061 : }
2062 :
2063 90313 : if (DEBUGLEVEL >= 10) {
2064 0 : dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2065 0 : (unsigned int)req->current_idx );
2066 0 : print_req_vectors(req);
2067 : }
2068 :
2069 90313 : if (req->current_idx > 1) {
2070 : /*
2071 : * We're going async in a compound
2072 : * chain after the first request has
2073 : * already been processed. Send an
2074 : * interim response containing the
2075 : * set of replies already generated.
2076 : */
2077 0 : int idx = req->current_idx;
2078 :
2079 0 : status = smb2_send_async_interim_response(req);
2080 0 : if (!NT_STATUS_IS_OK(status)) {
2081 0 : return status;
2082 : }
2083 0 : TALLOC_FREE(req->first_enc_key);
2084 :
2085 0 : req->current_idx = 1;
2086 :
2087 : /*
2088 : * Re-arrange the in.vectors to remove what
2089 : * we just sent.
2090 : */
2091 0 : memmove(&req->in.vector[1],
2092 0 : &req->in.vector[idx],
2093 0 : sizeof(req->in.vector[0])*(req->in.vector_count - idx));
2094 0 : req->in.vector_count = 1 + (req->in.vector_count - idx);
2095 :
2096 : /* Re-arrange the out.vectors to match. */
2097 0 : memmove(&req->out.vector[1],
2098 0 : &req->out.vector[idx],
2099 0 : sizeof(req->out.vector[0])*(req->out.vector_count - idx));
2100 0 : req->out.vector_count = 1 + (req->out.vector_count - idx);
2101 :
2102 0 : if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
2103 : /*
2104 : * We only have one remaining request as
2105 : * we've processed everything else.
2106 : * This is no longer a compound request.
2107 : */
2108 0 : req->compound_related = false;
2109 0 : outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2110 0 : flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
2111 0 : SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
2112 : }
2113 : }
2114 90313 : TALLOC_FREE(req->last_sign_key);
2115 :
2116 : /*
2117 : * smbd_smb2_request_pending_timer() just send a packet
2118 : * to the client and doesn't need any impersonation.
2119 : * So we use req->xconn->client->raw_ev_ctx instead
2120 : * of req->ev_ctx here.
2121 : */
2122 90313 : defer_endtime = timeval_current_ofs_usec(defer_time);
2123 90313 : req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
2124 : req, defer_endtime,
2125 : smbd_smb2_request_pending_timer,
2126 : req);
2127 90313 : if (req->async_te == NULL) {
2128 0 : return NT_STATUS_NO_MEMORY;
2129 : }
2130 :
2131 90313 : return NT_STATUS_OK;
2132 : }
2133 :
2134 : static
2135 254739 : struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
2136 : struct smbXsrv_connection *xconn,
2137 : bool *_has_channel)
2138 : {
2139 254739 : struct smbXsrv_channel_global0 *c = NULL;
2140 : NTSTATUS status;
2141 254739 : struct smb2_signing_key *key = NULL;
2142 254739 : bool has_channel = false;
2143 :
2144 254739 : status = smbXsrv_session_find_channel(session, xconn, &c);
2145 254739 : if (NT_STATUS_IS_OK(status)) {
2146 254223 : key = c->signing_key;
2147 254223 : has_channel = true;
2148 : }
2149 :
2150 254739 : if (!smb2_signing_key_valid(key)) {
2151 520 : key = session->global->signing_key;
2152 520 : has_channel = false;
2153 : }
2154 :
2155 254739 : if (_has_channel != NULL) {
2156 125173 : *_has_channel = has_channel;
2157 : }
2158 :
2159 254739 : return key;
2160 : }
2161 :
2162 635 : static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
2163 : uint64_t *new_nonce_high,
2164 : uint64_t *new_nonce_low)
2165 : {
2166 : uint64_t nonce_high;
2167 : uint64_t nonce_low;
2168 :
2169 635 : session->nonce_low += 1;
2170 635 : if (session->nonce_low == 0) {
2171 0 : session->nonce_low += 1;
2172 0 : session->nonce_high += 1;
2173 : }
2174 :
2175 : /*
2176 : * CCM and GCM algorithms must never have their
2177 : * nonce wrap, or the security of the whole
2178 : * communication and the keys is destroyed.
2179 : * We must drop the connection once we have
2180 : * transfered too much data.
2181 : *
2182 : * NOTE: We assume nonces greater than 8 bytes.
2183 : */
2184 635 : if (session->nonce_high >= session->nonce_high_max) {
2185 0 : return NT_STATUS_ENCRYPTION_FAILED;
2186 : }
2187 :
2188 635 : nonce_high = session->nonce_high_random;
2189 635 : nonce_high += session->nonce_high;
2190 635 : nonce_low = session->nonce_low;
2191 :
2192 635 : *new_nonce_high = nonce_high;
2193 635 : *new_nonce_low = nonce_low;
2194 635 : return NT_STATUS_OK;
2195 : }
2196 :
2197 21646 : static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
2198 : struct tevent_timer *te,
2199 : struct timeval current_time,
2200 : void *private_data)
2201 : {
2202 19645 : struct smbd_smb2_request *req =
2203 2001 : talloc_get_type_abort(private_data,
2204 : struct smbd_smb2_request);
2205 21646 : struct smbXsrv_connection *xconn = req->xconn;
2206 21646 : struct smbd_smb2_request_pending_state *state = NULL;
2207 21646 : uint8_t *outhdr = NULL;
2208 21646 : const uint8_t *inhdr = NULL;
2209 21646 : uint8_t *tf = NULL;
2210 21646 : uint8_t *hdr = NULL;
2211 21646 : uint8_t *body = NULL;
2212 21646 : uint8_t *dyn = NULL;
2213 21646 : uint32_t flags = 0;
2214 21646 : uint64_t message_id = 0;
2215 21646 : uint64_t async_id = 0;
2216 : NTSTATUS status;
2217 : bool ok;
2218 :
2219 21646 : TALLOC_FREE(req->async_te);
2220 :
2221 : /* Ensure our final reply matches the interim one. */
2222 21646 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2223 21646 : outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2224 21646 : flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2225 21646 : message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2226 :
2227 21646 : async_id = message_id; /* keep it simple for now... */
2228 :
2229 21646 : SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2230 21646 : SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
2231 :
2232 21646 : DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2233 : "going async\n",
2234 : smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2235 : (unsigned long long)async_id ));
2236 :
2237 : /*
2238 : * What we send is identical to a smbd_smb2_request_error
2239 : * packet with an error status of STATUS_PENDING. Make use
2240 : * of this fact sometime when refactoring. JRA.
2241 : */
2242 :
2243 21646 : state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
2244 21646 : if (state == NULL) {
2245 0 : smbd_server_connection_terminate(xconn,
2246 : nt_errstr(NT_STATUS_NO_MEMORY));
2247 0 : return;
2248 : }
2249 :
2250 21646 : tf = state->buf + NBT_HDR_SIZE;
2251 :
2252 21646 : hdr = tf + SMB2_TF_HDR_SIZE;
2253 21646 : body = hdr + SMB2_HDR_BODY;
2254 21646 : dyn = body + 8;
2255 :
2256 21646 : if (req->do_encryption) {
2257 21 : uint64_t nonce_high = 0;
2258 21 : uint64_t nonce_low = 0;
2259 21 : uint64_t session_id = req->session->global->session_wire_id;
2260 :
2261 21 : status = smb2_get_new_nonce(req->session,
2262 : &nonce_high,
2263 : &nonce_low);
2264 21 : if (!NT_STATUS_IS_OK(status)) {
2265 0 : smbd_server_connection_terminate(xconn,
2266 : nt_errstr(status));
2267 0 : return;
2268 : }
2269 :
2270 21 : SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2271 21 : SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2272 21 : SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2273 21 : SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2274 : }
2275 :
2276 21646 : SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
2277 21646 : SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
2278 21646 : SSVAL(hdr, SMB2_HDR_EPOCH, 0);
2279 21646 : SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_PENDING));
2280 21646 : SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
2281 :
2282 : /*
2283 : * The STATUS_PENDING response has SMB2_HDR_FLAG_SIGNED
2284 : * clearedm, but echoes the signature field.
2285 : */
2286 21646 : flags &= ~SMB2_HDR_FLAG_SIGNED;
2287 21646 : SIVAL(hdr, SMB2_HDR_FLAGS, flags);
2288 21646 : SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
2289 21646 : SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
2290 21646 : SBVAL(hdr, SMB2_HDR_PID, async_id);
2291 21646 : SBVAL(hdr, SMB2_HDR_SESSION_ID,
2292 : BVAL(outhdr, SMB2_HDR_SESSION_ID));
2293 21646 : memcpy(hdr+SMB2_HDR_SIGNATURE,
2294 21646 : outhdr+SMB2_HDR_SIGNATURE, 16);
2295 :
2296 21646 : SSVAL(body, 0x00, 0x08 + 1);
2297 :
2298 21646 : SCVAL(body, 0x02, 0);
2299 21646 : SCVAL(body, 0x03, 0);
2300 21646 : SIVAL(body, 0x04, 0);
2301 : /* Match W2K8R2... */
2302 21646 : SCVAL(dyn, 0x00, 0x21);
2303 :
2304 21646 : state->vector[0].iov_base = (void *)state->buf;
2305 21646 : state->vector[0].iov_len = NBT_HDR_SIZE;
2306 :
2307 21646 : if (req->do_encryption) {
2308 21 : state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = tf;
2309 21 : state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len =
2310 : SMB2_TF_HDR_SIZE;
2311 : } else {
2312 21625 : state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base = NULL;
2313 21625 : state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len = 0;
2314 : }
2315 :
2316 21646 : state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base = hdr;
2317 21646 : state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
2318 :
2319 21646 : state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
2320 21646 : state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len = 8;
2321 :
2322 21646 : state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base = dyn;
2323 21646 : state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len = 1;
2324 :
2325 21646 : ok = smb2_setup_nbt_length(state->vector,
2326 : 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2327 21646 : if (!ok) {
2328 0 : smbd_server_connection_terminate(
2329 : xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
2330 0 : return;
2331 : }
2332 :
2333 : /* Ensure we correctly go through crediting. Grant
2334 : the credits now, and zero credits on the final
2335 : response. */
2336 60936 : smb2_set_operation_credit(req->xconn,
2337 41291 : SMBD_SMB2_IN_HDR_IOV(req),
2338 : &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
2339 :
2340 : /*
2341 : * We add SMB2_HDR_FLAG_ASYNC after smb2_set_operation_credit()
2342 : * as it reacts on it
2343 : */
2344 21646 : SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2345 :
2346 21646 : if (DEBUGLVL(10)) {
2347 : int i;
2348 :
2349 0 : for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
2350 0 : dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2351 : (unsigned int)i,
2352 : (unsigned int)ARRAY_SIZE(state->vector),
2353 0 : (unsigned int)state->vector[i].iov_len);
2354 : }
2355 : }
2356 :
2357 21646 : if (req->do_encryption) {
2358 21 : struct smbXsrv_session *x = req->session;
2359 21 : struct smb2_signing_key *encryption_key = x->global->encryption_key;
2360 :
2361 21 : status = smb2_signing_encrypt_pdu(encryption_key,
2362 : &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2363 : SMBD_SMB2_NUM_IOV_PER_REQ);
2364 21 : if (!NT_STATUS_IS_OK(status)) {
2365 0 : smbd_server_connection_terminate(xconn,
2366 : nt_errstr(status));
2367 0 : return;
2368 : }
2369 : }
2370 :
2371 21646 : state->queue_entry.mem_ctx = state;
2372 21646 : state->queue_entry.vector = state->vector;
2373 21646 : state->queue_entry.count = ARRAY_SIZE(state->vector);
2374 21646 : DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
2375 21646 : xconn->smb2.send_queue_len++;
2376 :
2377 21646 : status = smbd_smb2_flush_send_queue(xconn);
2378 21646 : if (!NT_STATUS_IS_OK(status)) {
2379 0 : smbd_server_connection_terminate(xconn,
2380 : nt_errstr(status));
2381 0 : return;
2382 : }
2383 : }
2384 :
2385 18 : static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
2386 : {
2387 18 : struct smbXsrv_connection *xconn = req->xconn;
2388 : struct smbd_smb2_request *cur;
2389 : const uint8_t *inhdr;
2390 : uint32_t flags;
2391 : uint64_t search_message_id;
2392 : uint64_t search_async_id;
2393 : uint64_t found_id;
2394 :
2395 18 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2396 :
2397 18 : flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2398 18 : search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2399 18 : search_async_id = BVAL(inhdr, SMB2_HDR_PID);
2400 :
2401 : /*
2402 : * We don't need the request anymore cancel requests never
2403 : * have a response.
2404 : *
2405 : * We defer the TALLOC_FREE(req) to the caller.
2406 : */
2407 18 : DLIST_REMOVE(xconn->smb2.requests, req);
2408 :
2409 18 : for (cur = xconn->smb2.requests; cur; cur = cur->next) {
2410 : const uint8_t *outhdr;
2411 : uint64_t message_id;
2412 : uint64_t async_id;
2413 :
2414 18 : if (cur->session != req->session) {
2415 0 : continue;
2416 : }
2417 :
2418 18 : if (cur->compound_related) {
2419 : /*
2420 : * Never cancel anything in a compound request.
2421 : * Way too hard to deal with the result.
2422 : */
2423 0 : continue;
2424 : }
2425 :
2426 18 : outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
2427 :
2428 18 : message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2429 18 : async_id = BVAL(outhdr, SMB2_HDR_PID);
2430 :
2431 18 : if (flags & SMB2_HDR_FLAG_ASYNC) {
2432 18 : if (search_async_id == async_id) {
2433 18 : found_id = async_id;
2434 18 : break;
2435 : }
2436 : } else {
2437 0 : if (search_message_id == message_id) {
2438 0 : found_id = message_id;
2439 0 : break;
2440 : }
2441 : }
2442 : }
2443 :
2444 18 : if (cur && cur->subreq) {
2445 18 : inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
2446 18 : DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2447 : "cancel opcode[%s] mid %llu\n",
2448 : smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2449 : (unsigned long long)found_id ));
2450 18 : tevent_req_cancel(cur->subreq);
2451 : }
2452 :
2453 18 : return NT_STATUS_OK;
2454 : }
2455 :
2456 : /*************************************************************
2457 : Ensure an incoming tid is a valid one for us to access.
2458 : Change to the associated uid credentials and chdir to the
2459 : valid tid directory.
2460 : *************************************************************/
2461 :
2462 133802 : static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
2463 : {
2464 : const uint8_t *inhdr;
2465 : uint32_t in_flags;
2466 : uint32_t in_tid;
2467 : struct smbXsrv_tcon *tcon;
2468 : NTSTATUS status;
2469 133802 : NTTIME now = timeval_to_nttime(&req->request_time);
2470 :
2471 133802 : req->tcon = NULL;
2472 :
2473 133802 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2474 :
2475 133802 : in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2476 133802 : in_tid = IVAL(inhdr, SMB2_HDR_TID);
2477 :
2478 133802 : if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2479 0 : in_tid = req->last_tid;
2480 : }
2481 :
2482 133802 : req->last_tid = 0;
2483 :
2484 133802 : status = smb2srv_tcon_lookup(req->session,
2485 : in_tid, now, &tcon);
2486 133802 : if (!NT_STATUS_IS_OK(status)) {
2487 14 : return status;
2488 : }
2489 :
2490 238046 : if (!change_to_user_and_service(
2491 133788 : tcon->compat,
2492 133788 : req->session->global->session_wire_id))
2493 : {
2494 24 : return NT_STATUS_ACCESS_DENIED;
2495 : }
2496 :
2497 133764 : req->tcon = tcon;
2498 133764 : req->last_tid = in_tid;
2499 :
2500 133764 : return NT_STATUS_OK;
2501 : }
2502 :
2503 : /*************************************************************
2504 : Ensure an incoming session_id is a valid one for us to access.
2505 : *************************************************************/
2506 :
2507 157044 : static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
2508 : {
2509 : const uint8_t *inhdr;
2510 : uint32_t in_flags;
2511 : uint16_t in_opcode;
2512 : uint64_t in_session_id;
2513 157044 : struct smbXsrv_session *session = NULL;
2514 : struct auth_session_info *session_info;
2515 : NTSTATUS status;
2516 157044 : NTTIME now = timeval_to_nttime(&req->request_time);
2517 :
2518 157044 : req->session = NULL;
2519 157044 : req->tcon = NULL;
2520 :
2521 157044 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2522 :
2523 157044 : in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2524 157044 : in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2525 157044 : in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
2526 :
2527 157044 : if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2528 0 : in_session_id = req->last_session_id;
2529 : }
2530 :
2531 157044 : req->last_session_id = 0;
2532 :
2533 : /* look an existing session up */
2534 157044 : switch (in_opcode) {
2535 6774 : case SMB2_OP_SESSSETUP:
2536 : /*
2537 : * For a session bind request, we don't have the
2538 : * channel set up at this point yet, so we defer
2539 : * the verification that the connection belongs
2540 : * to the session to the session setup code, which
2541 : * can look at the session binding flags.
2542 : */
2543 6774 : status = smb2srv_session_lookup_client(req->xconn->client,
2544 : in_session_id, now,
2545 : &session);
2546 6774 : break;
2547 150270 : default:
2548 150270 : status = smb2srv_session_lookup_conn(req->xconn,
2549 : in_session_id, now,
2550 : &session);
2551 150270 : break;
2552 : }
2553 157044 : if (session) {
2554 143525 : req->session = session;
2555 143525 : req->last_session_id = in_session_id;
2556 : }
2557 157044 : if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
2558 13519 : switch (in_opcode) {
2559 5068 : case SMB2_OP_SESSSETUP:
2560 5068 : status = smb2srv_session_lookup_global(req->xconn->client,
2561 : in_session_id,
2562 : req,
2563 : &session);
2564 5068 : if (NT_STATUS_IS_OK(status)) {
2565 : /*
2566 : * We fallback to a session of
2567 : * another process in order to
2568 : * get the signing correct.
2569 : *
2570 : * We don't set req->last_session_id here.
2571 : */
2572 148 : req->session = session;
2573 : }
2574 5068 : break;
2575 8451 : default:
2576 8451 : break;
2577 : }
2578 110724 : }
2579 157044 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
2580 106 : switch (in_opcode) {
2581 12 : case SMB2_OP_SESSSETUP:
2582 12 : status = NT_STATUS_OK;
2583 12 : break;
2584 28 : case SMB2_OP_LOGOFF:
2585 : case SMB2_OP_CLOSE:
2586 : case SMB2_OP_LOCK:
2587 : case SMB2_OP_CANCEL:
2588 : case SMB2_OP_KEEPALIVE:
2589 : /*
2590 : * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2591 : * specifies that LOGOFF, CLOSE and (UN)LOCK
2592 : * should always be processed even on expired sessions.
2593 : *
2594 : * Also see the logic in
2595 : * smbd_smb2_request_process_lock().
2596 : *
2597 : * The smb2.session.expire2 test shows that
2598 : * CANCEL and KEEPALIVE/ECHO should also
2599 : * be processed.
2600 : */
2601 28 : status = NT_STATUS_OK;
2602 28 : break;
2603 66 : default:
2604 66 : break;
2605 : }
2606 120056 : }
2607 157044 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2608 1506 : switch (in_opcode) {
2609 0 : case SMB2_OP_TCON:
2610 : case SMB2_OP_CREATE:
2611 : case SMB2_OP_GETINFO:
2612 : case SMB2_OP_SETINFO:
2613 0 : return NT_STATUS_INVALID_HANDLE;
2614 1506 : default:
2615 : /*
2616 : * Notice the check for
2617 : * (session_info == NULL)
2618 : * below.
2619 : */
2620 1506 : status = NT_STATUS_OK;
2621 1506 : break;
2622 : }
2623 119074 : }
2624 157044 : if (!NT_STATUS_IS_OK(status)) {
2625 13437 : return status;
2626 : }
2627 :
2628 143607 : session_info = session->global->auth_session_info;
2629 143607 : if (session_info == NULL) {
2630 1496 : return NT_STATUS_INVALID_HANDLE;
2631 : }
2632 :
2633 142111 : return NT_STATUS_OK;
2634 : }
2635 :
2636 101278 : NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
2637 : uint32_t data_length)
2638 : {
2639 101278 : struct smbXsrv_connection *xconn = req->xconn;
2640 : uint16_t needed_charge;
2641 101278 : uint16_t credit_charge = 1;
2642 : const uint8_t *inhdr;
2643 :
2644 101278 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2645 :
2646 101278 : if (xconn->smb2.credits.multicredit) {
2647 100902 : credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
2648 100902 : credit_charge = MAX(credit_charge, 1);
2649 : }
2650 :
2651 101278 : needed_charge = (data_length - 1)/ 65536 + 1;
2652 :
2653 101278 : DBGC_DEBUG(DBGC_SMB2_CREDITS,
2654 : "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2655 : (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
2656 : credit_charge, needed_charge);
2657 :
2658 101278 : if (needed_charge > credit_charge) {
2659 0 : DBGC_WARNING(DBGC_SMB2_CREDITS,
2660 : "CreditCharge too low, given %d, needed %d\n",
2661 : credit_charge, needed_charge);
2662 0 : return NT_STATUS_INVALID_PARAMETER;
2663 : }
2664 :
2665 101278 : return NT_STATUS_OK;
2666 : }
2667 :
2668 156886 : NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
2669 : size_t expected_body_size)
2670 : {
2671 : struct iovec *inhdr_v;
2672 : const uint8_t *inhdr;
2673 : uint16_t opcode;
2674 : const uint8_t *inbody;
2675 : size_t body_size;
2676 156886 : size_t min_dyn_size = expected_body_size & 0x00000001;
2677 156886 : int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2678 :
2679 : /*
2680 : * The following should be checked already.
2681 : */
2682 156886 : if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2683 0 : return NT_STATUS_INTERNAL_ERROR;
2684 : }
2685 156886 : if (req->current_idx > max_idx) {
2686 0 : return NT_STATUS_INTERNAL_ERROR;
2687 : }
2688 :
2689 156886 : inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2690 156886 : if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2691 0 : return NT_STATUS_INTERNAL_ERROR;
2692 : }
2693 156886 : if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2694 0 : return NT_STATUS_INTERNAL_ERROR;
2695 : }
2696 :
2697 156886 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2698 156886 : opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2699 :
2700 156886 : switch (opcode) {
2701 89553 : case SMB2_OP_IOCTL:
2702 : case SMB2_OP_GETINFO:
2703 : case SMB2_OP_WRITE:
2704 89553 : min_dyn_size = 0;
2705 89553 : break;
2706 : }
2707 :
2708 : /*
2709 : * Now check the expected body size,
2710 : * where the last byte might be in the
2711 : * dynamic section..
2712 : */
2713 156886 : if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2714 0 : return NT_STATUS_INVALID_PARAMETER;
2715 : }
2716 156886 : if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2717 0 : return NT_STATUS_INVALID_PARAMETER;
2718 : }
2719 :
2720 156886 : inbody = SMBD_SMB2_IN_BODY_PTR(req);
2721 :
2722 156886 : body_size = SVAL(inbody, 0x00);
2723 156886 : if (body_size != expected_body_size) {
2724 0 : return NT_STATUS_INVALID_PARAMETER;
2725 : }
2726 :
2727 156886 : return NT_STATUS_OK;
2728 : }
2729 :
2730 0 : bool smbXsrv_is_encrypted(uint8_t encryption_flags)
2731 : {
2732 0 : return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
2733 0 : &&
2734 0 : (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
2735 : SMBXSRV_ENCRYPTION_DESIRED |
2736 : SMBXSRV_ENCRYPTION_REQUIRED)));
2737 : }
2738 :
2739 0 : bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
2740 : {
2741 0 : return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
2742 0 : (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
2743 : }
2744 :
2745 : /* Set a flag if not already set, return true if set */
2746 554510 : bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2747 : {
2748 554510 : if ((flag == 0) || (*flags & flag)) {
2749 532286 : return false;
2750 : }
2751 :
2752 22224 : *flags |= flag;
2753 22224 : return true;
2754 : }
2755 :
2756 : /*
2757 : * Update encryption state tracking flags, this can be used to
2758 : * determine whether whether the session or tcon is "encrypted".
2759 : */
2760 143557 : static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2761 : uint16_t opcode,
2762 : bool *update_session_globalp,
2763 : bool *update_tcon_globalp)
2764 : {
2765 : /* Default: assume unecrypted and unsigned */
2766 143557 : struct smbXsrv_session *session = req->session;
2767 143557 : struct smbXsrv_tcon *tcon = req->tcon;
2768 143557 : uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2769 143557 : uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2770 143557 : bool update_session = false;
2771 143557 : bool update_tcon = false;
2772 :
2773 143557 : if (session->table == NULL) {
2774 : /*
2775 : * sessions from smb2srv_session_lookup_global()
2776 : * have NT_STATUS_BAD_LOGON_SESSION_STATE
2777 : * and session->table == NULL.
2778 : *
2779 : * They only used to give the correct error
2780 : * status, we should not update any state.
2781 : */
2782 182 : goto out;
2783 : }
2784 :
2785 143375 : if (req->was_encrypted && req->do_encryption) {
2786 594 : encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2787 594 : sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2788 : } else {
2789 : /* Unencrypted packet, can be signed */
2790 142781 : if (req->do_signing) {
2791 124965 : sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2792 : }
2793 : }
2794 :
2795 286750 : update_session |= smbXsrv_set_crypto_flag(
2796 143375 : &session->global->encryption_flags, encrypt_flag);
2797 286750 : update_session |= smbXsrv_set_crypto_flag(
2798 143375 : &session->global->signing_flags, sign_flag);
2799 :
2800 143375 : if (tcon) {
2801 267528 : update_tcon |= smbXsrv_set_crypto_flag(
2802 133764 : &tcon->global->encryption_flags, encrypt_flag);
2803 238010 : update_tcon |= smbXsrv_set_crypto_flag(
2804 133764 : &tcon->global->signing_flags, sign_flag);
2805 : }
2806 :
2807 120351 : out:
2808 143557 : *update_session_globalp = update_session;
2809 143557 : *update_tcon_globalp = update_tcon;
2810 143557 : return;
2811 : }
2812 :
2813 0 : bool smbXsrv_is_signed(uint8_t signing_flags)
2814 : {
2815 : /*
2816 : * Signing is always enabled, so unless we got an unsigned
2817 : * packet and at least one signed packet that was not
2818 : * encrypted, the session or tcon is "signed".
2819 : */
2820 0 : return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2821 0 : (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2822 : }
2823 :
2824 0 : bool smbXsrv_is_partially_signed(uint8_t signing_flags)
2825 : {
2826 0 : return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
2827 0 : (signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
2828 : }
2829 :
2830 156904 : static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2831 : struct smbd_smb2_request *req,
2832 : bool modify_call)
2833 : {
2834 156904 : struct smbXsrv_connection *xconn = req->xconn;
2835 : const uint8_t *inhdr;
2836 : uint16_t channel_sequence;
2837 156904 : uint8_t generation_wrap = 0;
2838 : uint32_t flags;
2839 : int cmp;
2840 : struct smbXsrv_open *op;
2841 156904 : bool update_open = false;
2842 156904 : NTSTATUS status = NT_STATUS_OK;
2843 :
2844 156904 : SMB_ASSERT(!req->request_counters_updated);
2845 :
2846 156904 : if (xconn->protocol < PROTOCOL_SMB3_00) {
2847 78454 : return NT_STATUS_OK;
2848 : }
2849 :
2850 78450 : if (req->compat_chain_fsp == NULL) {
2851 19857 : return NT_STATUS_OK;
2852 : }
2853 :
2854 58593 : op = req->compat_chain_fsp->op;
2855 58593 : if (op == NULL) {
2856 0 : return NT_STATUS_OK;
2857 : }
2858 :
2859 58593 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2860 58593 : flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2861 58593 : channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2862 :
2863 58593 : cmp = channel_sequence - op->global->channel_sequence;
2864 58593 : if (cmp < 0) {
2865 : /*
2866 : * csn wrap. We need to watch out for long-running
2867 : * requests that are still sitting on a previously
2868 : * used csn. SMB2_OP_NOTIFY can take VERY long.
2869 : */
2870 0 : generation_wrap += 1;
2871 : }
2872 :
2873 58593 : if (abs(cmp) > INT16_MAX) {
2874 : /*
2875 : * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2876 : *
2877 : * If the channel sequence number of the request and the one
2878 : * known to the server are not equal, the channel sequence
2879 : * number and outstanding request counts are only updated
2880 : * "... if the unsigned difference using 16-bit arithmetic
2881 : * between ChannelSequence and Open.ChannelSequence is less than
2882 : * or equal to 0x7FFF ...".
2883 : * Otherwise, an error is returned for the modifying
2884 : * calls write, set_info, and ioctl.
2885 : *
2886 : * There are currently two issues with the description:
2887 : *
2888 : * * For the other calls, the document seems to imply
2889 : * that processing continues without adapting the
2890 : * counters (if the sequence numbers are not equal).
2891 : *
2892 : * TODO: This needs clarification!
2893 : *
2894 : * * Also, the behaviour if the difference is larger
2895 : * than 0x7FFF is not clear. The document seems to
2896 : * imply that if such a difference is reached,
2897 : * the server starts to ignore the counters or
2898 : * in the case of the modifying calls, return errors.
2899 : *
2900 : * TODO: This needs clarification!
2901 : *
2902 : * At this point Samba tries to be a little more
2903 : * clever than the description in the MS-SMB2 document
2904 : * by heuristically detecting and properly treating
2905 : * a 16 bit overflow of the client-submitted sequence
2906 : * number:
2907 : *
2908 : * If the stored channel sequence number is more than
2909 : * 0x7FFF larger than the one from the request, then
2910 : * the client-provided sequence number has likely
2911 : * overflown. We treat this case as valid instead
2912 : * of as failure.
2913 : *
2914 : * The MS-SMB2 behaviour would be setting cmp = -1.
2915 : */
2916 0 : cmp *= -1;
2917 : }
2918 :
2919 58593 : if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2920 0 : if (cmp == 0 && op->pre_request_count == 0) {
2921 0 : op->request_count += 1;
2922 0 : req->request_counters_updated = true;
2923 0 : } else if (cmp > 0 && op->pre_request_count == 0) {
2924 0 : op->pre_request_count += op->request_count;
2925 0 : op->request_count = 1;
2926 0 : op->global->channel_sequence = channel_sequence;
2927 0 : op->global->channel_generation += generation_wrap;
2928 0 : update_open = true;
2929 0 : req->request_counters_updated = true;
2930 0 : } else if (modify_call) {
2931 0 : return NT_STATUS_FILE_NOT_AVAILABLE;
2932 : }
2933 : } else {
2934 58593 : if (cmp == 0) {
2935 58593 : op->request_count += 1;
2936 58593 : req->request_counters_updated = true;
2937 0 : } else if (cmp > 0) {
2938 0 : op->pre_request_count += op->request_count;
2939 0 : op->request_count = 1;
2940 0 : op->global->channel_sequence = channel_sequence;
2941 0 : op->global->channel_generation += generation_wrap;
2942 0 : update_open = true;
2943 0 : req->request_counters_updated = true;
2944 0 : } else if (modify_call) {
2945 0 : return NT_STATUS_FILE_NOT_AVAILABLE;
2946 : }
2947 : }
2948 58593 : req->channel_generation = op->global->channel_generation;
2949 :
2950 58593 : if (update_open) {
2951 0 : status = smbXsrv_open_update(op);
2952 : }
2953 :
2954 58593 : return status;
2955 : }
2956 :
2957 157044 : NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
2958 : {
2959 157044 : struct smbXsrv_connection *xconn = req->xconn;
2960 157044 : const struct smbd_smb2_dispatch_table *call = NULL;
2961 157044 : const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
2962 : const uint8_t *inhdr;
2963 : uint16_t opcode;
2964 : uint32_t flags;
2965 : uint64_t mid;
2966 : NTSTATUS status;
2967 : NTSTATUS session_status;
2968 : uint32_t allowed_flags;
2969 : NTSTATUS return_value;
2970 157044 : struct smbXsrv_session *x = NULL;
2971 157044 : bool signing_required = false;
2972 157044 : bool encryption_desired = false;
2973 157044 : bool encryption_required = false;
2974 :
2975 157044 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2976 :
2977 157044 : DO_PROFILE_INC(request);
2978 :
2979 157044 : SMB_ASSERT(!req->request_counters_updated);
2980 :
2981 : /* TODO: verify more things */
2982 :
2983 157044 : flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2984 157044 : opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2985 157044 : mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2986 157044 : DBG_DEBUG("opcode[%s] mid = %"PRIu64"\n",
2987 : smb2_opcode_name(opcode),
2988 : mid);
2989 :
2990 157044 : if (xconn->protocol >= PROTOCOL_SMB2_02) {
2991 : /*
2992 : * once the protocol is negotiated
2993 : * SMB2_OP_NEGPROT is not allowed anymore
2994 : */
2995 148671 : if (opcode == SMB2_OP_NEGPROT) {
2996 : /* drop the connection */
2997 0 : return NT_STATUS_INVALID_PARAMETER;
2998 : }
2999 : } else {
3000 : /*
3001 : * if the protocol is not negotiated yet
3002 : * only SMB2_OP_NEGPROT is allowed.
3003 : */
3004 8373 : if (opcode != SMB2_OP_NEGPROT) {
3005 : /* drop the connection */
3006 0 : return NT_STATUS_INVALID_PARAMETER;
3007 : }
3008 : }
3009 :
3010 : /*
3011 : * Check if the client provided a valid session id.
3012 : *
3013 : * As some command don't require a valid session id
3014 : * we defer the check of the session_status
3015 : */
3016 157044 : session_status = smbd_smb2_request_check_session(req);
3017 157044 : x = req->session;
3018 157044 : if (x != NULL) {
3019 143673 : signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
3020 143673 : encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3021 143673 : encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
3022 : }
3023 :
3024 157044 : req->async_internal = false;
3025 157044 : req->do_signing = false;
3026 157044 : if (opcode != SMB2_OP_SESSSETUP) {
3027 150270 : req->do_encryption = encryption_desired;
3028 : } else {
3029 6774 : req->do_encryption = false;
3030 : }
3031 157044 : req->was_encrypted = false;
3032 157044 : if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
3033 624 : const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
3034 624 : uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
3035 :
3036 624 : if (x != NULL && x->global->session_wire_id != tf_session_id) {
3037 0 : DEBUG(0,("smbd_smb2_request_dispatch: invalid session_id"
3038 : "in SMB2_HDR[%llu], SMB2_TF[%llu]\n",
3039 : (unsigned long long)x->global->session_wire_id,
3040 : (unsigned long long)tf_session_id));
3041 : /*
3042 : * TODO: windows allows this...
3043 : * should we drop the connection?
3044 : *
3045 : * For now we just return ACCESS_DENIED
3046 : * (Windows clients never trigger this)
3047 : * and wait for an update of [MS-SMB2].
3048 : */
3049 0 : return smbd_smb2_request_error(req,
3050 : NT_STATUS_ACCESS_DENIED);
3051 : }
3052 :
3053 624 : req->was_encrypted = true;
3054 624 : req->do_encryption = true;
3055 : }
3056 :
3057 157044 : if (encryption_required && !req->was_encrypted) {
3058 0 : req->do_encryption = true;
3059 0 : return smbd_smb2_request_error(req,
3060 : NT_STATUS_ACCESS_DENIED);
3061 : }
3062 :
3063 157044 : call = smbd_smb2_call(opcode);
3064 157044 : if (call == NULL) {
3065 0 : return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3066 : }
3067 :
3068 157044 : allowed_flags = SMB2_HDR_FLAG_CHAINED |
3069 : SMB2_HDR_FLAG_SIGNED |
3070 : SMB2_HDR_FLAG_DFS;
3071 157044 : if (xconn->protocol >= PROTOCOL_SMB3_11) {
3072 78502 : allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3073 : }
3074 157044 : if (opcode == SMB2_OP_NEGPROT) {
3075 8373 : if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
3076 4846 : allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3077 : }
3078 : }
3079 157044 : if (opcode == SMB2_OP_CANCEL) {
3080 18 : allowed_flags |= SMB2_HDR_FLAG_ASYNC;
3081 : }
3082 157044 : if (xconn->protocol >= PROTOCOL_SMB3_00) {
3083 78590 : allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3084 : }
3085 157044 : if ((flags & ~allowed_flags) != 0) {
3086 0 : return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3087 : }
3088 :
3089 157044 : if (flags & SMB2_HDR_FLAG_CHAINED) {
3090 : /*
3091 : * This check is mostly for giving the correct error code
3092 : * for compounded requests.
3093 : */
3094 0 : if (!NT_STATUS_IS_OK(session_status)) {
3095 0 : return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3096 : }
3097 : } else {
3098 157044 : req->compat_chain_fsp = NULL;
3099 : }
3100 :
3101 157044 : if (req->was_encrypted) {
3102 624 : signing_required = false;
3103 156420 : } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
3104 125195 : struct smb2_signing_key *signing_key = NULL;
3105 125195 : bool has_channel = false;
3106 :
3107 125195 : if (x == NULL) {
3108 : /*
3109 : * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3110 : * If the SMB2 header of the SMB2 NEGOTIATE
3111 : * request has the SMB2_FLAGS_SIGNED bit set in the
3112 : * Flags field, the server MUST fail the request
3113 : * with STATUS_INVALID_PARAMETER.
3114 : *
3115 : * Microsoft test tool checks this.
3116 : */
3117 :
3118 22 : if ((opcode == SMB2_OP_NEGPROT) &&
3119 0 : (flags & SMB2_HDR_FLAG_SIGNED)) {
3120 0 : status = NT_STATUS_INVALID_PARAMETER;
3121 : } else {
3122 22 : status = NT_STATUS_USER_SESSION_DELETED;
3123 : }
3124 81 : return smbd_smb2_request_error(req, status);
3125 : }
3126 :
3127 125173 : signing_key = smbd_smb2_signing_key(x, xconn, &has_channel);
3128 :
3129 : /*
3130 : * If we have a signing key, we should
3131 : * sign the response
3132 : */
3133 125173 : if (smb2_signing_key_valid(signing_key) && opcode != SMB2_OP_CANCEL) {
3134 125165 : req->do_signing = true;
3135 : }
3136 :
3137 221621 : status = smb2_signing_check_pdu(signing_key,
3138 221621 : SMBD_SMB2_IN_HDR_IOV(req),
3139 : SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3140 125173 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
3141 63 : opcode == SMB2_OP_SESSSETUP && !has_channel &&
3142 34 : NT_STATUS_IS_OK(session_status))
3143 : {
3144 34 : if (!NT_STATUS_EQUAL(x->status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
3145 34 : struct smbXsrv_session *session = NULL;
3146 : NTSTATUS error;
3147 :
3148 34 : error = smb2srv_session_lookup_global(req->xconn->client,
3149 34 : x->global->session_wire_id,
3150 : req,
3151 : &session);
3152 34 : if (!NT_STATUS_IS_OK(error)) {
3153 0 : return smbd_smb2_request_error(req, error);
3154 : }
3155 :
3156 : /*
3157 : * We fallback to a session of
3158 : * another process in order to
3159 : * get the signing correct.
3160 : *
3161 : * We don't set req->last_session_id here.
3162 : */
3163 34 : req->session = x = session;
3164 : }
3165 34 : goto skipped_signing;
3166 : }
3167 125139 : if (!NT_STATUS_IS_OK(status)) {
3168 12 : return smbd_smb2_request_error(req, status);
3169 : }
3170 :
3171 : /*
3172 : * Now that we know the request was correctly signed
3173 : * we have to sign the response too.
3174 : */
3175 125127 : if (opcode != SMB2_OP_CANCEL) {
3176 125119 : req->do_signing = true;
3177 : }
3178 :
3179 125127 : if (!NT_STATUS_IS_OK(session_status)) {
3180 36 : return smbd_smb2_request_error(req, session_status);
3181 : }
3182 : }
3183 :
3184 156940 : if (opcode == SMB2_OP_IOCTL) {
3185 : /*
3186 : * Some special IOCTL calls don't require
3187 : * file, tcon nor session.
3188 : *
3189 : * They typically don't do any real action
3190 : * on behalf of the client.
3191 : *
3192 : * They are mainly used to alter the behavior
3193 : * of the connection for testing. So we can
3194 : * run as root and skip all file, tcon and session
3195 : * checks below.
3196 : */
3197 : static const struct smbd_smb2_dispatch_table _root_ioctl_call = {
3198 : _OP(SMB2_OP_IOCTL),
3199 : .as_root = true,
3200 : };
3201 81587 : const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3202 81587 : size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3203 : uint32_t in_ctl_code;
3204 81587 : size_t needed = 8;
3205 :
3206 81587 : if (needed > body_size) {
3207 0 : return smbd_smb2_request_error(req,
3208 : NT_STATUS_INVALID_PARAMETER);
3209 : }
3210 :
3211 81587 : in_ctl_code = IVAL(body, 0x04);
3212 : /*
3213 : * Only add trusted IOCTL codes here!
3214 : */
3215 81587 : switch (in_ctl_code) {
3216 0 : case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
3217 0 : call = &_root_ioctl_call;
3218 0 : break;
3219 2311 : case FSCTL_VALIDATE_NEGOTIATE_INFO:
3220 2311 : call = &_root_ioctl_call;
3221 2311 : break;
3222 0 : case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
3223 0 : call = &_root_ioctl_call;
3224 0 : break;
3225 : }
3226 : }
3227 :
3228 195427 : skipped_signing:
3229 :
3230 156974 : if (flags & SMB2_HDR_FLAG_CHAINED) {
3231 0 : req->compound_related = true;
3232 : }
3233 :
3234 156974 : if (call->need_session) {
3235 139450 : if (!NT_STATUS_IS_OK(session_status)) {
3236 30 : return smbd_smb2_request_error(req, session_status);
3237 : }
3238 : }
3239 :
3240 156944 : if (call->need_tcon) {
3241 133802 : SMB_ASSERT(call->need_session);
3242 :
3243 : /*
3244 : * This call needs to be run as user.
3245 : *
3246 : * smbd_smb2_request_check_tcon()
3247 : * calls change_to_user() on success.
3248 : * Which implies set_current_user_info()
3249 : * and chdir_current_service().
3250 : */
3251 133802 : status = smbd_smb2_request_check_tcon(req);
3252 133802 : if (!NT_STATUS_IS_OK(status)) {
3253 38 : return smbd_smb2_request_error(req, status);
3254 : }
3255 133764 : if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3256 0 : encryption_desired = true;
3257 : }
3258 133764 : if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
3259 0 : encryption_required = true;
3260 : }
3261 133764 : if (encryption_required && !req->was_encrypted) {
3262 0 : req->do_encryption = true;
3263 0 : return smbd_smb2_request_error(req,
3264 : NT_STATUS_ACCESS_DENIED);
3265 133764 : } else if (encryption_desired) {
3266 0 : req->do_encryption = true;
3267 : }
3268 23142 : } else if (call->need_session) {
3269 5618 : struct auth_session_info *session_info = NULL;
3270 :
3271 : /*
3272 : * Unless we also have need_tcon (see above),
3273 : * we still need to call set_current_user_info().
3274 : */
3275 :
3276 5618 : session_info = req->session->global->auth_session_info;
3277 5618 : if (session_info == NULL) {
3278 0 : return NT_STATUS_INVALID_HANDLE;
3279 : }
3280 :
3281 9423 : set_current_user_info(session_info->unix_info->sanitized_username,
3282 5618 : session_info->unix_info->unix_name,
3283 5618 : session_info->info->domain_name);
3284 : }
3285 :
3286 156906 : if (req->session) {
3287 143557 : bool update_session_global = false;
3288 143557 : bool update_tcon_global = false;
3289 :
3290 143557 : smb2srv_update_crypto_flags(req, opcode,
3291 : &update_session_global,
3292 : &update_tcon_global);
3293 :
3294 143557 : if (update_session_global) {
3295 6308 : status = smbXsrv_session_update(x);
3296 6308 : if (!NT_STATUS_IS_OK(status)) {
3297 0 : return smbd_smb2_request_error(req, status);
3298 : }
3299 : }
3300 143557 : if (update_tcon_global) {
3301 5447 : status = smbXsrv_tcon_update(req->tcon);
3302 5447 : if (!NT_STATUS_IS_OK(status)) {
3303 0 : return smbd_smb2_request_error(req, status);
3304 : }
3305 : }
3306 : }
3307 :
3308 156906 : if (call->fileid_ofs != 0) {
3309 114134 : size_t needed = call->fileid_ofs + 16;
3310 114134 : const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3311 114134 : size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3312 : uint64_t file_id_persistent;
3313 : uint64_t file_id_volatile;
3314 : struct files_struct *fsp;
3315 :
3316 114134 : SMB_ASSERT(call->need_tcon);
3317 :
3318 114134 : if (needed > body_size) {
3319 0 : return smbd_smb2_request_error(req,
3320 : NT_STATUS_INVALID_PARAMETER);
3321 : }
3322 :
3323 114134 : file_id_persistent = BVAL(body, call->fileid_ofs + 0);
3324 114134 : file_id_volatile = BVAL(body, call->fileid_ofs + 8);
3325 :
3326 114134 : fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
3327 114134 : if (fsp == NULL) {
3328 1657 : if (req->compound_related &&
3329 0 : !NT_STATUS_IS_OK(req->compound_create_err))
3330 : {
3331 0 : return smbd_smb2_request_error(req,
3332 : req->compound_create_err);
3333 : }
3334 : /*
3335 : * smbd_smb2_request_process_ioctl()
3336 : * has more checks in order to return more
3337 : * detailed error codes...
3338 : */
3339 1657 : if (opcode != SMB2_OP_IOCTL) {
3340 2 : return smbd_smb2_request_error(req,
3341 : NT_STATUS_FILE_CLOSED);
3342 : }
3343 : } else {
3344 112477 : if (fsp->fsp_flags.encryption_required && !req->was_encrypted) {
3345 0 : return smbd_smb2_request_error(req,
3346 : NT_STATUS_ACCESS_DENIED);
3347 : }
3348 : }
3349 : }
3350 :
3351 156904 : status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
3352 156904 : if (!NT_STATUS_IS_OK(status)) {
3353 0 : return smbd_smb2_request_error(req, status);
3354 : }
3355 :
3356 156904 : if (call->as_root) {
3357 25543 : SMB_ASSERT(call->fileid_ofs == 0);
3358 : /* This call needs to be run as root */
3359 25543 : change_to_root_user();
3360 : } else {
3361 131361 : SMB_ASSERT(call->need_tcon);
3362 : }
3363 :
3364 : #define _INBYTES(_r) \
3365 : iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3366 :
3367 156904 : switch (opcode) {
3368 8373 : case SMB2_OP_NEGPROT:
3369 8373 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_negprot, profile_p,
3370 : req->profile, _INBYTES(req));
3371 8373 : return_value = smbd_smb2_request_process_negprot(req);
3372 8373 : break;
3373 :
3374 6762 : case SMB2_OP_SESSSETUP:
3375 6762 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_sesssetup, profile_p,
3376 : req->profile, _INBYTES(req));
3377 6762 : return_value = smbd_smb2_request_process_sesssetup(req);
3378 6762 : break;
3379 :
3380 9 : case SMB2_OP_LOGOFF:
3381 9 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_logoff, profile_p,
3382 : req->profile, _INBYTES(req));
3383 9 : return_value = smbd_smb2_request_process_logoff(req);
3384 9 : break;
3385 :
3386 5609 : case SMB2_OP_TCON:
3387 5609 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_tcon, profile_p,
3388 : req->profile, _INBYTES(req));
3389 5609 : return_value = smbd_smb2_request_process_tcon(req);
3390 5609 : break;
3391 :
3392 2401 : case SMB2_OP_TDIS:
3393 2401 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_tdis, profile_p,
3394 : req->profile, _INBYTES(req));
3395 2401 : return_value = smbd_smb2_request_process_tdis(req);
3396 2401 : break;
3397 :
3398 17229 : case SMB2_OP_CREATE:
3399 17229 : if (req->subreq == NULL) {
3400 17229 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_create, profile_p,
3401 : req->profile, _INBYTES(req));
3402 : } else {
3403 0 : SMBPROFILE_IOBYTES_ASYNC_SET_BUSY(req->profile);
3404 : }
3405 17229 : return_value = smbd_smb2_request_process_create(req);
3406 17227 : break;
3407 :
3408 15148 : case SMB2_OP_CLOSE:
3409 15148 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_close, profile_p,
3410 : req->profile, _INBYTES(req));
3411 15148 : return_value = smbd_smb2_request_process_close(req);
3412 12658 : break;
3413 :
3414 0 : case SMB2_OP_FLUSH:
3415 0 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_flush, profile_p,
3416 : req->profile, _INBYTES(req));
3417 0 : return_value = smbd_smb2_request_process_flush(req);
3418 0 : break;
3419 :
3420 6358 : case SMB2_OP_READ:
3421 6358 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_read, profile_p,
3422 : req->profile, _INBYTES(req));
3423 6358 : return_value = smbd_smb2_request_process_read(req);
3424 6358 : break;
3425 :
3426 6348 : case SMB2_OP_WRITE:
3427 6348 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_write, profile_p,
3428 : req->profile, _INBYTES(req));
3429 6348 : return_value = smbd_smb2_request_process_write(req);
3430 6348 : break;
3431 :
3432 17 : case SMB2_OP_LOCK:
3433 17 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_lock, profile_p,
3434 : req->profile, _INBYTES(req));
3435 17 : return_value = smbd_smb2_request_process_lock(req);
3436 17 : break;
3437 :
3438 81585 : case SMB2_OP_IOCTL:
3439 81585 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_ioctl, profile_p,
3440 : req->profile, _INBYTES(req));
3441 81585 : return_value = smbd_smb2_request_process_ioctl(req);
3442 81585 : break;
3443 :
3444 18 : case SMB2_OP_CANCEL:
3445 18 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_cancel, profile_p,
3446 : req->profile, _INBYTES(req));
3447 18 : return_value = smbd_smb2_request_process_cancel(req);
3448 18 : SMBPROFILE_IOBYTES_ASYNC_END(req->profile, 0);
3449 :
3450 : /*
3451 : * We don't need the request anymore cancel requests never
3452 : * have a response.
3453 : *
3454 : * smbd_smb2_request_process_cancel() already called
3455 : * DLIST_REMOVE(xconn->smb2.requests, req);
3456 : */
3457 18 : TALLOC_FREE(req);
3458 :
3459 18 : break;
3460 :
3461 60 : case SMB2_OP_KEEPALIVE:
3462 60 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_keepalive, profile_p,
3463 : req->profile, _INBYTES(req));
3464 60 : return_value = smbd_smb2_request_process_keepalive(req);
3465 60 : break;
3466 :
3467 4287 : case SMB2_OP_QUERY_DIRECTORY:
3468 4287 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_find, profile_p,
3469 : req->profile, _INBYTES(req));
3470 4287 : return_value = smbd_smb2_request_process_query_directory(req);
3471 4287 : break;
3472 :
3473 60 : case SMB2_OP_NOTIFY:
3474 60 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_notify, profile_p,
3475 : req->profile, _INBYTES(req));
3476 60 : return_value = smbd_smb2_request_process_notify(req);
3477 60 : break;
3478 :
3479 1620 : case SMB2_OP_GETINFO:
3480 1620 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_getinfo, profile_p,
3481 : req->profile, _INBYTES(req));
3482 1620 : return_value = smbd_smb2_request_process_getinfo(req);
3483 1620 : break;
3484 :
3485 1020 : case SMB2_OP_SETINFO:
3486 1020 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_setinfo, profile_p,
3487 : req->profile, _INBYTES(req));
3488 1020 : return_value = smbd_smb2_request_process_setinfo(req);
3489 1020 : break;
3490 :
3491 0 : case SMB2_OP_BREAK:
3492 0 : SMBPROFILE_IOBYTES_ASYNC_START(smb2_break, profile_p,
3493 : req->profile, _INBYTES(req));
3494 0 : return_value = smbd_smb2_request_process_break(req);
3495 0 : break;
3496 :
3497 0 : default:
3498 0 : return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3499 0 : break;
3500 : }
3501 154412 : return return_value;
3502 : }
3503 :
3504 156976 : static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
3505 : {
3506 156976 : struct smbXsrv_connection *xconn = req->xconn;
3507 : const uint8_t *inhdr;
3508 : uint16_t channel_sequence;
3509 : struct smbXsrv_open *op;
3510 :
3511 156976 : if (!req->request_counters_updated) {
3512 98383 : return;
3513 : }
3514 :
3515 58593 : req->request_counters_updated = false;
3516 :
3517 58593 : if (xconn->protocol < PROTOCOL_SMB3_00) {
3518 0 : return;
3519 : }
3520 :
3521 58593 : if (req->compat_chain_fsp == NULL) {
3522 7949 : return;
3523 : }
3524 :
3525 50644 : op = req->compat_chain_fsp->op;
3526 50644 : if (op == NULL) {
3527 0 : return;
3528 : }
3529 :
3530 50644 : inhdr = SMBD_SMB2_IN_HDR_PTR(req);
3531 50644 : channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
3532 :
3533 96028 : if ((op->global->channel_sequence == channel_sequence) &&
3534 50644 : (op->global->channel_generation == req->channel_generation)) {
3535 50644 : SMB_ASSERT(op->request_count > 0);
3536 50644 : op->request_count -= 1;
3537 : } else {
3538 0 : SMB_ASSERT(op->pre_request_count > 0);
3539 0 : op->pre_request_count -= 1;
3540 : }
3541 : }
3542 :
3543 156976 : static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
3544 : {
3545 156976 : struct smbXsrv_connection *xconn = req->xconn;
3546 156976 : int first_idx = 1;
3547 156976 : struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
3548 156976 : struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
3549 156976 : struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
3550 : NTSTATUS status;
3551 : bool ok;
3552 :
3553 156976 : req->subreq = NULL;
3554 156976 : TALLOC_FREE(req->async_te);
3555 :
3556 : /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3557 156976 : smbd_smb2_request_reply_update_counts(req);
3558 :
3559 157283 : if (req->do_encryption &&
3560 921 : (firsttf->iov_len == 0) &&
3561 921 : (!smb2_signing_key_valid(req->first_enc_key)) &&
3562 1228 : (req->session != NULL) &&
3563 614 : smb2_signing_key_valid(req->session->global->encryption_key))
3564 : {
3565 614 : struct smb2_signing_key *encryption_key =
3566 614 : req->session->global->encryption_key;
3567 : uint8_t *tf;
3568 614 : uint64_t session_id = req->session->global->session_wire_id;
3569 : uint64_t nonce_high;
3570 : uint64_t nonce_low;
3571 :
3572 614 : status = smb2_get_new_nonce(req->session,
3573 : &nonce_high,
3574 : &nonce_low);
3575 614 : if (!NT_STATUS_IS_OK(status)) {
3576 0 : return status;
3577 : }
3578 :
3579 : /*
3580 : * We need to place the SMB2_TRANSFORM header before the
3581 : * first SMB2 header
3582 : */
3583 :
3584 : /*
3585 : * we need to remember the encryption key
3586 : * and defer the signing/encryption until
3587 : * we are sure that we do not change
3588 : * the header again.
3589 : */
3590 614 : status = smb2_signing_key_copy(req,
3591 : encryption_key,
3592 : &req->first_enc_key);
3593 614 : if (!NT_STATUS_IS_OK(status)) {
3594 0 : return status;
3595 : }
3596 :
3597 614 : tf = talloc_zero_array(req, uint8_t,
3598 : SMB2_TF_HDR_SIZE);
3599 614 : if (tf == NULL) {
3600 0 : return NT_STATUS_NO_MEMORY;
3601 : }
3602 :
3603 614 : SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3604 614 : SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
3605 614 : SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
3606 614 : SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
3607 :
3608 614 : firsttf->iov_base = (void *)tf;
3609 614 : firsttf->iov_len = SMB2_TF_HDR_SIZE;
3610 : }
3611 :
3612 156976 : if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
3613 0 : (smb2_signing_key_valid(req->last_sign_key)) &&
3614 0 : (firsttf->iov_len == 0))
3615 : {
3616 0 : int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
3617 0 : struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
3618 :
3619 : /*
3620 : * As we are sure the header of the last request in the
3621 : * compound chain will not change, we can to sign here
3622 : * with the last signing key we remembered.
3623 : */
3624 0 : status = smb2_signing_sign_pdu(req->last_sign_key,
3625 : lasthdr,
3626 : SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3627 0 : if (!NT_STATUS_IS_OK(status)) {
3628 0 : return status;
3629 : }
3630 : }
3631 156976 : TALLOC_FREE(req->last_sign_key);
3632 :
3633 156976 : SMBPROFILE_IOBYTES_ASYNC_END(req->profile,
3634 : iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ-1));
3635 :
3636 156976 : req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
3637 :
3638 156976 : if (req->current_idx < req->out.vector_count) {
3639 : /*
3640 : * We must process the remaining compound
3641 : * SMB2 requests before any new incoming SMB2
3642 : * requests. This is because incoming SMB2
3643 : * requests may include a cancel for a
3644 : * compound request we haven't processed
3645 : * yet.
3646 : */
3647 0 : struct tevent_immediate *im = tevent_create_immediate(req);
3648 0 : if (!im) {
3649 0 : return NT_STATUS_NO_MEMORY;
3650 : }
3651 :
3652 0 : if (req->do_signing && firsttf->iov_len == 0) {
3653 0 : struct smbXsrv_session *x = req->session;
3654 0 : struct smb2_signing_key *signing_key =
3655 0 : smbd_smb2_signing_key(x, xconn, NULL);
3656 :
3657 : /*
3658 : * we need to remember the signing key
3659 : * and defer the signing until
3660 : * we are sure that we do not change
3661 : * the header again.
3662 : */
3663 0 : status = smb2_signing_key_copy(req,
3664 : signing_key,
3665 : &req->last_sign_key);
3666 0 : if (!NT_STATUS_IS_OK(status)) {
3667 0 : return status;
3668 : }
3669 : }
3670 :
3671 : /*
3672 : * smbd_smb2_request_dispatch() will redo the impersonation.
3673 : * So we use req->xconn->client->raw_ev_ctx instead
3674 : * of req->ev_ctx here.
3675 : */
3676 0 : tevent_schedule_immediate(im,
3677 : req->xconn->client->raw_ev_ctx,
3678 : smbd_smb2_request_dispatch_immediate,
3679 : req);
3680 0 : return NT_STATUS_OK;
3681 : }
3682 :
3683 156976 : if (req->compound_related) {
3684 0 : req->compound_related = false;
3685 : }
3686 :
3687 156976 : ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
3688 156976 : if (!ok) {
3689 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
3690 : }
3691 :
3692 : /* Set credit for these operations (zero credits if this
3693 : is a final reply for an async operation). */
3694 156976 : smb2_calculate_credits(req, req);
3695 :
3696 : /*
3697 : * now check if we need to sign the current response
3698 : */
3699 156976 : if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3700 614 : status = smb2_signing_encrypt_pdu(req->first_enc_key,
3701 : firsttf,
3702 614 : req->out.vector_count - first_idx);
3703 614 : if (!NT_STATUS_IS_OK(status)) {
3704 0 : return status;
3705 : }
3706 156362 : } else if (req->do_signing) {
3707 129566 : struct smbXsrv_session *x = req->session;
3708 99527 : struct smb2_signing_key *signing_key =
3709 30039 : smbd_smb2_signing_key(x, xconn, NULL);
3710 :
3711 129566 : status = smb2_signing_sign_pdu(signing_key,
3712 : outhdr,
3713 : SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3714 129566 : if (!NT_STATUS_IS_OK(status)) {
3715 0 : return status;
3716 : }
3717 : }
3718 156976 : TALLOC_FREE(req->first_enc_key);
3719 :
3720 156976 : if (req->preauth != NULL) {
3721 4065 : gnutls_hash_hd_t hash_hnd = NULL;
3722 : size_t i;
3723 : int rc;
3724 :
3725 4065 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3726 4065 : if (rc < 0) {
3727 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3728 : }
3729 4065 : rc = gnutls_hash(hash_hnd,
3730 4065 : req->preauth->sha512_value,
3731 : sizeof(req->preauth->sha512_value));
3732 4065 : if (rc < 0) {
3733 0 : gnutls_hash_deinit(hash_hnd, NULL);
3734 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3735 : }
3736 20325 : for (i = 1; i < req->in.vector_count; i++) {
3737 28040 : rc = gnutls_hash(hash_hnd,
3738 16260 : req->in.vector[i].iov_base,
3739 16260 : req->in.vector[i].iov_len);
3740 16260 : if (rc < 0) {
3741 0 : gnutls_hash_deinit(hash_hnd, NULL);
3742 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3743 : }
3744 : }
3745 4065 : if (rc < 0) {
3746 0 : gnutls_hash_deinit(hash_hnd, NULL);
3747 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3748 : }
3749 4065 : gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3750 :
3751 4065 : rc = gnutls_hash(hash_hnd,
3752 4065 : req->preauth->sha512_value,
3753 : sizeof(req->preauth->sha512_value));
3754 4065 : if (rc < 0) {
3755 0 : gnutls_hash_deinit(hash_hnd, NULL);
3756 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3757 : }
3758 20325 : for (i = 1; i < req->out.vector_count; i++) {
3759 28040 : rc = gnutls_hash(hash_hnd,
3760 16260 : req->out.vector[i].iov_base,
3761 16260 : req->out.vector[i].iov_len);
3762 16260 : if (rc < 0) {
3763 0 : gnutls_hash_deinit(hash_hnd, NULL);
3764 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3765 : }
3766 : }
3767 :
3768 4065 : gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3769 :
3770 4065 : req->preauth = NULL;
3771 : }
3772 :
3773 : /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3774 277051 : if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3775 194305 : outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3776 : /* Dynamic part is NULL. Chop it off,
3777 : We're going to send it via sendfile. */
3778 0 : req->out.vector_count -= 1;
3779 : }
3780 :
3781 : /*
3782 : * We're done with this request -
3783 : * move it off the "being processed" queue.
3784 : */
3785 156976 : DLIST_REMOVE(xconn->smb2.requests, req);
3786 :
3787 156976 : req->queue_entry.mem_ctx = req;
3788 156976 : req->queue_entry.vector = req->out.vector;
3789 156976 : req->queue_entry.count = req->out.vector_count;
3790 156976 : DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3791 156976 : xconn->smb2.send_queue_len++;
3792 :
3793 156976 : status = smbd_smb2_flush_send_queue(xconn);
3794 156976 : if (!NT_STATUS_IS_OK(status)) {
3795 2492 : return status;
3796 : }
3797 :
3798 154484 : return NT_STATUS_OK;
3799 : }
3800 :
3801 : static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3802 :
3803 0 : void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3804 : struct tevent_immediate *im,
3805 : void *private_data)
3806 : {
3807 0 : struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3808 : struct smbd_smb2_request);
3809 0 : struct smbXsrv_connection *xconn = req->xconn;
3810 : NTSTATUS status;
3811 :
3812 0 : TALLOC_FREE(im);
3813 :
3814 0 : if (DEBUGLEVEL >= 10) {
3815 0 : DEBUG(10,("smbd_smb2_request_dispatch_immediate: idx[%d] of %d vectors\n",
3816 : req->current_idx, req->in.vector_count));
3817 0 : print_req_vectors(req);
3818 : }
3819 :
3820 0 : status = smbd_smb2_request_dispatch(req);
3821 0 : if (!NT_STATUS_IS_OK(status)) {
3822 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
3823 0 : return;
3824 : }
3825 :
3826 0 : status = smbd_smb2_request_next_incoming(xconn);
3827 0 : if (!NT_STATUS_IS_OK(status)) {
3828 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
3829 0 : return;
3830 : }
3831 : }
3832 :
3833 156976 : NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3834 : NTSTATUS status,
3835 : DATA_BLOB body, DATA_BLOB *dyn,
3836 : const char *location)
3837 : {
3838 : uint8_t *outhdr;
3839 : struct iovec *outbody_v;
3840 : struct iovec *outdyn_v;
3841 : uint32_t next_command_ofs;
3842 : uint64_t mid;
3843 :
3844 156976 : outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3845 156976 : mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
3846 :
3847 156976 : DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
3848 : "body[%u] dyn[%s:%u] at %s\n",
3849 : mid,
3850 : req->current_idx,
3851 : nt_errstr(status),
3852 : (unsigned int)body.length,
3853 : dyn ? "yes" : "no",
3854 : (unsigned int)(dyn ? dyn->length : 0),
3855 : location);
3856 :
3857 156976 : if (body.length < 2) {
3858 0 : return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3859 : }
3860 :
3861 156976 : if ((body.length % 2) != 0) {
3862 0 : return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
3863 : }
3864 :
3865 156976 : outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
3866 156976 : outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
3867 :
3868 156976 : next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
3869 156976 : SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
3870 :
3871 156976 : outbody_v->iov_base = (void *)body.data;
3872 156976 : outbody_v->iov_len = body.length;
3873 :
3874 156976 : if (dyn) {
3875 132740 : outdyn_v->iov_base = (void *)dyn->data;
3876 132740 : outdyn_v->iov_len = dyn->length;
3877 : } else {
3878 24236 : outdyn_v->iov_base = NULL;
3879 24236 : outdyn_v->iov_len = 0;
3880 : }
3881 :
3882 : /*
3883 : * See if we need to recalculate the offset to the next response
3884 : *
3885 : * Note that all responses may require padding (including the very last
3886 : * one).
3887 : */
3888 156976 : if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
3889 0 : next_command_ofs = SMB2_HDR_BODY;
3890 0 : next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
3891 0 : next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
3892 : }
3893 :
3894 156976 : if ((next_command_ofs % 8) != 0) {
3895 0 : size_t pad_size = 8 - (next_command_ofs % 8);
3896 0 : if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
3897 : /*
3898 : * if the dyn buffer is empty
3899 : * we can use it to add padding
3900 : */
3901 : uint8_t *pad;
3902 :
3903 0 : pad = talloc_zero_array(req,
3904 : uint8_t, pad_size);
3905 0 : if (pad == NULL) {
3906 0 : return smbd_smb2_request_error(req,
3907 : NT_STATUS_NO_MEMORY);
3908 : }
3909 :
3910 0 : outdyn_v->iov_base = (void *)pad;
3911 0 : outdyn_v->iov_len = pad_size;
3912 : } else {
3913 : /*
3914 : * For now we copy the dynamic buffer
3915 : * and add the padding to the new buffer
3916 : */
3917 : size_t old_size;
3918 : uint8_t *old_dyn;
3919 : size_t new_size;
3920 : uint8_t *new_dyn;
3921 :
3922 0 : old_size = SMBD_SMB2_OUT_DYN_LEN(req);
3923 0 : old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
3924 :
3925 0 : new_size = old_size + pad_size;
3926 0 : new_dyn = talloc_zero_array(req,
3927 : uint8_t, new_size);
3928 0 : if (new_dyn == NULL) {
3929 0 : return smbd_smb2_request_error(req,
3930 : NT_STATUS_NO_MEMORY);
3931 : }
3932 :
3933 0 : memcpy(new_dyn, old_dyn, old_size);
3934 0 : memset(new_dyn + old_size, 0, pad_size);
3935 :
3936 0 : outdyn_v->iov_base = (void *)new_dyn;
3937 0 : outdyn_v->iov_len = new_size;
3938 : }
3939 0 : next_command_ofs += pad_size;
3940 : }
3941 :
3942 156976 : if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
3943 156976 : SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
3944 : } else {
3945 0 : SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
3946 : }
3947 156976 : return smbd_smb2_request_reply(req);
3948 : }
3949 :
3950 5432 : NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
3951 : NTSTATUS status,
3952 : DATA_BLOB *info,
3953 : const char *location)
3954 : {
3955 5432 : struct smbXsrv_connection *xconn = req->xconn;
3956 : DATA_BLOB body;
3957 : DATA_BLOB _dyn;
3958 5432 : uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
3959 5432 : size_t unread_bytes = smbd_smb2_unread_bytes(req);
3960 :
3961 5432 : DBG_NOTICE("smbd_smb2_request_error_ex: idx[%d] status[%s] |%s| "
3962 : "at %s\n", req->current_idx, nt_errstr(status),
3963 : info ? " +info" : "", location);
3964 :
3965 5432 : if (unread_bytes) {
3966 : /* Recvfile error. Drain incoming socket. */
3967 : size_t ret;
3968 :
3969 0 : errno = 0;
3970 0 : ret = drain_socket(xconn->transport.sock, unread_bytes);
3971 0 : if (ret != unread_bytes) {
3972 : NTSTATUS error;
3973 :
3974 0 : if (errno == 0) {
3975 0 : error = NT_STATUS_IO_DEVICE_ERROR;
3976 : } else {
3977 0 : error = map_nt_error_from_unix_common(errno);
3978 : }
3979 :
3980 0 : DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
3981 : "ret[%u] errno[%d] => %s\n",
3982 : (unsigned)unread_bytes,
3983 : (unsigned)ret, errno, nt_errstr(error)));
3984 0 : return error;
3985 : }
3986 : }
3987 :
3988 5432 : body.data = outhdr + SMB2_HDR_BODY;
3989 5432 : body.length = 8;
3990 5432 : SSVAL(body.data, 0, 9);
3991 :
3992 5432 : if (info) {
3993 0 : SIVAL(body.data, 0x04, info->length);
3994 : } else {
3995 : /* Allocated size of req->out.vector[i].iov_base
3996 : * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
3997 : * 1 byte without having to do an alloc.
3998 : */
3999 5432 : info = &_dyn;
4000 5432 : info->data = ((uint8_t *)outhdr) +
4001 5432 : OUTVEC_ALLOC_SIZE - 1;
4002 5432 : info->length = 1;
4003 5432 : SCVAL(info->data, 0, 0);
4004 : }
4005 :
4006 : /*
4007 : * Note: Even if there is an error, continue to process the request.
4008 : * per MS-SMB2.
4009 : */
4010 :
4011 5432 : return smbd_smb2_request_done_ex(req, status, body, info, __location__);
4012 : }
4013 :
4014 : struct smbd_smb2_break_state {
4015 : struct tevent_req *req;
4016 : struct smbd_smb2_send_queue queue_entry;
4017 : uint8_t nbt_hdr[NBT_HDR_SIZE];
4018 : uint8_t hdr[SMB2_HDR_BODY];
4019 : struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
4020 : };
4021 :
4022 0 : static struct tevent_req *smbd_smb2_break_send(TALLOC_CTX *mem_ctx,
4023 : struct tevent_context *ev,
4024 : struct smbXsrv_connection *xconn,
4025 : uint64_t session_id,
4026 : const uint8_t *body,
4027 : size_t body_len)
4028 : {
4029 0 : struct tevent_req *req = NULL;
4030 0 : struct smbd_smb2_break_state *state = NULL;
4031 : NTSTATUS status;
4032 : bool ok;
4033 :
4034 0 : req = tevent_req_create(mem_ctx, &state,
4035 : struct smbd_smb2_break_state);
4036 0 : if (req == NULL) {
4037 0 : return NULL;
4038 : }
4039 :
4040 0 : state->req = req;
4041 0 : tevent_req_defer_callback(req, ev);
4042 :
4043 0 : SIVAL(state->hdr, 0, SMB2_MAGIC);
4044 0 : SSVAL(state->hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
4045 0 : SSVAL(state->hdr, SMB2_HDR_EPOCH, 0);
4046 0 : SIVAL(state->hdr, SMB2_HDR_STATUS, 0);
4047 0 : SSVAL(state->hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK);
4048 0 : SSVAL(state->hdr, SMB2_HDR_CREDIT, 0);
4049 0 : SIVAL(state->hdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
4050 0 : SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, 0);
4051 0 : SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
4052 0 : SIVAL(state->hdr, SMB2_HDR_PID, 0);
4053 0 : SIVAL(state->hdr, SMB2_HDR_TID, 0);
4054 0 : SBVAL(state->hdr, SMB2_HDR_SESSION_ID, session_id);
4055 0 : memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
4056 :
4057 0 : state->vector[0] = (struct iovec) {
4058 0 : .iov_base = state->nbt_hdr,
4059 : .iov_len = sizeof(state->nbt_hdr)
4060 : };
4061 :
4062 0 : state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
4063 : .iov_base = NULL,
4064 : .iov_len = 0
4065 : };
4066 :
4067 0 : state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
4068 0 : .iov_base = state->hdr,
4069 : .iov_len = sizeof(state->hdr)
4070 : };
4071 :
4072 0 : state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
4073 : .iov_base = discard_const_p(uint8_t, body),
4074 : .iov_len = body_len,
4075 : };
4076 :
4077 : /*
4078 : * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4079 : */
4080 :
4081 0 : ok = smb2_setup_nbt_length(state->vector,
4082 : 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
4083 0 : if (!ok) {
4084 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4085 0 : return tevent_req_post(req, ev);
4086 : }
4087 :
4088 : /*
4089 : * We require TCP acks for this PDU to the client!
4090 : * We want 5 retransmissions and timeout when the
4091 : * retransmission timeout (rto) passed 6 times.
4092 : *
4093 : * required_acked_bytes gets a dummy value of
4094 : * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4095 : * it'll get the real value when it's moved to
4096 : * xconn->ack.queue.
4097 : *
4098 : * state->queue_entry.ack.req gets completed with
4099 : * 1. tevent_req_done(), when all bytes are acked.
4100 : * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4101 : * the timeout expired before all bytes were acked.
4102 : * 2b. tevent_req_nterror(transport_error), when the
4103 : * connection got a disconnect from the kernel.
4104 : */
4105 0 : state->queue_entry.ack.timeout =
4106 0 : timeval_current_ofs_usec(xconn->ack.rto_usecs * 6);
4107 0 : state->queue_entry.ack.required_acked_bytes = UINT64_MAX;
4108 0 : state->queue_entry.ack.req = req;
4109 0 : state->queue_entry.mem_ctx = state;
4110 0 : state->queue_entry.vector = state->vector;
4111 0 : state->queue_entry.count = ARRAY_SIZE(state->vector);
4112 0 : DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
4113 0 : xconn->smb2.send_queue_len++;
4114 :
4115 0 : status = smbd_smb2_flush_send_queue(xconn);
4116 0 : if (tevent_req_nterror(req, status)) {
4117 0 : return tevent_req_post(req, ev);
4118 : }
4119 :
4120 0 : return req;
4121 : }
4122 :
4123 0 : static NTSTATUS smbd_smb2_break_recv(struct tevent_req *req)
4124 : {
4125 0 : return tevent_req_simple_recv_ntstatus(req);
4126 : }
4127 :
4128 : struct smbXsrv_pending_break {
4129 : struct smbXsrv_pending_break *prev, *next;
4130 : struct smbXsrv_client *client;
4131 : bool disable_oplock_break_retries;
4132 : uint64_t session_id;
4133 : uint64_t last_channel_id;
4134 : union {
4135 : uint8_t generic[1];
4136 : uint8_t oplock[0x18];
4137 : uint8_t lease[0x2c];
4138 : } body;
4139 : size_t body_len;
4140 : };
4141 :
4142 : static void smbXsrv_pending_break_done(struct tevent_req *subreq);
4143 :
4144 0 : static struct smbXsrv_pending_break *smbXsrv_pending_break_create(
4145 : struct smbXsrv_client *client,
4146 : uint64_t session_id)
4147 : {
4148 0 : struct smbXsrv_pending_break *pb = NULL;
4149 :
4150 0 : pb = talloc_zero(client, struct smbXsrv_pending_break);
4151 0 : if (pb == NULL) {
4152 0 : return NULL;
4153 : }
4154 0 : pb->client = client;
4155 0 : pb->session_id = session_id;
4156 0 : pb->disable_oplock_break_retries = lp_smb2_disable_oplock_break_retry();
4157 :
4158 0 : return pb;
4159 : }
4160 :
4161 : static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb);
4162 :
4163 0 : static NTSTATUS smbXsrv_pending_break_schedule(struct smbXsrv_pending_break *pb)
4164 : {
4165 0 : struct smbXsrv_client *client = pb->client;
4166 : NTSTATUS status;
4167 :
4168 0 : DLIST_ADD_END(client->pending_breaks, pb);
4169 0 : status = smbXsrv_client_pending_breaks_updated(client);
4170 0 : if (!NT_STATUS_IS_OK(status)) {
4171 0 : return status;
4172 : }
4173 :
4174 0 : status = smbXsrv_pending_break_submit(pb);
4175 0 : if (!NT_STATUS_IS_OK(status)) {
4176 0 : return status;
4177 : }
4178 :
4179 0 : return NT_STATUS_OK;
4180 : }
4181 :
4182 0 : static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb)
4183 : {
4184 0 : struct smbXsrv_client *client = pb->client;
4185 0 : struct smbXsrv_session *session = NULL;
4186 0 : struct smbXsrv_connection *xconn = NULL;
4187 0 : struct smbXsrv_connection *oplock_xconn = NULL;
4188 0 : struct tevent_req *subreq = NULL;
4189 : NTSTATUS status;
4190 :
4191 0 : if (pb->session_id != 0) {
4192 0 : status = get_valid_smbXsrv_session(client,
4193 : pb->session_id,
4194 : &session);
4195 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
4196 0 : return NT_STATUS_ABANDONED;
4197 : }
4198 0 : if (!NT_STATUS_IS_OK(status)) {
4199 0 : return status;
4200 : }
4201 :
4202 0 : if (pb->last_channel_id != 0) {
4203 : /*
4204 : * This is what current Windows servers
4205 : * do, they don't retry on all available
4206 : * channels. They only use the last channel.
4207 : *
4208 : * But it doesn't match the specification in
4209 : * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4210 : * Oplock Break"
4211 : *
4212 : * Per default disable_oplock_break_retries is false
4213 : * and we behave like the specification.
4214 : */
4215 0 : if (pb->disable_oplock_break_retries) {
4216 0 : return NT_STATUS_ABANDONED;
4217 : }
4218 : }
4219 : }
4220 :
4221 0 : for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
4222 0 : if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4223 0 : continue;
4224 : }
4225 :
4226 0 : if (xconn->channel_id == 0) {
4227 : /*
4228 : * non-multichannel case
4229 : */
4230 0 : break;
4231 : }
4232 :
4233 0 : if (session != NULL) {
4234 0 : struct smbXsrv_channel_global0 *c = NULL;
4235 :
4236 : /*
4237 : * Having a session means we're handling
4238 : * an oplock break and we only need to
4239 : * use channels available on the
4240 : * session.
4241 : */
4242 0 : status = smbXsrv_session_find_channel(session, xconn, &c);
4243 0 : if (!NT_STATUS_IS_OK(status)) {
4244 0 : continue;
4245 : }
4246 :
4247 : /*
4248 : * This is what current Windows servers
4249 : * do, they don't retry on all available
4250 : * channels. They only use the last channel.
4251 : *
4252 : * But it doesn't match the specification
4253 : * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4254 : * Oplock Break"
4255 : *
4256 : * Per default disable_oplock_break_retries is false
4257 : * and we behave like the specification.
4258 : */
4259 0 : if (pb->disable_oplock_break_retries) {
4260 0 : oplock_xconn = xconn;
4261 0 : continue;
4262 : }
4263 : }
4264 :
4265 0 : if (xconn->channel_id > pb->last_channel_id) {
4266 : /*
4267 : * multichannel case
4268 : */
4269 0 : break;
4270 : }
4271 : }
4272 :
4273 0 : if (xconn == NULL) {
4274 0 : xconn = oplock_xconn;
4275 : }
4276 :
4277 0 : if (xconn == NULL) {
4278 : /*
4279 : * If there's no remaining connection available
4280 : * tell the caller to stop...
4281 : */
4282 0 : return NT_STATUS_ABANDONED;
4283 : }
4284 :
4285 0 : pb->last_channel_id = xconn->channel_id;
4286 :
4287 0 : subreq = smbd_smb2_break_send(pb,
4288 : client->raw_ev_ctx,
4289 : xconn,
4290 : pb->session_id,
4291 0 : pb->body.generic,
4292 : pb->body_len);
4293 0 : if (subreq == NULL) {
4294 0 : return NT_STATUS_NO_MEMORY;
4295 : }
4296 0 : tevent_req_set_callback(subreq,
4297 : smbXsrv_pending_break_done,
4298 : pb);
4299 :
4300 0 : return NT_STATUS_OK;
4301 : }
4302 :
4303 0 : static void smbXsrv_pending_break_done(struct tevent_req *subreq)
4304 : {
4305 0 : struct smbXsrv_pending_break *pb =
4306 0 : tevent_req_callback_data(subreq,
4307 : struct smbXsrv_pending_break);
4308 0 : struct smbXsrv_client *client = pb->client;
4309 : NTSTATUS status;
4310 :
4311 0 : status = smbd_smb2_break_recv(subreq);
4312 0 : TALLOC_FREE(subreq);
4313 0 : if (!NT_STATUS_IS_OK(status)) {
4314 0 : status = smbXsrv_pending_break_submit(pb);
4315 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_ABANDONED)) {
4316 : /*
4317 : * If there's no remaing connection
4318 : * there's no need to send a break again.
4319 : */
4320 0 : goto remove;
4321 : }
4322 0 : if (!NT_STATUS_IS_OK(status)) {
4323 0 : smbd_server_disconnect_client(client, nt_errstr(status));
4324 0 : return;
4325 : }
4326 0 : return;
4327 : }
4328 :
4329 0 : remove:
4330 0 : DLIST_REMOVE(client->pending_breaks, pb);
4331 0 : TALLOC_FREE(pb);
4332 :
4333 0 : status = smbXsrv_client_pending_breaks_updated(client);
4334 0 : if (!NT_STATUS_IS_OK(status)) {
4335 0 : smbd_server_disconnect_client(client, nt_errstr(status));
4336 0 : return;
4337 : }
4338 : }
4339 :
4340 0 : NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_client *client,
4341 : struct smbXsrv_open *op,
4342 : uint8_t oplock_level)
4343 : {
4344 0 : struct smbXsrv_pending_break *pb = NULL;
4345 0 : uint8_t *body = NULL;
4346 :
4347 0 : pb = smbXsrv_pending_break_create(client,
4348 0 : op->compat->vuid);
4349 0 : if (pb == NULL) {
4350 0 : return NT_STATUS_NO_MEMORY;
4351 : }
4352 0 : pb->body_len = sizeof(pb->body.oplock);
4353 0 : body = pb->body.oplock;
4354 :
4355 0 : SSVAL(body, 0x00, pb->body_len);
4356 0 : SCVAL(body, 0x02, oplock_level);
4357 0 : SCVAL(body, 0x03, 0); /* reserved */
4358 0 : SIVAL(body, 0x04, 0); /* reserved */
4359 0 : SBVAL(body, 0x08, op->global->open_persistent_id);
4360 0 : SBVAL(body, 0x10, op->global->open_volatile_id);
4361 :
4362 0 : return smbXsrv_pending_break_schedule(pb);
4363 : }
4364 :
4365 0 : NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_client *client,
4366 : uint16_t new_epoch,
4367 : uint32_t lease_flags,
4368 : struct smb2_lease_key *lease_key,
4369 : uint32_t current_lease_state,
4370 : uint32_t new_lease_state)
4371 : {
4372 0 : struct smbXsrv_pending_break *pb = NULL;
4373 0 : uint8_t *body = NULL;
4374 :
4375 0 : pb = smbXsrv_pending_break_create(client,
4376 : 0); /* no session_id */
4377 0 : if (pb == NULL) {
4378 0 : return NT_STATUS_NO_MEMORY;
4379 : }
4380 0 : pb->body_len = sizeof(pb->body.lease);
4381 0 : body = pb->body.lease;
4382 :
4383 0 : SSVAL(body, 0x00, pb->body_len);
4384 0 : SSVAL(body, 0x02, new_epoch);
4385 0 : SIVAL(body, 0x04, lease_flags);
4386 0 : SBVAL(body, 0x08, lease_key->data[0]);
4387 0 : SBVAL(body, 0x10, lease_key->data[1]);
4388 0 : SIVAL(body, 0x18, current_lease_state);
4389 0 : SIVAL(body, 0x1c, new_lease_state);
4390 0 : SIVAL(body, 0x20, 0); /* BreakReason, MUST be 0 */
4391 0 : SIVAL(body, 0x24, 0); /* AccessMaskHint, MUST be 0 */
4392 0 : SIVAL(body, 0x28, 0); /* ShareMaskHint, MUST be 0 */
4393 :
4394 0 : return smbXsrv_pending_break_schedule(pb);
4395 : }
4396 :
4397 0 : static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
4398 : {
4399 : NTSTATUS status;
4400 : uint32_t flags;
4401 : uint64_t file_id_persistent;
4402 : uint64_t file_id_volatile;
4403 0 : struct smbXsrv_open *op = NULL;
4404 0 : struct files_struct *fsp = NULL;
4405 0 : const uint8_t *body = NULL;
4406 :
4407 : /*
4408 : * This is only called with a pktbuf
4409 : * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4410 : * bytes
4411 : */
4412 :
4413 0 : if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
4414 : /* Transform header. Cannot recvfile. */
4415 0 : return false;
4416 : }
4417 0 : if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
4418 : /* Not SMB2. Normal error path will cope. */
4419 0 : return false;
4420 : }
4421 0 : if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
4422 : /* Not SMB2. Normal error path will cope. */
4423 0 : return false;
4424 : }
4425 0 : if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
4426 : /* Needs to be a WRITE. */
4427 0 : return false;
4428 : }
4429 0 : if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
4430 : /* Chained. Cannot recvfile. */
4431 0 : return false;
4432 : }
4433 0 : flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
4434 0 : if (flags & SMB2_HDR_FLAG_CHAINED) {
4435 : /* Chained. Cannot recvfile. */
4436 0 : return false;
4437 : }
4438 0 : if (flags & SMB2_HDR_FLAG_SIGNED) {
4439 : /* Signed. Cannot recvfile. */
4440 0 : return false;
4441 : }
4442 :
4443 0 : body = &state->pktbuf[SMB2_HDR_BODY];
4444 :
4445 0 : file_id_persistent = BVAL(body, 0x10);
4446 0 : file_id_volatile = BVAL(body, 0x18);
4447 :
4448 0 : status = smb2srv_open_lookup(state->req->xconn,
4449 : file_id_persistent,
4450 : file_id_volatile,
4451 : 0, /* now */
4452 : &op);
4453 0 : if (!NT_STATUS_IS_OK(status)) {
4454 0 : return false;
4455 : }
4456 :
4457 0 : fsp = op->compat;
4458 0 : if (fsp == NULL) {
4459 0 : return false;
4460 : }
4461 0 : if (fsp->conn == NULL) {
4462 0 : return false;
4463 : }
4464 :
4465 0 : if (IS_IPC(fsp->conn)) {
4466 0 : return false;
4467 : }
4468 0 : if (IS_PRINT(fsp->conn)) {
4469 0 : return false;
4470 : }
4471 0 : if (fsp_is_alternate_stream(fsp)) {
4472 0 : return false;
4473 : }
4474 :
4475 0 : DEBUG(10,("Doing recvfile write len = %u\n",
4476 : (unsigned int)(state->pktfull - state->pktlen)));
4477 :
4478 0 : return true;
4479 : }
4480 :
4481 330669 : static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
4482 : {
4483 330669 : struct smbd_server_connection *sconn = xconn->client->sconn;
4484 330669 : struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4485 : size_t max_send_queue_len;
4486 : size_t cur_send_queue_len;
4487 :
4488 330669 : if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4489 : /*
4490 : * we're not supposed to do any io
4491 : */
4492 0 : return NT_STATUS_OK;
4493 : }
4494 :
4495 330669 : if (state->req != NULL) {
4496 : /*
4497 : * if there is already a tstream_readv_pdu
4498 : * pending, we are done.
4499 : */
4500 176117 : return NT_STATUS_OK;
4501 : }
4502 :
4503 154552 : max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
4504 154552 : cur_send_queue_len = xconn->smb2.send_queue_len;
4505 :
4506 154552 : if (cur_send_queue_len > max_send_queue_len) {
4507 : /*
4508 : * if we have a lot of requests to send,
4509 : * we wait until they are on the wire until we
4510 : * ask for the next request.
4511 : */
4512 0 : return NT_STATUS_OK;
4513 : }
4514 :
4515 : /* ask for the next request */
4516 154552 : ZERO_STRUCTP(state);
4517 154552 : state->req = smbd_smb2_request_allocate(xconn);
4518 154552 : if (state->req == NULL) {
4519 0 : return NT_STATUS_NO_MEMORY;
4520 : }
4521 154552 : state->req->sconn = sconn;
4522 154552 : state->req->xconn = xconn;
4523 154552 : state->min_recv_size = lp_min_receive_file_size();
4524 :
4525 154552 : TEVENT_FD_READABLE(xconn->transport.fde);
4526 :
4527 154552 : return NT_STATUS_OK;
4528 : }
4529 :
4530 5052 : NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
4531 : uint64_t expected_seq_low,
4532 : const uint8_t *inpdu, size_t size)
4533 : {
4534 5052 : struct smbd_server_connection *sconn = xconn->client->sconn;
4535 : NTSTATUS status;
4536 5052 : struct smbd_smb2_request *req = NULL;
4537 :
4538 5052 : DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n",
4539 : (unsigned int)size));
4540 :
4541 5052 : status = smbd_initialize_smb2(xconn, expected_seq_low);
4542 5052 : if (!NT_STATUS_IS_OK(status)) {
4543 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
4544 0 : return status;
4545 : }
4546 :
4547 : /*
4548 : * If a new connection joins the process, when we're
4549 : * already in a "pending break cycle", we need to
4550 : * turn on the ack checker on the new connection.
4551 : */
4552 5052 : status = smbXsrv_client_pending_breaks_updated(xconn->client);
4553 5052 : if (!NT_STATUS_IS_OK(status)) {
4554 : /*
4555 : * If there's a problem, we disconnect the whole
4556 : * client with all connections here!
4557 : *
4558 : * Instead of just the new connection.
4559 : */
4560 0 : smbd_server_disconnect_client(xconn->client, nt_errstr(status));
4561 0 : return status;
4562 : }
4563 :
4564 5052 : status = smbd_smb2_request_create(xconn, inpdu, size, &req);
4565 5052 : if (!NT_STATUS_IS_OK(status)) {
4566 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
4567 0 : return status;
4568 : }
4569 :
4570 5052 : status = smbd_smb2_request_validate(req);
4571 5052 : if (!NT_STATUS_IS_OK(status)) {
4572 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
4573 0 : return status;
4574 : }
4575 :
4576 5052 : status = smbd_smb2_request_setup_out(req);
4577 5052 : if (!NT_STATUS_IS_OK(status)) {
4578 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
4579 0 : return status;
4580 : }
4581 :
4582 : #ifdef WITH_PROFILE
4583 : /*
4584 : * this was already counted at the SMB1 layer =>
4585 : * smbd_smb2_request_dispatch() should not count it twice.
4586 : */
4587 5052 : if (profile_p->values.request_stats.count > 0) {
4588 0 : profile_p->values.request_stats.count--;
4589 : }
4590 : #endif
4591 5052 : status = smbd_smb2_request_dispatch(req);
4592 5052 : if (!NT_STATUS_IS_OK(status)) {
4593 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
4594 0 : return status;
4595 : }
4596 :
4597 5052 : status = smbd_smb2_request_next_incoming(xconn);
4598 5052 : if (!NT_STATUS_IS_OK(status)) {
4599 0 : smbd_server_connection_terminate(xconn, nt_errstr(status));
4600 0 : return status;
4601 : }
4602 :
4603 5052 : sconn->num_requests++;
4604 5052 : return NT_STATUS_OK;
4605 : }
4606 :
4607 665996 : static int socket_error_from_errno(int ret,
4608 : int sys_errno,
4609 : bool *retry)
4610 : {
4611 665996 : *retry = false;
4612 :
4613 665996 : if (ret >= 0) {
4614 663225 : return 0;
4615 : }
4616 :
4617 2771 : if (ret != -1) {
4618 0 : return EIO;
4619 : }
4620 :
4621 2771 : if (sys_errno == 0) {
4622 0 : return EIO;
4623 : }
4624 :
4625 2771 : if (sys_errno == EINTR) {
4626 0 : *retry = true;
4627 0 : return sys_errno;
4628 : }
4629 :
4630 2771 : if (sys_errno == EINPROGRESS) {
4631 0 : *retry = true;
4632 0 : return sys_errno;
4633 : }
4634 :
4635 2771 : if (sys_errno == EAGAIN) {
4636 0 : *retry = true;
4637 0 : return sys_errno;
4638 : }
4639 :
4640 : /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4641 2771 : if (sys_errno == ENOMEM) {
4642 0 : *retry = true;
4643 0 : return sys_errno;
4644 : }
4645 :
4646 : #ifdef EWOULDBLOCK
4647 : #if EWOULDBLOCK != EAGAIN
4648 : if (sys_errno == EWOULDBLOCK) {
4649 : *retry = true;
4650 : return sys_errno;
4651 : }
4652 : #endif
4653 : #endif
4654 :
4655 2771 : return sys_errno;
4656 : }
4657 :
4658 271307 : static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
4659 : {
4660 : int ret;
4661 : int err;
4662 : bool retry;
4663 : NTSTATUS status;
4664 :
4665 271307 : if (xconn->smb2.send_queue == NULL) {
4666 5694 : TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4667 5694 : return NT_STATUS_OK;
4668 : }
4669 :
4670 635216 : while (xconn->smb2.send_queue != NULL) {
4671 265626 : struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
4672 : bool ok;
4673 : struct msghdr msg;
4674 :
4675 265626 : if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4676 : /*
4677 : * we're not supposed to do any io
4678 : * just flush all pending stuff.
4679 : */
4680 0 : xconn->smb2.send_queue_len--;
4681 0 : DLIST_REMOVE(xconn->smb2.send_queue, e);
4682 :
4683 0 : talloc_free(e->mem_ctx);
4684 176130 : continue;
4685 : }
4686 :
4687 265626 : if (e->sendfile_header != NULL) {
4688 0 : size_t size = 0;
4689 0 : size_t i = 0;
4690 : uint8_t *buf;
4691 :
4692 0 : status = NT_STATUS_INTERNAL_ERROR;
4693 :
4694 0 : for (i=0; i < e->count; i++) {
4695 0 : size += e->vector[i].iov_len;
4696 : }
4697 :
4698 0 : if (size <= e->sendfile_header->length) {
4699 0 : buf = e->sendfile_header->data;
4700 : } else {
4701 0 : buf = talloc_array(e->mem_ctx, uint8_t, size);
4702 0 : if (buf == NULL) {
4703 55574 : return NT_STATUS_NO_MEMORY;
4704 : }
4705 : }
4706 :
4707 0 : size = 0;
4708 0 : for (i=0; i < e->count; i++) {
4709 0 : memcpy(buf+size,
4710 0 : e->vector[i].iov_base,
4711 0 : e->vector[i].iov_len);
4712 0 : size += e->vector[i].iov_len;
4713 : }
4714 :
4715 0 : e->sendfile_header->data = buf;
4716 0 : e->sendfile_header->length = size;
4717 0 : e->sendfile_status = &status;
4718 0 : e->count = 0;
4719 :
4720 0 : xconn->smb2.send_queue_len--;
4721 0 : DLIST_REMOVE(xconn->smb2.send_queue, e);
4722 :
4723 0 : size += e->sendfile_body_size;
4724 :
4725 : /*
4726 : * This triggers the sendfile path via
4727 : * the destructor.
4728 : */
4729 0 : talloc_free(e->mem_ctx);
4730 :
4731 0 : if (!NT_STATUS_IS_OK(status)) {
4732 0 : smbXsrv_connection_disconnect_transport(xconn,
4733 : status);
4734 0 : return status;
4735 : }
4736 0 : xconn->ack.unacked_bytes += size;
4737 0 : continue;
4738 : }
4739 :
4740 265626 : msg = (struct msghdr) {
4741 265626 : .msg_iov = e->vector,
4742 265626 : .msg_iovlen = e->count,
4743 : };
4744 :
4745 265626 : ret = sendmsg(xconn->transport.sock, &msg, 0);
4746 265626 : if (ret == 0) {
4747 : /* propagate end of file */
4748 0 : return NT_STATUS_INTERNAL_ERROR;
4749 : }
4750 265626 : err = socket_error_from_errno(ret, errno, &retry);
4751 265626 : if (retry) {
4752 : /* retry later */
4753 0 : TEVENT_FD_WRITEABLE(xconn->transport.fde);
4754 0 : return NT_STATUS_OK;
4755 : }
4756 265626 : if (err != 0) {
4757 2492 : status = map_nt_error_from_unix_common(err);
4758 2492 : smbXsrv_connection_disconnect_transport(xconn,
4759 : status);
4760 2492 : return status;
4761 : }
4762 :
4763 263134 : xconn->ack.unacked_bytes += ret;
4764 :
4765 263134 : ok = iov_advance(&e->vector, &e->count, ret);
4766 263134 : if (!ok) {
4767 0 : return NT_STATUS_INTERNAL_ERROR;
4768 : }
4769 :
4770 263134 : if (e->count > 0) {
4771 : /* we have more to write */
4772 87004 : TEVENT_FD_WRITEABLE(xconn->transport.fde);
4773 87004 : return NT_STATUS_OK;
4774 : }
4775 :
4776 176130 : xconn->smb2.send_queue_len--;
4777 176130 : DLIST_REMOVE(xconn->smb2.send_queue, e);
4778 :
4779 176130 : if (e->ack.req == NULL) {
4780 176130 : talloc_free(e->mem_ctx);
4781 176130 : continue;
4782 : }
4783 :
4784 0 : e->ack.required_acked_bytes = xconn->ack.unacked_bytes;
4785 0 : DLIST_ADD_END(xconn->ack.queue, e);
4786 : }
4787 :
4788 : /*
4789 : * Restart reads if we were blocked on
4790 : * draining the send queue.
4791 : */
4792 :
4793 176117 : status = smbd_smb2_request_next_incoming(xconn);
4794 176117 : if (!NT_STATUS_IS_OK(status)) {
4795 0 : return status;
4796 : }
4797 :
4798 176117 : return NT_STATUS_OK;
4799 : }
4800 :
4801 343086 : static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
4802 : uint16_t fde_flags)
4803 : {
4804 343086 : struct smbd_server_connection *sconn = xconn->client->sconn;
4805 343086 : struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4806 343086 : struct smbd_smb2_request *req = NULL;
4807 343086 : size_t min_recvfile_size = UINT32_MAX;
4808 : int ret;
4809 : int err;
4810 : bool retry;
4811 : NTSTATUS status;
4812 : NTTIME now;
4813 : struct msghdr msg;
4814 :
4815 343086 : if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4816 : /*
4817 : * we're not supposed to do any io
4818 : */
4819 0 : TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4820 0 : TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4821 0 : return NT_STATUS_OK;
4822 : }
4823 :
4824 343086 : if (fde_flags & TEVENT_FD_WRITE) {
4825 92685 : status = smbd_smb2_flush_send_queue(xconn);
4826 92685 : if (!NT_STATUS_IS_OK(status)) {
4827 0 : return status;
4828 : }
4829 : }
4830 :
4831 343086 : if (!(fde_flags & TEVENT_FD_READ)) {
4832 92487 : return NT_STATUS_OK;
4833 : }
4834 :
4835 250599 : if (state->req == NULL) {
4836 0 : TEVENT_FD_NOT_READABLE(xconn->transport.fde);
4837 0 : return NT_STATUS_OK;
4838 : }
4839 :
4840 285985 : again:
4841 402591 : if (!state->hdr.done) {
4842 154492 : state->hdr.done = true;
4843 :
4844 154492 : state->vector.iov_base = (void *)state->hdr.nbt;
4845 154492 : state->vector.iov_len = NBT_HDR_SIZE;
4846 : }
4847 :
4848 402591 : msg = (struct msghdr) {
4849 402591 : .msg_iov = &state->vector,
4850 : .msg_iovlen = 1,
4851 : };
4852 :
4853 402591 : ret = recvmsg(xconn->transport.sock, &msg, 0);
4854 402591 : if (ret == 0) {
4855 : /* propagate end of file */
4856 2221 : status = NT_STATUS_END_OF_FILE;
4857 2221 : smbXsrv_connection_disconnect_transport(xconn,
4858 : status);
4859 2221 : return status;
4860 : }
4861 400370 : err = socket_error_from_errno(ret, errno, &retry);
4862 400370 : if (retry) {
4863 : /* retry later */
4864 0 : TEVENT_FD_READABLE(xconn->transport.fde);
4865 0 : return NT_STATUS_OK;
4866 : }
4867 400370 : if (err != 0) {
4868 279 : status = map_nt_error_from_unix_common(err);
4869 279 : smbXsrv_connection_disconnect_transport(xconn,
4870 : status);
4871 279 : return status;
4872 : }
4873 :
4874 400091 : if (ret < state->vector.iov_len) {
4875 : uint8_t *base;
4876 96107 : base = (uint8_t *)state->vector.iov_base;
4877 96107 : base += ret;
4878 96107 : state->vector.iov_base = (void *)base;
4879 96107 : state->vector.iov_len -= ret;
4880 : /* we have more to read */
4881 96107 : TEVENT_FD_READABLE(xconn->transport.fde);
4882 96107 : return NT_STATUS_OK;
4883 : }
4884 :
4885 303984 : if (state->pktlen > 0) {
4886 151992 : if (state->doing_receivefile && !is_smb2_recvfile_write(state)) {
4887 : /*
4888 : * Not a possible receivefile write.
4889 : * Read the rest of the data.
4890 : */
4891 0 : state->doing_receivefile = false;
4892 :
4893 0 : state->pktbuf = talloc_realloc(state->req,
4894 : state->pktbuf,
4895 : uint8_t,
4896 : state->pktfull);
4897 0 : if (state->pktbuf == NULL) {
4898 0 : return NT_STATUS_NO_MEMORY;
4899 : }
4900 :
4901 0 : state->vector.iov_base = (void *)(state->pktbuf +
4902 0 : state->pktlen);
4903 0 : state->vector.iov_len = (state->pktfull -
4904 0 : state->pktlen);
4905 :
4906 0 : state->pktlen = state->pktfull;
4907 0 : goto again;
4908 : }
4909 :
4910 : /*
4911 : * Either this is a receivefile write so we've
4912 : * done a short read, or if not we have all the data.
4913 : */
4914 151992 : goto got_full;
4915 : }
4916 :
4917 : /*
4918 : * Now we analyze the NBT header
4919 : */
4920 151992 : if (state->hdr.nbt[0] != 0x00) {
4921 0 : state->min_recv_size = 0;
4922 : }
4923 151992 : state->pktfull = smb2_len(state->hdr.nbt);
4924 151992 : if (state->pktfull == 0) {
4925 0 : goto got_full;
4926 : }
4927 :
4928 151992 : if (state->min_recv_size != 0) {
4929 0 : min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4930 0 : min_recvfile_size += state->min_recv_size;
4931 : }
4932 :
4933 151992 : if (state->pktfull > min_recvfile_size) {
4934 : /*
4935 : * Might be a receivefile write. Read the SMB2 HEADER +
4936 : * SMB2_WRITE header first. Set 'doing_receivefile'
4937 : * as we're *attempting* receivefile write. If this
4938 : * turns out not to be a SMB2_WRITE request or otherwise
4939 : * not suitable then we'll just read the rest of the data
4940 : * the next time this function is called.
4941 : */
4942 0 : state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
4943 0 : state->doing_receivefile = true;
4944 : } else {
4945 151992 : state->pktlen = state->pktfull;
4946 : }
4947 :
4948 151992 : state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
4949 151992 : if (state->pktbuf == NULL) {
4950 0 : return NT_STATUS_NO_MEMORY;
4951 : }
4952 :
4953 151992 : state->vector.iov_base = (void *)state->pktbuf;
4954 151992 : state->vector.iov_len = state->pktlen;
4955 :
4956 151992 : goto again;
4957 :
4958 151992 : got_full:
4959 :
4960 151992 : if (state->hdr.nbt[0] != 0x00) {
4961 0 : DEBUG(1,("ignore NBT[0x%02X] msg\n",
4962 : state->hdr.nbt[0]));
4963 :
4964 0 : req = state->req;
4965 0 : ZERO_STRUCTP(state);
4966 0 : state->req = req;
4967 0 : state->min_recv_size = lp_min_receive_file_size();
4968 0 : req = NULL;
4969 0 : goto again;
4970 : }
4971 :
4972 151992 : req = state->req;
4973 151992 : state->req = NULL;
4974 :
4975 151992 : req->request_time = timeval_current();
4976 151992 : now = timeval_to_nttime(&req->request_time);
4977 :
4978 151992 : status = smbd_smb2_inbuf_parse_compound(xconn,
4979 : now,
4980 : state->pktbuf,
4981 : state->pktlen,
4982 : req,
4983 : &req->in.vector,
4984 : &req->in.vector_count);
4985 151992 : if (!NT_STATUS_IS_OK(status)) {
4986 0 : return status;
4987 : }
4988 :
4989 151992 : if (state->doing_receivefile) {
4990 0 : req->smb1req = talloc_zero(req, struct smb_request);
4991 0 : if (req->smb1req == NULL) {
4992 0 : return NT_STATUS_NO_MEMORY;
4993 : }
4994 0 : req->smb1req->unread_bytes = state->pktfull - state->pktlen;
4995 : }
4996 :
4997 151992 : ZERO_STRUCTP(state);
4998 :
4999 151992 : req->current_idx = 1;
5000 :
5001 151992 : DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
5002 : req->current_idx, req->in.vector_count));
5003 :
5004 151992 : status = smbd_smb2_request_validate(req);
5005 151992 : if (!NT_STATUS_IS_OK(status)) {
5006 0 : return status;
5007 : }
5008 :
5009 151992 : status = smbd_smb2_request_setup_out(req);
5010 151992 : if (!NT_STATUS_IS_OK(status)) {
5011 0 : return status;
5012 : }
5013 :
5014 151992 : status = smbd_smb2_request_dispatch(req);
5015 149500 : if (!NT_STATUS_IS_OK(status)) {
5016 0 : return status;
5017 : }
5018 :
5019 149500 : sconn->num_requests++;
5020 :
5021 : /* The timeout_processing function isn't run nearly
5022 : often enough to implement 'max log size' without
5023 : overrunning the size of the file by many megabytes.
5024 : This is especially true if we are running at debug
5025 : level 10. Checking every 50 SMB2s is a nice
5026 : tradeoff of performance vs log file size overrun. */
5027 :
5028 151172 : if ((sconn->num_requests % 50) == 0 &&
5029 1672 : need_to_check_log_size()) {
5030 354 : change_to_root_user();
5031 354 : check_log_size();
5032 : }
5033 :
5034 149500 : status = smbd_smb2_request_next_incoming(xconn);
5035 149500 : if (!NT_STATUS_IS_OK(status)) {
5036 0 : return status;
5037 : }
5038 :
5039 149500 : return NT_STATUS_OK;
5040 : }
5041 :
5042 343086 : static void smbd_smb2_connection_handler(struct tevent_context *ev,
5043 : struct tevent_fd *fde,
5044 : uint16_t flags,
5045 : void *private_data)
5046 : {
5047 235868 : struct smbXsrv_connection *xconn =
5048 107218 : talloc_get_type_abort(private_data,
5049 : struct smbXsrv_connection);
5050 : NTSTATUS status;
5051 :
5052 343086 : status = smbd_smb2_io_handler(xconn, flags);
5053 340594 : if (!NT_STATUS_IS_OK(status)) {
5054 2500 : smbd_server_connection_terminate(xconn, nt_errstr(status));
5055 50 : return;
5056 : }
5057 : }
|