/* * smb_vop_shrlock() * * See comments for smb_fsop_shrlock() */ int smb_vop_shrlock(vnode_t *vp, uint32_t uniq_fid, uint32_t desired_access, uint32_t share_access, cred_t *cr) { struct shrlock shr; struct shr_locowner shr_own; short new_access = 0; short deny = 0; int flag = 0; int cmd; cmd = (nbl_need_check(vp)) ? F_SHARE_NBMAND : F_SHARE; /* * Check if this is a metadata access */ if ((desired_access & FILE_DATA_ALL) == 0) { new_access |= F_MDACC; } else { if (desired_access & (ACE_READ_DATA | ACE_EXECUTE)) { new_access |= F_RDACC; flag |= FREAD; } if (desired_access & (ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_ADD_FILE)) { new_access |= F_WRACC; flag |= FWRITE; } if (SMB_DENY_READ(share_access)) { deny |= F_RDDNY; } if (SMB_DENY_WRITE(share_access)) { deny |= F_WRDNY; } if (cmd == F_SHARE_NBMAND) { if (desired_access & ACE_DELETE) new_access |= F_RMACC; if (SMB_DENY_DELETE(share_access)) { deny |= F_RMDNY; } } } shr.s_access = new_access; shr.s_deny = deny; shr.s_sysid = smb_ct.cc_sysid; shr.s_pid = uniq_fid; shr.s_own_len = sizeof (shr_own); shr.s_owner = (caddr_t)&shr_own; shr_own.sl_id = shr.s_sysid; shr_own.sl_pid = shr.s_pid; return (VOP_SHRLOCK(vp, cmd, &shr, flag, cr, NULL)); }
/* * check file sharing rules for current open request * against existing open instances of the same file * * Returns NT_STATUS_SHARING_VIOLATION if there is any * sharing conflict, otherwise returns NT_STATUS_SUCCESS. */ uint32_t smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access, uint32_t share_access) { ASSERT(of->f_magic == SMB_OFILE_MAGIC); mutex_enter(&of->f_mutex); if (of->f_state != SMB_OFILE_STATE_OPEN) { mutex_exit(&of->f_mutex); return (NT_STATUS_INVALID_HANDLE); } /* if it's just meta data */ if ((of->f_granted_access & FILE_DATA_ALL) == 0) { mutex_exit(&of->f_mutex); 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)) { mutex_exit(&of->f_mutex); return (NT_STATUS_SHARING_VIOLATION); } if (SMB_DENY_READ(share_access) && (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) { mutex_exit(&of->f_mutex); return (NT_STATUS_SHARING_VIOLATION); } if (SMB_DENY_WRITE(share_access) && (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { mutex_exit(&of->f_mutex); 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)) { mutex_exit(&of->f_mutex); return (NT_STATUS_SHARING_VIOLATION); } if (SMB_DENY_READ(of->f_share_access) && (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) { mutex_exit(&of->f_mutex); return (NT_STATUS_SHARING_VIOLATION); } if (SMB_DENY_WRITE(of->f_share_access) && (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { mutex_exit(&of->f_mutex); return (NT_STATUS_SHARING_VIOLATION); } mutex_exit(&of->f_mutex); return (NT_STATUS_SUCCESS); }