You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 _);
    }
}

关键说明

  1. Unix平台:保留原有mode(0o600)设置,确保文件权限为所有者读写,其他用户无任何访问权限。
  2. Windows平台:
    • 引入std::os::windows::fs::OpenOptionsExt trait,通过其security_attr方法传入自定义安全属性。
    • 构造安全描述符和访问控制列表,仅允许当前文件创建者拥有读写权限,拒绝其他所有用户访问。
    • 使用Windows API获取当前用户的SID,确保权限精准授予文件所有者。

依赖说明

代码使用了winapi crate,需在Cargo.toml中添加依赖:

[dependencies]
winapi = { version = "0.3", features = ["winnt", "securitybaseapi", "aclapi", "memoryapi"] }

内容的提问来源于stack exchange,提问作者Omer Shtivi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:22:28