smb_tree.c revision fc724630b14603e4c1147df68b7bf45f7de7431f
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * General Structures Layout
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * -------------------------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is a simplified diagram showing the relationship between most of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * main structures.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_INFO |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SESSION |<----->| SESSION |......| SESSION |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | USER |<----->| USER |......| USER |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | TREE |<----->| TREE |......| TREE |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | +-------+ +-------+ +-------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | | OFILE |<----->| OFILE |......| OFILE |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | +-------+ +-------+ +-------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------+ +------+ +------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | ODIR |<----->| ODIR |......| ODIR |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------+ +------+ +------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Tree State Machine
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ------------------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+ T0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_TREE_STATE_CONNECTED |<----------- Creation/Allocation
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | T1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +------------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_TREE_STATE_DISCONNECTING |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +------------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | T2
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+ T3
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_TREE_STATE_DISCONNECTED |----------> Deletion/Free
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_CONNECTED
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * While in this state:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree is queued in the list of trees of its user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - References will be given out if the tree is looked up.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - Files under that tree can be accessed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_DISCONNECTING
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * While in this state:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree is queued in the list of trees of its user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - References will not be given out if the tree is looked up.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The files and directories open under the tree are being closed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The resources associated with the tree remain.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_DISCONNECTED
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * While in this state:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree is queued in the list of trees of its user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - References will not be given out if the tree is looked up.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree has no more files and directories opened.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The resources associated with the tree remain.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_tree_connect(). A new tree is created and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * added to the list of trees of a user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_tree_disconnect().
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T2
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_tree_release(). The resources associated
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * with the tree are freed as well as the tree structure. For the transition
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to occur, the tree must be in the SMB_TREE_STATE_DISCONNECTED state and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the reference count be zero.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Comments
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * --------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The state machine of the tree structures is controlled by 3 elements:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The list of trees of the user it belongs to.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The mutex embedded in the structure itself.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The reference count.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * There's a mutex embedded in the tree structure used to protect its fields
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and there's a lock embedded in the list of trees of a user. To
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * increment or to decrement the reference count the mutex must be entered.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * To insert the tree into the list of trees of the user and to remove
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the tree from it, the lock must be entered in RW_WRITER mode.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Rules of access to a tree structure:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 1) In order to avoid deadlocks, when both (mutex and lock of the user
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * list) have to be entered, the lock must be entered first.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 2) All actions applied to a tree require a reference count.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * 3) There are 2 ways of getting a reference count: when a tree is
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * connected and when a tree is looked up.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * It should be noted that the reference count of a tree registers the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * number of references to the tree in other structures (such as an smb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * request). The reference count is not incremented in these 2 instances:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 1) The tree is connected. An tree is anchored by his state. If there's
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * no activity involving a tree currently connected, the reference
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * count of that tree is zero.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 2) The tree is queued in the list of trees of the user. The fact of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * being queued in that list is NOT registered by incrementing the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * reference count.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <sys/types.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <sys/refstr_impl.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <sys/feature_tests.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <sys/sunddi.h>
55bf511df53aad0fdb7eb3fa349f0308cc05234cas#include <sys/fsid.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <sys/vfs.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <sys/stat.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <sys/varargs.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_incl.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <smbsrv/lmerr.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_fsops.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <smbsrv/smb_door_svc.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#include <smbsrv/smb_share.h>
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright#include <sys/pathname.h>
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregoint smb_tcon_mute = 0;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic smb_tree_t *smb_tree_connect_disk(smb_request_t *, const char *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic smb_tree_t *smb_tree_connect_ipc(smb_request_t *, const char *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic smb_tree_t *smb_tree_alloc(smb_user_t *, const char *, const char *,
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright int32_t, smb_node_t *, uint32_t);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic void smb_tree_dealloc(smb_tree_t *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic boolean_t smb_tree_is_connected(smb_tree_t *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic boolean_t smb_tree_is_disconnected(smb_tree_t *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic const char *smb_tree_get_sharename(const char *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic int smb_tree_get_stype(const char *, const char *, int32_t *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic int smb_tree_getattr(smb_node_t *, smb_tree_t *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic void smb_tree_get_volname(vfs_t *, smb_tree_t *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic void smb_tree_get_flags(vfs_t *, smb_tree_t *);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic void smb_tree_log(smb_request_t *, const char *, const char *, ...);
7f667e74610492ddbce8ce60f52ece95d2401949jose borregostatic void smb_tree_close_odirs(smb_tree_t *, uint16_t);
7f667e74610492ddbce8ce60f52ece95d2401949jose borregostatic smb_odir_t *smb_tree_get_odir(smb_tree_t *, smb_odir_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Extract the share name and share type and connect as appropriate.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Share names are case insensitive so we map the share name to
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * lower-case as a convenience for internal processing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_t *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_connect(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego char *unc_path = sr->arg.tcon.path;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego char *service = sr->arg.tcon.service;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_t *tree = NULL;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego const char *name;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego int32_t stype;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) utf8_strlwr(unc_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((name = smb_tree_get_sharename(unc_path)) == NULL) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_tree_get_stype(name, service, &stype) != 0) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ERRDOS, ERROR_BAD_DEV_TYPE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (stype & STYPE_MASK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_DISKTREE:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree = smb_tree_connect_disk(sr, name);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_IPC:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree = smb_tree_connect_ipc(sr, name);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego break;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ERRDOS, ERROR_BAD_DEV_TYPE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Disconnect a tree.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_disconnect(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_refcnt);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_tree_is_connected(tree)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Indicate that the disconnect process has started.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_state = SMB_TREE_STATE_DISCONNECTING;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb atomic_dec_32(&tree->t_server->sv_open_trees);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The files opened under this tree are closed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_ofile_close_all(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The directories opened under this tree are closed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_tree_close_odirs(tree, 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_state = SMB_TREE_STATE_DISCONNECTED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Take a reference on a tree.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregoboolean_t
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_hold(
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego mutex_enter(&tree->t_mutex);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_tree_is_connected(tree)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_refcnt++;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego mutex_exit(&tree->t_mutex);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_TRUE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego mutex_exit(&tree->t_mutex);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_FALSE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Release a reference on a tree. If the tree is disconnected and the
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * reference count falls to zero, the tree will be deallocated.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_release(
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego mutex_enter(&tree->t_mutex);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(tree->t_refcnt);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_refcnt--;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_tree_is_disconnected(tree) && (tree->t_refcnt == 0)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego mutex_exit(&tree->t_mutex);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_dealloc(tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Close ofiles and odirs that match pid.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_close_pid(
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_t *tree,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego uint16_t pid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_ofile_close_all_by_pid(tree, pid);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_tree_close_odirs(tree, pid);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Check whether or not a tree supports the features identified by flags.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregoboolean_t
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_has_feature(smb_tree_t *tree, uint32_t flags)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return ((tree->t_flags & flags) == flags);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/* *************************** Static Functions ***************************** */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright#define SHARES_DIR ".zfs/shares/"
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wrightstatic void
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wrightsmb_tree_acl_access(cred_t *cred, const char *sharename, vnode_t *pathvp,
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright uint32_t *access)
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright{
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright int rc;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright vfs_t *vfsp;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright vnode_t *root = NULL;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright vnode_t *sharevp = NULL;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright char *sharepath;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright struct pathname pnp;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright size_t size;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright *access = ACE_ALL_PERMS; /* default to full "UNIX" access */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /*
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * Using the vnode of the share path, we then find the root
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * directory of the mounted file system. We will then look to
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * see if there is a .zfs/shares directory and if there is,
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * get the access information from the ACL/ACES values and
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * check against the cred.
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright vfsp = pathvp->v_vfsp;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if (vfsp != NULL)
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright rc = VFS_ROOT(vfsp, &root);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright else
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright rc = ENOENT;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if (rc != 0)
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright return;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /*
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * Find the share object, if there is one. Need to construct
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * the path to the .zfs/shares/<sharename> object and look it
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * up. root is called held but will be released by
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * lookuppnvp().
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright size = sizeof (SHARES_DIR) + strlen(sharename) + 1;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright sharepath = kmem_alloc(size, KM_SLEEP);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright (void) sprintf(sharepath, "%s%s", SHARES_DIR, sharename);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright pn_alloc(&pnp);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright (void) pn_set(&pnp, sharepath);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright rc = lookuppnvp(&pnp, NULL, NO_FOLLOW, NULL,
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright &sharevp, rootdir, root, kcred);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright pn_free(&pnp);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright kmem_free(sharepath, size);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /*
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * Now get the effective access value based on cred and ACL
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * values.
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if (rc == 0)
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright smb_vop_eaccess(sharevp, (int *)access, V_ACE_MASK, NULL, cred);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Connect a share for use with files and directories.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic smb_tree_t *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_connect_disk(smb_request_t *sr, const char *sharename)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_user_t *user = sr->uid_user;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_node_t *dir_snode = NULL;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_node_t *snode = NULL;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego char last_component[MAXNAMELEN];
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_t *tree;
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_share_t *si;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_attr_t attr;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego cred_t *u_cred;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego int rc;
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States uint32_t access = 0; /* read/write is assumed */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright uint32_t hostaccess = ACE_ALL_PERMS;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright uint32_t aclaccess;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego u_cred = user->u_cred;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(u_cred);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (user->u_flags & SMB_USER_FLAG_IPC) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_log(sr, sharename, "access denied: IPC only");
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States si = kmem_zalloc(sizeof (smb_share_t), KM_SLEEP);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States if (smb_kshare_getinfo(sr->sr_server->sv_lmshrd, (char *)sharename, si,
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego &sr->session->ipaddr) != NERR_Success) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_log(sr, sharename, "share not found");
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States kmem_free(si, sizeof (smb_share_t));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Handle the default administration shares: C$, D$ etc.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Only a user with admin rights is allowed to map these
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * shares.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States if (si->shr_flags & SMB_SHRF_ADMIN) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (!smb_user_is_admin(user)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_log(sr, sharename, "access denied: not admin");
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ERRSRV, ERRaccess);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States kmem_free(si, sizeof (smb_share_t));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego /*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Set up the OptionalSupport for this share.
8d7e41661dc4633488e93b13363137523ce59977jose borrego */
8d7e41661dc4633488e93b13363137523ce59977jose borrego sr->arg.tcon.optional_support = SMB_SUPPORT_SEARCH_BITS;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
8d7e41661dc4633488e93b13363137523ce59977jose borrego switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
8d7e41661dc4633488e93b13363137523ce59977jose borrego case SMB_SHRF_CSC_DISABLED:
8d7e41661dc4633488e93b13363137523ce59977jose borrego sr->arg.tcon.optional_support |= SMB_CSC_CACHE_NONE;
8d7e41661dc4633488e93b13363137523ce59977jose borrego break;
8d7e41661dc4633488e93b13363137523ce59977jose borrego case SMB_SHRF_CSC_AUTO:
8d7e41661dc4633488e93b13363137523ce59977jose borrego sr->arg.tcon.optional_support |= SMB_CSC_CACHE_AUTO_REINT;
8d7e41661dc4633488e93b13363137523ce59977jose borrego break;
8d7e41661dc4633488e93b13363137523ce59977jose borrego case SMB_SHRF_CSC_VDO:
8d7e41661dc4633488e93b13363137523ce59977jose borrego sr->arg.tcon.optional_support |= SMB_CSC_CACHE_VDO;
8d7e41661dc4633488e93b13363137523ce59977jose borrego break;
8d7e41661dc4633488e93b13363137523ce59977jose borrego case SMB_SHRF_CSC_MANUAL:
8d7e41661dc4633488e93b13363137523ce59977jose borrego default:
8d7e41661dc4633488e93b13363137523ce59977jose borrego /*
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Default to SMB_CSC_CACHE_MANUAL_REINT.
8d7e41661dc4633488e93b13363137523ce59977jose borrego */
8d7e41661dc4633488e93b13363137523ce59977jose borrego break;
8d7e41661dc4633488e93b13363137523ce59977jose borrego }
8d7e41661dc4633488e93b13363137523ce59977jose borrego
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright access = si->shr_access_value & SMB_SHRF_ACC_ALL;
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if (access == SMB_SHRF_ACC_RO) {
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright hostaccess &= ~ACE_ALL_WRITE_PERMS;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright } else if (access == SMB_SHRF_ACC_NONE) {
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States kmem_free(si, sizeof (smb_share_t));
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_tree_log(sr, sharename, "access denied: host access");
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States return (NULL);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States }
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Check that the shared directory exists.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States rc = smb_pathname_reduce(sr, u_cred, si->shr_path, 0, 0, &dir_snode,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego last_component);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (rc == 0) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego rc = smb_fsop_lookup(sr, u_cred, SMB_FOLLOW_LINKS, 0,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego dir_snode, last_component, &snode, &attr, 0, 0);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_node_release(dir_snode);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (rc) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (snode)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_node_release(snode);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_tree_log(sr, sharename, "bad path: %s", si->shr_path);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States kmem_free(si, sizeof (smb_share_t));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /*
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * Find share level ACL if it exists in the designated
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * location. Needs to be done after finding a valid path but
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * before the tree is allocated.
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright smb_tree_acl_access(u_cred, sharename, snode->vp, &aclaccess);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /* if an error, then no share file -- default to no ACL */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if (rc == 0) {
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /*
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * There need to be some permissions in order to have
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * any access.
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if ((aclaccess & ACE_ALL_PERMS) == 0) {
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright smb_tree_log(sr, sharename, "access denied: share ACL");
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright smbsr_error(sr, 0, ERRSRV, ERRaccess);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright kmem_free(si, sizeof (smb_share_t));
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright smb_node_release(snode);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright return (NULL);
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright }
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright }
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /*
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * Set tree ACL access to the minimum ACL permissions based on
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * hostaccess (those allowed by host based access) and
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * aclaccess (those from the ACL object for the share). This
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright * is done during the alloc.
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States tree = smb_tree_alloc(user, sharename, si->shr_path, STYPE_DISKTREE,
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright snode, hostaccess & aclaccess);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (tree == NULL)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_node_release(snode);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States kmem_free(si, sizeof (smb_share_t));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Connect an IPC share for use with named pipes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic smb_tree_t *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_connect_ipc(smb_request_t *sr, const char *name)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_user_t *user = sr->uid_user;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_t *tree;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((user->u_flags & SMB_USER_FLAG_IPC) &&
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego sr->sr_cfg->skc_restrict_anon) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_log(sr, name, "access denied: restrict anonymous");
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8d7e41661dc4633488e93b13363137523ce59977jose borrego sr->arg.tcon.optional_support = SMB_SUPPORT_SEARCH_BITS;
8d7e41661dc4633488e93b13363137523ce59977jose borrego
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright tree = smb_tree_alloc(user, name, name, STYPE_IPC, NULL, ACE_ALL_PERMS);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (tree == NULL) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_log(sr, name, "access denied");
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Allocate a tree.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic smb_tree_t *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_alloc(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_user_t *user,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego const char *sharename,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego const char *resource,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego int32_t stype,
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright smb_node_t *snode,
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright uint32_t access)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_t *tree;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego uint16_t tid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_idpool_alloc(&user->u_tid_pool, &tid))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree = kmem_cache_alloc(user->u_server->si_cache_tree, KM_SLEEP);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego bzero(tree, sizeof (smb_tree_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (STYPE_ISDSK(stype)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_tree_getattr(snode, tree) != 0) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_idpool_free(&user->u_tid_pool, tid);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego kmem_cache_free(user->u_server->si_cache_tree, tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_idpool_constructor(&tree->t_fid_pool)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_idpool_free(&user->u_tid_pool, tid);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego kmem_cache_free(user->u_server->si_cache_tree, tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (smb_idpool_constructor(&tree->t_odid_pool)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_idpool_destructor(&tree->t_fid_pool);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_idpool_free(&user->u_tid_pool, tid);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego kmem_cache_free(user->u_server->si_cache_tree, tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_llist_constructor(&tree->t_ofile_list, sizeof (smb_ofile_t),
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego offsetof(smb_ofile_t, f_lnd));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_llist_constructor(&tree->t_odir_list, sizeof (smb_odir_t),
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego offsetof(smb_odir_t, d_lnd));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) strlcpy(tree->t_sharename, sharename,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego sizeof (tree->t_sharename));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) strlcpy(tree->t_resource, resource, sizeof (tree->t_resource));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego mutex_init(&tree->t_mutex, NULL, MUTEX_DEFAULT, NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_user = user;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_session = user->u_session;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_server = user->u_server;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_refcnt = 1;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_tid = tid;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_res_type = stype;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_state = SMB_TREE_STATE_CONNECTED;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_magic = SMB_TREE_MAGIC;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright tree->t_access = access;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright /* if FS is readonly, enforce that here */
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright if (tree->t_flags & SMB_TREE_READONLY)
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright tree->t_access &= ~ACE_ALL_WRITE_PERMS;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (STYPE_ISDSK(stype)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_node_ref(snode);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_snode = snode;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_acltype = smb_fsop_acltype(snode);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_llist_enter(&user->u_tree_list, RW_WRITER);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_llist_insert_head(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego atomic_inc_32(&user->u_session->s_tree_cnt);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego atomic_inc_32(&user->u_server->sv_open_trees);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Deallocate a tree: release all resources associated with a tree and
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * remove the tree from the user's tree list.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * The tree being destroyed must be in the "destroying" state and the
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * reference count must be zero. This function assumes it's single threaded
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * i.e. only one thread will attempt to destroy a specific tree, which
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * should be the case if the tree is in disconnected and has a reference
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * count of zero.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_dealloc(smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_state == SMB_TREE_STATE_DISCONNECTED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_refcnt == 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Remove the tree from the user's tree list. This must be done
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * before any resources associated with the tree are released.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(&tree->t_user->u_tree_list, RW_WRITER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_remove(&tree->t_user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&tree->t_user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_magic = (uint32_t)~SMB_TREE_MAGIC;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_free(&tree->t_user->u_tid_pool, tree->t_tid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw atomic_dec_32(&tree->t_session->s_tree_cnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (tree->t_snode)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(tree->t_snode);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_destroy(&tree->t_mutex);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The list of open files and open directories should be empty.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_destructor(&tree->t_ofile_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_destructor(&tree->t_odir_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_destructor(&tree->t_fid_pool);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_idpool_destructor(&tree->t_odid_pool);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb kmem_cache_free(tree->t_server->si_cache_tree, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Determine whether or not a tree is connected.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * This function must be called with the tree mutex held.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic boolean_t
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_is_connected(smb_tree_t *tree)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego switch (tree->t_state) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego case SMB_TREE_STATE_CONNECTED:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_TRUE);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego case SMB_TREE_STATE_DISCONNECTING:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego case SMB_TREE_STATE_DISCONNECTED:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * The tree exists but being diconnected or destroyed.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_FALSE);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego default:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(0);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_FALSE);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Determine whether or not a tree is disconnected.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * This function must be called with the tree mutex held.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic boolean_t
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_is_disconnected(smb_tree_t *tree)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego switch (tree->t_state) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego case SMB_TREE_STATE_DISCONNECTED:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_TRUE);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego case SMB_TREE_STATE_CONNECTED:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego case SMB_TREE_STATE_DISCONNECTING:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_FALSE);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego default:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(0);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (B_FALSE);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Return a pointer to the share name within a share resource path.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * The share path may be a Uniform Naming Convention (UNC) string
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * (\\server\share) or simply the share name. We validate the UNC
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * format but we don't look at the server name.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic const char *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_get_sharename(const char *unc_path)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego const char *sharename = unc_path;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (sharename[0] == '\\') {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Looks like a UNC path, validate the format.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (sharename[1] != '\\')
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((sharename = strchr(sharename+2, '\\')) == NULL)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ++sharename;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego } else if (strchr(sharename, '\\') != NULL) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * This should be a share name (no embedded \'s).
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (NULL);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (sharename);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Map the service to a resource type. Valid values for service are:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * A: Disk share
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * LPT1: Printer
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * IPC Named pipe
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * COMM Communications device
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * ????? Any type of device (wildcard)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * We support IPC and disk shares; anything else is currently treated
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * as an error. IPC$ is reserved as the named pipe share.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic int
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_get_stype(const char *sharename, const char *service,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego int32_t *stype_ret)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego const char *any = "?????";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((strcmp(service, any) == 0) || (strcasecmp(service, "IPC") == 0)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (strcasecmp(sharename, "IPC$") == 0) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego *stype_ret = STYPE_IPC;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((strcmp(service, any) == 0) || (strcasecmp(service, "A:") == 0)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (strcasecmp(sharename, "IPC$") == 0)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (-1);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego *stype_ret = STYPE_DISKTREE;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (0);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Obtain the tree attributes: volume name, typename and flags.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic int
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_getattr(smb_node_t *node, smb_tree_t *tree)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego vfs_t *vfsp = SMB_NODE_VFS(node);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(vfsp);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (getvfs(&vfsp->vfs_fsid) != vfsp)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (ESTALE);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_get_volname(vfsp, tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_tree_get_flags(vfsp, tree);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego VFS_RELE(vfsp);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (0);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Extract the volume name.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic void
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_get_volname(vfs_t *vfsp, smb_tree_t *tree)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego refstr_t *vfs_mntpoint;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego const char *s;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego char *name;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego vfs_mntpoint = vfs_getmntpoint(vfsp);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego s = vfs_mntpoint->rs_string;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego s += strspn(s, "/");
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) strlcpy(tree->t_volume, s, SMB_VOLNAMELEN);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego refstr_rele(vfs_mntpoint);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego name = tree->t_volume;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) strsep((char **)&name, "/");
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Always set ACL support because the VFS will fake ACLs for file systems
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * that don't support them.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Some flags are dependent on the typename, which is also set up here.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * File system types are hardcoded in uts/common/os/vfs_conf.c.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic void
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_get_flags(vfs_t *vfsp, smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright typedef struct smb_mtype {
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright char *mt_name;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright size_t mt_namelen;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright uint32_t mt_flags;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright } smb_mtype_t;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright static smb_mtype_t smb_mtype[] = {
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright { "zfs", 3, SMB_TREE_UNICODE_ON_DISK },
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright { "ufs", 3, SMB_TREE_UNICODE_ON_DISK },
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright { "nfs", 3, SMB_TREE_NFS_MOUNTED },
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright { "tmpfs", 5, SMB_TREE_NO_EXPORT }
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright };
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright smb_mtype_t *mtype;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright char *name;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright uint32_t flags = SMB_TREE_SUPPORTS_ACLS;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright int i;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfsp->vfs_flag & VFS_RDONLY)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_READONLY;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfsp->vfs_flag & VFS_XATTR)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_STREAMS;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfs_optionisset(vfsp, MNTOPT_NOATIME, NULL))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_NO_ATIME;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego name = vfssw[vfsp->vfs_fstype].vsw_name;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright for (i = 0; i < sizeof (smb_mtype) / sizeof (smb_mtype[0]); ++i) {
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright mtype = &smb_mtype[i];
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright if (strncasecmp(name, mtype->mt_name, mtype->mt_namelen) == 0)
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright flags |= mtype->mt_flags;
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) strlcpy(tree->t_typename, name, SMB_TYPENAMELEN);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) utf8_strupr((char *)tree->t_typename);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfs_has_feature(vfsp, VFSFT_XVATTR))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_XVATTR;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfs_has_feature(vfsp, VFSFT_CASEINSENSITIVE))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_CASEINSENSITIVE;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfs_has_feature(vfsp, VFSFT_NOCASESENSITIVE))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_NO_CASESENSITIVE;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfs_has_feature(vfsp, VFSFT_DIRENTFLAGS))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_DIRENTFLAGS;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfs_has_feature(vfsp, VFSFT_ACLONCREATE))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_ACLONCREATE;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (vfs_has_feature(vfsp, VFSFT_ACEMASKONACCESS))
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego flags |= SMB_TREE_ACEMASKONACCESS;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright DTRACE_PROBE2(smb__tree__flags, uint32_t, flags, char *, name);
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego tree->t_flags = flags;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego}
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego/*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Report share access result to syslog.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregostatic void
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borregosmb_tree_log(smb_request_t *sr, const char *sharename, const char *fmt, ...)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego{
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego va_list ap;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego char buf[128];
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_user_t *user = sr->uid_user;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego ASSERT(user);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (smb_tcon_mute)
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((user->u_name) && (strcasecmp(sharename, "IPC$") == 0)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Only report normal users, i.e. ignore W2K misuse
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * of the IPC connection by filtering out internal
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * names such as nobody and root.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((strcmp(user->u_name, "root") == 0) ||
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (strcmp(user->u_name, "nobody") == 0)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego va_start(ap, fmt);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (void) vsnprintf(buf, 128, fmt, ap);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego va_end(ap);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego cmn_err(CE_NOTE, "smbd[%s\\%s]: %s %s",
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego user->u_domain, user->u_name, sharename, buf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego/*
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * smb_tree_lookup_odir
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego *
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Find the specified odir in the tree's list of odirs, and
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * attempt to obtain a hold on the odir.
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego *
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Returns NULL if odir not found or a hold cannot be obtained.
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego */
7f667e74610492ddbce8ce60f52ece95d2401949jose borregosmb_odir_t *
7f667e74610492ddbce8ce60f52ece95d2401949jose borregosmb_tree_lookup_odir(smb_tree_t *tree, uint16_t odid)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego{
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_odir_t *od;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_llist_t *od_list;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(tree);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(tree->t_magic == SMB_TREE_MAGIC);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od_list = &tree->t_odir_list;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_llist_enter(od_list, RW_READER);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = smb_llist_head(od_list);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego while (od) {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (od->d_odid == odid) {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (!smb_odir_hold(od))
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = NULL;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego break;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego }
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = smb_llist_next(od_list, od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego }
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_llist_exit(od_list);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego return (od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego}
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego/*
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * smb_tree_get_odir
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego *
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Find the next open odir in the tree's list of odirs, and obtain
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * a hold on it. (A hold can only be obtained on an open odir.)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * If the specified odir is NULL the search starts at the beginning
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * of the tree's odir list, otherwise the search starts after the
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * specified odir.
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego */
7f667e74610492ddbce8ce60f52ece95d2401949jose borregostatic smb_odir_t *
7f667e74610492ddbce8ce60f52ece95d2401949jose borregosmb_tree_get_odir(smb_tree_t *tree, smb_odir_t *od)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego{
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_llist_t *od_list;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(tree);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(tree->t_magic == SMB_TREE_MAGIC);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od_list = &tree->t_odir_list;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_llist_enter(od_list, RW_READER);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (od) {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(od->d_magic == SMB_ODIR_MAGIC);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = smb_llist_next(od_list, od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego } else {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = smb_llist_head(od_list);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego }
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego while (od) {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(od->d_magic == SMB_ODIR_MAGIC);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if (smb_odir_hold(od))
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego break;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = smb_llist_next(od_list, od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego }
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_llist_exit(od_list);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego return (od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego}
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego/*
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * smb_tree_close_odirs
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego *
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Close all open odirs in the tree's list which were opened by
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * the process identified by pid.
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * If pid is zero, close all open odirs in the tree's list.
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego */
7f667e74610492ddbce8ce60f52ece95d2401949jose borregostatic void
7f667e74610492ddbce8ce60f52ece95d2401949jose borregosmb_tree_close_odirs(smb_tree_t *tree, uint16_t pid)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego{
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_odir_t *od, *next_od;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(tree);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(tree->t_magic == SMB_TREE_MAGIC);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = smb_tree_get_odir(tree, NULL);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego while (od) {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(od->d_magic == SMB_ODIR_MAGIC);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ASSERT(od->d_tree == tree);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego next_od = smb_tree_get_odir(tree, od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego if ((pid == 0) || (od->d_opened_by_pid == pid))
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_odir_close(od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego smb_odir_release(od);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego od = next_od;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego }
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego}