From 3971a9b79d3d8bfde8e0100caa20266f64a4f4f3 Mon Sep 17 00:00:00 2001 From: Jeryl Vaz Date: Fri, 23 Apr 2021 16:48:41 +0200 Subject: [PATCH] Add getresuid() and getresgid() to unistd --- CHANGELOG.md | 4 ++++ src/unistd.rs | 53 ++++++++++++++++++++++++++++++++++++++++++--- test/test_unistd.rs | 19 ++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ead550eb1..2be0160442 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate +### Added +- Added `getresuid` and `getresgid` + (#[1430](https://github.com/nix-rust/nix/pull/1430)) + ### Added - Added TIMESTAMPNS support for linux (#[1402](https://github.com/nix-rust/nix/pull/1402)) diff --git a/src/unistd.rs b/src/unistd.rs index d3afeac633..5a7c772084 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -25,10 +25,12 @@ use crate::sys::stat::Mode; #[cfg(any(target_os = "android", target_os = "linux"))] pub use self::pivot_root::*; -#[cfg(any(target_os = "android", target_os = "freebsd", - target_os = "linux", target_os = "openbsd"))] +#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))] pub use self::setres::*; +#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))] +pub use self::getres::*; + /// User identifier /// /// Newtype pattern around `uid_t` (which is just alias). It prevents bugs caused by accidentally @@ -1078,7 +1080,7 @@ pub fn pipe() -> Result<(RawFd, RawFd)> { /// The following flags are supported, and will be set atomically as the pipe is /// created: /// -/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors. +/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors. #[cfg_attr(target_os = "linux", doc = "`O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode. ")] #[cfg_attr(target_os = "netbsd", doc = "`O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`. ")] /// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe. @@ -2524,6 +2526,51 @@ mod setres { } } +#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))] +mod getres { + use crate::Result; + use crate::errno::Errno; + use super::{Uid, Gid}; + + /// Gets the real, effective, and saved uid. + /// + /// ([see getresuid(2)](http://man7.org/linux/man-pages/man2/getresuid.2.html)) + /// + /// #Returns + /// + /// - `Ok((Uid, Uid, Uid))`: tuple of real, effective and saved uids on success. + /// - `Err(x)`: libc error code on failure. + /// + #[inline] + pub fn getresuid() -> Result<(Uid, Uid, Uid)> { + let mut ruid = libc::uid_t::max_value(); + let mut euid = libc::uid_t::max_value(); + let mut suid = libc::uid_t::max_value(); + let res = unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) }; + + Errno::result(res).map(|_| (Uid(ruid), Uid(euid), Uid(suid))) + } + + /// Gets the real, effective, and saved gid. + /// + /// ([see getresgid(2)](http://man7.org/linux/man-pages/man2/getresgid.2.html)) + /// + /// #Returns + /// + /// - `Ok((Gid, Gid, Gid))`: tuple of real, effective and saved gids on success. + /// - `Err(x)`: libc error code on failure. + /// + #[inline] + pub fn getresgid() -> Result<(Gid, Gid, Gid)> { + let mut rgid = libc::gid_t::max_value(); + let mut egid = libc::gid_t::max_value(); + let mut sgid = libc::gid_t::max_value(); + let res = unsafe { libc::getresgid(&mut rgid, &mut egid, &mut sgid) }; + + Errno::result(res).map(|_| (Gid(rgid), Gid(egid), Gid(sgid))) + } +} + libc_bitflags!{ /// Options for access() pub struct AccessFlags : c_int { diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 4acfff3792..c572fb7bfe 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -624,6 +624,25 @@ fn test_sysconf_unsupported() { assert!(open_max.expect("sysconf failed").is_none()) } + +#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))] +#[test] +fn test_getresuid() { + let resuid = getresuid().unwrap(); + assert!(resuid.0.as_raw() != libc::uid_t::max_value()); + assert!(resuid.1.as_raw() != libc::uid_t::max_value()); + assert!(resuid.2.as_raw() != libc::uid_t::max_value()); +} + +#[cfg(any(target_os = "android", target_os = "linux", target_os = "openbsd"))] +#[test] +fn test_getresgid() { + let resgid = getresgid().unwrap(); + assert!(resgid.0.as_raw() != libc::gid_t::max_value()); + assert!(resgid.1.as_raw() != libc::gid_t::max_value()); + assert!(resgid.2.as_raw() != libc::gid_t::max_value()); +} + // Test that we can create a pair of pipes. No need to verify that they pass // data; that's the domain of the OS, not nix. #[test]