Linux 如何确定Rust中流程的有效用户id?

Linux 如何确定Rust中流程的有效用户id?,linux,permissions,rust,Linux,Permissions,Rust,在Linux和其他POSIX系统上,程序可以以另一个用户的身份执行(即euid)。通常,您会调用geteuid和朋友来可靠地确定进程的当前身份。然而,我无法找到一种可靠的方法,仅使用rust的标准库来确定这些身份 我发现唯一接近的是std::os::unix::MetadataExt 目前是否可以使用rust的标准库确定过程的euid(和其他ID)?是否有我缺少的功能或特性?这将取决于操作系统特定的依赖关系,因为对于大多数可以为其生成代码的目标,该概念并不存在(或者按照您认为的方式执行!)。特别

在Linux和其他POSIX系统上,程序可以以另一个用户的身份执行(即
euid
)。通常,您会调用
geteuid
和朋友来可靠地确定进程的当前身份。然而,我无法找到一种可靠的方法,仅使用rust的标准库来确定这些身份

我发现唯一接近的是
std::os::unix::MetadataExt


目前是否可以使用rust的标准库确定过程的
euid
(和其他ID)?是否有我缺少的功能或特性?

这将取决于操作系统特定的依赖关系,因为对于大多数可以为其生成代码的目标,该概念并不存在(或者按照您认为的方式执行!)。特别是,您可以在
libc
板条箱中找到它,顾名思义,它是
libc
上的一个非常小的包装

std::os
命名空间通常被限制为使
std::process
std::thread
std::FS
模块的进程和FS功能运行的最低限度。因此,它不会在那里<出于类似的原因,code>MetadataExt以文件系统使用为目标

正如您所预料的,调用本身是难以想象的


它是一个不安全的
extern
导入,因此您必须将其包装在
unsafe
块中。

Rust 1.46.0似乎没有在标准库中公开此功能。如果您使用的是POSIX系统,并且不想依赖额外的依赖项,则有四个选项:

  • 您可以直接使用libc:

    #[link(name = "c")]
    extern "C" {
        fn geteuid() -> u32;
        fn getegid() -> u32;
    }
    
    如果您特别使用GNU/Linux,则根本不需要链接到libc,因为系统调用符号会通过VDSO自动提供给您的程序。换句话说,您可以使用不带
    链接
    属性的普通
    外部

  • 阅读
    /proc/self/status
    (可能仅限Linux?)。此文件包含以
    Uid:
    开头的行。这一行列出了真实的用户id、有效的用户id以及其他您可能发现的相关信息。有关更多信息,请参阅
    man proc

  • 如果您使用的是普通的GNU/Linux系统,则可以访问
    /proc/self
    目录本身的元数据。如所示,此目录的所有者应与进程的有效用户id匹配。您可以按如下方式获取euid:

    use std::os::unix::fs::MetadataExt;
    println!("metadata for {:?}", std::fs::metadata("/proc/self").map(|m| m.uid()));
    
    这种方法提供的一个好处是,与选项2相比,它相对便宜,因为它只是一个
    stat
    syscall(而不是打开文件并读取/解析其内容)

  • 如果您没有使用普通的GNU/Linux系统,您可能会发现创建一个新的虚拟文件并通过
    元数据
    正常获取所有者id是成功的


  • 也许吧?是的,看起来锈还没有暴露出这些信息。我会接受你的答案,并添加一个不依赖于板条箱的答案。