1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 /*
  26  * SMB Node State Machine
  27  * ----------------------
  28  *
  29  *
  30  *                  +----------- Creation/Allocation
  31  *                  |
  32  *                  | T0
  33  *                  |
  34  *                  v
  35  *    +----------------------------+
  36  *    |  SMB_NODE_STATE_AVAILABLE  |
  37  *    +----------------------------+
  38  *                  |
  39  *                  | T1
  40  *                  |
  41  *                  v
  42  *    +-----------------------------+
  43  *    |  SMB_NODE_STATE_DESTROYING  |
  44  *    +-----------------------------+
  45  *                  |
  46  *                  |
  47  *                  | T2
  48  *                  |
  49  *                  +----------> Deletion/Free
  50  *
  51  * Transition T0
  52  *
  53  *    This transition occurs in smb_node_lookup(). If the node looked for is
  54  *    not found in the has table a new node is created. The reference count is
  55  *    initialized to 1 and the state initialized to SMB_NODE_STATE_AVAILABLE.
  56  *
  57  * Transition T1
  58  *
  59  *    This transition occurs in smb_node_release(). If the reference count
  60  *    drops to zero the state is moved to SMB_NODE_STATE_DESTROYING and no more
  61  *    reference count will be given out for that node.
  62  *
  63  * Transition T2
  64  *
  65  *    This transition occurs in smb_node_release(). The structure is deleted.
  66  *
  67  * Comments
  68  * --------
  69  *
  70  *    The reason the smb node has 2 states is the following synchronization
  71  *    rule:
  72  *
  73  *    There's a mutex embedded in the node used to protect its fields and
  74  *    there's a lock embedded in the bucket of the hash table the node belongs
  75  *    to. To increment or to decrement the reference count the mutex must be
  76  *    entered. To insert the node into the bucket and to remove it from the
  77  *    bucket the lock must be entered in RW_WRITER mode. When both (mutex and
  78  *    lock) have to be entered, the lock has always to be entered first then
  79  *    the mutex. This prevents a deadlock between smb_node_lookup() and
  80  *    smb_node_release() from occurring. However, in smb_node_release() when the
  81  *    reference count drops to zero and triggers the deletion of the node, the
  82  *    mutex has to be released before entering the lock of the bucket (to
  83  *    remove the node). This creates a window during which the node that is
  84  *    about to be freed could be given out by smb_node_lookup(). To close that
  85  *    window the node is moved to the state SMB_NODE_STATE_DESTROYING before
  86  *    releasing the mutex. That way, even if smb_node_lookup() finds it, the
  87  *    state will indicate that the node should be treated as non existent (of
  88  *    course the state of the node should be tested/updated under the
  89  *    protection of the mutex).
  90  */
  91 #include <smbsrv/smb2_kproto.h>
  92 #include <smbsrv/smb_fsops.h>
  93 #include <smbsrv/smb_kstat.h>
  94 #include <sys/ddi.h>
  95 #include <sys/extdirent.h>
  96 #include <sys/pathname.h>
  97 #include <sys/sdt.h>
  98 #include <sys/nbmlock.h>
  99 #include <fs/fs_reparse.h>
 100 
 101 uint32_t smb_is_executable(char *);
 102 static void smb_node_create_audit_buf(smb_node_t *, int);
 103 static void smb_node_destroy_audit_buf(smb_node_t *);
 104 static void smb_node_audit(smb_node_t *);
 105 static smb_node_t *smb_node_alloc(char *, vnode_t *, smb_llist_t *, uint32_t);
 106 static void smb_node_free(smb_node_t *);
 107 static int smb_node_constructor(void *, void *, int);
 108 static void smb_node_destructor(void *, void *);
 109 static smb_llist_t *smb_node_get_hash(fsid_t *, smb_attr_t *, uint32_t *);
 110 
 111 static void smb_node_init_reparse(smb_node_t *, smb_attr_t *);
 112 static void smb_node_init_system(smb_node_t *);
 113 
 114 #define VALIDATE_DIR_NODE(_dir_, _node_) \
 115     ASSERT((_dir_)->n_magic == SMB_NODE_MAGIC); \
 116     ASSERT(((_dir_)->vp->v_xattrdir) || ((_dir_)->vp->v_type == VDIR)); \
 117     ASSERT((_dir_)->n_dnode != (_node_));
 118 
 119 /* round sz to DEV_BSIZE block */
 120 #define SMB_ALLOCSZ(sz) (((sz) + DEV_BSIZE-1) & ~(DEV_BSIZE-1))
 121 
 122 static kmem_cache_t     *smb_node_cache = NULL;
 123 static smb_llist_t      smb_node_hash_table[SMBND_HASH_MASK+1];
 124 static smb_node_t       *smb_root_node;
 125 
 126 /*
 127  * smb_node_init
 128  *
 129  * Initialization of the SMB node layer.
 130  *
 131  * This function is not multi-thread safe. The caller must make sure only one
 132  * thread makes the call.
 133  */
 134 void
 135 smb_node_init(void)
 136 {
 137         smb_attr_t      attr;
 138         smb_llist_t     *node_hdr;
 139         smb_node_t      *node;
 140         uint32_t        hashkey;
 141         int             i;
 142 
 143         if (smb_node_cache != NULL)
 144                 return;
 145 
 146         smb_node_cache = kmem_cache_create(SMBSRV_KSTAT_NODE_CACHE,
 147             sizeof (smb_node_t), 8, smb_node_constructor, smb_node_destructor,
 148             NULL, NULL, NULL, 0);
 149 
 150         for (i = 0; i <= SMBND_HASH_MASK; i++) {
 151                 smb_llist_constructor(&smb_node_hash_table[i],
 152                     sizeof (smb_node_t), offsetof(smb_node_t, n_lnd));
 153         }
 154 
 155         /*
 156          * The node cache is shared by all zones, so the smb_root_node
 157          * must represent the real (global zone) rootdir.
 158          * Note intentional use of kcred here.
 159          */
 160         attr.sa_mask = SMB_AT_ALL;
 161         VERIFY0(smb_vop_getattr(rootdir, NULL, &attr, 0, kcred));
 162         node_hdr = smb_node_get_hash(&rootdir->v_vfsp->vfs_fsid, &attr,
 163             &hashkey);
 164         node = smb_node_alloc("/", rootdir, node_hdr, hashkey);
 165         smb_llist_enter(node_hdr, RW_WRITER);
 166         smb_llist_insert_head(node_hdr, node);
 167         smb_llist_exit(node_hdr);
 168         smb_root_node = node;   /* smb_node_release in smb_node_fini */
 169 }
 170 
 171 /*
 172  * smb_node_fini
 173  *
 174  * This function is not multi-thread safe. The caller must make sure only one
 175  * thread makes the call.
 176  */
 177 void
 178 smb_node_fini(void)
 179 {
 180         int     i;
 181 
 182         if (smb_root_node != NULL) {
 183                 smb_node_release(smb_root_node);
 184                 smb_root_node = NULL;
 185         }
 186 
 187         if (smb_node_cache == NULL)
 188                 return;
 189 
 190 #ifdef DEBUG
 191         for (i = 0; i <= SMBND_HASH_MASK; i++) {
 192                 smb_llist_t     *bucket;
 193                 smb_node_t      *node;
 194 
 195                 /*
 196                  * The following sequence is just intended for sanity check.
 197                  * This will have to be modified when the code goes into
 198                  * production.
 199                  *
 200                  * The SMB node hash table should be emtpy at this point. If the
 201                  * hash table is not empty a panic will be triggered.
 202                  *
 203                  * The reason why SMB nodes are still remaining in the hash
 204                  * table is problably due to a mismatch between calls to
 205                  * smb_node_lookup() and smb_node_release(). You must track that
 206                  * down.
 207                  */
 208                 bucket = &smb_node_hash_table[i];
 209                 node = smb_llist_head(bucket);
 210                 while (node != NULL) {
 211                         cmn_err(CE_NOTE, "leaked node: 0x%p %s",
 212                             (void *)node, node->od_name);
 213                         node = smb_llist_next(bucket, node);
 214                 }
 215         }
 216 #endif
 217 
 218         for (i = 0; i <= SMBND_HASH_MASK; i++) {
 219                 smb_llist_destructor(&smb_node_hash_table[i]);
 220         }
 221         kmem_cache_destroy(smb_node_cache);
 222         smb_node_cache = NULL;
 223 }
 224 
 225 /*
 226  * smb_node_lookup()
 227  *
 228  * NOTE: This routine should only be called by the file system interface layer,
 229  * and not by SMB.
 230  *
 231  * smb_node_lookup() is called upon successful lookup, mkdir, and create
 232  * (for both non-streams and streams).  In each of these cases, a held vnode is
 233  * passed into this routine.  If a new smb_node is created it will take its
 234  * own hold on the vnode.  The caller's hold therefore still belongs to, and
 235  * should be released by, the caller.
 236  *
 237  * A reference is taken on the smb_node whether found in the hash table
 238  * or newly created.
 239  *
 240  * If an smb_node needs to be created, a reference is also taken on the
 241  * dnode (if passed in).
 242  *
 243  * See smb_node_release() for details on the release of these references.
 244  */
 245 
 246 /*ARGSUSED*/
 247 smb_node_t *
 248 smb_node_lookup(
 249     struct smb_request  *sr,
 250     struct open_param   *op,
 251     cred_t              *cred,
 252     vnode_t             *vp,
 253     char                *od_name,
 254     smb_node_t          *dnode,
 255     smb_node_t          *unode)
 256 {
 257         smb_llist_t             *node_hdr;
 258         smb_node_t              *node;
 259         smb_attr_t              attr;
 260         uint32_t                hashkey = 0;
 261         fsid_t                  fsid;
 262         int                     error;
 263         krw_t                   lock_mode;
 264         vnode_t                 *unnamed_vp = NULL;
 265 
 266         /*
 267          * smb_vop_getattr() is called here instead of smb_fsop_getattr(),
 268          * because the node may not yet exist.  We also do not want to call
 269          * it with the list lock held.
 270          */
 271 
 272         if (unode)
 273                 unnamed_vp = unode->vp;
 274 
 275         /*
 276          * This getattr is performed on behalf of the server
 277          * that's why kcred is used not the user's cred
 278          */
 279         attr.sa_mask = SMB_AT_ALL;
 280         error = smb_vop_getattr(vp, unnamed_vp, &attr, 0, zone_kcred());
 281         if (error)
 282                 return (NULL);
 283 
 284         if (sr && sr->tid_tree) {
 285                 /*
 286                  * The fsid for a file is that of the tree, even
 287                  * if the file resides in a different mountpoint
 288                  * under the share.
 289                  */
 290                 fsid = SMB_TREE_FSID(sr->tid_tree);
 291         } else {
 292                 /*
 293                  * This should be getting executed only for the
 294                  * tree root smb_node.
 295                  */
 296                 fsid = vp->v_vfsp->vfs_fsid;
 297         }
 298 
 299         node_hdr = smb_node_get_hash(&fsid, &attr, &hashkey);
 300         lock_mode = RW_READER;
 301 
 302         smb_llist_enter(node_hdr, lock_mode);
 303         for (;;) {
 304                 node = list_head(&node_hdr->ll_list);
 305                 while (node) {
 306                         ASSERT(node->n_magic == SMB_NODE_MAGIC);
 307                         ASSERT(node->n_hash_bucket == node_hdr);
 308                         if ((node->n_hashkey == hashkey) && (node->vp == vp)) {
 309                                 mutex_enter(&node->n_mutex);
 310                                 DTRACE_PROBE1(smb_node_lookup_hit,
 311                                     smb_node_t *, node);
 312                                 switch (node->n_state) {
 313                                 case SMB_NODE_STATE_AVAILABLE:
 314                                         /* The node was found. */
 315                                         node->n_refcnt++;
 316                                         if ((node->n_dnode == NULL) &&
 317                                             (dnode != NULL) &&
 318                                             (node != dnode) &&
 319                                             (strcmp(od_name, "..") != 0) &&
 320                                             (strcmp(od_name, ".") != 0)) {
 321                                                 VALIDATE_DIR_NODE(dnode, node);
 322                                                 node->n_dnode = dnode;
 323                                                 smb_node_ref(dnode);
 324                                         }
 325 
 326                                         smb_node_audit(node);
 327                                         mutex_exit(&node->n_mutex);
 328                                         smb_llist_exit(node_hdr);
 329                                         return (node);
 330 
 331                                 case SMB_NODE_STATE_DESTROYING:
 332                                         /*
 333                                          * Although the node exists it is about
 334                                          * to be destroyed. We act as it hasn't
 335                                          * been found.
 336                                          */
 337                                         mutex_exit(&node->n_mutex);
 338                                         break;
 339                                 default:
 340                                         /*
 341                                          * Although the node exists it is in an
 342                                          * unknown state. We act as it hasn't
 343                                          * been found.
 344                                          */
 345                                         ASSERT(0);
 346                                         mutex_exit(&node->n_mutex);
 347                                         break;
 348                                 }
 349                         }
 350                         node = smb_llist_next(node_hdr, node);
 351                 }
 352                 if ((lock_mode == RW_READER) && smb_llist_upgrade(node_hdr)) {
 353                         lock_mode = RW_WRITER;
 354                         continue;
 355                 }
 356                 break;
 357         }
 358         node = smb_node_alloc(od_name, vp, node_hdr, hashkey);
 359         smb_node_init_reparse(node, &attr);
 360 
 361         if (op)
 362                 node->flags |= smb_is_executable(op->fqi.fq_last_comp);
 363 
 364         if (dnode) {
 365                 smb_node_ref(dnode);
 366                 node->n_dnode = dnode;
 367                 ASSERT(dnode->n_dnode != node);
 368                 ASSERT((dnode->vp->v_xattrdir) ||
 369                     (dnode->vp->v_type == VDIR));
 370         }
 371 
 372         if (unode) {
 373                 smb_node_ref(unode);
 374                 node->n_unode = unode;
 375         }
 376 
 377         smb_node_init_system(node);
 378 
 379         DTRACE_PROBE1(smb_node_lookup_miss, smb_node_t *, node);
 380         smb_node_audit(node);
 381         smb_llist_insert_head(node_hdr, node);
 382         smb_llist_exit(node_hdr);
 383         return (node);
 384 }
 385 
 386 /*
 387  * smb_stream_node_lookup()
 388  *
 389  * Note: stream_name (the name that will be stored in the "od_name" field
 390  * of a stream's smb_node) is the same as the on-disk name for the stream
 391  * except that it does not have SMB_STREAM_PREFIX prepended.
 392  */
 393 
 394 smb_node_t *
 395 smb_stream_node_lookup(smb_request_t *sr, cred_t *cr, smb_node_t *fnode,
 396     vnode_t *xattrdirvp, vnode_t *vp, char *stream_name)
 397 {
 398         smb_node_t      *xattrdir_node;
 399         smb_node_t      *snode;
 400 
 401         xattrdir_node = smb_node_lookup(sr, NULL, cr, xattrdirvp, XATTR_DIR,
 402             fnode, NULL);
 403 
 404         if (xattrdir_node == NULL)
 405                 return (NULL);
 406 
 407         snode = smb_node_lookup(sr, NULL, cr, vp, stream_name, xattrdir_node,
 408             fnode);
 409 
 410         (void) smb_node_release(xattrdir_node);
 411         return (snode);
 412 }
 413 
 414 
 415 /*
 416  * This function should be called whenever a reference is needed on an
 417  * smb_node pointer.  The copy of an smb_node pointer from one non-local
 418  * data structure to another requires a reference to be taken on the smb_node
 419  * (unless the usage is localized).  Each data structure deallocation routine
 420  * will call smb_node_release() on its smb_node pointers.
 421  *
 422  * In general, an smb_node pointer residing in a structure should never be
 423  * stale.  A node pointer may be NULL, however, and care should be taken
 424  * prior to calling smb_node_ref(), which ASSERTs that the pointer is valid.
 425  * Care also needs to be taken with respect to racing deallocations of a
 426  * structure.
 427  */
 428 void
 429 smb_node_ref(smb_node_t *node)
 430 {
 431         SMB_NODE_VALID(node);
 432 
 433         mutex_enter(&node->n_mutex);
 434         switch (node->n_state) {
 435         case SMB_NODE_STATE_AVAILABLE:
 436                 node->n_refcnt++;
 437                 ASSERT(node->n_refcnt);
 438                 DTRACE_PROBE1(smb_node_ref_exit, smb_node_t *, node);
 439                 smb_node_audit(node);
 440                 break;
 441         default:
 442                 SMB_PANIC();
 443         }
 444         mutex_exit(&node->n_mutex);
 445 }
 446 
 447 /*
 448  * smb_node_lookup() takes a hold on an smb_node, whether found in the
 449  * hash table or newly created.  This hold is expected to be released
 450  * in the following manner.
 451  *
 452  * smb_node_lookup() takes an address of an smb_node pointer.  This should
 453  * be getting passed down via a lookup (whether path name or component), mkdir,
 454  * create.  If the original smb_node pointer resides in a data structure, then
 455  * the deallocation routine for the data structure is responsible for calling
 456  * smb_node_release() on the smb_node pointer.  Alternatively,
 457  * smb_node_release() can be called as soon as the smb_node pointer is no longer
 458  * needed.  In this case, callers are responsible for setting an embedded
 459  * pointer to NULL if it is known that the last reference is being released.
 460  *
 461  * If the passed-in address of the smb_node pointer belongs to a local variable,
 462  * then the caller with the local variable should call smb_node_release()
 463  * directly.
 464  *
 465  * smb_node_release() itself will call smb_node_release() on a node's n_dnode,
 466  * as smb_node_lookup() takes a hold on dnode.
 467  */
 468 void
 469 smb_node_release(smb_node_t *node)
 470 {
 471         SMB_NODE_VALID(node);
 472 
 473         mutex_enter(&node->n_mutex);
 474         ASSERT(node->n_refcnt);
 475         DTRACE_PROBE1(smb_node_release, smb_node_t *, node);
 476         if (--node->n_refcnt == 0) {
 477                 switch (node->n_state) {
 478 
 479                 case SMB_NODE_STATE_AVAILABLE:
 480                         node->n_state = SMB_NODE_STATE_DESTROYING;
 481                         mutex_exit(&node->n_mutex);
 482 
 483                         smb_llist_enter(node->n_hash_bucket, RW_WRITER);
 484                         smb_llist_remove(node->n_hash_bucket, node);
 485                         smb_llist_exit(node->n_hash_bucket);
 486 
 487                         /*
 488                          * Check if the file was deleted
 489                          */
 490                         if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
 491                                 smb_node_delete_on_close(node);
 492                         }
 493 
 494                         if (node->n_dnode) {
 495                                 ASSERT(node->n_dnode->n_magic ==
 496                                     SMB_NODE_MAGIC);
 497                                 smb_node_release(node->n_dnode);
 498                         }
 499 
 500                         if (node->n_unode) {
 501                                 ASSERT(node->n_unode->n_magic ==
 502                                     SMB_NODE_MAGIC);
 503                                 smb_node_release(node->n_unode);
 504                         }
 505 
 506                         smb_node_free(node);
 507                         return;
 508 
 509                 default:
 510                         SMB_PANIC();
 511                 }
 512         }
 513         smb_node_audit(node);
 514         mutex_exit(&node->n_mutex);
 515 }
 516 
 517 void
 518 smb_node_delete_on_close(smb_node_t *node)
 519 {
 520         smb_node_t      *d_snode;
 521         int             rc = 0;
 522         uint32_t        flags = 0;
 523 
 524         d_snode = node->n_dnode;
 525 
 526         ASSERT((node->flags & NODE_FLAGS_DELETE_ON_CLOSE) != 0);
 527 
 528         node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE;
 529         node->flags |= NODE_FLAGS_DELETE_COMMITTED;
 530         flags = node->n_delete_on_close_flags;
 531         ASSERT(node->od_name != NULL);
 532 
 533         if (smb_node_is_dir(node))
 534                 rc = smb_fsop_rmdir(0, node->delete_on_close_cred,
 535                     d_snode, node->od_name, flags);
 536         else
 537                 rc = smb_fsop_remove(0, node->delete_on_close_cred,
 538                     d_snode, node->od_name, flags);
 539         crfree(node->delete_on_close_cred);
 540         node->delete_on_close_cred = NULL;
 541 
 542         if (rc != 0)
 543                 cmn_err(CE_WARN, "File %s could not be removed, rc=%d\n",
 544                     node->od_name, rc);
 545         DTRACE_PROBE2(smb_node_delete_on_close, int, rc, smb_node_t *, node);
 546 }
 547 
 548 /*
 549  * smb_node_rename()
 550  *
 551  */
 552 void
 553 smb_node_rename(
 554     smb_node_t  *from_dnode,
 555     smb_node_t  *ret_node,
 556     smb_node_t  *to_dnode,
 557     char        *to_name)
 558 {
 559         SMB_NODE_VALID(from_dnode);
 560         SMB_NODE_VALID(to_dnode);
 561         SMB_NODE_VALID(ret_node);
 562 
 563         smb_node_ref(to_dnode);
 564         mutex_enter(&ret_node->n_mutex);
 565         switch (ret_node->n_state) {
 566         case SMB_NODE_STATE_AVAILABLE:
 567                 ret_node->n_dnode = to_dnode;
 568                 mutex_exit(&ret_node->n_mutex);
 569                 ASSERT(to_dnode->n_dnode != ret_node);
 570                 ASSERT((to_dnode->vp->v_xattrdir) ||
 571                     (to_dnode->vp->v_type == VDIR));
 572                 smb_node_release(from_dnode);
 573                 (void) strcpy(ret_node->od_name, to_name);
 574                 /*
 575                  * XXX Need to update attributes?
 576                  */
 577                 break;
 578         default:
 579                 SMB_PANIC();
 580         }
 581 }
 582 
 583 /*
 584  * Find/create an SMB node for the root of this zone and store it
 585  * in *svrootp.  Also create nodes leading to this directory.
 586  */
 587 int
 588 smb_node_root_init(smb_server_t *sv, smb_node_t **svrootp)
 589 {
 590         zone_t          *zone = curzone;
 591         int             error;
 592 
 593         ASSERT(zone->zone_id == sv->sv_zid);
 594         if (smb_root_node == NULL)
 595                 return (ENOENT);
 596 
 597         /*
 598          * We're getting smb nodes below the zone root here,
 599          * so need to use kcred, not zone_kcred().
 600          */
 601         error = smb_pathname(NULL, zone->zone_rootpath, 0,
 602             smb_root_node, smb_root_node, NULL, svrootp, kcred, NULL);
 603 
 604         return (error);
 605 }
 606 
 607 /*
 608  * Helper function for smb_node_set_delete_on_close(). Assumes node is a dir.
 609  * Return 0 if this is an empty dir. Otherwise return a NT_STATUS code.
 610  * Unfortunately, to find out if a directory is empty, we have to read it
 611  * and check for anything other than "." or ".." in the readdir buf.
 612  */
 613 static uint32_t
 614 smb_rmdir_possible(smb_node_t *n)
 615 {
 616         ASSERT(n->vp->v_type == VDIR);
 617         char *buf;
 618         char *bufptr;
 619         struct dirent64 *dp;
 620         uint32_t status = NT_STATUS_SUCCESS;
 621         int bsize = SMB_ODIR_BUFSIZE;
 622         int eof = 0;
 623 
 624         buf = kmem_alloc(SMB_ODIR_BUFSIZE, KM_SLEEP);
 625 
 626         /* Flags zero: no edirent, no ABE wanted here */
 627         if (smb_vop_readdir(n->vp, 0, buf, &bsize, &eof, 0, zone_kcred())) {
 628                 status = NT_STATUS_INTERNAL_ERROR;
 629                 goto out;
 630         }
 631 
 632         bufptr = buf;
 633         while (bsize > 0) {
 634                 /* LINTED pointer alignment */
 635                 dp = (struct dirent64 *)bufptr;
 636 
 637                 bufptr += dp->d_reclen;
 638                 bsize  -= dp->d_reclen;
 639                 if (bsize < 0) {
 640                         /* partial record */
 641                         status = NT_STATUS_DIRECTORY_NOT_EMPTY;
 642                         break;
 643                 }
 644 
 645                 if (strcmp(dp->d_name, ".") != 0 &&
 646                     strcmp(dp->d_name, "..") != 0) {
 647                         status = NT_STATUS_DIRECTORY_NOT_EMPTY;
 648                         break;
 649                 }
 650         }
 651 
 652 out:
 653         kmem_free(buf, SMB_ODIR_BUFSIZE);
 654         return (status);
 655 }
 656 
 657 /*
 658  * When DeleteOnClose is set on an smb_node, the common open code will
 659  * reject subsequent open requests for the file. Observation of Windows
 660  * 2000 indicates that subsequent opens should be allowed (assuming
 661  * there would be no sharing violation) until the file is closed using
 662  * the fid on which the DeleteOnClose was requested.
 663  *
 664  * If there are multiple opens with delete-on-close create options,
 665  * whichever the first file handle is closed will trigger the node to be
 666  * marked as delete-on-close. The credentials of that ofile will be used
 667  * as the delete-on-close credentials of the node.
 668  *
 669  * Note that "read-only" tests have already happened before this call.
 670  */
 671 uint32_t
 672 smb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags)
 673 {
 674         uint32_t status;
 675 
 676         /*
 677          * If the directory is not empty we should fail setting del-on-close
 678          * with STATUS_DIRECTORY_NOT_EMPTY. see MS's
 679          * "File System Behavior Overview" doc section 4.3.2
 680          */
 681         if (smb_node_is_dir(node)) {
 682                 status = smb_rmdir_possible(node);
 683                 if (status != 0) {
 684                         return (status);
 685                 }
 686         }
 687 
 688         mutex_enter(&node->n_mutex);
 689         if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
 690                 /* It was already marked.  We're done. */
 691                 mutex_exit(&node->n_mutex);
 692                 return (NT_STATUS_SUCCESS);
 693         }
 694 
 695         crhold(cr);
 696         node->delete_on_close_cred = cr;
 697         node->n_delete_on_close_flags = flags;
 698         node->flags |= NODE_FLAGS_DELETE_ON_CLOSE;
 699         mutex_exit(&node->n_mutex);
 700 
 701         /*
 702          * Tell any change notify calls to close their handles
 703          * and get out of the way.  FILE_ACTION_DELETE_PENDING
 704          * is a special, internal-only action for this purpose.
 705          */
 706         smb_node_notify_change(node, FILE_ACTION_DELETE_PENDING, NULL);
 707 
 708         return (NT_STATUS_SUCCESS);
 709 }
 710 
 711 void
 712 smb_node_reset_delete_on_close(smb_node_t *node)
 713 {
 714         mutex_enter(&node->n_mutex);
 715         if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
 716                 node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE;
 717                 crfree(node->delete_on_close_cred);
 718                 node->delete_on_close_cred = NULL;
 719                 node->n_delete_on_close_flags = 0;
 720         }
 721         mutex_exit(&node->n_mutex);
 722 }
 723 
 724 /*
 725  * smb_node_open_check
 726  *
 727  * check file sharing rules for current open request
 728  * against all existing opens for a file.
 729  *
 730  * Returns NT_STATUS_SHARING_VIOLATION if there is any
 731  * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
 732  */
 733 uint32_t
 734 smb_node_open_check(smb_node_t *node, uint32_t desired_access,
 735     uint32_t share_access)
 736 {
 737         smb_ofile_t *of;
 738         uint32_t status;
 739 
 740         SMB_NODE_VALID(node);
 741 
 742         smb_llist_enter(&node->n_ofile_list, RW_READER);
 743         of = smb_llist_head(&node->n_ofile_list);
 744         while (of) {
 745                 status = smb_ofile_open_check(of, desired_access, share_access);
 746 
 747                 switch (status) {
 748                 case NT_STATUS_INVALID_HANDLE:
 749                 case NT_STATUS_SUCCESS:
 750                         of = smb_llist_next(&node->n_ofile_list, of);
 751                         break;
 752                 default:
 753                         ASSERT(status == NT_STATUS_SHARING_VIOLATION);
 754                         DTRACE_PROBE3(conflict3,
 755                             smb_ofile_t, of,
 756                             uint32_t, desired_access,
 757                             uint32_t, share_access);
 758                         smb_llist_exit(&node->n_ofile_list);
 759                         return (status);
 760                 }
 761         }
 762 
 763         smb_llist_exit(&node->n_ofile_list);
 764         return (NT_STATUS_SUCCESS);
 765 }
 766 
 767 uint32_t
 768 smb_node_rename_check(smb_node_t *node)
 769 {
 770         smb_ofile_t     *of;
 771         uint32_t        status;
 772 
 773         SMB_NODE_VALID(node);
 774 
 775         /*
 776          * Intra-CIFS check
 777          */
 778         smb_llist_enter(&node->n_ofile_list, RW_READER);
 779         of = smb_llist_head(&node->n_ofile_list);
 780         while (of) {
 781                 status = smb_ofile_rename_check(of);
 782 
 783                 switch (status) {
 784                 case NT_STATUS_INVALID_HANDLE:
 785                 case NT_STATUS_SUCCESS:
 786                         of = smb_llist_next(&node->n_ofile_list, of);
 787                         break;
 788                 default:
 789                         ASSERT(status == NT_STATUS_SHARING_VIOLATION);
 790                         DTRACE_PROBE1(conflict1, smb_ofile_t, of);
 791                         smb_llist_exit(&node->n_ofile_list);
 792                         return (status);
 793                 }
 794         }
 795         smb_llist_exit(&node->n_ofile_list);
 796         return (NT_STATUS_SUCCESS);
 797 }
 798 
 799 uint32_t
 800 smb_node_delete_check(smb_node_t *node)
 801 {
 802         smb_ofile_t     *of;
 803         uint32_t        status;
 804 
 805         SMB_NODE_VALID(node);
 806 
 807         if (smb_node_is_dir(node))
 808                 return (NT_STATUS_SUCCESS);
 809 
 810         if (smb_node_is_reparse(node))
 811                 return (NT_STATUS_ACCESS_DENIED);
 812 
 813         /*
 814          * intra-CIFS check
 815          */
 816         smb_llist_enter(&node->n_ofile_list, RW_READER);
 817         of = smb_llist_head(&node->n_ofile_list);
 818         while (of) {
 819                 status = smb_ofile_delete_check(of);
 820 
 821                 switch (status) {
 822                 case NT_STATUS_INVALID_HANDLE:
 823                 case NT_STATUS_SUCCESS:
 824                         of = smb_llist_next(&node->n_ofile_list, of);
 825                         break;
 826                 default:
 827                         ASSERT(status == NT_STATUS_SHARING_VIOLATION);
 828                         DTRACE_PROBE1(conflict1, smb_ofile_t, of);
 829                         smb_llist_exit(&node->n_ofile_list);
 830                         return (status);
 831                 }
 832         }
 833         smb_llist_exit(&node->n_ofile_list);
 834         return (NT_STATUS_SUCCESS);
 835 }
 836 
 837 /*
 838  * smb_node_share_check
 839  *
 840  * Returns: TRUE    - ofiles have non-zero share access
 841  *          B_FALSE - ofile with share access NONE.
 842  */
 843 boolean_t
 844 smb_node_share_check(smb_node_t *node)
 845 {
 846         smb_ofile_t     *of;
 847         boolean_t       status = B_TRUE;
 848 
 849         SMB_NODE_VALID(node);
 850 
 851         smb_llist_enter(&node->n_ofile_list, RW_READER);
 852         of = smb_llist_head(&node->n_ofile_list);
 853         if (of)
 854                 status = smb_ofile_share_check(of);
 855         smb_llist_exit(&node->n_ofile_list);
 856 
 857         return (status);
 858 }
 859 
 860 /*
 861  * SMB Change Notification
 862  */
 863 
 864 void
 865 smb_node_fcn_subscribe(smb_node_t *node)
 866 {
 867 
 868         mutex_enter(&node->n_mutex);
 869         if (node->n_fcn_count == 0)
 870                 (void) smb_fem_fcn_install(node);
 871         node->n_fcn_count++;
 872         mutex_exit(&node->n_mutex);
 873 }
 874 
 875 void
 876 smb_node_fcn_unsubscribe(smb_node_t *node)
 877 {
 878 
 879         mutex_enter(&node->n_mutex);
 880         node->n_fcn_count--;
 881         if (node->n_fcn_count == 0)
 882                 smb_fem_fcn_uninstall(node);
 883         mutex_exit(&node->n_mutex);
 884 }
 885 
 886 void
 887 smb_node_notify_change(smb_node_t *node, uint_t action, const char *name)
 888 {
 889         smb_ofile_t     *of;
 890 
 891         SMB_NODE_VALID(node);
 892 
 893         smb_llist_enter(&node->n_ofile_list, RW_READER);
 894         of = smb_llist_head(&node->n_ofile_list);
 895         while (of) {
 896                 /*
 897                  * We'd rather deliver events only to ofiles that have
 898                  * subscribed.  There's no explicit synchronization with
 899                  * where this flag is set, but other actions cause this
 900                  * value to reach visibility soon enough for events to
 901                  * start arriving by the time we need them to start.
 902                  * Once nc_subscribed is set, it stays set for the
 903                  * life of the ofile.
 904                  */
 905                 if (of->f_notify.nc_subscribed)
 906                         smb_notify_ofile(of, action, name);
 907                 of = smb_llist_next(&node->n_ofile_list, of);
 908         }
 909         smb_llist_exit(&node->n_ofile_list);
 910 
 911         /*
 912          * After changes that add or remove a name,
 913          * we know the directory attributes changed,
 914          * and we can tell the immediate parent.
 915          */
 916         switch (action) {
 917         case FILE_ACTION_ADDED:
 918         case FILE_ACTION_REMOVED:
 919         case FILE_ACTION_RENAMED_NEW_NAME:
 920                 /*
 921                  * Note: FILE_ACTION_RENAMED_OLD_NAME is intentionally
 922                  * omitted, because it's always followed by another
 923                  * event with FILE_ACTION_RENAMED_NEW_NAME posted to
 924                  * the same directory, and we only need/want one.
 925                  */
 926                 if (node->n_dnode != NULL) {
 927                         smb_node_notify_change(node->n_dnode,
 928                             FILE_ACTION_MODIFIED, node->od_name);
 929                 }
 930                 break;
 931         }
 932 
 933         /*
 934          * If we wanted to support recursive notify events
 935          * (where a notify call on some directory receives
 936          * events from all objects below that directory),
 937          * we might deliver _SUBDIR_CHANGED to all our
 938          * parents, grandparents etc, here.  However, we
 939          * don't currently subscribe to changes on all the
 940          * child (and grandchild) objects that would be
 941          * needed to make that work. It's prohibitively
 942          * expensive to do that, and support for recursive
 943          * notify is optional anyway, so don't bother.
 944          */
 945 }
 946 
 947 /*
 948  * smb_node_start_crit()
 949  *
 950  * Enter critical region for share reservations.
 951  * See comments above smb_fsop_shrlock().
 952  */
 953 void
 954 smb_node_start_crit(smb_node_t *node, krw_t mode)
 955 {
 956         rw_enter(&node->n_lock, mode);
 957         nbl_start_crit(node->vp, mode);
 958 }
 959 
 960 /*
 961  * smb_node_end_crit()
 962  *
 963  * Exit critical region for share reservations.
 964  */
 965 void
 966 smb_node_end_crit(smb_node_t *node)
 967 {
 968         nbl_end_crit(node->vp);
 969         rw_exit(&node->n_lock);
 970 }
 971 
 972 int
 973 smb_node_in_crit(smb_node_t *node)
 974 {
 975         return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_lock));
 976 }
 977 
 978 void
 979 smb_node_rdlock(smb_node_t *node)
 980 {
 981         rw_enter(&node->n_lock, RW_READER);
 982 }
 983 
 984 void
 985 smb_node_wrlock(smb_node_t *node)
 986 {
 987         rw_enter(&node->n_lock, RW_WRITER);
 988 }
 989 
 990 void
 991 smb_node_unlock(smb_node_t *node)
 992 {
 993         rw_exit(&node->n_lock);
 994 }
 995 
 996 void
 997 smb_node_add_ofile(smb_node_t *node, smb_ofile_t *of)
 998 {
 999         SMB_NODE_VALID(node);
1000 
1001         smb_llist_enter(&node->n_ofile_list, RW_WRITER);
1002         smb_llist_insert_tail(&node->n_ofile_list, of);
1003         smb_llist_exit(&node->n_ofile_list);
1004 }
1005 
1006 void
1007 smb_node_rem_ofile(smb_node_t *node, smb_ofile_t *of)
1008 {
1009         SMB_NODE_VALID(node);
1010 
1011         smb_llist_enter(&node->n_ofile_list, RW_WRITER);
1012         smb_llist_remove(&node->n_ofile_list, of);
1013         smb_llist_exit(&node->n_ofile_list);
1014 }
1015 
1016 /*
1017  * smb_node_inc_open_ofiles
1018  */
1019 void
1020 smb_node_inc_open_ofiles(smb_node_t *node)
1021 {
1022         SMB_NODE_VALID(node);
1023         atomic_inc_32(&node->n_open_count);
1024 }
1025 
1026 /*
1027  * smb_node_dec_open_ofiles
1028  * returns new value
1029  */
1030 uint32_t
1031 smb_node_dec_open_ofiles(smb_node_t *node)
1032 {
1033         SMB_NODE_VALID(node);
1034         return (atomic_dec_32_nv(&node->n_open_count));
1035 }
1036 
1037 /*
1038  * smb_node_inc_opening_count
1039  */
1040 void
1041 smb_node_inc_opening_count(smb_node_t *node)
1042 {
1043         SMB_NODE_VALID(node);
1044         atomic_inc_32(&node->n_opening_count);
1045 }
1046 
1047 /*
1048  * smb_node_dec_opening_count
1049  */
1050 void
1051 smb_node_dec_opening_count(smb_node_t *node)
1052 {
1053         SMB_NODE_VALID(node);
1054         atomic_dec_32(&node->n_opening_count);
1055 }
1056 
1057 /*
1058  * smb_node_getmntpath
1059  */
1060 int
1061 smb_node_getmntpath(smb_node_t *node, char *buf, uint32_t buflen)
1062 {
1063         vnode_t *vp, *root_vp;
1064         vfs_t *vfsp;
1065         int err;
1066 
1067         ASSERT(node);
1068         ASSERT(node->vp);
1069         ASSERT(node->vp->v_vfsp);
1070 
1071         vp = node->vp;
1072         vfsp = vp->v_vfsp;
1073 
1074         if (VFS_ROOT(vfsp, &root_vp))
1075                 return (ENOENT);
1076 
1077         VN_HOLD(vp);
1078 
1079         /* NULL is passed in as we want to start at "/" */
1080         err = vnodetopath(NULL, root_vp, buf, buflen, zone_kcred());
1081 
1082         VN_RELE(vp);
1083         VN_RELE(root_vp);
1084         return (err);
1085 }
1086 
1087 /*
1088  * smb_node_getshrpath
1089  *
1090  * Determine the absolute pathname of 'node' within the share (tree).
1091  * For example if the node represents file "test1.txt" in directory
1092  * "dir1" the pathname would be: \dir1\test1.txt
1093  */
1094 int
1095 smb_node_getshrpath(smb_node_t *node, smb_tree_t *tree,
1096     char *buf, uint32_t buflen)
1097 {
1098         int rc;
1099 
1100         ASSERT(node);
1101         ASSERT(tree);
1102         ASSERT(tree->t_snode);
1103 
1104         rc = smb_node_getpath(node, tree->t_snode->vp, buf, buflen);
1105         (void) strsubst(buf, '/', '\\');
1106         return (rc);
1107 }
1108 
1109 /*
1110  * smb_node_getpath
1111  *
1112  * Determine the absolute pathname of 'node' from 'rootvp'.
1113  *
1114  * Using vnodetopath is only reliable for directory nodes (due to
1115  * its reliance on the DNLC for non-directory nodes). Thus, if node
1116  * represents a file, construct the pathname for the parent dnode
1117  * and append filename.
1118  * If node represents a named stream, construct the pathname for the
1119  * associated unnamed stream and append the stream name.
1120  *
1121  * The pathname returned in buf will be '/' separated.
1122  */
1123 int
1124 smb_node_getpath(smb_node_t *node, vnode_t *rootvp, char *buf, uint32_t buflen)
1125 {
1126         int rc;
1127         vnode_t *vp;
1128         smb_node_t *unode, *dnode;
1129         cred_t *kcr = zone_kcred();
1130 
1131         unode = (SMB_IS_STREAM(node)) ? node->n_unode : node;
1132         dnode = (smb_node_is_dir(unode)) ? unode : unode->n_dnode;
1133 
1134         /* find path to directory node */
1135         vp = dnode->vp;
1136         VN_HOLD(vp);
1137         if (rootvp) {
1138                 VN_HOLD(rootvp);
1139                 rc = vnodetopath(rootvp, vp, buf, buflen, kcr);
1140                 VN_RELE(rootvp);
1141         } else {
1142                 rc = vnodetopath(NULL, vp, buf, buflen, kcr);
1143         }
1144         VN_RELE(vp);
1145 
1146         if (rc != 0)
1147                 return (rc);
1148 
1149         /* append filename if necessary */
1150         if (!smb_node_is_dir(unode)) {
1151                 if (buf[strlen(buf) - 1] != '/')
1152                         (void) strlcat(buf, "/", buflen);
1153                 (void) strlcat(buf, unode->od_name, buflen);
1154         }
1155 
1156         /* append named stream name if necessary */
1157         if (SMB_IS_STREAM(node))
1158                 (void) strlcat(buf, node->od_name, buflen);
1159 
1160         return (rc);
1161 }
1162 
1163 /*
1164  * smb_node_getpath_nofail
1165  *
1166  * Same as smb_node_getpath, but try to reconstruct on failure,
1167  * and truncate from the beginning if we can't.
1168  */
1169 void
1170 smb_node_getpath_nofail(smb_node_t *node, vnode_t *rootvp, char *buf,
1171     uint32_t buflen)
1172 {
1173         int rc, len, addlen;
1174         vnode_t *vp;
1175         smb_node_t *unode, *dnode;
1176         cred_t *kcr = zone_kcred();
1177         boolean_t is_dir, is_stream;
1178 
1179         is_stream = (SMB_IS_STREAM(node) != NULL);
1180         unode = (is_stream) ? node->n_unode : node;
1181         is_dir = smb_node_is_dir(unode);
1182         dnode = (is_dir) ? unode : unode->n_dnode;
1183 
1184         /* find path to directory node */
1185         vp = dnode->vp;
1186         VN_HOLD(vp);
1187         if (rootvp) {
1188                 VN_HOLD(rootvp);
1189                 rc = vnodetopath(rootvp, vp, buf, buflen, kcr);
1190                 VN_RELE(rootvp);
1191         } else {
1192                 rc = vnodetopath(NULL, vp, buf, buflen, kcr);
1193         }
1194         VN_RELE(vp);
1195 
1196         /* On failure, reconstruct the path from the node_t's */
1197         if (rc != 0) {
1198                 smb_node_t *nodep = unode;
1199                 char *p = buf + buflen;
1200 
1201                 /* append named stream name if necessary */
1202                 if (is_stream) {
1203                         len = strlen(node->od_name) + 1;
1204                         ASSERT3U(buflen, >=, len);
1205                         p -= len;
1206                         (void) strcpy(p, node->od_name);
1207                 }
1208 
1209                 len = strlen(nodep->od_name) + 1;
1210                 p -= len;
1211                 while (nodep->n_dnode != NULL && nodep->vp != rootvp &&
1212                     p >= buf) {
1213                         (void) strcpy(p, nodep->od_name);
1214                         p[len - 1] = '/';
1215                         nodep = nodep->n_dnode;
1216                         len = strlen(nodep->od_name) + 1;
1217                         p -= len;
1218                 }
1219                 if (nodep->n_dnode != NULL && nodep->vp != rootvp) {
1220                         /* something went horribly wrong... */
1221 #ifdef DEBUG
1222                         cmn_err(CE_WARN,
1223                             "smb_node_getpath_nofail: buffer too small: "
1224                             "size %d", buflen);
1225 #else
1226                         cmn_err(CE_WARN,
1227                             "smb_node_getpath_nofail: couldn't get full path");
1228 #endif
1229                         p = buf;
1230                         *p = '*';
1231                 } else {
1232                         p += len - 1;
1233                         if (p >= buf)
1234                                 *p = '/';
1235                 }
1236 
1237                 buf[buflen - 1] = '\0';
1238                 (void) memmove(buf, p, strlen(p) + 1);
1239                 cmn_err(CE_NOTE,
1240                     "smb_node_getpath_nofail: vnodetopath failed, rc=%d", rc);
1241                 return;
1242         }
1243 
1244         len = strlen(buf) + 1;
1245 
1246         /* append filename if necessary */
1247         if (!is_dir) {
1248                 if (buf[len - 2] != '/' && strlcat(buf, "/", buflen) >= buflen)
1249                         goto trunc;
1250                 if (strlcat(buf, unode->od_name, buflen) >= buflen)
1251                         goto trunc;
1252         }
1253 
1254         /* append named stream name if necessary */
1255         if (!is_stream || strlcat(buf, node->od_name, buflen) < buflen)
1256                 return;
1257 
1258 trunc:
1259         buf[len - 1] = '\0';
1260         addlen = 0;
1261         /* append filename if necessary */
1262         if (!is_dir) {
1263                 if (buf[len - 2] != '/')
1264                         addlen++;
1265                 addlen += strlen(unode->od_name);
1266         }
1267 
1268         /* append named stream name if necessary */
1269         if (is_stream)
1270                 addlen += strlen(node->od_name);
1271 
1272         if ((buflen - len) < addlen) {
1273 #ifdef DEBUG
1274                 cmn_err(CE_WARN,
1275                     "smb_node_getpath_nofail: vnodetopath succeeded, "
1276                     "but buffer too small for filename");
1277 #else
1278                 cmn_err(CE_WARN,
1279                     "smb_node_getpath_nofail: couldn't get full path");
1280 #endif
1281                 addlen = addlen - (buflen - len);
1282                 (void) memmove(buf, buf + addlen, len - addlen);
1283                 buf[0] = '*';
1284         }
1285 
1286         /* append filename if necessary */
1287         if (!is_dir) {
1288                 if (buf[len - 2] != '/')
1289                         (void) strlcat(buf, "/", buflen);
1290                 (void) strlcat(buf, unode->od_name, buflen);
1291         }
1292 
1293         /* append named stream name if necessary */
1294         if (is_stream)
1295                 (void) strlcat(buf, node->od_name, buflen);
1296 }
1297 
1298 /*
1299  * smb_node_alloc
1300  */
1301 static smb_node_t *
1302 smb_node_alloc(
1303     char        *od_name,
1304     vnode_t     *vp,
1305     smb_llist_t *bucket,
1306     uint32_t    hashkey)
1307 {
1308         smb_node_t      *node;
1309         vnode_t         *root_vp;
1310 
1311         node = kmem_cache_alloc(smb_node_cache, KM_SLEEP);
1312 
1313         if (node->n_audit_buf != NULL)
1314                 node->n_audit_buf->anb_index = 0;
1315 
1316         node->flags = 0;
1317         VN_HOLD(vp);
1318         node->vp = vp;
1319         node->n_refcnt = 1;
1320         node->n_hash_bucket = bucket;
1321         node->n_hashkey = hashkey;
1322         node->n_open_count = 0;
1323         node->n_allocsz = 0;
1324         node->n_dnode = NULL;
1325         node->n_unode = NULL;
1326         node->delete_on_close_cred = NULL;
1327         node->n_delete_on_close_flags = 0;
1328         node->n_oplock.ol_fem = B_FALSE;
1329 
1330         (void) strlcpy(node->od_name, od_name, sizeof (node->od_name));
1331         if (strcmp(od_name, XATTR_DIR) == 0)
1332                 node->flags |= NODE_XATTR_DIR;
1333 
1334         if (VFS_ROOT(vp->v_vfsp, &root_vp) == 0) {
1335                 if (vp == root_vp)
1336                         node->flags |= NODE_FLAGS_VFSROOT;
1337                 VN_RELE(root_vp);
1338         }
1339 
1340         node->n_state = SMB_NODE_STATE_AVAILABLE;
1341         node->n_magic = SMB_NODE_MAGIC;
1342 
1343         return (node);
1344 }
1345 
1346 /*
1347  * smb_node_free
1348  */
1349 static void
1350 smb_node_free(smb_node_t *node)
1351 {
1352         SMB_NODE_VALID(node);
1353 
1354         node->n_magic = 0;
1355         VERIFY(!list_link_active(&node->n_lnd));
1356         VERIFY(node->n_lock_list.ll_count == 0);
1357         VERIFY(node->n_wlock_list.ll_count == 0);
1358         VERIFY(node->n_ofile_list.ll_count == 0);
1359         VERIFY(node->n_oplock.ol_fem == B_FALSE);
1360         VERIFY(MUTEX_NOT_HELD(&node->n_mutex));
1361         VERIFY(!RW_LOCK_HELD(&node->n_lock));
1362         VN_RELE(node->vp);
1363         kmem_cache_free(smb_node_cache, node);
1364 }
1365 
1366 /*
1367  * smb_node_constructor
1368  */
1369 static int
1370 smb_node_constructor(void *buf, void *un, int kmflags)
1371 {
1372         _NOTE(ARGUNUSED(kmflags, un))
1373 
1374         smb_node_t      *node = (smb_node_t *)buf;
1375 
1376         bzero(node, sizeof (smb_node_t));
1377 
1378         smb_llist_constructor(&node->n_ofile_list, sizeof (smb_ofile_t),
1379             offsetof(smb_ofile_t, f_node_lnd));
1380         smb_llist_constructor(&node->n_lock_list, sizeof (smb_lock_t),
1381             offsetof(smb_lock_t, l_lnd));
1382         smb_llist_constructor(&node->n_wlock_list, sizeof (smb_lock_t),
1383             offsetof(smb_lock_t, l_lnd));
1384         mutex_init(&node->n_oplock.ol_mutex, NULL, MUTEX_DEFAULT, NULL);
1385         cv_init(&node->n_oplock.WaitingOpenCV, NULL, CV_DEFAULT, NULL);
1386         rw_init(&node->n_lock, NULL, RW_DEFAULT, NULL);
1387         mutex_init(&node->n_mutex, NULL, MUTEX_DEFAULT, NULL);
1388         smb_node_create_audit_buf(node, kmflags);
1389         return (0);
1390 }
1391 
1392 /*
1393  * smb_node_destructor
1394  */
1395 static void
1396 smb_node_destructor(void *buf, void *un)
1397 {
1398         _NOTE(ARGUNUSED(un))
1399 
1400         smb_node_t      *node = (smb_node_t *)buf;
1401 
1402         smb_node_destroy_audit_buf(node);
1403         mutex_destroy(&node->n_mutex);
1404         rw_destroy(&node->n_lock);
1405         cv_destroy(&node->n_oplock.WaitingOpenCV);
1406         mutex_destroy(&node->n_oplock.ol_mutex);
1407         smb_llist_destructor(&node->n_lock_list);
1408         smb_llist_destructor(&node->n_wlock_list);
1409         smb_llist_destructor(&node->n_ofile_list);
1410 }
1411 
1412 /*
1413  * smb_node_create_audit_buf
1414  */
1415 static void
1416 smb_node_create_audit_buf(smb_node_t *node, int kmflags)
1417 {
1418         smb_audit_buf_node_t    *abn;
1419 
1420         if (smb_audit_flags & SMB_AUDIT_NODE) {
1421                 abn = kmem_zalloc(sizeof (smb_audit_buf_node_t), kmflags);
1422                 abn->anb_max_index = SMB_AUDIT_BUF_MAX_REC - 1;
1423                 node->n_audit_buf = abn;
1424         }
1425 }
1426 
1427 /*
1428  * smb_node_destroy_audit_buf
1429  */
1430 static void
1431 smb_node_destroy_audit_buf(smb_node_t *node)
1432 {
1433         if (node->n_audit_buf != NULL) {
1434                 kmem_free(node->n_audit_buf, sizeof (smb_audit_buf_node_t));
1435                 node->n_audit_buf = NULL;
1436         }
1437 }
1438 
1439 /*
1440  * smb_node_audit
1441  *
1442  * This function saves the calling stack in the audit buffer of the node passed
1443  * in.
1444  */
1445 static void
1446 smb_node_audit(smb_node_t *node)
1447 {
1448 #ifdef  _KERNEL
1449         smb_audit_buf_node_t    *abn;
1450         smb_audit_record_node_t *anr;
1451 
1452         if (node->n_audit_buf) {
1453                 abn = node->n_audit_buf;
1454                 anr = abn->anb_records;
1455                 anr += abn->anb_index;
1456                 abn->anb_index++;
1457                 abn->anb_index &= abn->anb_max_index;
1458                 anr->anr_refcnt = node->n_refcnt;
1459                 anr->anr_depth = getpcstack(anr->anr_stack,
1460                     SMB_AUDIT_STACK_DEPTH);
1461         }
1462 #else   /* _KERNEL */
1463         _NOTE(ARGUNUSED(node))
1464 #endif  /* _KERNEL */
1465 }
1466 
1467 static smb_llist_t *
1468 smb_node_get_hash(fsid_t *fsid, smb_attr_t *attr, uint32_t *phashkey)
1469 {
1470         uint32_t        hashkey;
1471 
1472         hashkey = fsid->val[0] + attr->sa_vattr.va_nodeid;
1473         hashkey += (hashkey >> 24) + (hashkey >> 16) + (hashkey >> 8);
1474         *phashkey = hashkey;
1475         return (&smb_node_hash_table[(hashkey & SMBND_HASH_MASK)]);
1476 }
1477 
1478 boolean_t
1479 smb_node_is_file(smb_node_t *node)
1480 {
1481         SMB_NODE_VALID(node);
1482         return (node->vp->v_type == VREG);
1483 }
1484 
1485 boolean_t
1486 smb_node_is_dir(smb_node_t *node)
1487 {
1488         SMB_NODE_VALID(node);
1489         return ((node->vp->v_type == VDIR) ||
1490             (node->flags & NODE_FLAGS_DFSLINK));
1491 }
1492 
1493 boolean_t
1494 smb_node_is_symlink(smb_node_t *node)
1495 {
1496         SMB_NODE_VALID(node);
1497         return ((node->vp->v_type == VLNK) &&
1498             ((node->flags & NODE_FLAGS_REPARSE) == 0));
1499 }
1500 
1501 boolean_t
1502 smb_node_is_dfslink(smb_node_t *node)
1503 {
1504         SMB_NODE_VALID(node);
1505         return ((node->vp->v_type == VLNK) &&
1506             (node->flags & NODE_FLAGS_DFSLINK));
1507 }
1508 
1509 boolean_t
1510 smb_node_is_reparse(smb_node_t *node)
1511 {
1512         SMB_NODE_VALID(node);
1513         return ((node->vp->v_type == VLNK) &&
1514             (node->flags & NODE_FLAGS_REPARSE));
1515 }
1516 
1517 boolean_t
1518 smb_node_is_vfsroot(smb_node_t *node)
1519 {
1520         SMB_NODE_VALID(node);
1521         return ((node->flags & NODE_FLAGS_VFSROOT) == NODE_FLAGS_VFSROOT);
1522 }
1523 
1524 boolean_t
1525 smb_node_is_system(smb_node_t *node)
1526 {
1527         SMB_NODE_VALID(node);
1528         return ((node->flags & NODE_FLAGS_SYSTEM) == NODE_FLAGS_SYSTEM);
1529 }
1530 
1531 /*
1532  * smb_node_file_is_readonly
1533  *
1534  * Checks if the file (which node represents) is marked readonly
1535  * in the filesystem.  Note that there may be handles open with
1536  * modify rights, and those continue to allow access even after
1537  * the DOS read-only flag has been set in the file system.
1538  */
1539 boolean_t
1540 smb_node_file_is_readonly(smb_node_t *node)
1541 {
1542         smb_attr_t attr;
1543 
1544         if (node == NULL)
1545                 return (B_FALSE);       /* pipes */
1546 
1547         bzero(&attr, sizeof (smb_attr_t));
1548         attr.sa_mask = SMB_AT_DOSATTR;
1549         (void) smb_fsop_getattr(NULL, zone_kcred(), node, &attr);
1550         return ((attr.sa_dosattr & FILE_ATTRIBUTE_READONLY) != 0);
1551 }
1552 
1553 /*
1554  * smb_node_setattr
1555  *
1556  * The sr may be NULL, for example when closing an ofile.
1557  * The ofile may be NULL, for example when a client request
1558  * specifies the file by pathname.
1559  *
1560  * Returns: errno
1561  *
1562  * Timestamps
1563  *
1564  * Windows and Unix have different models for timestamp updates.
1565  * [MS-FSA 2.1.5.14 Server Requests Setting of File Information]
1566  *
1567  * An open "handle" in Windows can control whether and when
1568  * any timestamp updates happen for that handle.  For example,
1569  * timestamps set via some handle are no longer updated by I/O
1570  * operations on that handle.  In Unix we don't really have any
1571  * way to avoid the timestamp updates that the file system does.
1572  * Therefore, we need to make some compromises, and simulate the
1573  * more important parts of the Windows file system semantics.
1574  *
1575  * For example, when an SMB client sets file times, set those
1576  * times in the file system (so the change will be visible to
1577  * other clients, at least until they change again) but we also
1578  * make those times "sticky" in our open handle, and reapply
1579  * those times when the handle is closed.  That reapply on close
1580  * simulates the Windows behavior where the timestamp updates
1581  * would be discontinued after they were set.  These "sticky"
1582  * attributes are returned in any query on the handle where
1583  * they are stored.
1584  *
1585  * Other than the above, the file system layer takes care of the
1586  * normal time stamp updates, such as updating the mtime after a
1587  * write, and ctime after an attribute change.
1588  *
1589  * Dos Attributes are stored persistently, but with a twist:
1590  * In Windows, when you set the "read-only" bit on some file,
1591  * existing writable handles to that file continue to have
1592  * write access.  (because access check happens at open)
1593  * If we were to set the read-only bit directly, we would
1594  * cause errors in subsequent writes on any of our open
1595  * (and writable) file handles.  So here too, we have to
1596  * simulate the Windows behavior.  We keep the read-only
1597  * bit "pending" in the smb_node (so it will be visible in
1598  * any new opens of the file) and apply it on close.
1599  *
1600  * File allocation size is also simulated, and not persistent.
1601  * When the file allocation size is set it is first rounded up
1602  * to block size. If the file size is smaller than the allocation
1603  * size the file is truncated by setting the filesize to allocsz.
1604  */
1605 int
1606 smb_node_setattr(smb_request_t *sr, smb_node_t *node,
1607     cred_t *cr, smb_ofile_t *of, smb_attr_t *attr)
1608 {
1609         int rc;
1610         uint_t times_mask;
1611         smb_attr_t tmp_attr;
1612         smb_node_t *unnamed_node;
1613 
1614         SMB_NODE_VALID(node);
1615 
1616         /* set attributes specified in attr */
1617         if (attr->sa_mask == 0)
1618                 return (0);  /* nothing to do (caller bug?) */
1619 
1620         /*
1621          * Allocation size and EOF position interact.
1622          * We don't persistently store the allocation size
1623          * but make it look like we do while there are opens.
1624          * Note: We update the caller's attr in the cases
1625          * where they're setting only one of allocsz|size.
1626          */
1627         switch (attr->sa_mask & (SMB_AT_ALLOCSZ | SMB_AT_SIZE)) {
1628 
1629         case SMB_AT_ALLOCSZ:
1630                 /*
1631                  * Setting the allocation size but not EOF position.
1632                  * Get the current EOF in tmp_attr and (if necessary)
1633                  * truncate to the (rounded up) allocation size.
1634                  * Using kcred here because if we don't have access,
1635                  * we want to fail at setattr below and not here.
1636                  */
1637                 bzero(&tmp_attr, sizeof (smb_attr_t));
1638                 tmp_attr.sa_mask = SMB_AT_SIZE;
1639                 rc = smb_fsop_getattr(NULL, zone_kcred(), node, &tmp_attr);
1640                 if (rc != 0)
1641                         return (rc);
1642                 attr->sa_allocsz = SMB_ALLOCSZ(attr->sa_allocsz);
1643                 if (tmp_attr.sa_vattr.va_size > attr->sa_allocsz) {
1644                         /* truncate the file to allocsz */
1645                         attr->sa_vattr.va_size = attr->sa_allocsz;
1646                         attr->sa_mask |= SMB_AT_SIZE;
1647                 }
1648                 break;
1649 
1650         case SMB_AT_SIZE:
1651                 /*
1652                  * Setting the EOF position but not allocation size.
1653                  * If the new EOF position would be greater than
1654                  * the allocation size, increase the latter.
1655                  */
1656                 if (node->n_allocsz < attr->sa_vattr.va_size) {
1657                         attr->sa_mask |= SMB_AT_ALLOCSZ;
1658                         attr->sa_allocsz =
1659                             SMB_ALLOCSZ(attr->sa_vattr.va_size);
1660                 }
1661                 break;
1662 
1663         case SMB_AT_ALLOCSZ | SMB_AT_SIZE:
1664                 /*
1665                  * Setting both.  Increase alloc size if needed.
1666                  */
1667                 if (attr->sa_allocsz < attr->sa_vattr.va_size)
1668                         attr->sa_allocsz =
1669                             SMB_ALLOCSZ(attr->sa_vattr.va_size);
1670                 break;
1671 
1672         default:
1673                 break;
1674         }
1675 
1676         /*
1677          * If we have an open file, and we set the size,
1678          * then set the "written" flag so that at close,
1679          * we can force an mtime update.
1680          */
1681         if (of != NULL && (attr->sa_mask & SMB_AT_SIZE) != 0)
1682                 of->f_written = B_TRUE;
1683 
1684         /*
1685          * When operating on an open file, some settable attributes
1686          * become "sticky" in the open file object until close.
1687          * (see above re. timestamps)
1688          */
1689         times_mask = attr->sa_mask & SMB_AT_TIMES;
1690         if (of != NULL && times_mask != 0) {
1691                 smb_attr_t *pa;
1692 
1693                 SMB_OFILE_VALID(of);
1694                 mutex_enter(&of->f_mutex);
1695                 pa = &of->f_pending_attr;
1696 
1697                 pa->sa_mask |= times_mask;
1698 
1699                 if (times_mask & SMB_AT_ATIME)
1700                         pa->sa_vattr.va_atime =
1701                             attr->sa_vattr.va_atime;
1702                 if (times_mask & SMB_AT_MTIME)
1703                         pa->sa_vattr.va_mtime =
1704                             attr->sa_vattr.va_mtime;
1705                 if (times_mask & SMB_AT_CTIME)
1706                         pa->sa_vattr.va_ctime =
1707                             attr->sa_vattr.va_ctime;
1708                 if (times_mask & SMB_AT_CRTIME)
1709                         pa->sa_crtime =
1710                             attr->sa_crtime;
1711 
1712                 mutex_exit(&of->f_mutex);
1713 
1714                 /*
1715                  * The f_pending_attr times are reapplied in
1716                  * smb_ofile_close().
1717                  */
1718 
1719                 /*
1720                  * If this change is comming directly from a client
1721                  * (sr != NULL) and it's a persistent handle, save
1722                  * the "sticky times" in the handle.
1723                  */
1724                 if (sr != NULL && of->dh_persist) {
1725                         smb2_dh_update_times(sr, of, attr);
1726                 }
1727         }
1728 
1729         if ((attr->sa_mask & SMB_AT_ALLOCSZ) != 0) {
1730                 mutex_enter(&node->n_mutex);
1731                 /*
1732                  * Simulate n_allocsz persistence only while
1733                  * there are opens.  See smb_node_getattr
1734                  */
1735                 if (node->n_open_count != 0)
1736                         node->n_allocsz = attr->sa_allocsz;
1737                 mutex_exit(&node->n_mutex);
1738         }
1739 
1740         rc = smb_fsop_setattr(sr, cr, node, attr);
1741         if (rc != 0)
1742                 return (rc);
1743 
1744         if (node->n_dnode != NULL) {
1745                 smb_node_notify_change(node->n_dnode,
1746                     FILE_ACTION_MODIFIED, node->od_name);
1747         }
1748 
1749         if ((unnamed_node = SMB_IS_STREAM(node)) != NULL) {
1750                 ASSERT(unnamed_node->n_magic == SMB_NODE_MAGIC);
1751                 ASSERT(unnamed_node->n_state != SMB_NODE_STATE_DESTROYING);
1752                 smb_node_notify_change(node->n_dnode,
1753                     FILE_ACTION_MODIFIED_STREAM, node->od_name);
1754         }
1755 
1756         return (0);
1757 }
1758 
1759 /*
1760  * smb_node_getattr
1761  *
1762  * Get attributes from the file system and apply any smb-specific
1763  * overrides for size, dos attributes and timestamps
1764  *
1765  * When node->n_pending_readonly is set on a node, pretend that
1766  * we've already set this node readonly at the filesystem level.
1767  * We can't actually do that until all writable handles are closed
1768  * or those writable handles would suddenly loose their access.
1769  *
1770  * Returns: errno
1771  */
1772 int
1773 smb_node_getattr(smb_request_t *sr, smb_node_t *node, cred_t *cr,
1774     smb_ofile_t *of, smb_attr_t *attr)
1775 {
1776         int rc;
1777         uint_t want_mask, pend_mask;
1778         boolean_t isdir;
1779 
1780         SMB_NODE_VALID(node);
1781 
1782         /* Deal with some interdependencies */
1783         if (attr->sa_mask & SMB_AT_ALLOCSZ)
1784                 attr->sa_mask |= SMB_AT_SIZE;
1785         if (attr->sa_mask & SMB_AT_DOSATTR)
1786                 attr->sa_mask |= SMB_AT_TYPE;
1787 
1788         rc = smb_fsop_getattr(sr, cr, node, attr);
1789         if (rc != 0)
1790                 return (rc);
1791 
1792         isdir = smb_node_is_dir(node);
1793 
1794         mutex_enter(&node->n_mutex);
1795 
1796         if (attr->sa_mask & SMB_AT_DOSATTR) {
1797                 if (attr->sa_dosattr == 0) {
1798                         attr->sa_dosattr = (isdir) ?
1799                             FILE_ATTRIBUTE_DIRECTORY:
1800                             FILE_ATTRIBUTE_NORMAL;
1801                 }
1802         }
1803 
1804         /*
1805          * Also fix-up sa_allocsz, which is not persistent.
1806          * When there are no open files, allocsz is faked.
1807          * While there are open files, we pretend we have a
1808          * persistent allocation size in n_allocsz, and
1809          * keep that up-to-date here, increasing it when
1810          * we see the file size grow past it.
1811          */
1812         if (attr->sa_mask & SMB_AT_ALLOCSZ) {
1813                 if (isdir) {
1814                         attr->sa_allocsz = 0;
1815                 } else if (node->n_open_count == 0) {
1816                         attr->sa_allocsz =
1817                             SMB_ALLOCSZ(attr->sa_vattr.va_size);
1818                 } else {
1819                         if (node->n_allocsz < attr->sa_vattr.va_size)
1820                                 node->n_allocsz =
1821                                     SMB_ALLOCSZ(attr->sa_vattr.va_size);
1822                         attr->sa_allocsz = node->n_allocsz;
1823                 }
1824         }
1825 
1826         mutex_exit(&node->n_mutex);
1827 
1828         if (isdir) {
1829                 attr->sa_vattr.va_size = 0;
1830                 attr->sa_vattr.va_nlink = 1;
1831         }
1832 
1833         /*
1834          * getattr with an ofile gets any "pending" times that
1835          * might have been previously set via this ofile.
1836          * This is what makes these times "sticky".
1837          */
1838         want_mask = attr->sa_mask & SMB_AT_TIMES;
1839         if (of != NULL && want_mask != 0) {
1840                 smb_attr_t *pa;
1841 
1842                 SMB_OFILE_VALID(of);
1843                 mutex_enter(&of->f_mutex);
1844                 pa = &of->f_pending_attr;
1845 
1846                 pend_mask = pa->sa_mask;
1847 
1848                 if (want_mask & pend_mask & SMB_AT_ATIME)
1849                         attr->sa_vattr.va_atime =
1850                             pa->sa_vattr.va_atime;
1851                 if (want_mask & pend_mask & SMB_AT_MTIME)
1852                         attr->sa_vattr.va_mtime =
1853                             pa->sa_vattr.va_mtime;
1854                 if (want_mask & pend_mask & SMB_AT_CTIME)
1855                         attr->sa_vattr.va_ctime =
1856                             pa->sa_vattr.va_ctime;
1857                 if (want_mask & pend_mask & SMB_AT_CRTIME)
1858                         attr->sa_crtime =
1859                             pa->sa_crtime;
1860 
1861                 mutex_exit(&of->f_mutex);
1862         }
1863 
1864 
1865         return (0);
1866 }
1867 
1868 
1869 #ifndef _KERNEL
1870 extern int reparse_vnode_parse(vnode_t *vp, nvlist_t *nvl);
1871 #endif  /* _KERNEL */
1872 
1873 /*
1874  * Check to see if the node represents a reparse point.
1875  * If yes, whether the reparse point contains a DFS link.
1876  */
1877 static void
1878 smb_node_init_reparse(smb_node_t *node, smb_attr_t *attr)
1879 {
1880         nvlist_t *nvl;
1881         nvpair_t *rec;
1882         char *rec_type;
1883 
1884         if ((attr->sa_dosattr & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
1885                 return;
1886 
1887         if ((nvl = reparse_init()) == NULL)
1888                 return;
1889 
1890         if (reparse_vnode_parse(node->vp, nvl) != 0) {
1891                 reparse_free(nvl);
1892                 return;
1893         }
1894 
1895         node->flags |= NODE_FLAGS_REPARSE;
1896 
1897         rec = nvlist_next_nvpair(nvl, NULL);
1898         while (rec != NULL) {
1899                 rec_type = nvpair_name(rec);
1900                 if ((rec_type != NULL) &&
1901                     (strcasecmp(rec_type, DFS_REPARSE_SVCTYPE) == 0)) {
1902                         node->flags |= NODE_FLAGS_DFSLINK;
1903                         break;
1904                 }
1905                 rec = nvlist_next_nvpair(nvl, rec);
1906         }
1907 
1908         reparse_free(nvl);
1909 }
1910 
1911 /*
1912  * smb_node_init_system
1913  *
1914  * If the node represents a special system file set NODE_FLAG_SYSTEM.
1915  * System files:
1916  * - any node whose parent dnode has NODE_FLAG_SYSTEM set
1917  * - any node whose associated unnamed stream node (unode) has
1918  *   NODE_FLAG_SYSTEM set
1919  * - .$EXTEND at root of share (quota management)
1920  */
1921 static void
1922 smb_node_init_system(smb_node_t *node)
1923 {
1924         smb_node_t *dnode = node->n_dnode;
1925         smb_node_t *unode = node->n_unode;
1926 
1927         if ((dnode) && (dnode->flags & NODE_FLAGS_SYSTEM)) {
1928                 node->flags |= NODE_FLAGS_SYSTEM;
1929                 return;
1930         }
1931 
1932         if ((unode) && (unode->flags & NODE_FLAGS_SYSTEM)) {
1933                 node->flags |= NODE_FLAGS_SYSTEM;
1934                 return;
1935         }
1936 
1937         if ((dnode) && (smb_node_is_vfsroot(node->n_dnode) &&
1938             (strcasecmp(node->od_name, ".$EXTEND") == 0))) {
1939                 node->flags |= NODE_FLAGS_SYSTEM;
1940         }
1941 }