Skip to content

Commit

Permalink
Merge #1342
Browse files Browse the repository at this point in the history
1342: feat(unistd): Add getpeereid(3) r=asomers a=woodruffw

`getpeereid(3)` is not POSIX, but it's present on many BSD-derived Unices. It's also the standard mechanism on those OSes for retrieving socket peer credentials (compare `getsockopt` + `SO_PEERCRED` on Linux, which `nix` already supports).

Closes #1339.

Co-authored-by: William Woodruff <william@yossarian.net>
  • Loading branch information
bors[bot] and woodruffw committed Nov 29, 2020
2 parents af66aa2 + 1299538 commit 8e00776
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306))

- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342))
### Changed
### Fixed

Expand Down Expand Up @@ -59,7 +60,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))
Expand Down
22 changes: 21 additions & 1 deletion src/unistd.rs
Expand Up @@ -1065,7 +1065,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.
Expand Down Expand Up @@ -2785,3 +2785,23 @@ pub fn ttyname(fd: RawFd) -> Result<PathBuf> {
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)))
}
39 changes: 39 additions & 0 deletions test/test_unistd.rs
Expand Up @@ -1044,3 +1044,42 @@ fn test_ttyname_invalid_fd() {
fn test_ttyname_invalid_fd() {
assert_eq!(ttyname(-1), Err(Error::Sys(Errno::ENOTTY)));
}

#[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());
}

0 comments on commit 8e00776

Please sign in to comment.