smb_tree.c revision 148c5f43199ca0b43fc8e3b643aab11cd66ea327
* This is a simplified diagram showing the relationship between most of the * +-------------------+ +-------------------+ +-------------------+ * | SESSION |<----->| SESSION |......| SESSION | * +-------------------+ +-------------------+ +-------------------+ * +-------------------+ +-------------------+ +-------------------+ * | USER |<----->| USER |......| USER | * +-------------------+ +-------------------+ +-------------------+ * +-------------------+ +-------------------+ +-------------------+ * | TREE |<----->| TREE |......| TREE | * +-------------------+ +-------------------+ +-------------------+ * | +-------+ +-------+ +-------+ * | | OFILE |<----->| OFILE |......| OFILE | * | +-------+ +-------+ +-------+ * +-------+ +------+ +------+ * | ODIR |<----->| ODIR |......| ODIR | * +-------+ +------+ +------+ * +-----------------------------+ T0 * +-----------------------------+ * +------------------------------+ * | SMB_TREE_STATE_DISCONNECTING | * +------------------------------+ * +-----------------------------+ T3 * +-----------------------------+ * SMB_TREE_STATE_CONNECTED * - The tree is queued in the list of trees of its user. * - References will be given out if the tree is looked up. * - Files under that tree can be accessed. * SMB_TREE_STATE_DISCONNECTING * - The tree is queued in the list of trees of its user. * - References will not be given out if the tree is looked up. * - The files and directories open under the tree are being closed. * - The resources associated with the tree remain. * SMB_TREE_STATE_DISCONNECTED * - The tree is queued in the list of trees of its user. * - References will not be given out if the tree is looked up. * - The tree has no more files and directories opened. * - The resources associated with the tree remain. * This transition occurs in smb_tree_connect(). A new tree is created and * added to the list of trees of a user. * This transition occurs in smb_tree_disconnect(). * This transition occurs in smb_tree_release(). The resources associated * with the tree are freed as well as the tree structure. For the transition * to occur, the tree must be in the SMB_TREE_STATE_DISCONNECTED state and * the reference count be zero. * The state machine of the tree structures is controlled by 3 elements: * - The list of trees of the user it belongs to. * - The mutex embedded in the structure itself. * There's a mutex embedded in the tree structure used to protect its fields * and there's a lock embedded in the list of trees of a user. To * increment or to decrement the reference count the mutex must be entered. * To insert the tree into the list of trees of the user and to remove * the tree from it, the lock must be entered in RW_WRITER mode. * Rules of access to a tree structure: * 1) In order to avoid deadlocks, when both (mutex and lock of the user * list) have to be entered, the lock must be entered first. * 2) All actions applied to a tree require a reference count. * 3) There are 2 ways of getting a reference count: when a tree is * connected and when a tree is looked up. * It should be noted that the reference count of a tree registers the * number of references to the tree in other structures (such as an smb * request). The reference count is not incremented in these 2 instances: * 1) The tree is connected. An tree is anchored by his state. If there's * no activity involving a tree currently connected, the reference * count of that tree is zero. * 2) The tree is queued in the list of trees of the user. The fact of * being queued in that list is NOT registered by incrementing the * Lookup the share name dispatch the appropriate stype handler. * Share names are case insensitive so we map the share name to * lower-case as a convenience for internal processing. * Valid service values are: * IPC Named pipe (IPC$ is reserved as the named pipe share). * COMM Communications device * ????? Any type of device (wildcard) * Indicate that the disconnect process has started. * The files opened under this tree are closed. * The directories opened under this tree are closed. * Take a reference on a tree. * Release a reference on a tree. If the tree is disconnected and the * reference count falls to zero, post the object for deletion. * Object deletion is deferred to avoid modifying a list while an * iteration may be in progress. /* flush the ofile and odir lists' delete queues */ * Close ofiles and odirs that match pid. * Check whether or not a tree supports the features identified by flags. * If the enumeration request is for tree data, handle the request * here. Otherwise, pass it on to the ofiles. * This function should be called with a hold on the tree. * Close a file by its unique id. /* *************************** Static Functions ***************************** */ * Calculates permissions given by the share's ACL to the * user in the passed request. The default is full access. * If any error occurs, full access is granted. * Using the vnode of the share path find the root directory * of the mounted file system. Then look to see if there is a * .zfs/shares directory and if there is, lookup the file with * the same name as the share name in it. The ACL set for this * file is the share's ACL which is used for access check here. * An autohome share owner gets full access to the share. * Everyone else is denied access. * The hold on 'root' is released by the lookuppnvp() that follows * Now get the effective access value based on cred and ACL values. * Performs the following access checks for a disk share: * - If user is Guest, guestok property of the share should be * - If this is an Admin share, the user should have administrative * - Host based access control lists * Returns the access allowed or 0 if access is denied. * Connect a share for use with files and directories. const char *
any =
"?????";
* Check that the shared directory exists. * Set up the OptionalSupport for this share. * Default to SMB_CSC_CACHE_MANUAL_REINT. * Shares have both a share and host based access control. The access * granted will be minimum permissions based on both hostaccess * (permissions allowed by host based access) and aclaccess (from the const char *
any =
"?????";
* Check that the shared directory exists. * Connect an IPC share for use with named pipes. const char *
any =
"?????";
/* if FS is readonly, enforce that here */ * Deallocate a tree. The open file and open directory lists should be * Remove the tree from the user's tree list before freeing resources * associated with the tree. * Determine whether or not a tree is connected. * This function must be called with the tree mutex held. * The tree exists but being diconnected or destroyed. * Determine whether or not a tree is disconnected. * This function must be called with the tree mutex held. * Return a pointer to the share name within a share resource path. * The share path may be a Uniform Naming Convention (UNC) string * (\\server\share) or simply the share name. We validate the UNC * format but we don't look at the server name. * Looks like a UNC path, validate the format. * This should be a share name (no embedded \'s). * Obtain the tree attributes: volume name, typename and flags. * Extract the volume name. * Always set ACL support because the VFS will fake ACLs for file systems * that don't support them. * Some flags are dependent on the typename, which is also set up here. * Report share access result to syslog. * Only report normal users, i.e. ignore W2K misuse * of the IPC connection by filtering out internal * names such as nobody and root. * Find the specified odir in the tree's list of odirs, and * attempt to obtain a hold on the odir. * Returns NULL if odir not found or a hold cannot be obtained. * Get the next open ofile in the list. A reference is taken on * the ofile, which can be released later with smb_ofile_release(). * If the specified ofile is NULL, search from the beginning of the * list. Otherwise, the search starts just after that ofile. * Returns NULL if there are no open files in the list. * Find the next odir in the tree's list of odirs, and obtain a * If the specified odir is NULL the search starts at the beginning * of the tree's odir list, otherwise the search starts after the * Close all open odirs in the tree's list which were opened by * the process identified by pid. * If pid is zero, close all open odirs in the tree's list. * Private function to support smb_tree_enum. * Encode connection information into a buffer: connection information * needed in user space to support RPC requests. * Note: ci_numusers should be the number of users connected to * the share rather than the number of references on the tree but * we don't have a mechanism to track users/share in smbsrv yet.