Skip to content

Commit eb4e312

Browse files
bors[bot]woodruffw
andauthored
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 <[email protected]>
2 parents 0fd17fc + ae25804 commit eb4e312

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
77
### Added
88
- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306))
99

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

@@ -70,7 +71,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
7071
- Derived `Ord`, `PartialOrd` for `unistd::Pid` (#[1189](https://github.com/nix-rust/nix/pull/1189))
7172
- Added `select::FdSet::fds` method to iterate over file descriptors in a set.
7273
([#1207](https://github.com/nix-rust/nix/pull/1207))
73-
- Added support for UDP generic segmentation offload (GSO) and generic
74+
- Added support for UDP generic segmentation offload (GSO) and generic
7475
receive offload (GRO) ([#1209](https://github.com/nix-rust/nix/pull/1209))
7576
- Added support for `sendmmsg` and `recvmmsg` calls
7677
(#[1208](https://github.com/nix-rust/nix/pull/1208))

src/unistd.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2795,3 +2795,23 @@ pub fn ttyname(fd: RawFd) -> Result<PathBuf> {
27952795
buf.truncate(nul);
27962796
Ok(OsString::from_vec(buf).into())
27972797
}
2798+
2799+
/// Get the effective user ID and group ID associated with a Unix domain socket.
2800+
///
2801+
/// See also [getpeereid(3)](https://www.freebsd.org/cgi/man.cgi?query=getpeereid)
2802+
#[cfg(any(
2803+
target_os = "macos",
2804+
target_os = "ios",
2805+
target_os = "freebsd",
2806+
target_os = "openbsd",
2807+
target_os = "netbsd",
2808+
target_os = "dragonfly",
2809+
))]
2810+
pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> {
2811+
let mut uid = 1;
2812+
let mut gid = 1;
2813+
2814+
let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) };
2815+
2816+
Errno::result(ret).map(|_| (Uid(uid), Gid(gid)))
2817+
}

test/test_unistd.rs

+39
Original file line numberDiff line numberDiff line change
@@ -1068,3 +1068,42 @@ fn test_ttyname_not_pty() {
10681068
fn test_ttyname_invalid_fd() {
10691069
assert_eq!(ttyname(-1), Err(Error::Sys(Errno::EBADF)));
10701070
}
1071+
1072+
#[test]
1073+
#[cfg(any(
1074+
target_os = "macos",
1075+
target_os = "ios",
1076+
target_os = "freebsd",
1077+
target_os = "openbsd",
1078+
target_os = "netbsd",
1079+
target_os = "dragonfly",
1080+
))]
1081+
fn test_getpeereid() {
1082+
use std::os::unix::net::UnixStream;
1083+
let (sock_a, sock_b) = UnixStream::pair().unwrap();
1084+
1085+
let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap();
1086+
let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap();
1087+
1088+
let uid = geteuid();
1089+
let gid = getegid();
1090+
1091+
assert_eq!(uid, uid_a);
1092+
assert_eq!(gid, gid_a);
1093+
assert_eq!(uid_a, uid_b);
1094+
assert_eq!(gid_a, gid_b);
1095+
}
1096+
1097+
#[test]
1098+
#[cfg(any(
1099+
target_os = "macos",
1100+
target_os = "ios",
1101+
target_os = "freebsd",
1102+
target_os = "openbsd",
1103+
target_os = "netbsd",
1104+
target_os = "dragonfly",
1105+
))]
1106+
fn test_getpeereid_invalid_fd() {
1107+
// getpeereid is not POSIX, so error codes are inconsistent between different Unices.
1108+
assert!(getpeereid(-1).is_err());
1109+
}

0 commit comments

Comments
 (0)