Skip to content

Commit 8cff207

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 d07b7f8 + 7c3a353 commit 8cff207

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

CHANGELOG.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
66
## [Unreleased] - ReleaseDate
77
### Added
88
- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306))
9-
109
- Added `personality` (#[1331](https://github.com/nix-rust/nix/pull/1331))
11-
1210
- Added limited Fuchsia support (#[1285](https://github.com/nix-rust/nix/pull/1285))
13-
11+
- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342))
1412
### Fixed
1513
### Changed
1614

src/unistd.rs

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

test/test_unistd.rs

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

0 commit comments

Comments
 (0)