1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2019 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 #include <sys/atomic.h> 27 #include <sys/synch.h> 28 #include <sys/types.h> 29 #include <sys/sdt.h> 30 #include <sys/random.h> 31 #include <smbsrv/netbios.h> 32 #include <smbsrv/smb2_kproto.h> 33 #include <smbsrv/string.h> 34 #include <netinet/tcp.h> 35 36 /* How many iovec we'll handle as a local array (no allocation) */ 37 #define SMB_LOCAL_IOV_MAX 16 38 39 #define SMB_NEW_KID() atomic_inc_64_nv(&smb_kids) 40 41 static volatile uint64_t smb_kids; 42 43 /* 44 * We track the keepalive in minutes, but this constant 45 * specifies it in seconds, so convert to minutes. 46 */ 47 uint32_t smb_keep_alive = SMB_PI_KEEP_ALIVE_MIN / 60; 48 49 /* 50 * This is the maximum time we'll allow a "session" to exist with no 51 * authenticated smb_user_t objects on it. This allows a client to 52 * logoff their "one and only" user session and then logon as some 53 * different user. (There are some tests that do that.) The same 54 * timeout mechanism also reduces the impact of clients that might 55 * open TCP connections but never authenticate. 56 */ 57 int smb_session_auth_tmo = 30; /* sec. */ 58 59 /* 60 * There are many smbtorture test cases that send 61 * racing requests, and where the tests fail if we 62 * don't execute them in exactly the order sent. 63 * These are test bugs. The protocol makes no 64 * guarantees about execution order of requests 65 * that are concurrently active. 66 * 67 * Nonetheless, smbtorture has many useful tests, 68 * so we have this work-around we can enable to 69 * basically force sequential execution. When 70 * enabled, insert a delay after each request is 71 * issued a taskq job. Enable this with mdb by 72 * setting smb_reader_delay to 10. Don't make it 73 * more than 500 or so or the server will appear 74 * to be so slow that tests may time out. 75 */ 76 int smb_reader_delay = 0; /* mSec. */ 77 78 static int smbsr_newrq_initial(smb_request_t *); 79 80 static void smb_session_cancel(smb_session_t *); 81 static int smb_session_reader(smb_session_t *); 82 static int smb_session_xprt_puthdr(smb_session_t *, 83 uint8_t msg_type, uint32_t msg_len, 84 uint8_t *dst, size_t dstlen); 85 static void smb_session_disconnect_trees(smb_session_t *); 86 static void smb_request_init_command_mbuf(smb_request_t *sr); 87 static void smb_session_genkey(smb_session_t *); 88 89 /* 90 * This (legacy) code is in support of an "idle timeout" feature, 91 * which is apparently incomplete. To complete it, we should: 92 * when the keep_alive timer expires, check whether the client 93 * has any open files, and if not then kill their session. 94 * Right now the timers are there, but nothing happens when 95 * a timer expires. 96 * 97 * Todo: complete logic to kill idle sessions. 98 * 99 * Only called when sv_cfg.skc_keepalive != 0 100 */ 101 void 102 smb_session_timers(smb_server_t *sv) 103 { 104 smb_session_t *session; 105 smb_llist_t *ll; 106 107 ll = &sv->sv_session_list; 108 smb_llist_enter(ll, RW_READER); 109 session = smb_llist_head(ll); 110 while (session != NULL) { 111 /* 112 * Walk through the table and decrement each keep_alive 113 * timer that has not timed out yet. (keepalive > 0) 114 */ 115 SMB_SESSION_VALID(session); 116 if (session->keep_alive && 117 (session->keep_alive != (uint32_t)-1)) 118 session->keep_alive--; 119 120 session = smb_llist_next(ll, session); 121 } 122 smb_llist_exit(ll); 123 } 124 125 /* 126 * Send a session message - supports SMB-over-NBT and SMB-over-TCP. 127 * If an mbuf chain is provided (optional), it will be freed and 128 * set to NULL -- unconditionally! (error or not) 129 * 130 * Builds a I/O vector (uio/iov) to do the send from mbufs, plus one 131 * segment for the 4-byte NBT header. 132 */ 133 int 134 smb_session_send(smb_session_t *session, uint8_t nbt_type, mbuf_chain_t *mbc) 135 { 136 uio_t uio; 137 iovec_t local_iov[SMB_LOCAL_IOV_MAX]; 138 iovec_t *alloc_iov = NULL; 139 int alloc_sz = 0; 140 mbuf_t *m; 141 uint8_t nbt_hdr[NETBIOS_HDR_SZ]; 142 uint32_t nbt_len; 143 int i, nseg; 144 int rc; 145 146 switch (session->s_state) { 147 case SMB_SESSION_STATE_DISCONNECTED: 148 case SMB_SESSION_STATE_TERMINATED: 149 rc = ENOTCONN; 150 goto out; 151 default: 152 break; 153 } 154 155 /* 156 * Setup the IOV. First, count the number of IOV segments 157 * (plus one for the NBT header) and decide whether we 158 * need to allocate an iovec or can use local_iov; 159 */ 160 bzero(&uio, sizeof (uio)); 161 nseg = 1; 162 m = (mbc != NULL) ? mbc->chain : NULL; 163 while (m != NULL) { 164 nseg++; 165 m = m->m_next; 166 } 167 if (nseg <= SMB_LOCAL_IOV_MAX) { 168 uio.uio_iov = local_iov; 169 } else { 170 alloc_sz = nseg * sizeof (iovec_t); 171 alloc_iov = kmem_alloc(alloc_sz, KM_SLEEP); 172 uio.uio_iov = alloc_iov; 173 } 174 uio.uio_iovcnt = nseg; 175 uio.uio_segflg = UIO_SYSSPACE; 176 uio.uio_extflg = UIO_COPY_DEFAULT; 177 178 /* 179 * Build the iov list, meanwhile computing the length of 180 * the SMB payload (to put in the NBT header). 181 */ 182 uio.uio_iov[0].iov_base = (void *)nbt_hdr; 183 uio.uio_iov[0].iov_len = sizeof (nbt_hdr); 184 i = 1; 185 nbt_len = 0; 186 m = (mbc != NULL) ? mbc->chain : NULL; 187 while (m != NULL) { 188 uio.uio_iov[i].iov_base = m->m_data; 189 uio.uio_iov[i++].iov_len = m->m_len; 190 nbt_len += m->m_len; 191 m = m->m_next; 192 } 193 ASSERT3S(i, ==, nseg); 194 195 /* 196 * Set the NBT header, set uio_resid 197 */ 198 uio.uio_resid = nbt_len + NETBIOS_HDR_SZ; 199 rc = smb_session_xprt_puthdr(session, nbt_type, nbt_len, 200 nbt_hdr, NETBIOS_HDR_SZ); 201 if (rc != 0) 202 goto out; 203 204 smb_server_add_txb(session->s_server, (int64_t)uio.uio_resid); 205 rc = smb_net_send_uio(session, &uio); 206 207 out: 208 if (alloc_iov != NULL) 209 kmem_free(alloc_iov, alloc_sz); 210 if ((mbc != NULL) && (mbc->chain != NULL)) { 211 m_freem(mbc->chain); 212 mbc->chain = NULL; 213 mbc->flags = 0; 214 } 215 return (rc); 216 } 217 218 /* 219 * Read, process and respond to a NetBIOS session request. 220 * 221 * A NetBIOS session must be established for SMB-over-NetBIOS. Validate 222 * the calling and called name format and save the client NetBIOS name, 223 * which is used when a NetBIOS session is established to check for and 224 * cleanup leftover state from a previous session. 225 * 226 * Session requests are not valid for SMB-over-TCP, which is unfortunate 227 * because without the client name leftover state cannot be cleaned up 228 * if the client is behind a NAT server. 229 */ 230 static int 231 smb_netbios_session_request(struct smb_session *session) 232 { 233 int rc; 234 char *calling_name; 235 char *called_name; 236 char client_name[NETBIOS_NAME_SZ]; 237 struct mbuf_chain mbc; 238 char *names = NULL; 239 smb_wchar_t *wbuf = NULL; 240 smb_xprt_t hdr; 241 char *p; 242 int rc1, rc2; 243 244 session->keep_alive = smb_keep_alive; 245 246 if ((rc = smb_session_xprt_gethdr(session, &hdr)) != 0) 247 return (rc); 248 249 DTRACE_PROBE2(receive__session__req__xprthdr, struct session *, session, 250 smb_xprt_t *, &hdr); 251 252 if ((hdr.xh_type != SESSION_REQUEST) || 253 (hdr.xh_length != NETBIOS_SESSION_REQUEST_DATA_LENGTH)) { 254 DTRACE_PROBE1(receive__session__req__failed, 255 struct session *, session); 256 return (EINVAL); 257 } 258 259 names = kmem_alloc(hdr.xh_length, KM_SLEEP); 260 261 if ((rc = smb_sorecv(session->sock, names, hdr.xh_length)) != 0) { 262 kmem_free(names, hdr.xh_length); 263 DTRACE_PROBE1(receive__session__req__failed, 264 struct session *, session); 265 return (rc); 266 } 267 268 DTRACE_PROBE3(receive__session__req__data, struct session *, session, 269 char *, names, uint32_t, hdr.xh_length); 270 271 called_name = &names[0]; 272 calling_name = &names[NETBIOS_ENCODED_NAME_SZ + 2]; 273 274 rc1 = netbios_name_isvalid(called_name, 0); 275 rc2 = netbios_name_isvalid(calling_name, client_name); 276 277 if (rc1 == 0 || rc2 == 0) { 278 279 DTRACE_PROBE3(receive__invalid__session__req, 280 struct session *, session, char *, names, 281 uint32_t, hdr.xh_length); 282 283 kmem_free(names, hdr.xh_length); 284 MBC_INIT(&mbc, MAX_DATAGRAM_LENGTH); 285 (void) smb_mbc_encodef(&mbc, "b", 286 DATAGRAM_INVALID_SOURCE_NAME_FORMAT); 287 (void) smb_session_send(session, NEGATIVE_SESSION_RESPONSE, 288 &mbc); 289 return (EINVAL); 290 } 291 292 DTRACE_PROBE3(receive__session__req__calling__decoded, 293 struct session *, session, 294 char *, calling_name, char *, client_name); 295 296 /* 297 * The client NetBIOS name is in oem codepage format. 298 * We need to convert it to unicode and store it in 299 * multi-byte format. We also need to strip off any 300 * spaces added as part of the NetBIOS name encoding. 301 */ 302 wbuf = kmem_alloc((SMB_PI_MAX_HOST * sizeof (smb_wchar_t)), KM_SLEEP); 303 (void) oemtoucs(wbuf, client_name, SMB_PI_MAX_HOST, OEM_CPG_850); 304 (void) smb_wcstombs(session->workstation, wbuf, SMB_PI_MAX_HOST); 305 kmem_free(wbuf, (SMB_PI_MAX_HOST * sizeof (smb_wchar_t))); 306 307 if ((p = strchr(session->workstation, ' ')) != 0) 308 *p = '\0'; 309 310 kmem_free(names, hdr.xh_length); 311 return (smb_session_send(session, POSITIVE_SESSION_RESPONSE, NULL)); 312 } 313 314 /* 315 * Read 4-byte header from the session socket and build an in-memory 316 * session transport header. See smb_xprt_t definition for header 317 * format information. 318 * 319 * Direct hosted NetBIOS-less SMB (SMB-over-TCP) uses port 445. The 320 * first byte of the four-byte header must be 0 and the next three 321 * bytes contain the length of the remaining data. 322 */ 323 int 324 smb_session_xprt_gethdr(smb_session_t *session, smb_xprt_t *ret_hdr) 325 { 326 int rc; 327 unsigned char buf[NETBIOS_HDR_SZ]; 328 329 if ((rc = smb_sorecv(session->sock, buf, NETBIOS_HDR_SZ)) != 0) 330 return (rc); 331 332 switch (session->s_local_port) { 333 case IPPORT_NETBIOS_SSN: 334 ret_hdr->xh_type = buf[0]; 335 ret_hdr->xh_length = (((uint32_t)buf[1] & 1) << 16) | 336 ((uint32_t)buf[2] << 8) | 337 ((uint32_t)buf[3]); 338 break; 339 340 case IPPORT_SMB: 341 ret_hdr->xh_type = buf[0]; 342 343 if (ret_hdr->xh_type != 0) { 344 cmn_err(CE_WARN, "invalid NBT type (%u) from %s", 345 ret_hdr->xh_type, session->ip_addr_str); 346 return (EPROTO); 347 } 348 349 ret_hdr->xh_length = ((uint32_t)buf[1] << 16) | 350 ((uint32_t)buf[2] << 8) | 351 ((uint32_t)buf[3]); 352 break; 353 354 default: 355 cmn_err(CE_WARN, "invalid port %u", session->s_local_port); 356 return (EPROTO); 357 } 358 359 return (0); 360 } 361 362 /* 363 * Encode a transport session packet header into a 4-byte buffer. 364 */ 365 static int 366 smb_session_xprt_puthdr(smb_session_t *session, 367 uint8_t msg_type, uint32_t msg_length, 368 uint8_t *buf, size_t buflen) 369 { 370 if (buf == NULL || buflen < NETBIOS_HDR_SZ) { 371 return (-1); 372 } 373 374 switch (session->s_local_port) { 375 case IPPORT_NETBIOS_SSN: 376 /* Per RFC 1001, 1002: msg. len < 128KB */ 377 if (msg_length >= (1 << 17)) 378 return (-1); 379 buf[0] = msg_type; 380 buf[1] = ((msg_length >> 16) & 1); 381 buf[2] = (msg_length >> 8) & 0xff; 382 buf[3] = msg_length & 0xff; 383 break; 384 385 case IPPORT_SMB: 386 /* 387 * SMB over TCP is like NetBIOS but the one byte 388 * message type is always zero, and the length 389 * part is three bytes. It could actually use 390 * longer messages, but this is conservative. 391 */ 392 if (msg_length >= (1 << 24)) 393 return (-1); 394 buf[0] = msg_type; 395 buf[1] = (msg_length >> 16) & 0xff; 396 buf[2] = (msg_length >> 8) & 0xff; 397 buf[3] = msg_length & 0xff; 398 break; 399 400 default: 401 cmn_err(CE_WARN, "invalid port %u", session->s_local_port); 402 return (-1); 403 } 404 405 return (0); 406 } 407 408 static void 409 smb_request_init_command_mbuf(smb_request_t *sr) 410 { 411 412 /* 413 * Setup mbuf using the buffer we allocated. 414 */ 415 MBC_ATTACH_BUF(&sr->command, sr->sr_request_buf, sr->sr_req_length); 416 417 sr->command.flags = 0; 418 sr->command.shadow_of = NULL; 419 } 420 421 /* 422 * smb_request_cancel 423 * 424 * Handle a cancel for a request properly depending on the current request 425 * state. 426 */ 427 void 428 smb_request_cancel(smb_request_t *sr) 429 { 430 void (*cancel_method)(smb_request_t *) = NULL; 431 432 mutex_enter(&sr->sr_mutex); 433 switch (sr->sr_state) { 434 435 case SMB_REQ_STATE_INITIALIZING: 436 case SMB_REQ_STATE_SUBMITTED: 437 case SMB_REQ_STATE_ACTIVE: 438 case SMB_REQ_STATE_CLEANED_UP: 439 sr->sr_state = SMB_REQ_STATE_CANCELLED; 440 break; 441 442 case SMB_REQ_STATE_WAITING_AUTH: 443 case SMB_REQ_STATE_WAITING_FCN1: 444 case SMB_REQ_STATE_WAITING_LOCK: 445 case SMB_REQ_STATE_WAITING_PIPE: 446 /* 447 * These are states that have a cancel_method. 448 * Make the state change now, to ensure that 449 * we call cancel_method exactly once. Do the 450 * method call below, after we drop sr_mutex. 451 * When the cancelled request thread resumes, 452 * it should re-take sr_mutex and set sr_state 453 * to CANCELLED, then return STATUS_CANCELLED. 454 */ 455 sr->sr_state = SMB_REQ_STATE_CANCEL_PENDING; 456 cancel_method = sr->cancel_method; 457 VERIFY(cancel_method != NULL); 458 break; 459 460 case SMB_REQ_STATE_WAITING_FCN2: 461 case SMB_REQ_STATE_COMPLETED: 462 case SMB_REQ_STATE_CANCEL_PENDING: 463 case SMB_REQ_STATE_CANCELLED: 464 /* 465 * No action required for these states since the request 466 * is completing. 467 */ 468 break; 469 470 case SMB_REQ_STATE_FREE: 471 default: 472 SMB_PANIC(); 473 } 474 mutex_exit(&sr->sr_mutex); 475 476 if (cancel_method != NULL) { 477 cancel_method(sr); 478 } 479 } 480 481 /* 482 * smb_session_receiver 483 * 484 * Receives request from the network and dispatches them to a worker. 485 * 486 * When we receive a disconnect here, it _could_ be due to the server 487 * having initiated disconnect, in which case the session state will be 488 * SMB_SESSION_STATE_TERMINATED and we want to keep that state so later 489 * tear-down logic will know which side initiated. 490 */ 491 void 492 smb_session_receiver(smb_session_t *session) 493 { 494 int rc = 0; 495 timeout_id_t tmo = NULL; 496 497 SMB_SESSION_VALID(session); 498 499 session->s_thread = curthread; 500 501 if (session->s_local_port == IPPORT_NETBIOS_SSN) { 502 rc = smb_netbios_session_request(session); 503 if (rc != 0) { 504 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 505 if (session->s_state != SMB_SESSION_STATE_TERMINATED) 506 session->s_state = 507 SMB_SESSION_STATE_DISCONNECTED; 508 smb_rwx_rwexit(&session->s_lock); 509 return; 510 } 511 } 512 513 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 514 session->s_state = SMB_SESSION_STATE_ESTABLISHED; 515 session->s_auth_tmo = timeout((tmo_func_t)smb_session_disconnect, 516 session, SEC_TO_TICK(smb_session_auth_tmo)); 517 smb_rwx_rwexit(&session->s_lock); 518 519 (void) smb_session_reader(session); 520 521 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 522 if (session->s_state != SMB_SESSION_STATE_TERMINATED) 523 session->s_state = SMB_SESSION_STATE_DISCONNECTED; 524 tmo = session->s_auth_tmo; 525 session->s_auth_tmo = NULL; 526 smb_rwx_rwexit(&session->s_lock); 527 528 /* Timeout callback takes s_lock. See untimeout(9f) */ 529 if (tmo != NULL) 530 (void) untimeout(tmo); 531 532 smb_soshutdown(session->sock); 533 534 DTRACE_PROBE2(session__drop, struct session *, session, int, rc); 535 536 smb_session_cancel(session); 537 /* 538 * At this point everything related to the session should have been 539 * cleaned up and we expect that nothing will attempt to use the 540 * socket. 541 */ 542 } 543 544 /* 545 * smb_session_disconnect 546 * 547 * Server-initiated disconnect (i.e. server shutdown) 548 */ 549 void 550 smb_session_disconnect(smb_session_t *session) 551 { 552 SMB_SESSION_VALID(session); 553 554 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 555 switch (session->s_state) { 556 case SMB_SESSION_STATE_INITIALIZED: 557 case SMB_SESSION_STATE_CONNECTED: 558 case SMB_SESSION_STATE_ESTABLISHED: 559 case SMB_SESSION_STATE_NEGOTIATED: 560 smb_soshutdown(session->sock); 561 session->s_state = SMB_SESSION_STATE_TERMINATED; 562 break; 563 case SMB_SESSION_STATE_DISCONNECTED: 564 case SMB_SESSION_STATE_TERMINATED: 565 break; 566 } 567 smb_rwx_rwexit(&session->s_lock); 568 } 569 570 /* 571 * Read and process SMB requests. 572 * 573 * Returns: 574 * 0 Success 575 * 1 Unable to read transport header 576 * 2 Invalid transport header type 577 * 3 Invalid SMB length (too small) 578 * 4 Unable to read SMB header 579 * 5 Invalid SMB header (bad magic number) 580 * 6 Unable to read SMB data 581 */ 582 static int 583 smb_session_reader(smb_session_t *session) 584 { 585 smb_server_t *sv; 586 smb_request_t *sr = NULL; 587 smb_xprt_t hdr; 588 uint8_t *req_buf; 589 uint32_t resid; 590 int rc; 591 592 sv = session->s_server; 593 594 for (;;) { 595 596 rc = smb_session_xprt_gethdr(session, &hdr); 597 if (rc) 598 return (rc); 599 600 DTRACE_PROBE2(session__receive__xprthdr, session_t *, session, 601 smb_xprt_t *, &hdr); 602 603 if (hdr.xh_type != SESSION_MESSAGE) { 604 /* 605 * Anything other than SESSION_MESSAGE or 606 * SESSION_KEEP_ALIVE is an error. A SESSION_REQUEST 607 * may indicate a new session request but we need to 608 * close this session and we can treat it as an error 609 * here. 610 */ 611 if (hdr.xh_type == SESSION_KEEP_ALIVE) { 612 session->keep_alive = smb_keep_alive; 613 continue; 614 } 615 return (EPROTO); 616 } 617 618 if (hdr.xh_length == 0) { 619 /* zero length is another form of keep alive */ 620 session->keep_alive = smb_keep_alive; 621 continue; 622 } 623 624 if (hdr.xh_length < SMB_HEADER_LEN) 625 return (EPROTO); 626 if (hdr.xh_length > session->cmd_max_bytes) 627 return (EPROTO); 628 629 session->keep_alive = smb_keep_alive; 630 631 /* 632 * Allocate a request context, read the whole message. 633 * If the request alloc fails, we've disconnected 634 * and won't be able to send the reply anyway, so bail now. 635 */ 636 if ((sr = smb_request_alloc(session, hdr.xh_length)) == NULL) 637 break; 638 639 req_buf = (uint8_t *)sr->sr_request_buf; 640 resid = hdr.xh_length; 641 642 rc = smb_sorecv(session->sock, req_buf, resid); 643 if (rc) { 644 smb_request_free(sr); 645 break; 646 } 647 648 /* accounting: received bytes */ 649 smb_server_add_rxb(sv, 650 (int64_t)(hdr.xh_length + NETBIOS_HDR_SZ)); 651 652 /* 653 * Initialize command MBC to represent the received data. 654 */ 655 smb_request_init_command_mbuf(sr); 656 657 DTRACE_PROBE1(session__receive__smb, smb_request_t *, sr); 658 659 rc = session->newrq_func(sr); 660 sr = NULL; /* enqueued or freed */ 661 if (rc != 0) 662 break; 663 664 /* See notes where this is defined (above). */ 665 if (smb_reader_delay) { 666 delay(MSEC_TO_TICK(smb_reader_delay)); 667 } 668 } 669 return (rc); 670 } 671 672 /* 673 * This is the initial handler for new smb requests, called from 674 * from smb_session_reader when we have not yet seen any requests. 675 * The first SMB request must be "negotiate", which determines 676 * which protocol and dialect we'll be using. That's the ONLY 677 * request type handled here, because with all later requests, 678 * we know the protocol and handle those with either the SMB1 or 679 * SMB2 handlers: smb1sr_post() or smb2sr_post(). 680 * Those do NOT allow SMB negotiate, because that's only allowed 681 * as the first request on new session. 682 * 683 * This and other "post a request" handlers must either enqueue 684 * the new request for the session taskq, or smb_request_free it 685 * (in case we've decided to drop this connection). In this 686 * (special) new request handler, we always free the request. 687 * 688 * Return value is 0 for success, and anything else will 689 * terminate the reader thread (drop the connection). 690 */ 691 static int 692 smbsr_newrq_initial(smb_request_t *sr) 693 { 694 uint32_t magic; 695 int rc = EPROTO; 696 697 mutex_enter(&sr->sr_mutex); 698 sr->sr_state = SMB_REQ_STATE_ACTIVE; 699 mutex_exit(&sr->sr_mutex); 700 701 magic = SMB_READ_PROTOCOL(sr->sr_request_buf); 702 if (magic == SMB_PROTOCOL_MAGIC) 703 rc = smb1_newrq_negotiate(sr); 704 if (magic == SMB2_PROTOCOL_MAGIC) 705 rc = smb2_newrq_negotiate(sr); 706 707 mutex_enter(&sr->sr_mutex); 708 sr->sr_state = SMB_REQ_STATE_COMPLETED; 709 mutex_exit(&sr->sr_mutex); 710 711 smb_request_free(sr); 712 return (rc); 713 } 714 715 /* 716 * Port will be IPPORT_NETBIOS_SSN or IPPORT_SMB. 717 */ 718 smb_session_t * 719 smb_session_create(ksocket_t new_so, uint16_t port, smb_server_t *sv, 720 int family) 721 { 722 struct sockaddr_in sin; 723 socklen_t slen; 724 struct sockaddr_in6 sin6; 725 smb_session_t *session; 726 int64_t now; 727 uint16_t rport; 728 729 session = kmem_cache_alloc(smb_cache_session, KM_SLEEP); 730 bzero(session, sizeof (smb_session_t)); 731 732 if (smb_idpool_constructor(&session->s_uid_pool)) { 733 kmem_cache_free(smb_cache_session, session); 734 return (NULL); 735 } 736 if (smb_idpool_constructor(&session->s_tid_pool)) { 737 smb_idpool_destructor(&session->s_uid_pool); 738 kmem_cache_free(smb_cache_session, session); 739 return (NULL); 740 } 741 742 now = ddi_get_lbolt64(); 743 744 session->s_server = sv; 745 session->s_kid = SMB_NEW_KID(); 746 session->s_state = SMB_SESSION_STATE_INITIALIZED; 747 session->native_os = NATIVE_OS_UNKNOWN; 748 session->opentime = now; 749 session->keep_alive = smb_keep_alive; 750 session->activity_timestamp = now; 751 smb_session_genkey(session); 752 753 mutex_init(&session->s_credits_mutex, NULL, MUTEX_DEFAULT, NULL); 754 755 smb_slist_constructor(&session->s_req_list, sizeof (smb_request_t), 756 offsetof(smb_request_t, sr_session_lnd)); 757 758 smb_llist_constructor(&session->s_user_list, sizeof (smb_user_t), 759 offsetof(smb_user_t, u_lnd)); 760 761 smb_llist_constructor(&session->s_tree_list, sizeof (smb_tree_t), 762 offsetof(smb_tree_t, t_lnd)); 763 764 smb_llist_constructor(&session->s_xa_list, sizeof (smb_xa_t), 765 offsetof(smb_xa_t, xa_lnd)); 766 767 smb_net_txl_constructor(&session->s_txlst); 768 769 smb_rwx_init(&session->s_lock); 770 771 session->s_srqueue = &sv->sv_srqueue; 772 smb_server_get_cfg(sv, &session->s_cfg); 773 774 if (new_so == NULL) { 775 /* 776 * This call is creating the special "server" session, 777 * used for kshare export, oplock breaks, CA import. 778 * CA import creates temporary trees on this session 779 * and those should never get map/unmap up-calls, so 780 * force the map/unmap flags zero on this session. 781 * Set a "modern" dialect for CA import too, so 782 * pathname parse doesn't do OS/2 stuff, etc. 783 */ 784 session->s_cfg.skc_execflags = 0; 785 session->dialect = session->s_cfg.skc_max_protocol; 786 } else { 787 if (family == AF_INET) { 788 slen = sizeof (sin); 789 (void) ksocket_getsockname(new_so, 790 (struct sockaddr *)&sin, &slen, CRED()); 791 bcopy(&sin.sin_addr, 792 &session->local_ipaddr.au_addr.au_ipv4, 793 sizeof (in_addr_t)); 794 slen = sizeof (sin); 795 (void) ksocket_getpeername(new_so, 796 (struct sockaddr *)&sin, &slen, CRED()); 797 bcopy(&sin.sin_addr, 798 &session->ipaddr.au_addr.au_ipv4, 799 sizeof (in_addr_t)); 800 rport = sin.sin_port; 801 } else { 802 slen = sizeof (sin6); 803 (void) ksocket_getsockname(new_so, 804 (struct sockaddr *)&sin6, &slen, CRED()); 805 bcopy(&sin6.sin6_addr, 806 &session->local_ipaddr.au_addr.au_ipv6, 807 sizeof (in6_addr_t)); 808 slen = sizeof (sin6); 809 (void) ksocket_getpeername(new_so, 810 (struct sockaddr *)&sin6, &slen, CRED()); 811 bcopy(&sin6.sin6_addr, 812 &session->ipaddr.au_addr.au_ipv6, 813 sizeof (in6_addr_t)); 814 rport = sin6.sin6_port; 815 } 816 session->ipaddr.a_family = family; 817 session->local_ipaddr.a_family = family; 818 session->s_local_port = port; 819 session->s_remote_port = ntohs(rport); 820 session->sock = new_so; 821 (void) smb_inet_ntop(&session->ipaddr, 822 session->ip_addr_str, INET6_ADDRSTRLEN); 823 if (port == IPPORT_NETBIOS_SSN) 824 smb_server_inc_nbt_sess(sv); 825 else 826 smb_server_inc_tcp_sess(sv); 827 } 828 829 /* 830 * The initial new request handler is special, 831 * and only accepts negotiation requests. 832 */ 833 session->newrq_func = smbsr_newrq_initial; 834 835 /* These may increase in SMB2 negotiate. */ 836 session->cmd_max_bytes = SMB_REQ_MAX_SIZE; 837 session->reply_max_bytes = SMB_REQ_MAX_SIZE; 838 839 session->s_magic = SMB_SESSION_MAGIC; 840 return (session); 841 } 842 843 void 844 smb_session_delete(smb_session_t *session) 845 { 846 847 ASSERT(session->s_magic == SMB_SESSION_MAGIC); 848 849 if (session->enc_mech != NULL) 850 smb3_encrypt_fini(session); 851 852 if (session->sign_fini != NULL) 853 session->sign_fini(session); 854 855 if (session->signing.mackey != NULL) { 856 kmem_free(session->signing.mackey, 857 session->signing.mackey_len); 858 } 859 860 session->s_magic = 0; 861 862 smb_rwx_destroy(&session->s_lock); 863 smb_net_txl_destructor(&session->s_txlst); 864 865 mutex_destroy(&session->s_credits_mutex); 866 867 smb_slist_destructor(&session->s_req_list); 868 smb_llist_destructor(&session->s_tree_list); 869 smb_llist_destructor(&session->s_user_list); 870 smb_llist_destructor(&session->s_xa_list); 871 872 ASSERT(session->s_tree_cnt == 0); 873 ASSERT(session->s_file_cnt == 0); 874 ASSERT(session->s_dir_cnt == 0); 875 876 smb_idpool_destructor(&session->s_tid_pool); 877 smb_idpool_destructor(&session->s_uid_pool); 878 if (session->sock != NULL) { 879 if (session->s_local_port == IPPORT_NETBIOS_SSN) 880 smb_server_dec_nbt_sess(session->s_server); 881 else 882 smb_server_dec_tcp_sess(session->s_server); 883 smb_sodestroy(session->sock); 884 } 885 kmem_cache_free(smb_cache_session, session); 886 } 887 888 static void 889 smb_session_cancel(smb_session_t *session) 890 { 891 smb_xa_t *xa, *nextxa; 892 893 /* All the request currently being treated must be canceled. */ 894 smb_session_cancel_requests(session, NULL, NULL); 895 896 /* 897 * We wait for the completion of all the requests associated with 898 * this session. 899 */ 900 smb_slist_wait_for_empty(&session->s_req_list); 901 902 /* 903 * Cleanup transact state objects 904 */ 905 xa = smb_llist_head(&session->s_xa_list); 906 while (xa) { 907 nextxa = smb_llist_next(&session->s_xa_list, xa); 908 smb_xa_close(xa); 909 xa = nextxa; 910 } 911 912 /* 913 * At this point the reference count of the files and directories 914 * should be zero. It should be possible to destroy them without 915 * any problem, which should trigger the destruction of other objects. 916 */ 917 smb_session_logoff(session); 918 } 919 920 /* 921 * Cancel requests. If a non-null tree is specified, only requests specific 922 * to that tree will be cancelled. If a non-null sr is specified, that sr 923 * will be not be cancelled - this would typically be the caller's sr. 924 */ 925 void 926 smb_session_cancel_requests( 927 smb_session_t *session, 928 smb_tree_t *tree, 929 smb_request_t *exclude_sr) 930 { 931 smb_request_t *sr; 932 933 smb_slist_enter(&session->s_req_list); 934 sr = smb_slist_head(&session->s_req_list); 935 936 while (sr) { 937 ASSERT(sr->sr_magic == SMB_REQ_MAGIC); 938 if ((sr != exclude_sr) && 939 (tree == NULL || sr->tid_tree == tree)) 940 smb_request_cancel(sr); 941 942 sr = smb_slist_next(&session->s_req_list, sr); 943 } 944 945 smb_slist_exit(&session->s_req_list); 946 } 947 948 /* 949 * Find a user on the specified session by SMB UID. 950 */ 951 smb_user_t * 952 smb_session_lookup_uid(smb_session_t *session, uint16_t uid) 953 { 954 return (smb_session_lookup_uid_st(session, 0, uid, 955 SMB_USER_STATE_LOGGED_ON)); 956 } 957 958 /* 959 * Find a user on the specified session by SMB2 SSNID. 960 */ 961 smb_user_t * 962 smb_session_lookup_ssnid(smb_session_t *session, uint64_t ssnid) 963 { 964 return (smb_session_lookup_uid_st(session, ssnid, 0, 965 SMB_USER_STATE_LOGGED_ON)); 966 } 967 968 smb_user_t * 969 smb_session_lookup_uid_st(smb_session_t *session, uint64_t ssnid, 970 uint16_t uid, smb_user_state_t st) 971 { 972 smb_user_t *user; 973 smb_llist_t *user_list; 974 975 SMB_SESSION_VALID(session); 976 977 user_list = &session->s_user_list; 978 smb_llist_enter(user_list, RW_READER); 979 980 for (user = smb_llist_head(user_list); 981 user != NULL; 982 user = smb_llist_next(user_list, user)) { 983 984 SMB_USER_VALID(user); 985 ASSERT(user->u_session == session); 986 987 if (user->u_ssnid != ssnid && user->u_uid != uid) 988 continue; 989 990 mutex_enter(&user->u_mutex); 991 if (user->u_state == st) { 992 // smb_user_hold_internal(user); 993 user->u_refcnt++; 994 mutex_exit(&user->u_mutex); 995 break; 996 } 997 mutex_exit(&user->u_mutex); 998 } 999 1000 smb_llist_exit(user_list); 1001 return (user); 1002 } 1003 1004 /* 1005 * Find a tree by tree-id. 1006 */ 1007 smb_tree_t * 1008 smb_session_lookup_tree( 1009 smb_session_t *session, 1010 uint16_t tid) 1011 { 1012 smb_tree_t *tree; 1013 1014 SMB_SESSION_VALID(session); 1015 1016 smb_llist_enter(&session->s_tree_list, RW_READER); 1017 tree = smb_llist_head(&session->s_tree_list); 1018 1019 while (tree) { 1020 ASSERT3U(tree->t_magic, ==, SMB_TREE_MAGIC); 1021 ASSERT(tree->t_session == session); 1022 1023 if (tree->t_tid == tid) { 1024 if (smb_tree_hold(tree)) { 1025 smb_llist_exit(&session->s_tree_list); 1026 return (tree); 1027 } else { 1028 smb_llist_exit(&session->s_tree_list); 1029 return (NULL); 1030 } 1031 } 1032 1033 tree = smb_llist_next(&session->s_tree_list, tree); 1034 } 1035 1036 smb_llist_exit(&session->s_tree_list); 1037 return (NULL); 1038 } 1039 1040 /* 1041 * Disconnect all trees that match the specified client process-id. 1042 * Used by the SMB1 "process exit" request. 1043 */ 1044 void 1045 smb_session_close_pid( 1046 smb_session_t *session, 1047 uint32_t pid) 1048 { 1049 smb_llist_t *tree_list = &session->s_tree_list; 1050 smb_tree_t *tree; 1051 1052 smb_llist_enter(tree_list, RW_READER); 1053 1054 tree = smb_llist_head(tree_list); 1055 while (tree) { 1056 if (smb_tree_hold(tree)) { 1057 smb_tree_close_pid(tree, pid); 1058 smb_tree_release(tree); 1059 } 1060 tree = smb_llist_next(tree_list, tree); 1061 } 1062 1063 smb_llist_exit(tree_list); 1064 } 1065 1066 static void 1067 smb_session_tree_dtor(void *arg) 1068 { 1069 smb_tree_t *tree = arg; 1070 1071 smb_tree_disconnect(tree, B_TRUE); 1072 /* release the ref acquired during the traversal loop */ 1073 smb_tree_release(tree); 1074 } 1075 1076 1077 /* 1078 * Disconnect all trees that this user has connected. 1079 */ 1080 void 1081 smb_session_disconnect_owned_trees( 1082 smb_session_t *session, 1083 smb_user_t *owner) 1084 { 1085 smb_tree_t *tree; 1086 smb_llist_t *tree_list = &session->s_tree_list; 1087 1088 SMB_SESSION_VALID(session); 1089 SMB_USER_VALID(owner); 1090 1091 smb_llist_enter(tree_list, RW_READER); 1092 1093 tree = smb_llist_head(tree_list); 1094 while (tree) { 1095 if ((tree->t_owner == owner) && 1096 smb_tree_hold(tree)) { 1097 /* 1098 * smb_tree_hold() succeeded, hence we are in state 1099 * SMB_TREE_STATE_CONNECTED; schedule this tree 1100 * for disconnect after smb_llist_exit because 1101 * the "unmap exec" up-call can block, and we'd 1102 * rather not block with the tree list locked. 1103 */ 1104 smb_llist_post(tree_list, tree, smb_session_tree_dtor); 1105 } 1106 tree = smb_llist_next(tree_list, tree); 1107 } 1108 1109 /* drop the lock and flush the dtor queue */ 1110 smb_llist_exit(tree_list); 1111 } 1112 1113 /* 1114 * Disconnect all trees that this user has connected. 1115 */ 1116 static void 1117 smb_session_disconnect_trees( 1118 smb_session_t *session) 1119 { 1120 smb_llist_t *tree_list = &session->s_tree_list; 1121 smb_tree_t *tree; 1122 1123 smb_llist_enter(tree_list, RW_READER); 1124 1125 tree = smb_llist_head(tree_list); 1126 while (tree) { 1127 if (smb_tree_hold(tree)) { 1128 smb_llist_post(tree_list, tree, 1129 smb_session_tree_dtor); 1130 } 1131 tree = smb_llist_next(tree_list, tree); 1132 } 1133 1134 /* drop the lock and flush the dtor queue */ 1135 smb_llist_exit(tree_list); 1136 } 1137 1138 /* 1139 * Variant of smb_session_tree_dtor that also 1140 * cancels requests using this tree. 1141 */ 1142 static void 1143 smb_session_tree_kill(void *arg) 1144 { 1145 smb_tree_t *tree = arg; 1146 1147 SMB_TREE_VALID(tree); 1148 1149 smb_tree_disconnect(tree, B_TRUE); 1150 smb_session_cancel_requests(tree->t_session, tree, NULL); 1151 1152 /* release the ref acquired during the traversal loop */ 1153 smb_tree_release(tree); 1154 } 1155 1156 /* 1157 * Disconnect all trees that match the specified share name, 1158 * and kill requests using those trees. 1159 */ 1160 void 1161 smb_session_disconnect_share( 1162 smb_session_t *session, 1163 const char *sharename) 1164 { 1165 smb_llist_t *ll; 1166 smb_tree_t *tree; 1167 1168 SMB_SESSION_VALID(session); 1169 1170 ll = &session->s_tree_list; 1171 smb_llist_enter(ll, RW_READER); 1172 1173 for (tree = smb_llist_head(ll); 1174 tree != NULL; 1175 tree = smb_llist_next(ll, tree)) { 1176 1177 SMB_TREE_VALID(tree); 1178 ASSERT(tree->t_session == session); 1179 1180 if (smb_strcasecmp(tree->t_sharename, sharename, 0) != 0) 1181 continue; 1182 1183 if (smb_tree_hold(tree)) { 1184 smb_llist_post(ll, tree, 1185 smb_session_tree_kill); 1186 } 1187 } 1188 1189 smb_llist_exit(ll); 1190 } 1191 1192 /* 1193 * Logoff all users associated with the specified session. 1194 * 1195 * This is called for both server-initiated disconnect 1196 * (SMB_SESSION_STATE_TERMINATED) and client-initiated 1197 * disconnect (SMB_SESSION_STATE_DISCONNECTED). 1198 * If client-initiated, save durable handles. 1199 */ 1200 void 1201 smb_session_logoff(smb_session_t *session) 1202 { 1203 smb_llist_t *ulist; 1204 smb_user_t *user; 1205 1206 SMB_SESSION_VALID(session); 1207 1208 top: 1209 ulist = &session->s_user_list; 1210 smb_llist_enter(ulist, RW_READER); 1211 1212 user = smb_llist_head(ulist); 1213 while (user) { 1214 SMB_USER_VALID(user); 1215 ASSERT(user->u_session == session); 1216 1217 mutex_enter(&user->u_mutex); 1218 switch (user->u_state) { 1219 case SMB_USER_STATE_LOGGING_ON: 1220 case SMB_USER_STATE_LOGGED_ON: 1221 // smb_user_hold_internal(user); 1222 user->u_refcnt++; 1223 mutex_exit(&user->u_mutex); 1224 smb_user_logoff(user); 1225 smb_user_release(user); 1226 break; 1227 1228 case SMB_USER_STATE_LOGGED_OFF: 1229 case SMB_USER_STATE_LOGGING_OFF: 1230 mutex_exit(&user->u_mutex); 1231 break; 1232 1233 default: 1234 mutex_exit(&user->u_mutex); 1235 ASSERT(0); 1236 break; 1237 } 1238 1239 user = smb_llist_next(ulist, user); 1240 } 1241 1242 /* Needed below (Was the list empty?) */ 1243 user = smb_llist_head(ulist); 1244 1245 smb_llist_exit(ulist); 1246 1247 /* 1248 * It's possible for user objects to remain due to references 1249 * obtained via smb_server_lookup_ssnid(), when an SMB2 1250 * session setup is destroying a previous session. 1251 * 1252 * Wait for user objects to clear out (last refs. go away, 1253 * then smb_user_delete takes them out of the list). When 1254 * the last user object is removed, the session state is 1255 * set to SHUTDOWN and s_lock is signaled. 1256 * 1257 * Not all places that call smb_user_release necessarily 1258 * flush the delete queue, so after we wait for the list 1259 * to empty out, go back to the top and recheck the list 1260 * delete queue to make sure smb_user_delete happens. 1261 */ 1262 if (user == NULL) { 1263 /* User list is empty. */ 1264 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 1265 session->s_state = SMB_SESSION_STATE_SHUTDOWN; 1266 smb_rwx_rwexit(&session->s_lock); 1267 } else { 1268 smb_rwx_rwenter(&session->s_lock, RW_READER); 1269 if (session->s_state != SMB_SESSION_STATE_SHUTDOWN) { 1270 (void) smb_rwx_cvwait(&session->s_lock, 1271 MSEC_TO_TICK(200)); 1272 smb_rwx_rwexit(&session->s_lock); 1273 goto top; 1274 } 1275 smb_rwx_rwexit(&session->s_lock); 1276 } 1277 ASSERT(session->s_state == SMB_SESSION_STATE_SHUTDOWN); 1278 1279 /* 1280 * User list should be empty now. 1281 */ 1282 #ifdef DEBUG 1283 if (ulist->ll_count != 0) { 1284 cmn_err(CE_WARN, "user list not empty?"); 1285 debug_enter("s_user_list"); 1286 } 1287 #endif 1288 1289 /* 1290 * User logoff happens first so we'll set preserve_opens 1291 * for client-initiated disconnect. When that's done 1292 * there should be no trees left, but check anyway. 1293 */ 1294 smb_session_disconnect_trees(session); 1295 } 1296 1297 /* 1298 * Copy the session workstation/client name to buf. If the workstation 1299 * is an empty string (which it will be on TCP connections), use the 1300 * client IP address. 1301 */ 1302 void 1303 smb_session_getclient(smb_session_t *sn, char *buf, size_t buflen) 1304 { 1305 1306 *buf = '\0'; 1307 1308 if (sn->workstation[0] != '\0') { 1309 (void) strlcpy(buf, sn->workstation, buflen); 1310 return; 1311 } 1312 1313 (void) strlcpy(buf, sn->ip_addr_str, buflen); 1314 } 1315 1316 /* 1317 * Check whether or not the specified client name is the client of this 1318 * session. The name may be in UNC format (\\CLIENT). 1319 * 1320 * A workstation/client name is setup on NBT connections as part of the 1321 * NetBIOS session request but that isn't available on TCP connections. 1322 * If the session doesn't have a client name we typically return the 1323 * client IP address as the workstation name on MSRPC requests. So we 1324 * check for the IP address here in addition to the workstation name. 1325 */ 1326 boolean_t 1327 smb_session_isclient(smb_session_t *sn, const char *client) 1328 { 1329 1330 client += strspn(client, "\\"); 1331 1332 if (smb_strcasecmp(client, sn->workstation, 0) == 0) 1333 return (B_TRUE); 1334 1335 if (smb_strcasecmp(client, sn->ip_addr_str, 0) == 0) 1336 return (B_TRUE); 1337 1338 return (B_FALSE); 1339 } 1340 1341 /* 1342 * smb_request_alloc 1343 * 1344 * Allocate an smb_request_t structure from the kmem_cache. Partially 1345 * initialize the found/new request. 1346 * 1347 * Returns pointer to a request, or NULL if the session state is 1348 * one in which new requests are no longer allowed. 1349 */ 1350 smb_request_t * 1351 smb_request_alloc(smb_session_t *session, int req_length) 1352 { 1353 smb_request_t *sr; 1354 1355 ASSERT(session->s_magic == SMB_SESSION_MAGIC); 1356 ASSERT(req_length <= session->cmd_max_bytes); 1357 1358 sr = kmem_cache_alloc(smb_cache_request, KM_SLEEP); 1359 1360 /* 1361 * Future: Use constructor to pre-initialize some fields. For now 1362 * there are so many fields that it is easiest just to zero the 1363 * whole thing and start over. 1364 */ 1365 bzero(sr, sizeof (smb_request_t)); 1366 1367 mutex_init(&sr->sr_mutex, NULL, MUTEX_DEFAULT, NULL); 1368 smb_srm_init(sr); 1369 sr->session = session; 1370 sr->sr_server = session->s_server; 1371 sr->sr_gmtoff = session->s_server->si_gmtoff; 1372 sr->sr_cfg = &session->s_cfg; 1373 sr->command.max_bytes = req_length; 1374 sr->reply.max_bytes = session->reply_max_bytes; 1375 sr->sr_req_length = req_length; 1376 if (req_length) 1377 sr->sr_request_buf = kmem_alloc(req_length, KM_SLEEP); 1378 sr->sr_magic = SMB_REQ_MAGIC; 1379 sr->sr_state = SMB_REQ_STATE_INITIALIZING; 1380 1381 /* 1382 * Only allow new SMB requests in some states. 1383 */ 1384 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 1385 switch (session->s_state) { 1386 case SMB_SESSION_STATE_CONNECTED: 1387 case SMB_SESSION_STATE_INITIALIZED: 1388 case SMB_SESSION_STATE_ESTABLISHED: 1389 case SMB_SESSION_STATE_NEGOTIATED: 1390 smb_slist_insert_tail(&session->s_req_list, sr); 1391 break; 1392 1393 default: 1394 ASSERT(0); 1395 /* FALLTHROUGH */ 1396 case SMB_SESSION_STATE_DISCONNECTED: 1397 case SMB_SESSION_STATE_SHUTDOWN: 1398 case SMB_SESSION_STATE_TERMINATED: 1399 /* Disallow new requests in these states. */ 1400 if (sr->sr_request_buf) 1401 kmem_free(sr->sr_request_buf, sr->sr_req_length); 1402 sr->session = NULL; 1403 sr->sr_magic = 0; 1404 mutex_destroy(&sr->sr_mutex); 1405 kmem_cache_free(smb_cache_request, sr); 1406 sr = NULL; 1407 break; 1408 } 1409 smb_rwx_rwexit(&session->s_lock); 1410 1411 return (sr); 1412 } 1413 1414 /* 1415 * smb_request_free 1416 * 1417 * release the memories which have been allocated for a smb request. 1418 */ 1419 void 1420 smb_request_free(smb_request_t *sr) 1421 { 1422 ASSERT(sr->sr_magic == SMB_REQ_MAGIC); 1423 ASSERT(sr->session); 1424 ASSERT(sr->r_xa == NULL); 1425 1426 if (sr->fid_ofile != NULL) { 1427 smb_ofile_release(sr->fid_ofile); 1428 } 1429 1430 if (sr->tid_tree != NULL) 1431 smb_tree_release(sr->tid_tree); 1432 1433 if (sr->uid_user != NULL) 1434 smb_user_release(sr->uid_user); 1435 1436 if (sr->tform_ssn != NULL) 1437 smb_user_release(sr->tform_ssn); 1438 1439 /* 1440 * The above may have left work on the delete queues 1441 */ 1442 smb_llist_flush(&sr->session->s_tree_list); 1443 smb_llist_flush(&sr->session->s_user_list); 1444 1445 smb_slist_remove(&sr->session->s_req_list, sr); 1446 1447 sr->session = NULL; 1448 1449 smb_srm_fini(sr); 1450 1451 if (sr->sr_request_buf) 1452 kmem_free(sr->sr_request_buf, sr->sr_req_length); 1453 if (sr->command.chain) 1454 m_freem(sr->command.chain); 1455 if (sr->reply.chain) 1456 m_freem(sr->reply.chain); 1457 if (sr->raw_data.chain) 1458 m_freem(sr->raw_data.chain); 1459 1460 sr->sr_magic = 0; 1461 mutex_destroy(&sr->sr_mutex); 1462 kmem_cache_free(smb_cache_request, sr); 1463 } 1464 1465 boolean_t 1466 smb_session_oplocks_enable(smb_session_t *session) 1467 { 1468 SMB_SESSION_VALID(session); 1469 if (session->s_cfg.skc_oplock_enable == 0) 1470 return (B_FALSE); 1471 else 1472 return (B_TRUE); 1473 } 1474 1475 boolean_t 1476 smb_session_levelII_oplocks(smb_session_t *session) 1477 { 1478 SMB_SESSION_VALID(session); 1479 1480 /* Older clients only do Level II oplocks if negotiated. */ 1481 if ((session->capabilities & CAP_LEVEL_II_OPLOCKS) != 0) 1482 return (B_TRUE); 1483 1484 return (B_FALSE); 1485 } 1486 1487 static void 1488 smb_session_genkey(smb_session_t *session) 1489 { 1490 uint8_t tmp_key[SMB_CHALLENGE_SZ]; 1491 1492 (void) random_get_pseudo_bytes(tmp_key, SMB_CHALLENGE_SZ); 1493 bcopy(tmp_key, &session->challenge_key, SMB_CHALLENGE_SZ); 1494 session->challenge_len = SMB_CHALLENGE_SZ; 1495 1496 (void) random_get_pseudo_bytes(tmp_key, 4); 1497 session->sesskey = tmp_key[0] | tmp_key[1] << 8 | 1498 tmp_key[2] << 16 | tmp_key[3] << 24; 1499 } 1500