Print this page
NEX-19647 panic in smb_notify_encode_action
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-18761 panic in smb_ofile_free with vdbench
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-17431 (HyperV) Windows VM goes panic after failover
NEX-18639 Panic in smb_ofile_release with expired ofile
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-15958 panic importing CA share after failover
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-15958 panic importing CA share after failover
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-15931 Panic removing files in SMB3 CA share
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-15931 Panic removing files in SMB3 CA share
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-13653 Obsolete SMB server work-around for ZFS read-only
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5273 SMB 3 Encryption
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9360 SMB1 fails renaming an open file
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-8495 Panic after SMB flush on a named pipe
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5844 want SMB2 ioctl FSCTL_SRV_COPYCHUNK
NEX-6124 smb_fsop_read/write should allow file != sr->fid_ofile
NEX-6125 smbtorture invalid response with smb2.ioctl
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6096 Enable compile warnings re. parentheses in smbsrv
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
NEX-6042 SMB resilient handle lock replay
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-5977 smbtorture smb2.notify.mask fails after NEX-3553
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3553 SMB2/3 durable handles
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-5586 SMB2 ofiles need real Persistent IDs
NEX-5313 SMB2 oplock break notification should use TID=0
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5537 Want reference counts for users, trees...
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5312 delete_on_close should be acted on earlier
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-3906 Prefer that SMB change notify not tie up a worker thread
NEX-5278 SMB notify should buffer per file handle
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-3432 CLONE - NEX-3232 Symantec Backup Exec fails opening files over SMB
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Daniel Borek <daniel.borek@nexenta.com>
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-39 Use AF_UNIX pipes for RPC
SMB-65 SMB server in non-global zones (use zone_kcred())
SMB-65 SMB server in non-global zones (kmem_caches)
common kmem_cache instances across zones
separate GZ-only init from NGZ init
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #7815 SMB server delivers old modification time... (fix allocsz)
re #7815 SMB server delivers old modification time...
re #11215 rb3676 sesctl to SGI JBOD hangs in biowait() with a command stuck in mptsas driver
re #10734 NT Trans. Notify returning too quickly


   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 2015 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright 2016 Syneto S.R.L. All rights reserved.
  25  * Copyright (c) 2016 by Delphix. All rights reserved.

  26  */
  27 
  28 /*
  29  * General Structures Layout
  30  * -------------------------
  31  *
  32  * This is a simplified diagram showing the relationship between most of the
  33  * main structures.
  34  *
  35  * +-------------------+
  36  * |     SMB_INFO      |
  37  * +-------------------+
  38  *          |
  39  *          |
  40  *          v
  41  * +-------------------+       +-------------------+      +-------------------+
  42  * |     SESSION       |<----->|     SESSION       |......|      SESSION      |
  43  * +-------------------+       +-------------------+      +-------------------+
  44  *   |          |
  45  *   |          |


  54  * |       TREE        |<----->|       TREE        |......|       TREE        |
  55  * +-------------------+       +-------------------+      +-------------------+
  56  *      |         |
  57  *      |         |
  58  *      |         v
  59  *      |     +-------+       +-------+      +-------+
  60  *      |     | OFILE |<----->| OFILE |......| OFILE |
  61  *      |     +-------+       +-------+      +-------+
  62  *      |
  63  *      |
  64  *      v
  65  *  +-------+       +------+      +------+
  66  *  | ODIR  |<----->| ODIR |......| ODIR |
  67  *  +-------+       +------+      +------+
  68  *
  69  *
  70  * Ofile State Machine
  71  * ------------------
  72  *
  73  *    +-------------------------+        T0
  74  *    |  SMB_OFILE_STATE_OPEN   |<----------- Creation/Allocation






















  75  *    +-------------------------+
  76  *                  |
  77  *                  | T1
  78  *                  |
  79  *                  v
  80  *    +-------------------------+
  81  *    | SMB_OFILE_STATE_CLOSING |
  82  *    +-------------------------+
  83  *                  |
  84  *                  | T2
  85  *                  |
  86  *                  v
  87  *    +-------------------------+    T3
  88  *    | SMB_OFILE_STATE_CLOSED  |----------> Deletion/Free
  89  *    +-------------------------+
  90  *
  91  * SMB_OFILE_STATE_OPEN
  92  *
  93  *    While in this state:
  94  *      - The ofile is queued in the list of ofiles of its tree.
  95  *      - References will be given out if the ofile is looked up.
  96  *























  97  * SMB_OFILE_STATE_CLOSING
  98  *



  99  *    While in this state:
 100  *      - The ofile is queued in the list of ofiles of its tree.
 101  *      - References will not be given out if the ofile is looked up.
 102  *      - The file is closed and the locks held are being released.
 103  *      - The resources associated with the ofile remain.
 104  *
 105  * SMB_OFILE_STATE_CLOSED
 106  *
 107  *    While in this state:
 108  *      - The ofile is queued in the list of ofiles of its tree.
 109  *      - References will not be given out if the ofile is looked up.
 110  *      - The resources associated with the ofile remain.
 111  *
































 112  * Transition T0
 113  *
 114  *    This transition occurs in smb_ofile_open(). A new ofile is created and
 115  *    added to the list of ofiles of a tree.
 116  *
 117  * Transition T1
 118  *
 119  *    This transition occurs in smb_ofile_close().


 120  *
 121  * Transition T2
 122  *
 123  *    This transition occurs in smb_ofile_release(). The resources associated
 124  *    with the ofile are freed as well as the ofile structure. For the
 125  *    transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED
 126  *    state and the reference count be zero.
 127  *












































 128  * Comments
 129  * --------
 130  *
 131  *    The state machine of the ofile structures is controlled by 3 elements:
 132  *      - The list of ofiles of the tree it belongs to.
 133  *      - The mutex embedded in the structure itself.
 134  *      - The reference count.
 135  *
 136  *    There's a mutex embedded in the ofile structure used to protect its fields
 137  *    and there's a lock embedded in the list of ofiles of a tree. To
 138  *    increment or to decrement the reference count the mutex must be entered.
 139  *    To insert the ofile into the list of ofiles of the tree and to remove
 140  *    the ofile from it, the lock must be entered in RW_WRITER mode.
 141  *
 142  *    Rules of access to a ofile structure:
 143  *
 144  *    1) In order to avoid deadlocks, when both (mutex and lock of the ofile
 145  *       list) have to be entered, the lock must be entered first.

 146  *
 147  *    2) All actions applied to an ofile require a reference count.
 148  *
 149  *    3) There are 2 ways of getting a reference count. One is when the ofile
 150  *       is opened. The other one when the ofile is looked up. This translates
 151  *       into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid().
 152  *
 153  *    It should be noted that the reference count of an ofile registers the
 154  *    number of references to the ofile in other structures (such as an smb
 155  *    request). The reference count is not incremented in these 2 instances:
 156  *
 157  *    1) The ofile is open. An ofile is anchored by its state. If there's
 158  *       no activity involving an ofile currently open, the reference count
 159  *       of that ofile is zero.
 160  *
 161  *    2) The ofile is queued in the list of ofiles of its tree. The fact of
 162  *       being queued in that list is NOT registered by incrementing the
 163  *       reference count.
 164  */
 165 #include <smbsrv/smb_kproto.h>
 166 #include <smbsrv/smb_fsops.h>


 167 
 168 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *);
 169 static smb_ofile_t *smb_ofile_close_and_next(smb_ofile_t *);


 170 static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t,
 171     uint32_t *);
 172 static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *);
 173 static void smb_ofile_netinfo_fini(smb_netfileinfo_t *);
 174 
 175 /*
 176  * smb_ofile_open


 177  */
















 178 smb_ofile_t *
 179 smb_ofile_open(
 180     smb_request_t       *sr,
 181     smb_node_t          *node,
 182     struct open_param   *op,
 183     uint16_t            ftype,
 184     uint32_t            uniqid,
 185     smb_error_t         *err)
 186 {
 187         smb_tree_t      *tree = sr->tid_tree;

 188         smb_ofile_t     *of;
 189         uint16_t        fid;
 190         smb_attr_t      attr;
 191         int             rc;
 192         enum errstates { EMPTY, FIDALLOC, CRHELD, MUTEXINIT };
 193         enum errstates  state = EMPTY;
 194 
 195         if (smb_idpool_alloc(&tree->t_fid_pool, &fid)) {
 196                 err->status = NT_STATUS_TOO_MANY_OPENED_FILES;
 197                 err->errcls = ERRDOS;
 198                 err->errcode = ERROR_TOO_MANY_OPEN_FILES;
 199                 return (NULL);
 200         }
 201         state = FIDALLOC;
 202 
 203         of = kmem_cache_alloc(smb_cache_ofile, KM_SLEEP);
 204         bzero(of, sizeof (smb_ofile_t));
 205         of->f_magic = SMB_OFILE_MAGIC;







 206         of->f_refcnt = 1;
 207         of->f_fid = fid;
 208         of->f_uniqid = uniqid;


 209         of->f_opened_by_pid = sr->smb_pid;
 210         of->f_granted_access = op->desired_access;
 211         of->f_share_access = op->share_access;
 212         of->f_create_options = op->create_options;
 213         of->f_cr = (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) ?
 214             smb_user_getprivcred(sr->uid_user) : sr->uid_user->u_cred;



 215         crhold(of->f_cr);
 216         state = CRHELD;
 217         of->f_ftype = ftype;
 218         of->f_server = tree->t_server;
 219         of->f_session = tree->t_session;
 220         /*
 221          * grab a ref for of->f_user
 222          * released in smb_ofile_delete()
 223          */
 224         smb_user_hold_internal(sr->uid_user);
 225         of->f_user = sr->uid_user;
 226         of->f_tree = tree;
 227         of->f_node = node;
 228 
 229         mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL);
 230         state = MUTEXINIT;
 231         of->f_state = SMB_OFILE_STATE_OPEN;
 232 
 233         if (ftype == SMB_FTYPE_MESG_PIPE) {
 234                 /* See smb_opipe_open. */
 235                 of->f_pipe = op->pipe;
 236                 smb_server_inc_pipes(of->f_server);
 237         } else {
 238                 ASSERT(ftype == SMB_FTYPE_DISK); /* Regular file, not a pipe */
 239                 ASSERT(node);
 240 
 241                 /*
 242                  * Note that the common open path often adds bits like
 243                  * READ_CONTROL, so the logic "is this open exec-only"
 244                  * needs to look at only the FILE_DATA_ALL bits.
 245                  */
 246                 if ((of->f_granted_access & FILE_DATA_ALL) == FILE_EXECUTE)
 247                         of->f_flags |= SMB_OFLAGS_EXECONLY;
 248 
 249                 bzero(&attr, sizeof (smb_attr_t));
 250                 attr.sa_mask = SMB_AT_UID | SMB_AT_DOSATTR;
 251                 rc = smb_node_getattr(NULL, node, of->f_cr, NULL, &attr);
 252                 if (rc != 0) {
 253                         err->status = NT_STATUS_INTERNAL_ERROR;
 254                         err->errcls = ERRDOS;
 255                         err->errcode = ERROR_INTERNAL_ERROR;
 256                         goto errout;
 257                 }
 258                 if (crgetuid(of->f_cr) == attr.sa_vattr.va_uid) {
 259                         /*
 260                          * Add this bit for the file's owner even if it's not
 261                          * specified in the request (Windows behavior).



 262                          */
 263                         of->f_granted_access |= FILE_READ_ATTRIBUTES;


 264                 }
 265 
 266                 if (smb_node_is_file(node)) {
 267                         of->f_mode =
 268                             smb_fsop_amask_to_omode(of->f_granted_access);
 269                         if (smb_fsop_open(node, of->f_mode, of->f_cr) != 0) {
 270                                 err->status = NT_STATUS_ACCESS_DENIED;
 271                                 err->errcls = ERRDOS;
 272                                 err->errcode = ERROR_ACCESS_DENIED;
 273                                 goto errout;
 274                         }
 275                 }
 276 
 277                 if (tree->t_flags & SMB_TREE_READONLY)
 278                         of->f_flags |= SMB_OFLAGS_READONLY;
 279 
 280                 /*
 281                  * Note that if we created_readonly, that
 282                  * will _not_ yet show in attr.sa_dosattr
 283                  * so creating a readonly file gives the
 284                  * caller a writable handle as it should.

 285                  */
 286                 if (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)
 287                         of->f_flags |= SMB_OFLAGS_READONLY;






 288 















 289                 smb_node_inc_open_ofiles(node);
 290                 smb_node_add_ofile(node, of);
 291                 smb_node_ref(node);
 292                 smb_server_inc_files(of->f_server);



 293         }
 294         smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
 295         smb_llist_insert_tail(&tree->t_ofile_list, of);
 296         smb_llist_exit(&tree->t_ofile_list);
 297         atomic_inc_32(&tree->t_open_files);
 298         atomic_inc_32(&of->f_session->s_file_cnt);
 299         return (of);
 300 
 301 errout:
 302         switch (state) {
 303         case MUTEXINIT:
 304                 mutex_destroy(&of->f_mutex);
 305                 smb_user_release(of->f_user);
 306                 /*FALLTHROUGH*/
 307         case CRHELD:
 308                 crfree(of->f_cr);
 309                 of->f_magic = 0;
 310                 kmem_cache_free(smb_cache_ofile, of);
 311                 /*FALLTHROUGH*/
 312         case FIDALLOC:
 313                 smb_idpool_free(&tree->t_fid_pool, fid);
 314                 /*FALLTHROUGH*/
 315         case EMPTY:
 316                 break;
 317         }
 318         return (NULL);
 319 }
 320 
 321 /*
 322  * smb_ofile_close





 323  */
 324 void
 325 smb_ofile_close(smb_ofile_t *of, int32_t mtime_sec)
 326 {
 327         smb_attr_t *pa;
 328         timestruc_t now;
 329         uint32_t flags = 0;
 330 
 331         SMB_OFILE_VALID(of);
 332 
 333         mutex_enter(&of->f_mutex);
 334         ASSERT(of->f_refcnt);
 335         if (of->f_state != SMB_OFILE_STATE_OPEN) {





 336                 mutex_exit(&of->f_mutex);



 337                 return;
 338         }
 339         of->f_state = SMB_OFILE_STATE_CLOSING;
 340         mutex_exit(&of->f_mutex);
 341 



 342         switch (of->f_ftype) {
 343         case SMB_FTYPE_BYTE_PIPE:
 344         case SMB_FTYPE_MESG_PIPE:
 345                 smb_opipe_close(of);
 346                 smb_server_dec_pipes(of->f_server);
 347                 break;
 348 
 349         case SMB_FTYPE_DISK:
 350         case SMB_FTYPE_PRINTER:









 351                 /*
 352                  * In here we make changes to of->f_pending_attr
 353                  * while not holding of->f_mutex.  This is OK
 354                  * because we've changed f_state to CLOSING,
 355                  * so no more threads will take this path.
 356                  */
 357                 pa = &of->f_pending_attr;
 358                 if (mtime_sec != 0) {
 359                         pa->sa_vattr.va_mtime.tv_sec = mtime_sec;
 360                         pa->sa_mask |= SMB_AT_MTIME;
 361                 }
 362 
 363                 /*
 364                  * If we have ever modified data via this handle
 365                  * (write or truncate) and if the mtime was not
 366                  * set via this handle, update the mtime again
 367                  * during the close.  Windows expects this.
 368                  * [ MS-FSA 2.1.5.4 "Update Timestamps" ]
 369                  */
 370                 if (of->f_written &&
 371                     (pa->sa_mask & SMB_AT_MTIME) == 0) {
 372                         pa->sa_mask |= SMB_AT_MTIME;
 373                         gethrestime(&now);
 374                         pa->sa_vattr.va_mtime = now;
 375                 }
 376 
 377                 if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) {
 378                         if (smb_tree_has_feature(of->f_tree,
 379                             SMB_TREE_CATIA)) {
 380                                 flags |= SMB_CATIA;
 381                         }
 382                         (void) smb_node_set_delete_on_close(of->f_node,
 383                             of->f_cr, flags);
 384                 }
 385                 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid);
 386                 smb_node_destroy_lock_by_ofile(of->f_node, of);
 387 
 388                 if (smb_node_is_file(of->f_node)) {
 389                         (void) smb_fsop_close(of->f_node, of->f_mode,
 390                             of->f_cr);
 391                         smb_oplock_release(of->f_node, of);
 392                 } else {
 393                         /*
 394                          * If there was an odir, close it.
 395                          */
 396                         if (of->f_odir != NULL)
 397                                 smb_odir_close(of->f_odir);

















 398                 }


 399                 if (smb_node_dec_open_ofiles(of->f_node) == 0) {
 400                         /*
 401                          * Last close. The f_pending_attr has
 402                          * only times (atime,ctime,mtime) so
 403                          * we can borrow it to commit the
 404                          * n_pending_dosattr from the node.


 405                          */
 406                         pa->sa_dosattr =
 407                             of->f_node->n_pending_dosattr;
 408                         if (pa->sa_dosattr != 0)
 409                                 pa->sa_mask |= SMB_AT_DOSATTR;
 410                         /* Let's leave this zero when not in use. */
 411                         of->f_node->n_allocsz = 0;

 412                 }
 413                 if (pa->sa_mask != 0) {
 414                         /*
 415                          * Commit any pending attributes from
 416                          * the ofile we're closing.  Note that
 417                          * we pass NULL as the ofile to setattr
 418                          * so it will write to the file system
 419                          * and not keep anything on the ofile.
 420                          * This clears n_pending_dosattr if
 421                          * there are no opens, otherwise the
 422                          * dosattr will be pending again.
 423                          */
 424                         (void) smb_node_setattr(NULL, of->f_node,
 425                             of->f_cr, NULL, pa);
 426                 }
 427 
 428                 /*
 429                  * Cancel any notify change requests that
 430                  * may be using this open instance.
 431                  */
 432                 if (of->f_node->n_fcn.fcn_count)
 433                         smb_notify_file_closed(of);
 434 
 435                 smb_server_dec_files(of->f_server);
 436                 break;
 437         }
 438         atomic_dec_32(&of->f_tree->t_open_files);
 439 
 440         mutex_enter(&of->f_mutex);
 441         ASSERT(of->f_refcnt);
 442         ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING);
 443         of->f_state = SMB_OFILE_STATE_CLOSED;
 444         mutex_exit(&of->f_mutex);
 445 }
 446 
 447 /*
 448  * smb_ofile_close_all



 449  *




 450  *



 451  */
 452 void
 453 smb_ofile_close_all(
 454     smb_tree_t          *tree)
 455 {
 456         smb_ofile_t     *of;
 457 
 458         ASSERT(tree);
 459         ASSERT(tree->t_magic == SMB_TREE_MAGIC);

















 460 
 461         smb_llist_enter(&tree->t_ofile_list, RW_READER);
 462         of = smb_llist_head(&tree->t_ofile_list);
 463         while (of) {
 464                 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 465                 ASSERT(of->f_tree == tree);
 466                 of = smb_ofile_close_and_next(of);
 467         }
 468         smb_llist_exit(&tree->t_ofile_list);







 469 }
 470 
 471 /*
 472  * smb_ofiles_close_by_pid
 473  *
 474  *
 475  */
 476 void
 477 smb_ofile_close_all_by_pid(
 478     smb_tree_t          *tree,
 479     uint16_t            pid)
 480 {
 481         smb_ofile_t     *of;

 482 
 483         ASSERT(tree);
 484         ASSERT(tree->t_magic == SMB_TREE_MAGIC);
 485 
 486         smb_llist_enter(&tree->t_ofile_list, RW_READER);
 487         of = smb_llist_head(&tree->t_ofile_list);
 488         while (of) {



 489                 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 490                 ASSERT(of->f_tree == tree);
 491                 if (of->f_opened_by_pid == pid) {
 492                         of = smb_ofile_close_and_next(of);
 493                 } else {
 494                         of = smb_llist_next(&tree->t_ofile_list, of);
 495                 }
 496         }
 497         smb_llist_exit(&tree->t_ofile_list);





 498 }
 499 
 500 /*
 501  * If the enumeration request is for ofile data, handle it here.
 502  * Otherwise, return.
 503  *
 504  * This function should be called with a hold on the ofile.
 505  */
 506 int
 507 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum)
 508 {
 509         uint8_t *pb;
 510         uint_t nbytes;
 511         int rc;
 512 
 513         ASSERT(of);
 514         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 515         ASSERT(of->f_refcnt);
 516 
 517         if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE)


 524 
 525         if (svcenum->se_nitems >= svcenum->se_nlimit) {
 526                 svcenum->se_nitems = svcenum->se_nlimit;
 527                 return (0);
 528         }
 529 
 530         pb = &svcenum->se_buf[svcenum->se_bused];
 531 
 532         rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail,
 533             &nbytes);
 534         if (rc == 0) {
 535                 svcenum->se_bavail -= nbytes;
 536                 svcenum->se_bused += nbytes;
 537                 svcenum->se_nitems++;
 538         }
 539 
 540         return (rc);
 541 }
 542 
 543 /*















































 544  * Take a reference on an open file.
 545  */
 546 boolean_t
 547 smb_ofile_hold(smb_ofile_t *of)
 548 {
 549         ASSERT(of);
 550         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 551 
 552         mutex_enter(&of->f_mutex);
 553 
 554         if (of->f_state != SMB_OFILE_STATE_OPEN) {
 555                 mutex_exit(&of->f_mutex);
 556                 return (B_FALSE);
 557         }
 558         of->f_refcnt++;
 559 
 560         mutex_exit(&of->f_mutex);
 561         return (B_TRUE);
 562 }
 563 
 564 /*
 565  * Release a reference on a file.  If the reference count falls to
 566  * zero and the file has been closed, post the object for deletion.
 567  * Object deletion is deferred to avoid modifying a list while an
 568  * iteration may be in progress.




 569  */
 570 void
 571 smb_ofile_release(smb_ofile_t *of)
 572 {



 573         SMB_OFILE_VALID(of);
 574 
 575         mutex_enter(&of->f_mutex);
 576         ASSERT(of->f_refcnt);
 577         of->f_refcnt--;

 578         switch (of->f_state) {
 579         case SMB_OFILE_STATE_OPEN:
 580         case SMB_OFILE_STATE_CLOSING:

 581                 break;
 582 
 583         case SMB_OFILE_STATE_CLOSED:
 584                 if (of->f_refcnt == 0)
 585                         smb_tree_post_ofile(of->f_tree, of);




 586                 break;
 587 














 588         default:
 589                 ASSERT(0);
 590                 break;
 591         }
 592         mutex_exit(&of->f_mutex);
 593 }
 594 
 595 /*
 596  * smb_ofile_request_complete
 597  *
 598  * During oplock acquisition, all other oplock requests on the node
 599  * are blocked until the acquire request completes and the response
 600  * is on the wire.
 601  * Call smb_oplock_broadcast to notify the node that the request
 602  * has completed.
 603  *
 604  * THIS MECHANISM RELIES ON THE FACT THAT THE OFILE IS NOT REMOVED
 605  * FROM THE SR UNTIL REQUEST COMPLETION (when the sr is destroyed)
 606  */
 607 void
 608 smb_ofile_request_complete(smb_ofile_t *of)
 609 {
 610         SMB_OFILE_VALID(of);
 611 
 612         switch (of->f_ftype) {
 613         case SMB_FTYPE_DISK:
 614                 ASSERT(of->f_node);
 615                 smb_oplock_broadcast(of->f_node);
 616                 break;
 617         case SMB_FTYPE_MESG_PIPE:
 618                 break;
 619         default:
 620                 break;
 621         }
 622 }
 623 
 624 /*
 625  * smb_ofile_lookup_by_fid
 626  *
 627  * Find the open file whose fid matches the one specified in the request.
 628  * If we can't find the fid or the shares (trees) don't match, we have a
 629  * bad fid.
 630  */
 631 smb_ofile_t *
 632 smb_ofile_lookup_by_fid(
 633     smb_request_t       *sr,
 634     uint16_t            fid)
 635 {
 636         smb_tree_t      *tree = sr->tid_tree;
 637         smb_llist_t     *of_list;
 638         smb_ofile_t     *of;
 639 
 640         ASSERT(tree->t_magic == SMB_TREE_MAGIC);


 645         of = smb_llist_head(of_list);
 646         while (of) {
 647                 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 648                 ASSERT(of->f_tree == tree);
 649                 if (of->f_fid == fid)
 650                         break;
 651                 of = smb_llist_next(of_list, of);
 652         }
 653         if (of == NULL)
 654                 goto out;
 655 
 656         /*
 657          * Only allow use of a given FID with the same UID that
 658          * was used to open it.  MS-CIFS 3.3.5.14
 659          */
 660         if (of->f_user != sr->uid_user) {
 661                 of = NULL;
 662                 goto out;
 663         }
 664 

 665         mutex_enter(&of->f_mutex);
 666         if (of->f_state != SMB_OFILE_STATE_OPEN) {
 667                 mutex_exit(&of->f_mutex);
 668                 of = NULL;
 669                 goto out;
 670         }
 671         of->f_refcnt++;
 672         mutex_exit(&of->f_mutex);
 673 
 674 out:
 675         smb_llist_exit(of_list);
 676         return (of);
 677 }
 678 
 679 /*
 680  * smb_ofile_lookup_by_uniqid
 681  *
 682  * Find the open file whose uniqid matches the one specified in the request.
 683  */
 684 smb_ofile_t *


 695 
 696         while (of) {
 697                 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 698                 ASSERT(of->f_tree == tree);
 699 
 700                 if (of->f_uniqid == uniqid) {
 701                         if (smb_ofile_hold(of)) {
 702                                 smb_llist_exit(of_list);
 703                                 return (of);
 704                         }
 705                 }
 706 
 707                 of = smb_llist_next(of_list, of);
 708         }
 709 
 710         smb_llist_exit(of_list);
 711         return (NULL);
 712 }
 713 
 714 /*









































































































































































































 715  * Disallow NetFileClose on certain ofiles to avoid side-effects.
 716  * Closing a tree root is not allowed: use NetSessionDel or NetShareDel.
 717  * Closing SRVSVC connections is not allowed because this NetFileClose
 718  * request may depend on this ofile.
 719  */
 720 boolean_t
 721 smb_ofile_disallow_fclose(smb_ofile_t *of)
 722 {
 723         ASSERT(of);
 724         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 725         ASSERT(of->f_refcnt);
 726 
 727         switch (of->f_ftype) {
 728         case SMB_FTYPE_DISK:
 729                 ASSERT(of->f_tree);
 730                 return (of->f_node == of->f_tree->t_snode);
 731 
 732         case SMB_FTYPE_MESG_PIPE:
 733                 ASSERT(of->f_pipe);
 734                 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0)


 867 {
 868         boolean_t       rc;
 869 
 870         SMB_OFILE_VALID(of);
 871 
 872         mutex_enter(&of->f_mutex);
 873         rc = smb_ofile_is_open_locked(of);
 874         mutex_exit(&of->f_mutex);
 875         return (rc);
 876 }
 877 
 878 /* *************************** Static Functions ***************************** */
 879 
 880 /*
 881  * Determine whether or not an ofile is open.
 882  * This function must be called with the mutex held.
 883  */
 884 static boolean_t
 885 smb_ofile_is_open_locked(smb_ofile_t *of)
 886 {


 887         switch (of->f_state) {
 888         case SMB_OFILE_STATE_OPEN:




 889                 return (B_TRUE);
 890 
 891         case SMB_OFILE_STATE_CLOSING:
 892         case SMB_OFILE_STATE_CLOSED:

 893                 return (B_FALSE);
 894 
 895         default:
 896                 ASSERT(0);
 897                 return (B_FALSE);
 898         }
 899 }
 900 
 901 /*
 902  * This function closes the file passed in (if appropriate) and returns the
 903  * next open file in the list of open files of the tree of the open file passed
 904  * in. It requires that the list of open files of the tree be entered in
 905  * RW_READER mode before being called.







 906  */
 907 static smb_ofile_t *
 908 smb_ofile_close_and_next(smb_ofile_t *of)
 909 {
 910         smb_ofile_t     *next_of;
 911         smb_tree_t      *tree;
 912 
 913         ASSERT(of);
 914         ASSERT(of->f_magic == SMB_OFILE_MAGIC);


 915 













 916         mutex_enter(&of->f_mutex);
 917         switch (of->f_state) {
 918         case SMB_OFILE_STATE_OPEN:
 919                 /* The file is still open. */
 920                 of->f_refcnt++;
 921                 ASSERT(of->f_refcnt);
 922                 tree = of->f_tree;
 923                 mutex_exit(&of->f_mutex);
 924                 smb_llist_exit(&of->f_tree->t_ofile_list);
 925                 smb_ofile_close(of, 0);
 926                 smb_ofile_release(of);
 927                 smb_llist_enter(&tree->t_ofile_list, RW_READER);
 928                 next_of = smb_llist_head(&tree->t_ofile_list);
 929                 break;
 930         case SMB_OFILE_STATE_CLOSING:
 931         case SMB_OFILE_STATE_CLOSED:
 932                 /*
 933                  * The ofile exists but is closed or
 934                  * in the process being closed.

 935                  */



















 936                 mutex_exit(&of->f_mutex);
 937                 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of);
 938                 break;
 939         default:
 940                 ASSERT(0);
 941                 mutex_exit(&of->f_mutex);
 942                 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of);
 943                 break;
 944         }
 945         return (next_of);
 946 }
 947 
 948 /*
 949  * Delete an ofile.
 950  *
 951  * Remove the ofile from the tree list before freeing resources
 952  * associated with the ofile.







 953  */
 954 void
 955 smb_ofile_delete(void *arg)
 956 {
 957         smb_tree_t      *tree;
 958         smb_ofile_t     *of = (smb_ofile_t *)arg;

 959 
 960         SMB_OFILE_VALID(of);
 961         ASSERT(of->f_refcnt == 0);
 962         ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED);
 963         ASSERT(!SMB_OFILE_OPLOCK_GRANTED(of));
 964 
 965         tree = of->f_tree;




 966         smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
 967         smb_llist_remove(&tree->t_ofile_list, of);
 968         smb_idpool_free(&tree->t_fid_pool, of->f_fid);
 969         atomic_dec_32(&tree->t_session->s_file_cnt);
 970         smb_llist_exit(&tree->t_ofile_list);

 971 






















 972         mutex_enter(&of->f_mutex);


 973         mutex_exit(&of->f_mutex);
 974 
 975         switch (of->f_ftype) {
 976         case SMB_FTYPE_BYTE_PIPE:
 977         case SMB_FTYPE_MESG_PIPE:
 978                 smb_opipe_dealloc(of->f_pipe);
 979                 of->f_pipe = NULL;
 980                 break;
 981         case SMB_FTYPE_DISK:


 982                 if (of->f_odir != NULL)
 983                         smb_odir_release(of->f_odir);
 984                 smb_node_rem_ofile(of->f_node, of);









 985                 smb_node_release(of->f_node);
 986                 break;
 987         default:
 988                 ASSERT(!"f_ftype");
 989                 break;
 990         }
 991 























 992         of->f_magic = (uint32_t)~SMB_OFILE_MAGIC;


 993         mutex_destroy(&of->f_mutex);
 994         crfree(of->f_cr);
 995         smb_user_release(of->f_user);
 996         kmem_cache_free(smb_cache_ofile, of);
 997 }
 998 
 999 /*
1000  * smb_ofile_access
1001  *
1002  * This function will check to see if the access requested is granted.
1003  * Returns NT status codes.
1004  */
1005 uint32_t
1006 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access)
1007 {
1008 
1009         if ((of == NULL) || (cr == zone_kcred()))
1010                 return (NT_STATUS_SUCCESS);
1011 
1012         /*
1013          * If the request is for something
1014          * I don't grant it is an error
1015          */


1031  * Returns: B_TRUE  - share access non-zero
1032  *          B_FALSE - share access NONE
1033  */
1034 boolean_t
1035 smb_ofile_share_check(smb_ofile_t *of)
1036 {
1037         return (!SMB_DENY_ALL(of->f_share_access));
1038 }
1039 
1040 /*
1041  * check file sharing rules for current open request
1042  * against existing open instances of the same file
1043  *
1044  * Returns NT_STATUS_SHARING_VIOLATION if there is any
1045  * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
1046  */
1047 uint32_t
1048 smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access,
1049     uint32_t share_access)
1050 {


1051         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1052 
1053         mutex_enter(&of->f_mutex);
1054 
1055         if (of->f_state != SMB_OFILE_STATE_OPEN) {
1056                 mutex_exit(&of->f_mutex);
1057                 return (NT_STATUS_INVALID_HANDLE);
1058         }
1059 
1060         /* if it's just meta data */
1061         if ((of->f_granted_access & FILE_DATA_ALL) == 0) {
1062                 mutex_exit(&of->f_mutex);
1063                 return (NT_STATUS_SUCCESS);
1064         }
1065 
1066         /*
1067          * Check requested share access against the
1068          * open granted (desired) access
1069          */
1070         if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) {
1071                 mutex_exit(&of->f_mutex);
1072                 return (NT_STATUS_SHARING_VIOLATION);
1073         }
1074 
1075         if (SMB_DENY_READ(share_access) &&
1076             (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1077                 mutex_exit(&of->f_mutex);
1078                 return (NT_STATUS_SHARING_VIOLATION);
1079         }
1080 
1081         if (SMB_DENY_WRITE(share_access) &&
1082             (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1083                 mutex_exit(&of->f_mutex);
1084                 return (NT_STATUS_SHARING_VIOLATION);
1085         }
1086 
1087         /* check requested desired access against the open share access */
1088         if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) {
1089                 mutex_exit(&of->f_mutex);
1090                 return (NT_STATUS_SHARING_VIOLATION);
1091         }
1092 
1093         if (SMB_DENY_READ(of->f_share_access) &&
1094             (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1095                 mutex_exit(&of->f_mutex);
1096                 return (NT_STATUS_SHARING_VIOLATION);
1097         }
1098 
1099         if (SMB_DENY_WRITE(of->f_share_access) &&
1100             (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1101                 mutex_exit(&of->f_mutex);
1102                 return (NT_STATUS_SHARING_VIOLATION);
1103         }
1104 


1105         mutex_exit(&of->f_mutex);
1106         return (NT_STATUS_SUCCESS);
1107 }
1108 
1109 /*
1110  * smb_ofile_rename_check
1111  *
1112  * An open file can be renamed if
1113  *
1114  *  1. isn't opened for data writing or deleting
1115  *
1116  *  2. Opened with "Deny Delete" share mode
1117  *         But not opened for data reading or executing
1118  *         (opened for accessing meta data)
1119  */
1120 
1121 uint32_t
1122 smb_ofile_rename_check(smb_ofile_t *of)
1123 {


1124         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1125 
1126         mutex_enter(&of->f_mutex);
1127 
1128         if (of->f_state != SMB_OFILE_STATE_OPEN) {
1129                 mutex_exit(&of->f_mutex);
1130                 return (NT_STATUS_INVALID_HANDLE);
1131         }
1132 
1133         if (of->f_granted_access &
1134             (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
1135                 mutex_exit(&of->f_mutex);
1136                 return (NT_STATUS_SHARING_VIOLATION);
1137         }
1138 
1139         if ((of->f_share_access & FILE_SHARE_DELETE) == 0) {
1140                 if (of->f_granted_access &
1141                     (FILE_READ_DATA | FILE_EXECUTE)) {
1142                         mutex_exit(&of->f_mutex);
1143                         return (NT_STATUS_SHARING_VIOLATION);
1144                 }
1145         }
1146 


1147         mutex_exit(&of->f_mutex);
1148         return (NT_STATUS_SUCCESS);
1149 }
1150 
1151 /*
1152  * smb_ofile_delete_check
1153  *
1154  * An open file can be deleted only if opened for
1155  * accessing meta data. Share modes aren't important
1156  * in this case.
1157  *
1158  * NOTE: there is another mechanism for deleting an
1159  * open file that NT clients usually use.
1160  * That's setting "Delete on close" flag for an open
1161  * file.  In this way the file will be deleted after
1162  * last close. This flag can be set by SmbTrans2SetFileInfo
1163  * with FILE_DISPOSITION_INFO information level.
1164  * For setting this flag, the file should be opened by
1165  * DELETE access in the FID that is passed in the Trans2
1166  * request.
1167  */
1168 
1169 uint32_t
1170 smb_ofile_delete_check(smb_ofile_t *of)
1171 {


1172         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1173 
1174         mutex_enter(&of->f_mutex);
1175 
1176         if (of->f_state != SMB_OFILE_STATE_OPEN) {
1177                 mutex_exit(&of->f_mutex);
1178                 return (NT_STATUS_INVALID_HANDLE);
1179         }
1180 
1181         if (of->f_granted_access &
1182             (FILE_READ_DATA | FILE_WRITE_DATA |
1183             FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) {
1184                 mutex_exit(&of->f_mutex);
1185                 return (NT_STATUS_SHARING_VIOLATION);
1186         }
1187 


1188         mutex_exit(&of->f_mutex);
1189         return (NT_STATUS_SUCCESS);
1190 }
1191 
1192 cred_t *
1193 smb_ofile_getcred(smb_ofile_t *of)
1194 {
1195         return (of->f_cr);
1196 }
1197 
1198 /*
1199  * smb_ofile_set_delete_on_close
1200  *
1201  * Set the DeleteOnClose flag on the smb file. When the file is closed,
1202  * the flag will be transferred to the smb node, which will commit the
1203  * delete operation and inhibit subsequent open requests.
1204  *
1205  * When DeleteOnClose is set on an smb_node, the common open code will
1206  * reject subsequent open requests for the file. Observation of Windows
1207  * 2000 indicates that subsequent opens should be allowed (assuming
1208  * there would be no sharing violation) until the file is closed using
1209  * the fid on which the DeleteOnClose was requested.
1210  */
1211 void
1212 smb_ofile_set_delete_on_close(smb_ofile_t *of)
1213 {













1214         mutex_enter(&of->f_mutex);
1215         of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE;
1216         mutex_exit(&of->f_mutex);
1217 }
1218 
1219 /*
1220  * Encode open file information into a buffer; needed in user space to
1221  * support RPC requests.
1222  */
1223 static int
1224 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen,
1225     uint32_t *nbytes)
1226 {
1227         smb_netfileinfo_t       fi;
1228         int                     rc;
1229 
1230         rc = smb_ofile_netinfo_init(of, &fi);
1231         if (rc == 0) {
1232                 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes);
1233                 smb_ofile_netinfo_fini(&fi);




   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 2016 Syneto S.R.L. All rights reserved.
  24  * Copyright (c) 2016 by Delphix. All rights reserved.
  25  * Copyright 2019 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 /*
  29  * General Structures Layout
  30  * -------------------------
  31  *
  32  * This is a simplified diagram showing the relationship between most of the
  33  * main structures.
  34  *
  35  * +-------------------+
  36  * |     SMB_INFO      |
  37  * +-------------------+
  38  *          |
  39  *          |
  40  *          v
  41  * +-------------------+       +-------------------+      +-------------------+
  42  * |     SESSION       |<----->|     SESSION       |......|      SESSION      |
  43  * +-------------------+       +-------------------+      +-------------------+
  44  *   |          |
  45  *   |          |


  54  * |       TREE        |<----->|       TREE        |......|       TREE        |
  55  * +-------------------+       +-------------------+      +-------------------+
  56  *      |         |
  57  *      |         |
  58  *      |         v
  59  *      |     +-------+       +-------+      +-------+
  60  *      |     | OFILE |<----->| OFILE |......| OFILE |
  61  *      |     +-------+       +-------+      +-------+
  62  *      |
  63  *      |
  64  *      v
  65  *  +-------+       +------+      +------+
  66  *  | ODIR  |<----->| ODIR |......| ODIR |
  67  *  +-------+       +------+      +------+
  68  *
  69  *
  70  * Ofile State Machine
  71  * ------------------
  72  *
  73  *    +-------------------------+        T0
  74  *    |  SMB_OFILE_STATE_OPEN   |<--+-------- Creation/Allocation
  75  *    +-------------------------+   |
  76  *          |           |           | T5
  77  *          |           |       +---------------------------+
  78  *          |           |       | SMB_OFILE_STATE_RECONNECT |
  79  *          |           |       +---------------------------+
  80  *          |           |           ^
  81  *          |           v           |
  82  *          |   +---------------+   |
  83  *          |   | STATE_SAVE_DH |   |
  84  *          |   | STATE_SAVING  |   |
  85  *          |   +---------------+   |
  86  *          |           |           | T4
  87  *          | T1        | T3    +--------------------------+
  88  *          |           +------>| SMB_OFILE_STATE_ORPHANED |
  89  *          v                   +--------------------------+
  90  *    +-------------------------+   |           |
  91  *    | SMB_OFILE_STATE_CLOSING |<--+ T6     | T7
  92  *    +-------------------------+               |
  93  *          |           ^                       v
  94  *          | T2        | T8    +-------------------------+
  95  *          |           +-------| SMB_OFILE_STATE_EXPIRED |
  96  *          v                   +-------------------------+
  97  *    +-------------------------+












  98  *    | SMB_OFILE_STATE_CLOSED  |----------> Deletion/Free
  99  *    +-------------------------+    T9
 100  *
 101  * SMB_OFILE_STATE_OPEN
 102  *
 103  *    While in this state:
 104  *      - The ofile is queued in the list of ofiles of its tree.
 105  *      - References will be given out if the ofile is looked up.
 106  *
 107  * SMB_OFILE_STATE_SAVE_DH
 108  *
 109  *    Similar to state _CLOSING, but instead of deleting the ofile,
 110  *    it leaves the ofile in state _ORPHANED (for later reclaim).
 111  *    Will move to _SAVING after last ref, then _ORPHANED.
 112  *
 113  *    While in this state:
 114  *      - The ofile has been marked for preservation during a
 115  *        walk of the tree ofile list to close multiple files.
 116  *      - References will not be given out if the ofile is looked up,
 117  *        except for oplock break processing.
 118  *      - Still affects Sharing Violation rules
 119  *
 120  * SMB_OFILE_STATE_SAVING
 121  *
 122  *    Transient state used to keep oplock break processing out
 123  *    while the ofile moves to state _ORPHANED.
 124  *
 125  *    While in this state:
 126  *      - References will not be given out if the ofile is looked up,
 127  *        except for oplock break processing.
 128  *      - Still affects Sharing Violation rules
 129  *
 130  * SMB_OFILE_STATE_CLOSING
 131  *
 132  *    Close has been requested.  Stay in this state until the last
 133  *    ref. is gone, then move to state _CLOSED
 134  *
 135  *    While in this state:
 136  *      - The ofile is queued in the list of ofiles of its tree.
 137  *      - References will not be given out if the ofile is looked up.
 138  *      - The file is closed and the locks held are being released.
 139  *      - The resources associated with the ofile remain.
 140  *
 141  * SMB_OFILE_STATE_CLOSED
 142  *
 143  *    While in this state:
 144  *      - The ofile is queued in the list of ofiles of its tree.
 145  *      - References will not be given out if the ofile is looked up.
 146  *      - The resources associated with the ofile remain.
 147  *
 148  * SMB_OFILE_STATE_ORPHANED
 149  *
 150  *    While in this state:
 151  *      - The ofile is queued in the list of ofiles of its tree.
 152  *      - Can be reclaimed by the original owner
 153  *      - References will not be given out if the ofile is looked up.
 154  *      - All the tree, user, and session "up" pointers are NULL!
 155  *      - Will eventually be "expired" if not reclaimed
 156  *      - Can be closed if its oplock is broken
 157  *      - Still affects Sharing Violation rules
 158  *
 159  * SMB_OFILE_STATE_EXPIRED
 160  *
 161  *    While in this state:
 162  *      - The ofile is queued in the list of ofiles of its tree.
 163  *      - References will not be given out if the ofile is looked up.
 164  *      - The ofile has not been reclaimed and will soon be closed,
 165  *        due to, for example, the durable handle timer expiring, or its
 166  *        oplock being broken.
 167  *      - Cannot be reclaimed at this point
 168  *
 169  * SMB_OFILE_STATE_RECONNECT
 170  *
 171  *    Transient state used to keep oplock break processing out
 172  *    while the ofile moves from state _ORPHANED to _OPEN.
 173  *
 174  *    While in this state:
 175  *      - The ofile is being reclaimed; do not touch it.
 176  *      - References will not be given out if the ofile is looked up.
 177  *      - Still affects Sharing Violation rules
 178  *      - see smb2_dh_reconnect() for which members need to be avoided
 179  *
 180  * Transition T0
 181  *
 182  *    This transition occurs in smb_ofile_open(). A new ofile is created and
 183  *    added to the list of ofiles of a tree.
 184  *
 185  * Transition T1
 186  *
 187  *    This transition occurs in smb_ofile_close(). Note that this only happens
 188  *    when we determine that an ofile should be closed in spite of its durable
 189  *    handle properties.
 190  *
 191  * Transition T2
 192  *
 193  *    This transition occurs in smb_ofile_release(). The resources associated
 194  *    with the ofile are freed as well as the ofile structure. For the
 195  *    transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED
 196  *    state and the reference count be zero.
 197  *
 198  * Transition T3
 199  *
 200  *    This transition occurs in smb_ofile_orphan_dh(). It happens during an
 201  *    smb2 logoff, or during a session disconnect when certain conditions are
 202  *    met. The ofile and structures above it will be kept around until the ofile
 203  *    either gets reclaimed, expires after f_timeout_offset nanoseconds, or its
 204  *    oplock is broken.
 205  *
 206  * Transition T4
 207  *
 208  *    This transition occurs in smb2_dh_reconnect(). An smb2 create request
 209  *    with a DURABLE_HANDLE_RECONNECT(_V2) create context has been
 210  *    recieved from the original owner. If leases are supported or it's
 211  *    RECONNECT_V2, reconnect is subject to additional conditions. The ofile
 212  *    will be unwired from the old, disconnected session, tree, and user,
 213  *    and wired up to its new context.
 214  *
 215  * Transition T5
 216  *
 217  *    This transition occurs in smb2_dh_reconnect(). The ofile has been
 218  *    successfully reclaimed.
 219  *
 220  * Transition T6
 221  *
 222  *    This transition occurs in smb_ofile_close(). The ofile has been orphaned
 223  *    while some thread was blocked, and that thread closes the ofile. Can only
 224  *    happen when the ofile is orphaned due to an SMB2 LOGOFF request.
 225  *
 226  * Transition T7
 227  *
 228  *    This transition occurs in smb_session_durable_timers() and
 229  *    smb_oplock_send_brk(). The ofile will soon be closed.
 230  *    In the former case, f_timeout_offset nanoseconds have passed since
 231  *    the ofile was orphaned. In the latter, an oplock break occured
 232  *    on the ofile while it was orphaned.
 233  *
 234  * Transition T8
 235  *
 236  *    This transition occurs in smb_ofile_close().
 237  *
 238  * Transition T9
 239  *
 240  *    This transition occurs in smb_ofile_delete().
 241  *
 242  * Comments
 243  * --------
 244  *
 245  *    The state machine of the ofile structures is controlled by 3 elements:
 246  *      - The list of ofiles of the tree it belongs to.
 247  *      - The mutex embedded in the structure itself.
 248  *      - The reference count.
 249  *
 250  *    There's a mutex embedded in the ofile structure used to protect its fields
 251  *    and there's a lock embedded in the list of ofiles of a tree. To
 252  *    increment or to decrement the reference count the mutex must be entered.
 253  *    To insert the ofile into the list of ofiles of the tree and to remove
 254  *    the ofile from it, the lock must be entered in RW_WRITER mode.
 255  *
 256  *    Rules of access to a ofile structure:
 257  *
 258  *    1) In order to avoid deadlocks, when both (mutex and lock of the ofile
 259  *       list) have to be entered, the lock must be entered first. Additionally,
 260  *       f_mutex must not be held when removing the ofile from sv_persistid_ht.
 261  *
 262  *    2) All actions applied to an ofile require a reference count.
 263  *
 264  *    3) There are 2 ways of getting a reference count. One is when the ofile
 265  *       is opened. The other one when the ofile is looked up. This translates
 266  *       into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid().
 267  *
 268  *    It should be noted that the reference count of an ofile registers the
 269  *    number of references to the ofile in other structures (such as an smb
 270  *    request). The reference count is not incremented in these 2 instances:
 271  *
 272  *    1) The ofile is open. An ofile is anchored by its state. If there's
 273  *       no activity involving an ofile currently open, the reference count
 274  *       of that ofile is zero.
 275  *
 276  *    2) The ofile is queued in the list of ofiles of its tree. The fact of
 277  *       being queued in that list is NOT registered by incrementing the
 278  *       reference count.
 279  */
 280 #include <smbsrv/smb2_kproto.h>
 281 #include <smbsrv/smb_fsops.h>
 282 #include <sys/time.h>
 283 #include <sys/random.h>
 284 
 285 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *);
 286 static void smb_ofile_delete(void *arg);
 287 static void smb_ofile_save_dh(void *arg);
 288 
 289 static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t,
 290     uint32_t *);
 291 static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *);
 292 static void smb_ofile_netinfo_fini(smb_netfileinfo_t *);
 293 
 294 /*
 295  * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
 296  * which is used to uniquely identify open instances for the
 297  * VFS share reservation and POSIX locks.
 298  */
 299 static volatile uint32_t smb_fids = 0;
 300 #define SMB_UNIQ_FID()  atomic_inc_32_nv(&smb_fids)
 301 
 302 /*
 303  * smb_ofile_alloc
 304  * Allocate an ofile and fill in it's "up" pointers, but
 305  * do NOT link it into the tree's list of ofiles or the
 306  * node's list of ofiles.  An ofile in this state is a
 307  * "proposed" open passed to the oplock break code.
 308  *
 309  * If we don't get as far as smb_ofile_open with this OF,
 310  * call smb_ofile_free() to free this object.
 311  *
 312  * Note: The following sr members may be null during
 313  * persistent handle import: session, uid_usr, tid_tree
 314  */
 315 smb_ofile_t *
 316 smb_ofile_alloc(
 317     smb_request_t       *sr,
 318     smb_arg_open_t      *op,
 319     smb_node_t          *node, /* optional (may be NULL) */
 320     uint16_t            ftype,
 321     uint16_t            tree_fid)

 322 {
 323         smb_user_t      *user = sr->uid_user;        /* optional */
 324         smb_tree_t      *tree = sr->tid_tree;        /* optional */
 325         smb_ofile_t     *of;





 326 








 327         of = kmem_cache_alloc(smb_cache_ofile, KM_SLEEP);
 328         bzero(of, sizeof (smb_ofile_t));
 329         of->f_magic = SMB_OFILE_MAGIC;
 330 
 331         mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL);
 332         list_create(&of->f_notify.nc_waiters, sizeof (smb_request_t),
 333             offsetof(smb_request_t, sr_waiters));
 334         mutex_init(&of->dh_nvlock, NULL, MUTEX_DEFAULT, NULL);
 335 
 336         of->f_state = SMB_OFILE_STATE_ALLOC;
 337         of->f_refcnt = 1;
 338         of->f_ftype = ftype;
 339         of->f_fid = tree_fid;
 340         /* of->f_persistid see smb2_create */
 341         of->f_uniqid = SMB_UNIQ_FID();
 342         of->f_opened_by_pid = sr->smb_pid;
 343         of->f_granted_access = op->desired_access;
 344         of->f_share_access = op->share_access;
 345         of->f_create_options = op->create_options;
 346         if (user != NULL) {
 347                 if ((op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) != 0)
 348                         of->f_cr = smb_user_getprivcred(user);
 349                 else
 350                         of->f_cr = user->u_cred;
 351                 crhold(of->f_cr);
 352         }
 353         of->f_server = sr->sr_server;
 354         of->f_session = sr->session;      /* may be NULL */









 355 
 356         (void) memset(of->f_lock_seq, -1, SMB_OFILE_LSEQ_MAX);


 357 
 358         of->f_mode = smb_fsop_amask_to_omode(of->f_granted_access);
 359         if ((of->f_granted_access & FILE_DATA_ALL) == FILE_EXECUTE)
 360                 of->f_flags |= SMB_OFLAGS_EXECONLY;




 361 
 362         /*
 363          * In case a lease is requested, copy the lease keys now so
 364          * any oplock breaks during open don't break those on our
 365          * other handles that might have the same lease.
 366          */
 367         bcopy(op->lease_key, of->TargetOplockKey, SMB_LEASE_KEY_SZ);
 368         bcopy(op->parent_lease_key, of->ParentOplockKey, SMB_LEASE_KEY_SZ);
 369 










 370         /*
 371          * grab a ref for of->f_user and of->f_tree
 372          * We know the user and tree must be "live" because
 373          * this SR holds references to them.  The node ref. is
 374          * held by our caller, until smb_ofile_open puts this
 375          * ofile on the node ofile list with smb_node_add_ofile.
 376          */
 377         if (user != NULL) {
 378                 smb_user_hold_internal(user);
 379                 of->f_user = user;
 380         }
 381         if (tree != NULL) {
 382                 smb_tree_hold_internal(tree);
 383                 of->f_tree = tree;






 384         }
 385         of->f_node = node;   /* may be NULL */
 386 
 387         return (of);
 388 }
 389 
 390 /*
 391  * smb_ofile_open
 392  *
 393  * Complete an open on an ofile that was previously allocated by
 394  * smb_ofile_alloc, by putting it on the tree ofile list and
 395  * (if it's a file) the node ofile list.
 396  */
 397 void
 398 smb_ofile_open(
 399     smb_request_t       *sr,
 400     smb_arg_open_t      *op,
 401     smb_ofile_t         *of)
 402 {
 403         smb_tree_t      *tree = sr->tid_tree;
 404         smb_node_t      *node = of->f_node;
 405 
 406         ASSERT(of->f_state == SMB_OFILE_STATE_ALLOC);
 407         of->f_state = SMB_OFILE_STATE_OPEN;
 408 
 409         switch (of->f_ftype) {
 410         case SMB_FTYPE_BYTE_PIPE:
 411         case SMB_FTYPE_MESG_PIPE:
 412                 /* See smb_opipe_open. */
 413                 of->f_pipe = op->pipe;
 414                 smb_server_inc_pipes(of->f_server);
 415                 break;
 416         case SMB_FTYPE_DISK:
 417         case SMB_FTYPE_PRINTER:
 418                 /* Regular file, not a pipe */
 419                 ASSERT(node != NULL);
 420 
 421                 smb_node_inc_open_ofiles(node);
 422                 smb_node_add_ofile(node, of);
 423                 smb_node_ref(node);
 424                 smb_server_inc_files(of->f_server);
 425                 break;
 426         default:
 427                 ASSERT(0);
 428         }
 429         smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
 430         smb_llist_insert_tail(&tree->t_ofile_list, of);
 431         smb_llist_exit(&tree->t_ofile_list);
 432         atomic_inc_32(&tree->t_open_files);
 433         atomic_inc_32(&of->f_session->s_file_cnt);

 434 


















 435 }
 436 
 437 /*
 438  * smb_ofile_close
 439  *
 440  * Incoming states: (where from)
 441  *   SMB_OFILE_STATE_OPEN  protocol close, smb_ofile_drop
 442  *   SMB_OFILE_STATE_EXPIRED  called via smb2_dh_expire
 443  *   SMB_OFILE_STATE_ORPHANED  smb_server_cleanup_sessions()
 444  */
 445 void
 446 smb_ofile_close(smb_ofile_t *of, int32_t mtime_sec)
 447 {
 448         smb_attr_t *pa;
 449         timestruc_t now;

 450 
 451         SMB_OFILE_VALID(of);
 452 
 453         mutex_enter(&of->f_mutex);
 454         ASSERT(of->f_refcnt);
 455 
 456         switch (of->f_state) {
 457         case SMB_OFILE_STATE_OPEN:
 458         case SMB_OFILE_STATE_ORPHANED:
 459         case SMB_OFILE_STATE_EXPIRED:
 460                 of->f_state = SMB_OFILE_STATE_CLOSING;
 461                 mutex_exit(&of->f_mutex);
 462                 break;
 463         default:
 464                 mutex_exit(&of->f_mutex);
 465                 return;
 466         }


 467 
 468         /*
 469          * Only one thread here (the one that that set f_state closing)
 470          */
 471         switch (of->f_ftype) {
 472         case SMB_FTYPE_BYTE_PIPE:
 473         case SMB_FTYPE_MESG_PIPE:
 474                 smb_opipe_close(of);
 475                 smb_server_dec_pipes(of->f_server);
 476                 break;
 477 
 478         case SMB_FTYPE_DISK:
 479                 if (of->dh_persist)
 480                         smb2_dh_close_persistent(of);
 481                 if (of->f_persistid != 0)
 482                         smb_ofile_del_persistid(of);
 483                 if (of->f_lease != NULL)
 484                         smb2_lease_ofile_close(of);
 485                 smb_oplock_break_CLOSE(of->f_node, of);
 486                 /* FALLTHROUGH */
 487 
 488         case SMB_FTYPE_PRINTER: /* or FTYPE_DISK */
 489                 /*
 490                  * In here we make changes to of->f_pending_attr
 491                  * while not holding of->f_mutex.  This is OK
 492                  * because we've changed f_state to CLOSING,
 493                  * so no more threads will take this path.
 494                  */
 495                 pa = &of->f_pending_attr;
 496                 if (mtime_sec != 0) {
 497                         pa->sa_vattr.va_mtime.tv_sec = mtime_sec;
 498                         pa->sa_mask |= SMB_AT_MTIME;
 499                 }
 500 
 501                 /*
 502                  * If we have ever modified data via this handle
 503                  * (write or truncate) and if the mtime was not
 504                  * set via this handle, update the mtime again
 505                  * during the close.  Windows expects this.
 506                  * [ MS-FSA 2.1.5.4 "Update Timestamps" ]
 507                  */
 508                 if (of->f_written &&
 509                     (pa->sa_mask & SMB_AT_MTIME) == 0) {
 510                         pa->sa_mask |= SMB_AT_MTIME;
 511                         gethrestime(&now);
 512                         pa->sa_vattr.va_mtime = now;
 513                 }
 514 
 515                 if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) {
 516                         /* We delete using the on-disk name. */
 517                         uint32_t flags = SMB_CASE_SENSITIVE;


 518                         (void) smb_node_set_delete_on_close(of->f_node,
 519                             of->f_cr, flags);
 520                 }
 521                 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid);
 522                 smb_node_destroy_lock_by_ofile(of->f_node, of);
 523 
 524                 if (smb_node_is_file(of->f_node)) {
 525                         (void) smb_fsop_close(of->f_node, of->f_mode,
 526                             of->f_cr);

 527                 } else {
 528                         /*
 529                          * If there was an odir, close it.
 530                          */
 531                         if (of->f_odir != NULL)
 532                                 smb_odir_close(of->f_odir);
 533                         /*
 534                          * Cancel any notify change requests that
 535                          * might be watching this open file (dir),
 536                          * and unsubscribe it from node events.
 537                          *
 538                          * Can't hold f_mutex when calling smb_notify_ofile.
 539                          * Don't really need it when unsubscribing, but
 540                          * harmless, and consistent with subscribing.
 541                          */
 542                         if (of->f_notify.nc_subscribed)
 543                                 smb_notify_ofile(of,
 544                                     FILE_ACTION_HANDLE_CLOSED, NULL);
 545                         mutex_enter(&of->f_mutex);
 546                         if (of->f_notify.nc_subscribed) {
 547                                 of->f_notify.nc_subscribed = B_FALSE;
 548                                 smb_node_fcn_unsubscribe(of->f_node);
 549                                 of->f_notify.nc_filter = 0;
 550                         }
 551                         mutex_exit(&of->f_mutex);
 552                 }
 553                 if (smb_node_dec_open_ofiles(of->f_node) == 0) {
 554                         /*
 555                          * Last close.  If we're not deleting
 556                          * the file, apply any pending attrs.
 557                          * Leave allocsz zero when no open files,
 558                          * just to avoid confusion, because it's
 559                          * only updated when there are opens.
 560                          * XXX: Just do this on _every_ close.
 561                          */
 562                         mutex_enter(&of->f_node->n_mutex);
 563                         if (of->f_node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
 564                                 smb_node_delete_on_close(of->f_node);
 565                                 pa->sa_mask = 0;
 566                         }
 567                         of->f_node->n_allocsz = 0;
 568                         mutex_exit(&of->f_node->n_mutex);
 569                 }
 570                 if (pa->sa_mask != 0) {
 571                         /*
 572                          * Commit any pending attributes from
 573                          * the ofile we're closing.  Note that
 574                          * we pass NULL as the ofile to setattr
 575                          * so it will write to the file system
 576                          * and not keep anything on the ofile.



 577                          */
 578                         (void) smb_node_setattr(NULL, of->f_node,
 579                             of->f_cr, NULL, pa);
 580                 }
 581 







 582                 smb_server_dec_files(of->f_server);
 583                 break;
 584         }

 585 
 586         /*
 587          * Keep f_state == SMB_OFILE_STATE_CLOSING
 588          * until the last ref. is dropped, in
 589          * smb_ofile_release()
 590          */
 591 }
 592 
 593 /*
 594  * "Destructor" function for smb_ofile_close_all, and
 595  * smb_ofile_close_all_by_pid, called after the llist lock
 596  * for tree list has been exited.  Our job is to either
 597  * close this ofile, or (if durable) set state _SAVE_DH.
 598  *
 599  * The next interesting thing happens when the last ref.
 600  * on this ofile calls smb_ofile_release(), where we
 601  * eihter delete the ofile, or (if durable) leave it
 602  * in the persistid hash table for possible reclaim.
 603  *
 604  * This is run via smb_llist_post (after smb_llist_exit)
 605  * because smb_ofile_close can block, and we'd rather not
 606  * block while holding the ofile list as reader.
 607  */
 608 static void
 609 smb_ofile_drop(void *arg)

 610 {
 611         smb_ofile_t     *of = arg;
 612 
 613         mutex_enter(&of->f_mutex);
 614         switch (of->f_state) {
 615         case SMB_OFILE_STATE_OPEN:
 616                 /* DH checks under mutex. */
 617                 if (of->f_ftype == SMB_FTYPE_DISK &&
 618                     of->dh_vers != SMB2_NOT_DURABLE &&
 619                     smb_dh_should_save(of)) {
 620                         /*
 621                          * Tell smb_ofile_release() to
 622                          * make this an _ORPHANED DH.
 623                          */
 624                         of->f_state = SMB_OFILE_STATE_SAVE_DH;
 625                         mutex_exit(&of->f_mutex);
 626                         break;
 627                 }
 628                 /* OK close it. */
 629                 mutex_exit(&of->f_mutex);
 630                 smb_ofile_close(of, 0);
 631                 break;
 632 
 633         default:
 634                 /* Something else closed it already. */
 635                 mutex_exit(&of->f_mutex);
 636                 break;


 637         }
 638 
 639         /*
 640          * Release the ref acquired during the traversal loop.
 641          * Note that on the last ref, this ofile will be
 642          * removed from the tree list etc.
 643          * See: smb_llist_post, smb_ofile_delete
 644          */
 645         smb_ofile_release(of);
 646 }
 647 
 648 /*
 649  * smb_ofile_close_all
 650  *
 651  *
 652  */
 653 void
 654 smb_ofile_close_all(
 655     smb_tree_t          *tree,
 656     uint32_t            pid)
 657 {
 658         smb_ofile_t     *of;
 659         smb_llist_t     *ll;
 660 
 661         ASSERT(tree);
 662         ASSERT(tree->t_magic == SMB_TREE_MAGIC);
 663 
 664         ll = &tree->t_ofile_list;
 665 
 666         smb_llist_enter(ll, RW_READER);
 667         for (of = smb_llist_head(ll);
 668             of != NULL;
 669             of = smb_llist_next(ll, of)) {
 670                 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 671                 ASSERT(of->f_tree == tree);
 672                 if (pid != 0 && of->f_opened_by_pid != pid)
 673                         continue;
 674                 if (smb_ofile_hold(of)) {
 675                         smb_llist_post(ll, of, smb_ofile_drop);
 676                 }
 677         }
 678 
 679         /*
 680          * Drop the lock and process the llist dtor queue.
 681          * Calls smb_ofile_drop on ofiles that were open.
 682          */
 683         smb_llist_exit(ll);
 684 }
 685 
 686 /*
 687  * If the enumeration request is for ofile data, handle it here.
 688  * Otherwise, return.
 689  *
 690  * This function should be called with a hold on the ofile.
 691  */
 692 int
 693 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum)
 694 {
 695         uint8_t *pb;
 696         uint_t nbytes;
 697         int rc;
 698 
 699         ASSERT(of);
 700         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 701         ASSERT(of->f_refcnt);
 702 
 703         if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE)


 710 
 711         if (svcenum->se_nitems >= svcenum->se_nlimit) {
 712                 svcenum->se_nitems = svcenum->se_nlimit;
 713                 return (0);
 714         }
 715 
 716         pb = &svcenum->se_buf[svcenum->se_bused];
 717 
 718         rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail,
 719             &nbytes);
 720         if (rc == 0) {
 721                 svcenum->se_bavail -= nbytes;
 722                 svcenum->se_bused += nbytes;
 723                 svcenum->se_nitems++;
 724         }
 725 
 726         return (rc);
 727 }
 728 
 729 /*
 730  * Take a reference on an open file, in any of the states:
 731  *   RECONNECT, SAVE_DH, OPEN, ORPHANED.
 732  * Return TRUE if ref taken.  Used for oplock breaks.
 733  *
 734  * Note: When the oplock break code calls this, it holds the
 735  * node ofile list lock and node oplock mutex.  When we see
 736  * an ofile in states RECONNECT or SAVING, we know the ofile
 737  * is gaining or losing it's tree, and that happens quickly,
 738  * so we just wait for that work to finish.  However, the
 739  * waiting for state transitions here means we have to be
 740  * careful not to re-enter the node list lock or otherwise
 741  * block on things that could cause a deadlock.  Waiting
 742  * just on of->f_mutex here is OK.
 743  */
 744 boolean_t
 745 smb_ofile_hold_olbrk(smb_ofile_t *of)
 746 {
 747         boolean_t ret = B_FALSE;
 748 
 749         ASSERT(of);
 750         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 751 
 752         mutex_enter(&of->f_mutex);
 753 
 754 again:
 755         switch (of->f_state) {
 756         case SMB_OFILE_STATE_RECONNECT:
 757         case SMB_OFILE_STATE_SAVING:
 758                 cv_wait(&of->f_cv, &of->f_mutex);
 759                 goto again;
 760 
 761         case SMB_OFILE_STATE_OPEN:
 762         case SMB_OFILE_STATE_ORPHANED:
 763         case SMB_OFILE_STATE_SAVE_DH:
 764                 of->f_refcnt++;
 765                 ret = B_TRUE;
 766                 break;
 767 
 768         default:
 769                 break;
 770         }
 771         mutex_exit(&of->f_mutex);
 772 
 773         return (ret);
 774 }
 775 
 776 /*
 777  * Take a reference on an open file.
 778  */
 779 boolean_t
 780 smb_ofile_hold(smb_ofile_t *of)
 781 {
 782         ASSERT(of);
 783         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 784 
 785         mutex_enter(&of->f_mutex);
 786 
 787         if (of->f_state != SMB_OFILE_STATE_OPEN) {
 788                 mutex_exit(&of->f_mutex);
 789                 return (B_FALSE);
 790         }
 791         of->f_refcnt++;
 792 
 793         mutex_exit(&of->f_mutex);
 794         return (B_TRUE);
 795 }
 796 
 797 /*
 798  * Release a reference on a file.  If the reference count falls to
 799  * zero and the file has been closed, post the object for deletion.
 800  * Object deletion is deferred to avoid modifying a list while an
 801  * iteration may be in progress.
 802  *
 803  * We're careful to avoid dropping f_session etc. until the last
 804  * reference goes away.  The oplock break code depends on that
 805  * not changing while it holds a ref. on an ofile.
 806  */
 807 void
 808 smb_ofile_release(smb_ofile_t *of)
 809 {
 810         smb_tree_t *tree = of->f_tree;
 811         boolean_t delete = B_FALSE;
 812 
 813         SMB_OFILE_VALID(of);
 814 
 815         mutex_enter(&of->f_mutex);
 816         ASSERT(of->f_refcnt > 0);
 817         of->f_refcnt--;
 818 
 819         switch (of->f_state) {
 820         case SMB_OFILE_STATE_OPEN:
 821         case SMB_OFILE_STATE_ORPHANED:
 822         case SMB_OFILE_STATE_EXPIRED:
 823                 break;
 824 
 825         case SMB_OFILE_STATE_SAVE_DH:
 826                 ASSERT(tree != NULL);
 827                 if (of->f_refcnt == 0) {
 828                         of->f_state = SMB_OFILE_STATE_SAVING;
 829                         smb_llist_post(&tree->t_ofile_list, of,
 830                             smb_ofile_save_dh);
 831                 }
 832                 break;
 833 
 834         case SMB_OFILE_STATE_CLOSING:
 835                 /* Note, tree == NULL on _ORPHANED */
 836                 if (of->f_refcnt == 0) {
 837                         of->f_state = SMB_OFILE_STATE_CLOSED;
 838                         if (tree == NULL) {
 839                                 /* Skip smb_llist_post */
 840                                 delete = B_TRUE;
 841                                 break;
 842                         }
 843                         smb_llist_post(&tree->t_ofile_list, of,
 844                             smb_ofile_delete);
 845                 }
 846                 break;
 847 
 848         default:
 849                 ASSERT(0);
 850                 break;
 851         }
 852         mutex_exit(&of->f_mutex);

 853 
 854         /*
 855          * When we drop the last ref. on an expired DH, it's no longer
 856          * in any tree, so skip the smb_llist_post and just call
 857          * smb_ofile_delete directly.







 858          */
 859         if (delete) {
 860                 smb_ofile_delete(of);












 861         }
 862 }
 863 
 864 /*
 865  * smb_ofile_lookup_by_fid
 866  *
 867  * Find the open file whose fid matches the one specified in the request.
 868  * If we can't find the fid or the shares (trees) don't match, we have a
 869  * bad fid.
 870  */
 871 smb_ofile_t *
 872 smb_ofile_lookup_by_fid(
 873     smb_request_t       *sr,
 874     uint16_t            fid)
 875 {
 876         smb_tree_t      *tree = sr->tid_tree;
 877         smb_llist_t     *of_list;
 878         smb_ofile_t     *of;
 879 
 880         ASSERT(tree->t_magic == SMB_TREE_MAGIC);


 885         of = smb_llist_head(of_list);
 886         while (of) {
 887                 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 888                 ASSERT(of->f_tree == tree);
 889                 if (of->f_fid == fid)
 890                         break;
 891                 of = smb_llist_next(of_list, of);
 892         }
 893         if (of == NULL)
 894                 goto out;
 895 
 896         /*
 897          * Only allow use of a given FID with the same UID that
 898          * was used to open it.  MS-CIFS 3.3.5.14
 899          */
 900         if (of->f_user != sr->uid_user) {
 901                 of = NULL;
 902                 goto out;
 903         }
 904 
 905         /* inline smb_ofile_hold() */
 906         mutex_enter(&of->f_mutex);
 907         if (of->f_state != SMB_OFILE_STATE_OPEN) {
 908                 mutex_exit(&of->f_mutex);
 909                 of = NULL;
 910                 goto out;
 911         }
 912         of->f_refcnt++;
 913         mutex_exit(&of->f_mutex);
 914 
 915 out:
 916         smb_llist_exit(of_list);
 917         return (of);
 918 }
 919 
 920 /*
 921  * smb_ofile_lookup_by_uniqid
 922  *
 923  * Find the open file whose uniqid matches the one specified in the request.
 924  */
 925 smb_ofile_t *


 936 
 937         while (of) {
 938                 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
 939                 ASSERT(of->f_tree == tree);
 940 
 941                 if (of->f_uniqid == uniqid) {
 942                         if (smb_ofile_hold(of)) {
 943                                 smb_llist_exit(of_list);
 944                                 return (of);
 945                         }
 946                 }
 947 
 948                 of = smb_llist_next(of_list, of);
 949         }
 950 
 951         smb_llist_exit(of_list);
 952         return (NULL);
 953 }
 954 
 955 /*
 956  * Durable ID (or persistent ID)
 957  */
 958 
 959 static smb_ofile_t *
 960 smb_ofile_hold_cb(smb_ofile_t *of)
 961 {
 962         smb_ofile_t *ret = of;
 963 
 964         mutex_enter(&of->f_mutex);
 965         if (of->f_state == SMB_OFILE_STATE_ORPHANED)
 966                 /* inline smb_ofile_hold() */
 967                 of->f_refcnt++;
 968         else
 969                 ret = NULL;
 970 
 971         mutex_exit(&of->f_mutex);
 972         return (ret);
 973 }
 974 
 975 /*
 976  * Lookup an ofile by persistent ID, and return ONLY if in state ORPHANED
 977  * This is used by SMB2 create "reclaim".
 978  */
 979 smb_ofile_t *
 980 smb_ofile_lookup_by_persistid(smb_request_t *sr, uint64_t persistid)
 981 {
 982         smb_hash_t *hash;
 983         smb_bucket_t *bucket;
 984         smb_llist_t *ll;
 985         smb_ofile_t *of;
 986         uint_t idx;
 987 
 988         if (persistid == 0)
 989                 return (NULL);
 990 
 991         hash = sr->sr_server->sv_persistid_ht;
 992         idx = smb_hash_uint64(hash, persistid);
 993         bucket = &hash->buckets[idx];
 994         ll = &bucket->b_list;
 995 
 996         smb_llist_enter(ll, RW_READER);
 997         of = smb_llist_head(ll);
 998         while (of != NULL) {
 999                 if (of->f_persistid == persistid)
1000                         break;
1001                 of = smb_llist_next(ll, of);
1002         }
1003         if (of != NULL)
1004                 of = smb_ofile_hold_cb(of);
1005         smb_llist_exit(ll);
1006 
1007         return (of);
1008 }
1009 
1010 /*
1011  * Create a (unique) durable/persistent ID for a new ofile,
1012  * and add this ofile to the persistid hash table.  This ID
1013  * is referred to as the persistent ID in the protocol spec,
1014  * so that's what we call it too, though the persistence may
1015  * vary.  "Durable" handles are persistent across reconnects
1016  * but not server reboots.  Persistent handles are persistent
1017  * across server reboots too.
1018  *
1019  * Note that persistent IDs need to be unique for the lifetime of
1020  * any given ofile.  For normal (non-persistent) ofiles we can just
1021  * use a persistent ID derived from the ofile memory address, as
1022  * these don't ever live beyond the current OS boot lifetime.
1023  *
1024  * Persistent handles are re-imported after server restart, and
1025  * generally have a different memory address after import than
1026  * they had in the previous OS boot lifetime, so for these we
1027  * use a randomly assigned value that won't conflict with any
1028  * non-persistent (durable) handles.  Ensuring that a randomly
1029  * generated ID is unique requres a search of the ofiles in one
1030  * hash bucket, which we'd rather avoid for non-persistent opens.
1031  *
1032  * The solution used here is to divide the persistent ID space
1033  * in half (odd and even values) where durable opens use an ID
1034  * derived from the ofile address (which is always even), and
1035  * persistent opens use an ID generated randomly (always odd).
1036  *
1037  * smb_ofile_set_persistid_dh() sets a durable handle ID and
1038  * smb_ofile_set_persistid_ph() sets a persistent handle ID.
1039  */
1040 void
1041 smb_ofile_set_persistid_dh(smb_ofile_t *of)
1042 {
1043         smb_hash_t *hash = of->f_server->sv_persistid_ht;
1044         smb_bucket_t *bucket;
1045         smb_llist_t *ll;
1046         uint64_t persistid;
1047         uint_t idx;
1048 
1049         persistid = (uintptr_t)of;
1050         /* Avoid showing object addresses */
1051         persistid ^= ((uintptr_t)&smb_cache_ofile);
1052         /* make sure it's even */
1053         persistid &= ~((uint64_t)1);
1054 
1055         idx = smb_hash_uint64(hash, persistid);
1056         bucket = &hash->buckets[idx];
1057         ll = &bucket->b_list;
1058         smb_llist_enter(ll, RW_WRITER);
1059         if (of->f_persistid == 0) {
1060                 of->f_persistid = persistid;
1061                 smb_llist_insert_tail(ll, of);
1062         }
1063         smb_llist_exit(ll);
1064 }
1065 
1066 void
1067 smb_ofile_set_persistid_ph(smb_ofile_t *of)
1068 {
1069         uint64_t persistid;
1070         int rc;
1071 
1072 top:
1073         (void) random_get_pseudo_bytes((uint8_t *)&persistid,
1074             sizeof (persistid));
1075         if (persistid == 0) {
1076                 cmn_err(CE_NOTE, "random gave all zeros!");
1077                 goto top;
1078         }
1079         /* make sure it's odd */
1080         persistid |= (uint64_t)1;
1081 
1082         /*
1083          * Try inserting with this persistent ID.
1084          */
1085         rc = smb_ofile_insert_persistid(of, persistid);
1086         if (rc == EEXIST)
1087                 goto top;
1088         if (rc != 0) {
1089                 cmn_err(CE_NOTE, "set persistid rc=%d", rc);
1090         }
1091 }
1092 
1093 /*
1094  * Insert an ofile into the persistid hash table.
1095  * If the persistent ID is in use, error.
1096  */
1097 int
1098 smb_ofile_insert_persistid(smb_ofile_t *new_of, uint64_t persistid)
1099 {
1100         smb_hash_t *hash = new_of->f_server->sv_persistid_ht;
1101         smb_bucket_t *bucket;
1102         smb_llist_t *ll;
1103         smb_ofile_t *of;
1104         uint_t idx;
1105 
1106         ASSERT(persistid != 0);
1107 
1108         /*
1109          * Look to see if this key alreay exists.
1110          */
1111         idx = smb_hash_uint64(hash, persistid);
1112         bucket = &hash->buckets[idx];
1113         ll = &bucket->b_list;
1114 
1115         smb_llist_enter(ll, RW_WRITER);
1116         of = smb_llist_head(ll);
1117         while (of != NULL) {
1118                 if (of->f_persistid == persistid) {
1119                         /* already in use */
1120                         smb_llist_exit(ll);
1121                         return (EEXIST);
1122                 }
1123                 of = smb_llist_next(ll, of);
1124         }
1125 
1126         /* Not found, so OK to insert. */
1127         if (new_of->f_persistid == 0) {
1128                 new_of->f_persistid = persistid;
1129                 smb_llist_insert_tail(ll, new_of);
1130         }
1131         smb_llist_exit(ll);
1132 
1133         return (0);
1134 }
1135 
1136 void
1137 smb_ofile_del_persistid(smb_ofile_t *of)
1138 {
1139         smb_hash_t *hash = of->f_server->sv_persistid_ht;
1140         smb_bucket_t *bucket;
1141         smb_llist_t *ll;
1142         uint_t idx;
1143 
1144         idx = smb_hash_uint64(hash, of->f_persistid);
1145         bucket = &hash->buckets[idx];
1146         ll = &bucket->b_list;
1147         smb_llist_enter(ll, RW_WRITER);
1148         if (of->f_persistid != 0) {
1149                 smb_llist_remove(ll, of);
1150                 of->f_persistid = 0;
1151         }
1152         smb_llist_exit(ll);
1153 }
1154 
1155 
1156 /*
1157  * Disallow NetFileClose on certain ofiles to avoid side-effects.
1158  * Closing a tree root is not allowed: use NetSessionDel or NetShareDel.
1159  * Closing SRVSVC connections is not allowed because this NetFileClose
1160  * request may depend on this ofile.
1161  */
1162 boolean_t
1163 smb_ofile_disallow_fclose(smb_ofile_t *of)
1164 {
1165         ASSERT(of);
1166         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1167         ASSERT(of->f_refcnt);
1168 
1169         switch (of->f_ftype) {
1170         case SMB_FTYPE_DISK:
1171                 ASSERT(of->f_tree);
1172                 return (of->f_node == of->f_tree->t_snode);
1173 
1174         case SMB_FTYPE_MESG_PIPE:
1175                 ASSERT(of->f_pipe);
1176                 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0)


1309 {
1310         boolean_t       rc;
1311 
1312         SMB_OFILE_VALID(of);
1313 
1314         mutex_enter(&of->f_mutex);
1315         rc = smb_ofile_is_open_locked(of);
1316         mutex_exit(&of->f_mutex);
1317         return (rc);
1318 }
1319 
1320 /* *************************** Static Functions ***************************** */
1321 
1322 /*
1323  * Determine whether or not an ofile is open.
1324  * This function must be called with the mutex held.
1325  */
1326 static boolean_t
1327 smb_ofile_is_open_locked(smb_ofile_t *of)
1328 {
1329         ASSERT(MUTEX_HELD(&of->f_mutex));
1330 
1331         switch (of->f_state) {
1332         case SMB_OFILE_STATE_OPEN:
1333         case SMB_OFILE_STATE_SAVE_DH:
1334         case SMB_OFILE_STATE_SAVING:
1335         case SMB_OFILE_STATE_ORPHANED:
1336         case SMB_OFILE_STATE_RECONNECT:
1337                 return (B_TRUE);
1338 
1339         case SMB_OFILE_STATE_CLOSING:
1340         case SMB_OFILE_STATE_CLOSED:
1341         case SMB_OFILE_STATE_EXPIRED:
1342                 return (B_FALSE);
1343 
1344         default:
1345                 ASSERT(0);
1346                 return (B_FALSE);
1347         }
1348 }
1349 
1350 /*
1351  * smb_ofile_save_dh
1352  *
1353  * Called via smb_llist_post (after smb_llist_exit) when the last ref.
1354  * on this ofile has gone, and this ofile is a "durable handle" (DH)
1355  * that has state we've decided to save.
1356  *
1357  * This does parts of what smb_ofile_delete would do, including:
1358  * remove the ofile from the tree ofile list and related.
1359  *
1360  * We leave the ofile in state ORPHANED, ready for reconnect
1361  * or expiration via smb2_dh_expire (see smb_ofile_delete).
1362  */
1363 static void
1364 smb_ofile_save_dh(void *arg)
1365 {
1366         smb_ofile_t     *of = (smb_ofile_t *)arg;
1367         smb_tree_t      *tree = of->f_tree;
1368 
1369         SMB_OFILE_VALID(of);
1370         ASSERT(of->f_refcnt == 0);
1371         ASSERT(of->f_ftype == SMB_FTYPE_DISK);
1372         ASSERT(of->f_state == SMB_OFILE_STATE_SAVING);
1373 
1374         atomic_dec_32(&of->f_session->s_file_cnt);
1375         atomic_dec_32(&of->f_tree->t_open_files);
1376         smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
1377         smb_llist_remove(&tree->t_ofile_list, of);
1378         smb_llist_exit(&tree->t_ofile_list);
1379 
1380         /*
1381          * This ofile is no longer on t_ofile_list, however...
1382          *
1383          * This is called via smb_llist_post, which means it may run
1384          * BEFORE smb_ofile_release drops f_mutex (if another thread
1385          * flushes the delete queue before we do).  Synchronize.
1386          */
1387         mutex_enter(&of->f_mutex);
1388         DTRACE_PROBE1(ofile__exit, smb_ofile_t, of);





1389         mutex_exit(&of->f_mutex);
1390 







1391         /*
1392          * Keep f_notify state, lease, and
1393          * keep on node ofile list.
1394          * Keep of->f_cr until reclaim.
1395          */
1396 
1397         ASSERT(of->f_fid != 0);
1398         smb_idpool_free(&tree->t_fid_pool, of->f_fid);
1399         of->f_fid = 0;
1400         smb_tree_release(of->f_tree);
1401         of->f_tree = NULL;
1402         smb_user_release(of->f_user);
1403         of->f_user = NULL;
1404         of->f_session = NULL;
1405 
1406         /*
1407          * Make it "orphaned" so it can now be reclaimed.
1408          * Note that smb_ofile_hold_olbrk() may have blocked
1409          * for state SMB_OFILE_STATE_SAVING, so wake it.
1410          */
1411         mutex_enter(&of->f_mutex);
1412         of->dh_expire_time = gethrtime() + of->dh_timeout_offset;
1413         of->f_state = SMB_OFILE_STATE_ORPHANED;
1414         cv_broadcast(&of->f_cv);
1415         mutex_exit(&of->f_mutex);









1416 }
1417 
1418 /*
1419  * Delete an ofile.
1420  *
1421  * Approximately the inverse of smb_ofile_alloc()
1422  * Called via smb_llist_post (after smb_llist_exit)
1423  * when the last ref. on this ofile has gone.
1424  *
1425  * Normally,this removes the ofile from the tree list and
1426  * then frees resources held on the ofile.  However, when
1427  * we're expiring an orphaned durable handle, the linkage
1428  * into the tree lists etc. have already been destroyed.
1429  * This case is distinguished by of->f_tree == NULL.
1430  */
1431 static void
1432 smb_ofile_delete(void *arg)
1433 {

1434         smb_ofile_t     *of = (smb_ofile_t *)arg;
1435         smb_tree_t      *tree = of->f_tree;
1436 
1437         SMB_OFILE_VALID(of);
1438         ASSERT(of->f_refcnt == 0);
1439         ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED);

1440 
1441         if (tree != NULL) {
1442                 ASSERT(of->f_user != NULL);
1443                 ASSERT(of->f_session != NULL);
1444                 atomic_dec_32(&of->f_session->s_file_cnt);
1445                 atomic_dec_32(&of->f_tree->t_open_files);
1446                 smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
1447                 smb_llist_remove(&tree->t_ofile_list, of);


1448                 smb_llist_exit(&tree->t_ofile_list);
1449         }
1450 
1451         /*
1452          * Remove this ofile from the node's n_ofile_list so it
1453          * can't be found by list walkers like notify or oplock.
1454          * Keep the node ref. until later in this function so
1455          * of->f_node remains valid while we destroy the ofile.
1456          */
1457         if (of->f_ftype == SMB_FTYPE_DISK ||
1458             of->f_ftype == SMB_FTYPE_PRINTER) {
1459                 ASSERT(of->f_node != NULL);
1460                 /*
1461                  * Note smb_ofile_close did smb_node_dec_open_ofiles()
1462                  */
1463                 smb_node_rem_ofile(of->f_node, of);
1464         }
1465 
1466         /*
1467          * This ofile is no longer on any lists, however...
1468          *
1469          * This is called via smb_llist_post, which means it may run
1470          * BEFORE smb_ofile_release drops f_mutex (if another thread
1471          * flushes the delete queue before we do).  Synchronize.
1472          */
1473         mutex_enter(&of->f_mutex);
1474         of->f_state = SMB_OFILE_STATE_ALLOC;
1475         DTRACE_PROBE1(ofile__exit, smb_ofile_t, of);
1476         mutex_exit(&of->f_mutex);
1477 
1478         switch (of->f_ftype) {
1479         case SMB_FTYPE_BYTE_PIPE:
1480         case SMB_FTYPE_MESG_PIPE:
1481                 smb_opipe_dealloc(of->f_pipe);
1482                 of->f_pipe = NULL;
1483                 break;
1484         case SMB_FTYPE_DISK:
1485                 ASSERT(of->f_notify.nc_subscribed == B_FALSE);
1486                 MBC_FLUSH(&of->f_notify.nc_buffer);
1487                 if (of->f_odir != NULL)
1488                         smb_odir_release(of->f_odir);
1489                 if (of->f_lease != NULL) {
1490                         smb2_lease_rele(of->f_lease);
1491                         of->f_lease = NULL;
1492                 }
1493                 /* FALLTHROUGH */
1494         case SMB_FTYPE_PRINTER:
1495                 /*
1496                  * Did smb_node_rem_ofile above.
1497                  */
1498                 ASSERT(of->f_node != NULL);
1499                 smb_node_release(of->f_node);
1500                 break;
1501         default:
1502                 ASSERT(!"f_ftype");
1503                 break;
1504         }
1505 
1506         smb_ofile_free(of);
1507 }
1508 
1509 void
1510 smb_ofile_free(smb_ofile_t *of)
1511 {
1512         smb_tree_t      *tree = of->f_tree;
1513 
1514         ASSERT(of->f_state == SMB_OFILE_STATE_ALLOC);
1515 
1516         /* Make sure it's not in the persistid hash. */
1517         ASSERT(of->f_persistid == 0);
1518 
1519         if (tree != NULL) {
1520                 if (of->f_fid != 0)
1521                         smb_idpool_free(&tree->t_fid_pool, of->f_fid);
1522                 smb_tree_release(of->f_tree);
1523                 smb_user_release(of->f_user);
1524         }
1525 
1526         if (of->f_cr != NULL)
1527                 crfree(of->f_cr);
1528 
1529         of->f_magic = (uint32_t)~SMB_OFILE_MAGIC;
1530         list_destroy(&of->f_notify.nc_waiters);
1531         mutex_destroy(&of->dh_nvlock);
1532         mutex_destroy(&of->f_mutex);


1533         kmem_cache_free(smb_cache_ofile, of);
1534 }
1535 
1536 /*
1537  * smb_ofile_access
1538  *
1539  * This function will check to see if the access requested is granted.
1540  * Returns NT status codes.
1541  */
1542 uint32_t
1543 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access)
1544 {
1545 
1546         if ((of == NULL) || (cr == zone_kcred()))
1547                 return (NT_STATUS_SUCCESS);
1548 
1549         /*
1550          * If the request is for something
1551          * I don't grant it is an error
1552          */


1568  * Returns: B_TRUE  - share access non-zero
1569  *          B_FALSE - share access NONE
1570  */
1571 boolean_t
1572 smb_ofile_share_check(smb_ofile_t *of)
1573 {
1574         return (!SMB_DENY_ALL(of->f_share_access));
1575 }
1576 
1577 /*
1578  * check file sharing rules for current open request
1579  * against existing open instances of the same file
1580  *
1581  * Returns NT_STATUS_SHARING_VIOLATION if there is any
1582  * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
1583  */
1584 uint32_t
1585 smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access,
1586     uint32_t share_access)
1587 {
1588         uint32_t ret;
1589 
1590         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1591 
1592         mutex_enter(&of->f_mutex);
1593 
1594         if (!smb_ofile_is_open_locked(of)) {
1595                 ret = NT_STATUS_INVALID_HANDLE;
1596                 goto out;
1597         }
1598 
1599         /* if it's just meta data */
1600         if ((of->f_granted_access & FILE_DATA_ALL) == 0) {
1601                 ret = NT_STATUS_SUCCESS;
1602                 goto out;
1603         }
1604 
1605         /*
1606          * Check requested share access against the
1607          * open granted (desired) access
1608          */
1609         if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) {
1610                 ret = NT_STATUS_SHARING_VIOLATION;
1611                 goto out;
1612         }
1613 
1614         if (SMB_DENY_READ(share_access) &&
1615             (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1616                 ret = NT_STATUS_SHARING_VIOLATION;
1617                 goto out;
1618         }
1619 
1620         if (SMB_DENY_WRITE(share_access) &&
1621             (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1622                 ret = NT_STATUS_SHARING_VIOLATION;
1623                 goto out;
1624         }
1625 
1626         /* check requested desired access against the open share access */
1627         if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) {
1628                 ret = NT_STATUS_SHARING_VIOLATION;
1629                 goto out;
1630         }
1631 
1632         if (SMB_DENY_READ(of->f_share_access) &&
1633             (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1634                 ret = NT_STATUS_SHARING_VIOLATION;
1635                 goto out;
1636         }
1637 
1638         if (SMB_DENY_WRITE(of->f_share_access) &&
1639             (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1640                 ret = NT_STATUS_SHARING_VIOLATION;
1641                 goto out;
1642         }
1643 
1644         ret = NT_STATUS_SUCCESS;
1645 out:
1646         mutex_exit(&of->f_mutex);
1647         return (ret);
1648 }
1649 
1650 /*
1651  * smb_ofile_rename_check
1652  *
1653  * This does the work described in MS-FSA 2.1.5.1.2.2 (Algorithm
1654  * to Check Sharing Access to an Existing Stream or Directory),
1655  * where the "open in-progress" has DesiredAccess = DELETE and
1656  * SharingMode = SHARE_READ | SHARE_WRITE | SHARE_DELETE.



1657  */
1658 
1659 uint32_t
1660 smb_ofile_rename_check(smb_ofile_t *of)
1661 {
1662         uint32_t ret;
1663 
1664         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1665 
1666         mutex_enter(&of->f_mutex);
1667 
1668         if (!smb_ofile_is_open_locked(of)) {
1669                 ret = NT_STATUS_INVALID_HANDLE;
1670                 goto out;
1671         }
1672 
1673         if ((of->f_granted_access & FILE_DATA_ALL) == 0) {
1674                 ret = NT_STATUS_SUCCESS;
1675                 goto out;

1676         }
1677 
1678         if ((of->f_share_access & FILE_SHARE_DELETE) == 0) {
1679                 ret = NT_STATUS_SHARING_VIOLATION;
1680                 goto out;


1681         }

1682 
1683         ret = NT_STATUS_SUCCESS;
1684 out:
1685         mutex_exit(&of->f_mutex);
1686         return (ret);
1687 }
1688 
1689 /*
1690  * smb_ofile_delete_check
1691  *
1692  * An open file can be deleted only if opened for
1693  * accessing meta data. Share modes aren't important
1694  * in this case.
1695  *
1696  * NOTE: there is another mechanism for deleting an
1697  * open file that NT clients usually use.
1698  * That's setting "Delete on close" flag for an open
1699  * file.  In this way the file will be deleted after
1700  * last close. This flag can be set by SmbTrans2SetFileInfo
1701  * with FILE_DISPOSITION_INFO information level.
1702  * For setting this flag, the file should be opened by
1703  * DELETE access in the FID that is passed in the Trans2
1704  * request.
1705  */
1706 
1707 uint32_t
1708 smb_ofile_delete_check(smb_ofile_t *of)
1709 {
1710         uint32_t ret;
1711 
1712         ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1713 
1714         mutex_enter(&of->f_mutex);
1715 
1716         if (!smb_ofile_is_open_locked(of)) {
1717                 ret = NT_STATUS_INVALID_HANDLE;
1718                 goto out;
1719         }
1720 
1721         if (of->f_granted_access &
1722             (FILE_READ_DATA | FILE_WRITE_DATA |
1723             FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) {
1724                 ret = NT_STATUS_SHARING_VIOLATION;
1725                 goto out;
1726         }
1727 
1728         ret = NT_STATUS_SUCCESS;
1729 out:
1730         mutex_exit(&of->f_mutex);
1731         return (ret);
1732 }
1733 
1734 cred_t *
1735 smb_ofile_getcred(smb_ofile_t *of)
1736 {
1737         return (of->f_cr);
1738 }
1739 
1740 /*
1741  * smb_ofile_set_delete_on_close
1742  *
1743  * Set the DeleteOnClose flag on the smb file. When the file is closed,
1744  * the flag will be transferred to the smb node, which will commit the
1745  * delete operation and inhibit subsequent open requests.
1746  *
1747  * When DeleteOnClose is set on an smb_node, the common open code will
1748  * reject subsequent open requests for the file. Observation of Windows
1749  * 2000 indicates that subsequent opens should be allowed (assuming
1750  * there would be no sharing violation) until the file is closed using
1751  * the fid on which the DeleteOnClose was requested.
1752  */
1753 void
1754 smb_ofile_set_delete_on_close(smb_request_t *sr, smb_ofile_t *of)
1755 {
1756         uint32_t        status;
1757 
1758         /*
1759          * Break any oplock handle caching.
1760          */
1761         status = smb_oplock_break_SETINFO(of->f_node, of,
1762             FileDispositionInformation);
1763         if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
1764                 if (sr->session->dialect >= SMB_VERS_2_BASE)
1765                         (void) smb2sr_go_async(sr);
1766                 (void) smb_oplock_wait_break(of->f_node, 0);
1767         }
1768 
1769         mutex_enter(&of->f_mutex);
1770         of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE;
1771         mutex_exit(&of->f_mutex);
1772 }
1773 
1774 /*
1775  * Encode open file information into a buffer; needed in user space to
1776  * support RPC requests.
1777  */
1778 static int
1779 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen,
1780     uint32_t *nbytes)
1781 {
1782         smb_netfileinfo_t       fi;
1783         int                     rc;
1784 
1785         rc = smb_ofile_netinfo_init(of, &fi);
1786         if (rc == 0) {
1787                 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes);
1788                 smb_ofile_netinfo_fini(&fi);