【问题标题】:How to determine the effective user id of a process in Rust?如何确定 Rust 中进程的有效用户 ID?
【发布时间】:2020-01-16 23:57:42
【问题描述】:

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

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

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

【问题讨论】:

标签: linux permissions rust


【解决方案1】:

这将依赖于特定于操作系统的依赖项,因为对于您可以为其构建 rust 代码的大多数目标,该概念不存在(或做您认为会做的事!)。特别是,您会在libc crate 中找到它,顾名思义,它是libc 的一个非常小的包装器。

std::os 命名空间通常被限制在最低限度,以使 std::processstd::threadstd::fs 模块的进程和 FS 功能可用。因此,它不会在那里。出于类似的原因,MetadataExt 的目标是文件系统的使用。

正如您所料,调用本身就是geteuid

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

【讨论】:

  • 是的,Rust 似乎还没有公开这些信息。我会接受你的回答,并在下面添加一个不依赖于 crates.io 的答案。
【解决方案2】:

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

  1. 你可以直接使用libc:

    #[link(name = "c")]
    extern "C" {
        fn geteuid() -> u32;
        fn getegid() -> u32;
    }
    

    如果您特别使用 GNU/Linux,则根本不需要链接到 libc,因为系统调用符号会通过 VDSO 自动提供给您的程序。换句话说,您可以使用没有link 属性的普通extern 块。

  2. 阅读/proc/self/status(可能仅限Linux?)。此文件包含以Uid: 开头的行。此行列出了真实用户 ID、有效用户 ID 以及您可能还认为相关的其他信息。更多信息请参考man proc

  3. 如果您使用的是普通的 GNU/Linux 系统,则可以访问 /proc/self 目录本身的元数据。作为pointed out in this question,此目录的所有者应与进程的有效用户标识匹配。您可以通过以下方式获取euid:

    use std::os::unix::fs::MetadataExt;
    println!("metadata for {:?}", std::fs::metadata("/proc/self").map(|m| m.uid()));
    

    这种方法提供的一个好处是,与选项 #2 相比,它相对便宜,因为它只是一个 stat 系统调用(而不是打开文件并读取/解析其内容)。

  4. 如果您使用的不是普通的 GNU/Linux 系统,您可能会成功创建一个新的虚拟文件并正常通过 Metadata 获取所有者 ID。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多