Rust Windows平台实现文件仅所有者读写权限的方法
支持Windows平台的pgpass文件权限控制修改方案
要让代码在Windows平台实现和Unix一致的「仅所有者读写」权限,需要针对Windows平台单独实现权限设置逻辑,利用Windows安全属性API配置文件访问控制。以下是修改后的完整代码:
use std::fs::{self, OpenOptions}; use std::path::PathBuf; use std::os::windows::fs::OpenOptionsExt; use winapi::um::winnt::{ FILE_GENERIC_READ, FILE_GENERIC_WRITE, SECURITY_DESCRIPTOR, ACL, ACCESS_ALLOWED_ACE, SECURITY_ATTRIBUTES, WELL_KNOWN_SID_TYPE, WinCurrentUserSid }; use winapi::um::securitybaseapi::{InitializeSecurityDescriptor, SetSecurityDescriptorDacl}; use winapi::um::aclapi::{CreateWellKnownSid, AddAccessAllowedAce, InitializeAcl}; use winapi::shared::minwindef::{DWORD, BOOL, TRUE, FALSE}; fn create_pgpass_file(pgpass_file: PathBuf) -> Result<fs::File, errors::ToolsError> { let mut open_options = OpenOptions::new(); open_options.write(true).create(true); set_permissions(&mut open_options); open_options .open(pgpass_file) .map_err(errors::ToolsError::FailedToCreatePgpassFile) } #[cfg(target_family = "unix")] fn set_permissions(open_options: &mut OpenOptions) { // Unix平台保持原逻辑:仅所有者拥有读写权限 open_options.mode(0o600); } #[cfg(target_family = "windows")] fn set_permissions(open_options: &mut OpenOptions) { // Windows平台构造安全属性,限制仅当前用户(文件所有者)读写 unsafe { let mut sd = std::mem::zeroed::<SECURITY_DESCRIPTOR>(); InitializeSecurityDescriptor(&mut sd, winapi::um::winnt::SECURITY_DESCRIPTOR_REVISION); // 初始化ACL(访问控制列表),预留足够内存存储ACE规则 let acl_size = std::mem::size_of::<ACL>() + std::mem::size_of::<ACCESS_ALLOWED_ACE>(); let mut acl = vec![0u8; acl_size]; let acl_ptr = acl.as_mut_ptr() as *mut ACL; InitializeAcl(acl_ptr, acl_size as DWORD, winapi::um::winnt::ACL_REVISION); // 获取当前用户的SID(安全标识符) let mut owner_sid: *mut winapi::um::winnt::SID = std::ptr::null_mut(); let mut sid_size = 0; // 先查询所需内存大小 CreateWellKnownSid(WinCurrentUserSid, std::ptr::null_mut(), std::ptr::null_mut(), &mut sid_size); // 分配内存存储SID owner_sid = winapi::um::memoryapi::LocalAlloc(0, sid_size) as *mut winapi::um::winnt::SID; CreateWellKnownSid(WinCurrentUserSid, std::ptr::null_mut(), owner_sid, &mut sid_size); // 添加允许当前用户读写文件的ACE规则 AddAccessAllowedAce( acl_ptr, winapi::um::winnt::ACL_REVISION, FILE_GENERIC_READ | FILE_GENERIC_WRITE, owner_sid ); // 将ACL绑定到安全描述符,拒绝权限继承,仅应用于当前文件 SetSecurityDescriptorDacl(&mut sd, TRUE, acl_ptr, FALSE); // 构造安全属性结构体 let mut sa = std::mem::zeroed::<SECURITY_ATTRIBUTES>(); sa.nLength = std::mem::size_of::<SECURITY_ATTRIBUTES>() as DWORD; sa.lpSecurityDescriptor = &mut sd as *mut _; sa.bInheritHandle = FALSE; // 将安全属性应用到文件创建选项 open_options.security_attr(&sa); // 释放分配的SID内存 winapi::um::memoryapi::LocalFree(owner_sid as *mut _); } }
关键说明
- Unix平台:保留原有
mode(0o600)设置,确保文件权限为所有者读写,其他用户无任何访问权限。 - Windows平台:
- 引入
std::os::windows::fs::OpenOptionsExttrait,通过其security_attr方法传入自定义安全属性。 - 构造安全描述符和访问控制列表,仅允许当前文件创建者拥有读写权限,拒绝其他所有用户访问。
- 使用Windows API获取当前用户的SID,确保权限精准授予文件所有者。
- 引入
依赖说明
代码使用了winapi crate,需在Cargo.toml中添加依赖:
[dependencies] winapi = { version = "0.3", features = ["winnt", "securitybaseapi", "aclapi", "memoryapi"] }
内容的提问来源于stack exchange,提问作者Omer Shtivi
相关产品推荐
相关产品推荐

