diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-12-22 16:49:42 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-22 16:49:42 +0000 |
commit | 8cff207a136258977b1d944955181fd477b11ccc (patch) | |
tree | 527ff9f58cb9fc2a12dd45b709fb7da5aad10ad0 | |
parent | d07b7f81a046ded5bd25cde744bbf47a884e3e93 (diff) | |
parent | 7c3a3535fc1502fb22867683a2ece20ff29bf314 (diff) | |
download | nix-8cff207a136258977b1d944955181fd477b11ccc.zip |
Merge #1342
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>
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/unistd.rs | 20 | ||||
-rw-r--r-- | test/test_unistd.rs | 39 |
3 files changed, 60 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index cdd06714..64e33f33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate ### Added - Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306)) - - Added `personality` (#[1331](https://github.com/nix-rust/nix/pull/1331)) - - Added limited Fuchsia support (#[1285](https://github.com/nix-rust/nix/pull/1285)) - +- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342)) ### Fixed ### Changed diff --git a/src/unistd.rs b/src/unistd.rs index 20d7c79a..dd335596 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2804,3 +2804,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))) +} diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 0f6cf7d3..16a8a05d 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -1069,3 +1069,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()); +} |