smb_fsops.c revision faa1795a28a5c712eed6d0a3f84d98c368a316c6
3853N/A * The contents of this file are subject to the terms of the 3853N/A * Common Development and Distribution License (the "License"). 3853N/A * You may not use this file except in compliance with the License. 3853N/A * See the License for the specific language governing permissions 3853N/A * and limitations under the License. 3853N/A * When distributing Covered Code, include this CDDL HEADER in each 3853N/A * If applicable, add the following below this CDDL HEADER, with the 3853N/A * fields enclosed by brackets "[]" replaced with your own identifying 3853N/A * information: Portions Copyright [yyyy] [name of copyright owner] 3853N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3853N/A * Use is subject to license terms. 3853N/A#
pragma ident "%Z%%M% %I% %E% SMI" 3853N/A * The smb_fsop_* functions have knowledge of CIFS semantics. 3853N/A * The smb_vop_* functions have minimal knowledge of CIFS semantics and 3853N/A * serve as an interface to the VFS layer. 3853N/A * Hence, smb_request_t and smb_node_t structures should not be passed 3853N/A * from the smb_fsop_* layer to the smb_vop_* layer. 3853N/A * In general, CIFS service code should only ever call smb_fsop_* 3853N/A * functions directly, and never smb_vop_* functions directly. 3853N/A * smb_fsop_* functions should call smb_vop_* functions where possible, instead 3853N/A * of their smb_fsop_* counterparts. However, there are times when 4803N/A * Note: Stream names cannot be mangled. 4141N/A * Assuming that same vnode is returned as we had before 4060N/A * Ideally we should be able to specify the owner and owning 4060N/A * group at create time along with the ACL. Since we cannot 4060N/A * do that right now, kcred is passed to smb_vop_setattr so it 4060N/A * doesn't fail due to lack of permission. 3853N/A * For filesystems that don't support ACL-on-create, try 4803N/A * to set the specified SD after create, which could actually 3853N/A * fail because of conflicts between inherited security 3853N/A * attributes upon creation and the specified SD. 3853N/A * Passing kcred to smb_fsop_sdwrite() to overcome this issue. 3853N/A * All SMB functions should use this wrapper to ensure that 3853N/A * all the smb_vop_creates are performed with the appropriate credentials. 3853N/A * Please document any direct calls to explain the reason 3853N/A * for avoiding this wrapper. 3853N/A * It is assumed that a reference exists on snode coming into this routine. 3853N/A * *ret_snode is returned with a reference upon success. No reference is 3853N/A * taken if an error is returned. 3853N/A * Look up the unnamed stream. 3853N/A * Mangle processing in smb_fsop_lookup() for the unnamed 3853N/A * stream won't be needed (as it was done above), but 4500N/A * it may be needed on any link target (which 4500N/A * smb_fsop_lookup() will provide). 4060N/A * The second parameter of smb_vop_setattr() is set to 4060N/A * NULL, even though an unnamed stream exists. This is 3853N/A * because we want to set the UID and GID on the named 3853N/A * stream in this case for consistency with the (unnamed 3853N/A * stream) file (see comments for smb_vop_setattr()). 3853N/A * SD sent by client in Windows format. Needs to be 3853N/A * converted to FS format. No inheritance. 3853N/A * No incoming SD and filesystem is ZFS 3853N/A * Server applies Windows inheritance rules, 3853N/A * see smb_fsop_sdinherit() comments as to why. 3853N/A * No incoming SD and filesystem is not ZFS 3853N/A * let the filesystem handles the inheritance. 3853N/A * All SMB functions should use this wrapper to ensure that 3853N/A * the the calls are performed with the appropriate credentials. 3853N/A * Please document any direct call to explain the reason 3853N/A * for avoiding this wrapper. 3853N/A * It is assumed that a reference exists on snode coming into this routine. 3853N/A * *ret_snode is returned with a reference upon success. No reference is 3853N/A * taken if an error is returned. 3853N/A * If the name passed in by the client has an unmangled 3853N/A * equivalent that is found in the specified directory, 3853N/A * then the mkdir cannot succeed. Return EEXIST. 3853N/A * Only if ENOENT is returned will a mkdir be attempted. 3853N/A * SD sent by client in Windows format. Needs to be 3853N/A * converted to FS format. No inheritance. 3853N/A * No incoming SD and filesystem is ZFS 3853N/A * Server applies Windows inheritance rules, 3853N/A * see smb_fsop_sdinherit() comments as to why. 4500N/A * All SMB functions should use this wrapper to ensure that 3853N/A * the the calls are performed with the appropriate credentials. 3853N/A * Please document any direct call to explain the reason 3853N/A * for avoiding this wrapper. 3853N/A * It is assumed that a reference exists on snode coming into this routine. 3853N/A * od: This means that the name passed in is an on-disk name. 3853N/A * A null smb_request might be passed to this function. 3853N/A * The state of the node could be SMB_NODE_STATE_DESTROYING if this 3853N/A * function is called during the deletion of the node (because of 4803N/A * If the passed-in name is an on-disk name, 4803N/A * then we need to do a case-sensitive remove. 4803N/A * This is important if the on-disk name 4803N/A * corresponds to a mangled name passed in by 4803N/A * the client. We want to make sure to remove 4803N/A * the exact file specified by the client, 4803N/A * instead of letting the underlying file system 4803N/A * do a remove on the "first match." 4803N/A * It is assumed that "name" corresponds to the path 4803N/A * passed in by the client, and no need of suppressing 4803N/A * case-insensitive lookups is needed. 4803N/A * Look up the unnamed stream (i.e. fname). 4803N/A * Unmangle processing will be done on fname 4803N/A * as well as any link target. 3853N/A * Need to find out what permission is required by NTFS 3853N/A * We passed "1" as the "od" parameter 3853N/A * to smb_unmangle_name(), such that longname 3853N/A * is the real (case-sensitive) on-disk name. 3853N/A * We make sure we do a remove on this exact 3853N/A * name, as the name was mangled and denotes 3853N/A * This function removes a file's streams without removing the 3853N/A * It is assumed that snode is not a link. 3853N/A * All SMB functions should use this wrapper to ensure that 3853N/A * the the calls are performed with the appropriate credentials. 3853N/A * Please document any direct call to explain the reason 3853N/A * for avoiding this wrapper. 3853N/A * It is assumed that a reference exists on snode coming into this routine. 3853N/A * od: This means that the name passed in is an on-disk name. 3853N/A * The state of the node could be SMB_NODE_STATE_DESTROYING if this 3853N/A * function is called during the deletion of the node (because of 3853N/A * If the passed-in name is an on-disk name, 3853N/A * then we need to do a case-sensitive rmdir. 3853N/A * This is important if the on-disk name 3853N/A * corresponds to a mangled name passed in by 3853N/A * the client. We want to make sure to remove 3853N/A * the exact directory specified by the client, 3853N/A * instead of letting the underlying file system 3853N/A * do a rmdir on the "first match." 3853N/A * We passed "1" as the "od" parameter 3853N/A * to smb_unmangle_name(), such that longname 3853N/A * is the real (case-sensitive) on-disk name. 3853N/A * We make sure we do a rmdir on this exact 3853N/A * name, as the name was mangled and denotes 3853N/A * All SMB functions should use this wrapper to ensure that 3853N/A * the the calls are performed with the appropriate credentials. 3853N/A * Please document any direct call to explain the reason 3853N/A * for avoiding this wrapper. 3853N/A * It is assumed that a reference exists on snode coming into this routine. 3853N/A /* if anything else is also requested */ 3853N/A * All SMB functions should use this smb_fsop_readdir wrapper to ensure that 4500N/A * the smb_vop_readdir is performed with the appropriate credentials. 4500N/A * Please document any direct call to smb_vop_readdir to explain the reason 4500N/A * for avoiding this wrapper. 4141N/A * It is assumed that a reference exists on snode coming into this routine. 4141N/A * Need to find out what permission(s) NTFS requires for getting * All SMB functions should use this smb_vop_getdents wrapper to ensure that * the smb_vop_getdents is performed with the appropriate credentials. * Please document any direct call to smb_vop_getdents to explain the reason * for avoiding this wrapper. * It is assumed that a reference exists on snode coming into this routine. * All SMB functions should use this smb_vop_rename wrapper to ensure that * the smb_vop_rename is performed with the appropriate credentials. * Please document any direct call to smb_vop_rename to explain the reason * for avoiding this wrapper. * It is assumed that references exist on from_dir_snode and to_dir_snode coming * Note: There is no need to check SMB_TREE_CASE_INSENSITIVE(sr) * A case-sensitive rename is always done in this routine * because we are using the on-disk name from an earlier lookup. * If a mangled name was passed in by the caller (denoting a * deterministic lookup), then the exact file must be renamed * (i.e. SMB_IGNORE_CASE must not be passed to VOP_RENAME, or * else the underlying file system might return a "first-match" * on this on-disk name, possibly resulting in the wrong file). * XXX: Lock required through smb_node_release() below? * All SMB functions should use this wrapper to ensure that * the the calls are performed with the appropriate credentials. * Please document any direct call to explain the reason * for avoiding this wrapper. * It is assumed that a reference exists on snode coming into this routine. * A null smb_request might be passed to this function. /* sr could be NULL in some cases */ /* if uid and/or gid is requested */ /* if anything else is also requested */ * Use kcred to update the node attr because this * call is not being made on behalf of the user. * All SMB functions should use this wrapper to ensure that * the the calls are performed with the appropriate credentials. * Please document any direct call to explain the reason * for avoiding this wrapper. * It is assumed that a reference exists on snode coming into this routine. * Streams permission are checked against the unnamed stream, * but in FS level they have their own permissions. To avoid * rejection by FS due to lack of permission on the actual * extended attr kcred is passed for streams. * Use kcred to update the node attr because this * call is not being made on behalf of the user. * This is a wrapper function used for smb_write and smb_write_raw operations. * It is assumed that a reference exists on snode coming into this routine. * Streams permission are checked against the unnamed stream, * but in FS level they have their own permissions. To avoid * rejection by FS due to lack of permission on the actual * extended attr kcred is passed for streams. * Use kcred to update the node attr because this * call is not being made on behalf of the user. * This is a wrapper function used for stat operations. * Streams authorization should be performed against the * it's not part of DACL. It's only granted via proper /* Links don't have ACL */ * FS doesn't understand 32-bit mask, need to map * Sanity checks on dir_snode done in smb_fsop_lookup(). * Note: This function is called only from the open path. * It will check if the file is a stream. * It will also return an error if the looked-up file is in * The following check is required for streams processing, below * Look up the unnamed stream (i.e. fname). * Unmangle processing will be done on fname * as well as any link target. * od_name is the on-disk name of the stream, except * without the prepended stream prefix (SMB_STREAM_PREFIX) * What permissions NTFS requires for stream lookup if any? * All SMB functions should use this smb_vop_lookup wrapper to ensure that * the smb_vop_lookup is performed with the appropriate credentials and using * case insensitive compares. Please document any direct call to smb_vop_lookup * to explain the reason for avoiding this wrapper. * It is assumed that a reference exists on dir_snode coming into this routine * (and that it is safe from deallocation). * Same with the root_node. * *ret_snode is returned with a reference upon success. No reference is * taken if an error is returned. * Note: The returned ret_snode may be in a child mount. This is ok for * Other smb_fsop_* routines will call SMB_TREE_ROOT_FS() to prevent * operations on files not in the parent mount. char *
ret_name83)
/* Must be at least MANGLE_NAMELEN chars */ * We passed "1" as the "od" parameter * to smb_unmangle_name(), such that longname * is the real (case-sensitive) on-disk name. * We make sure we do a lookup on this exact * name, as the name was mangled and denotes * The link is assumed to be for the last component * of a path. Hence any ENOTDIR error will be returned * Release the original VLNK vnode * smb_vop_traverse_check() may have returned a different vnode * smb_fsop_stream_readdir() * ret_snode and ret_attr are optional parameters (i.e. NULL may be passed in) * This routine will return only NTFS streams. If an NTFS stream is not * found at the offset specified, the directory will be read until an NTFS * stream is found or until EOF. * Note: Sanity checks done in caller * (smb_fsop_readdir(), smb_fsop_remove_streams()) * XXX NTFS permission requirements if any? * Retrieve filesystem ACL. Depends on requested ACLs in * fs_sd->sd_secinfo, it'll set DACL and SACL pointers in * fs_sd. Note that requesting a DACL/SACL doesn't mean that * the corresponding field in fs_sd should be non-NULL upon * return, since the target ACL might not contain that type of * Returned ACL is always in ACE_T (aka ZFS) format. * If successful the allocated memory for the ACL should be freed * using smb_fsacl_free() or smb_fssd_term() * Streams don't have ACL, any read ACL attempt on a stream * should be performed on the unnamed stream. * Stores the filesystem ACL provided in fs_sd->sd_acl. * Streams don't have ACL, any write ACL attempt on a stream * should be performed on the unnamed stream. * Read the requested security descriptor items from filesystem. * The items are specified in fs_sd->sd_secinfo. * File's uid/gid is fetched in two cases: * 1. it's explicitly requested * 2. target ACL is ACE_T (ZFS ACL). They're needed for * owner@/group@ entries. In this case kcred should be used * because uid/gid are fetched on behalf of smb server. * Windows require READ_CONTROL to read owner/group SID since * they're part of Security Descriptor. * ZFS only requires read_attribute. Need to have a explicit * From SMB point of view DACL and SACL are two separate list * which can be manipulated independently without one affecting * the other, but entries for both DACL and SACL will end up * in the same ACL if target filesystem supports ACE_T ACLs. * So, if either DACL or SACL is present in the client set request * the entries corresponding to the non-present ACL shouldn't * be touched in the FS ACL. * fs_sd parameter contains DACL and SACL specified by SMB * specify both or one of these ACLs (if none is specified * we don't get this far). When both DACL and SACL are given * by client the existing ACL should be overwritten. If only * one of them is specified the entries corresponding to the other * ACL should not be touched. For example, if only DACL * is specified in input fs_sd, the function reads audit entries * of the existing ACL of the file and point fs_sd->sd_zsdacl * pointer to the fetched SACL, this way when smb_fsop_sdwrite() * function is called the passed fs_sd would point to the specified * DACL by client and fetched SACL from filesystem, so the file * will end up with correct ACL. /* Don't bother if target FS doesn't support ACE_T */ * Don't overwrite existing audit entries * Don't overwrite existing access entries * Stores the given uid, gid and acl in filesystem. * Provided items in fs_sd are specified by fs_sd->sd_secinfo. * A SMB security descriptor could contain owner, primary group, * DACL and SACL. Setting an SD should be atomic but here it has to * be done via two separate FS operations: VOP_SETATTR and * VOP_SETSECATTR. Therefore, this function has to simulate the * atomicity as well as it can. * Get the current uid, gid so if smb_fsop_aclwrite fails * we can revert uid, gid changes. * We use root cred here so the operation doesn't fail * due to lack of permission for the user to read the attrs * Revert uid/gid changes if required. * Inherit the security descriptor from the parent container. * This function is called after FS has created the file/folder * so if this doesn't do anything it means FS inheritance is * Do inheritance for ZFS internally. * If we want to let ZFS does the inheritance the * following setting should be true: * - aclinherit = passthrough * - aclmode = passthrough * This will result in right effective permissions but * ZFS will always add 6 ACEs for owner, owning group * and others to be POSIX compliant. This is not what * implements Windows rules and overwrite whatever ZFS * comes up with. This way we also don't have to care * about ZFS aclinherit and aclmode settings. * No forced inheritance for non-ZFS filesystems. /* Fetch parent directory's ACL */ * Returns the effective permission of the given credential for the * This is just a workaround. We need VFS/FS support for this. * Streams authorization should be performed against the * FS doesn't understand 32-bit mask * For the current open request, check file sharing rules * against existing opens. * Returns NT_STATUS_SHARING_VIOLATION if there is any * sharing conflict. Returns NT_STATUS_SUCCESS otherwise. * Full system-wide share reservation synchronization is available * when the nbmand (non-blocking mandatory) mount option is set * (i.e. nbl_need_crit() is true) and nbmand critical regions are used. * This provides synchronization with NFS and local processes. The * critical regions are entered in VOP_SHRLOCK()/fs_shrlock() (called * from smb_open_subr()/smb_fsop_shrlock()/smb_vop_shrlock()) as well * as the CIFS rename and delete paths. * The CIFS server will also enter the nbl critical region in the open, * rename, and delete paths when nbmand is not set. There is limited * coordination with local and VFS share reservations in this case. * Note that when the nbmand mount option is not set, the VFS layer * only processes advisory reservations and the delete mode is not checked. * Whether or not the nbmand mount option is set, intra-CIFS share * checking is done in the open, delete, and rename paths using a CIFS * critical region (node->n_share_lock). /* Allow access if the request is just for meta data */ * smb_fsop_frlock_callback * smb wrapper function for fs_frlock * this should never happen, as we are not attempting * to set Mandatory Locks, cmd = F_SETLK_NBMAND * smb wrapper function for fs_frlock