From ae258047b3e491eb62e6803f2c1401f4caafe7be Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Thu, 26 Nov 2020 13:09:21 -0500 Subject: [PATCH] unistd: Add getpeereid(3) Closes #1339. --- CHANGELOG.md | 3 ++- src/unistd.rs | 20 ++++++++++++++++++++ test/test_unistd.rs | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 719d84dc5a..05a0f3a955 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306)) +- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342)) ### Fixed ### Changed @@ -70,7 +71,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Derived `Ord`, `PartialOrd` for `unistd::Pid` (#[1189](https://github.com/nix-rust/nix/pull/1189)) - Added `select::FdSet::fds` method to iterate over file descriptors in a set. ([#1207](https://github.com/nix-rust/nix/pull/1207)) -- Added support for UDP generic segmentation offload (GSO) and generic +- Added support for UDP generic segmentation offload (GSO) and generic receive offload (GRO) ([#1209](https://github.com/nix-rust/nix/pull/1209)) - Added support for `sendmmsg` and `recvmmsg` calls (#[1208](https://github.com/nix-rust/nix/pull/1208)) diff --git a/src/unistd.rs b/src/unistd.rs index 0352f9727d..799fdf623f 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2795,3 +2795,23 @@ pub fn ttyname(fd: RawFd) -> Result { buf.truncate(nul); Ok(OsString::from_vec(buf).into()) } + +/// Get the effective user ID and group ID associated with a Unix domain socket. +/// +/// See also [getpeereid(3)](https://www.freebsd.org/cgi/man.cgi?query=getpeereid) +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly", +))] +pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> { + let mut uid = 1; + let mut gid = 1; + + let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) }; + + Errno::result(ret).map(|_| (Uid(uid), Gid(gid))) +} diff --git a/test/test_unistd.rs b/test/test_unistd.rs index d169d6e099..fd10c00881 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -1068,3 +1068,42 @@ fn test_ttyname_not_pty() { fn test_ttyname_invalid_fd() { assert_eq!(ttyname(-1), Err(Error::Sys(Errno::EBADF))); } + +#[test] +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly", +))] +fn test_getpeereid() { + use std::os::unix::net::UnixStream; + let (sock_a, sock_b) = UnixStream::pair().unwrap(); + + let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap(); + let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap(); + + let uid = geteuid(); + let gid = getegid(); + + assert_eq!(uid, uid_a); + assert_eq!(gid, gid_a); + assert_eq!(uid_a, uid_b); + assert_eq!(gid_a, gid_b); +} + +#[test] +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly", +))] +fn test_getpeereid_invalid_fd() { + // getpeereid is not POSIX, so error codes are inconsistent between different Unices. + assert!(getpeereid(-1).is_err()); +}