summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/smbsrv/smb_node.c
diff options
context:
space:
mode:
authoras200622 <none@none>2008-01-05 20:52:22 -0800
committeras200622 <none@none>2008-01-05 20:52:22 -0800
commitdc20a3024900c47dd2ee44b9707e6df38f7d62a5 (patch)
treee0957e6b6d6b5c0117800046c765b78d69f80ce1 /usr/src/uts/common/fs/smbsrv/smb_node.c
parentbda89588bd7667394a834e8a9a34612cce2ae9c3 (diff)
downloadillumos-gate-dc20a3024900c47dd2ee44b9707e6df38f7d62a5.tar.gz
6560095 SNAS shows SIDs for Built-in Groups members instead of name
6582153 SMB signing and sealing (redirector) 6582192 Remove SMB config cache 6582210 Consistent Logging Strategy 6582214 Unified error reporting strategy 6593360 Confusing log message: [ID 334764 user.error] Ads is not enable 6597854 The shares are not accessible if doing Run \\ip-addr 6610587 RPC-WINREG test has failed on smbtorture. 6610650 Workgroup: authentication problem when client's LM level > 2 6611277 Should not be able to join domain when Snas ipc-mode=anon and W2K DC IPC=No access without anonymous 6613675 Creating a file with DOS readonly bit set requires special handling 6626113 libshare_smb leaks file descriptor on unload 6626119 libshare_smb leaks file descriptor on door call failure 6626126 libsmb configuration leaks memory 6629314 smbd logging forgets newlines, creating a mess 6629954 smb local group support should be re-enabled 6630424 libshare having trouble starting smb/server 6631739 rdr_ipcmode does change to "Fallback,anon". 6631985 SMB daemon doesn't locate a new ADS server if ads_site property has been modified. 6631987 SMB daemon reads /etc/resolv.conf once when it starts up. 6633202 smbfs client caused CIFS server panic 6635175 lint error reported when building smbsrv module when either mars or ceres lint was used 6636763 Get core if using sharemgr set-share -r with nonexistent share 6640934 libshare tries to enable smb service if any filesystem is shared over smb 6641051 The CIFS server needs to use the VFS nbmand mechanism for system-wide share reservations 6642047 Changes to SMF properties of the CIFS service - PSARC/2007/686 6642302 Do not add null when marshalling non-null-terminated NDR strings 6642368 Cross protocol byte range locking is needed --HG-- rename : usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c => deleted_files/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c rename : usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c => deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c rename : usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c => deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_client.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_heap.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_encdec.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlndo.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlndr.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_server.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_svc.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c
Diffstat (limited to 'usr/src/uts/common/fs/smbsrv/smb_node.c')
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_node.c257
1 files changed, 253 insertions, 4 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb_node.c b/usr/src/uts/common/fs/smbsrv/smb_node.c
index 5ea8c5f1c3..13be0f3cf3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_node.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_node.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -84,6 +84,7 @@
#include <smbsrv/smb_fsops.h>
#include <sys/pathname.h>
#include <sys/sdt.h>
+#include <sys/nbmlock.h>
uint32_t smb_is_executable(char *path);
static void smb_node_delete_on_close(smb_node_t *node);
@@ -138,7 +139,6 @@ smb_node_lookup(
fs_desc_t fsd;
int error;
krw_t lock_mode;
- caller_context_t ct;
vnode_t *unnamed_vp = NULL;
/*
@@ -154,9 +154,8 @@ smb_node_lookup(
* This getattr is performed on behalf of the server
* that's why kcred is used not the user's cred
*/
- smb_get_caller_context(sr, &ct);
attr->sa_mask = SMB_AT_ALL;
- error = smb_vop_getattr(vp, unnamed_vp, attr, 0, kcred, &ct);
+ error = smb_vop_getattr(vp, unnamed_vp, attr, 0, kcred);
if (error)
return (NULL);
@@ -208,6 +207,7 @@ smb_node_lookup(
smb_node_ref(dir_snode);
}
node->attr = *attr;
+ node->n_size = attr->sa_vattr.va_size;
smb_audit_node(node);
smb_rwx_xexit(&node->n_lock);
@@ -768,3 +768,252 @@ smb_node_reset_delete_on_close(smb_node_t *node)
}
smb_rwx_xexit(&node->n_lock);
}
+
+/*
+ * smb_node_share_check
+ *
+ * check file sharing rules for current open request
+ * against all existing opens for a file.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
+ */
+uint32_t
+smb_node_open_check(struct smb_node *node, cred_t *cr,
+ uint32_t desired_access, uint32_t share_access)
+{
+ smb_ofile_t *of;
+ uint32_t status;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ of = smb_llist_head(&node->n_ofile_list);
+ while (of) {
+ status = smb_node_share_check(node, cr, desired_access,
+ share_access, of);
+ if (status == NT_STATUS_SHARING_VIOLATION) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (status);
+ }
+ of = smb_llist_next(&node->n_ofile_list, of);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_open_share_check
+ *
+ * check file sharing rules for current open request
+ * against the given existing open.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
+ */
+uint32_t
+smb_node_share_check(
+ struct smb_node *node,
+ cred_t *cr,
+ uint32_t desired_access,
+ uint32_t share_access,
+ smb_ofile_t *of)
+{
+ /*
+ * It appears that share modes are not relevant to
+ * directories, but this check will remain as it is not
+ * clear whether it was originally put here for a reason.
+ */
+ if (node->attr.sa_vattr.va_type == VDIR) {
+ if (SMB_DENY_RW(of->f_share_access) &&
+ (node->n_orig_uid != crgetuid(cr))) {
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+
+ return (NT_STATUS_SUCCESS);
+ }
+
+ /* if it's just meta data */
+ if ((of->f_granted_access & FILE_DATA_ALL) == 0)
+ return (NT_STATUS_SUCCESS);
+
+ /*
+ * Check requested share access against the
+ * open granted (desired) access
+ */
+ if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_READ(share_access) &&
+ (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_WRITE(share_access) &&
+ (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ /* check requested desired access against the open share access */
+ if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_READ(of->f_share_access) &&
+ (desired_access & (FILE_READ_DATA | FILE_EXECUTE)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_WRITE(of->f_share_access) &&
+ (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_rename_share_check
+ *
+ * An open file can be renamed if
+ *
+ * 1. isn't opened for data writing or deleting
+ *
+ * 2. Opened with "Deny Delete" share mode
+ * But not opened for data reading or executing
+ * (opened for accessing meta data)
+ */
+
+DWORD
+smb_node_rename_check(struct smb_node *node)
+{
+ struct smb_ofile *open;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ /*
+ * Intra-CIFS check
+ */
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ open = smb_llist_head(&node->n_ofile_list);
+ while (open) {
+ if (open->f_granted_access &
+ (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+
+ if ((open->f_share_access & FILE_SHARE_DELETE) == 0) {
+ if (open->f_granted_access &
+ (FILE_READ_DATA | FILE_EXECUTE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+ }
+ open = smb_llist_next(&node->n_ofile_list, open);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ /*
+ * system-wide share check
+ */
+
+ if (nbl_share_conflict(node->vp, NBL_RENAME, NULL))
+ return (NT_STATUS_SHARING_VIOLATION);
+ else
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_node_delete_check
+ *
+ * An open file can be deleted only if opened for
+ * accessing meta data. Share modes aren't important
+ * in this case.
+ *
+ * NOTE: there is another mechanism for deleting an
+ * open file that NT clients usually use.
+ * That's setting "Delete on close" flag for an open
+ * file. In this way the file will be deleted after
+ * last close. This flag can be set by SmbTrans2SetFileInfo
+ * with FILE_DISPOSITION_INFO information level.
+ * For setting this flag, the file should be opened by
+ * DELETE access in the FID that is passed in the Trans2
+ * request.
+ */
+DWORD
+smb_node_delete_check(smb_node_t *node)
+{
+ smb_ofile_t *file;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return (NT_STATUS_SUCCESS);
+
+ /*
+ * intra-CIFS check
+ */
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ file = smb_llist_head(&node->n_ofile_list);
+ while (file) {
+ ASSERT(file->f_magic == SMB_OFILE_MAGIC);
+ if (file->f_granted_access &
+ (FILE_READ_DATA |
+ FILE_WRITE_DATA |
+ FILE_APPEND_DATA |
+ FILE_EXECUTE |
+ DELETE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+ file = smb_llist_next(&node->n_ofile_list, file);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ /*
+ * system-wide share check
+ */
+
+ if (nbl_share_conflict(node->vp, NBL_REMOVE, NULL))
+ return (NT_STATUS_SHARING_VIOLATION);
+ else
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_node_start_crit()
+ *
+ * Enter critical region for share reservations.
+ * See comments above smb_fsop_shrlock().
+ */
+
+void
+smb_node_start_crit(smb_node_t *node, krw_t mode)
+{
+ rw_enter(&node->n_share_lock, mode);
+ nbl_start_crit(node->vp, mode);
+}
+
+/*
+ * smb_node_end_crit()
+ *
+ * Exit critical region for share reservations.
+ */
+
+void
+smb_node_end_crit(smb_node_t *node)
+{
+ nbl_end_crit(node->vp);
+ rw_exit(&node->n_share_lock);
+}
+
+int
+smb_node_in_crit(smb_node_t *node)
+{
+ return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_share_lock));
+}