如何确定 Rust 中进程的有效用户 ID?
Posted
技术标签:
【中文标题】如何确定 Rust 中进程的有效用户 ID?【英文标题】:How to determine the effective user id of a process in Rust? 【发布时间】:2020-01-16 23:57:42 【问题描述】:在 Linux 和其他 POSIX 系统上,程序可以在另一个用户的身份下执行(即euid
)。通常,您会调用geteuid
和朋友来可靠地确定进程的当前身份。但是,我无法找到一种可靠的方法来仅使用 rust 的标准库来确定这些身份。
我发现唯一接近的是std::os::unix::MetadataExt
。
目前是否可以使用 rust 的标准库来确定进程的euid
(和其他 ID)?是否有我缺少的功能或特征?
【问题讨论】:
也许doc.rust-lang.org/1.9.0/libc/fn.geteuid.html ? 【参考方案1】:这将依赖于特定于操作系统的依赖项,因为对于您可以为其构建 rust 代码的大多数目标,该概念不存在(或做您认为会做的事!)。特别是,您会在libc
crate 中找到它,顾名思义,它是libc
的一个非常小的包装器。
std::os
命名空间通常被限制在最低限度,以使 std::process
、std::thread
和 std::fs
模块的进程和 FS 功能可用。因此,它不会在那里。出于类似的原因,MetadataExt
的目标是文件系统的使用。
正如您所料,调用本身就是geteuid
。
这是一个不安全的 extern
导入,因此您必须将其包装在 unsafe
块中。
【讨论】:
是的,Rust 似乎还没有公开这些信息。我会接受你的回答,并在下面添加一个不依赖于 crates.io 的答案。【参考方案2】:Rust 1.46.0 似乎没有在标准库中公开此功能。如果您使用的是 POSIX 系统并且不想依赖额外的依赖项,您有四个选择:
你可以直接使用libc:
#[link(name = "c")]
extern "C"
fn geteuid() -> u32;
fn getegid() -> u32;
如果您特别使用 GNU/Linux,则根本不需要链接到 libc,因为系统调用符号会通过 VDSO 自动提供给您的程序。换句话说,您可以使用没有link
属性的普通extern
块。
阅读/proc/self/status
(可能仅限Linux?)。此文件包含以Uid:
开头的行。此行列出了真实用户 ID、有效用户 ID 以及您可能还认为相关的其他信息。更多信息请参考man proc
。
如果您使用的是普通的 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
系统调用(而不是打开文件并读取/解析其内容)。
如果您使用的不是普通的 GNU/Linux 系统,您可能会成功创建一个新的虚拟文件并正常通过 Metadata
获取所有者 ID。
【讨论】:
以上是关于如何确定 Rust 中进程的有效用户 ID?的主要内容,如果未能解决你的问题,请参考以下文章