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