Skip to content

Commit bbe4318

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 062bec3 + 000e671 commit bbe4318

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ 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))
11+
### Changed
1012
### Fixed
1113
### Changed
1214
### Removed

src/unistd.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2785,3 +2785,23 @@ pub fn ttyname(fd: RawFd) -> Result<PathBuf> {
27852785
buf.truncate(nul);
27862786
Ok(OsString::from_vec(buf).into())
27872787
}
2788+
2789+
/// Get the effective user ID and group ID associated with a Unix domain socket.
2790+
///
2791+
/// See also [getpeereid(3)](https://www.freebsd.org/cgi/man.cgi?query=getpeereid)
2792+
#[cfg(any(
2793+
target_os = "macos",
2794+
target_os = "ios",
2795+
target_os = "freebsd",
2796+
target_os = "openbsd",
2797+
target_os = "netbsd",
2798+
target_os = "dragonfly",
2799+
))]
2800+
pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> {
2801+
let mut uid = 1;
2802+
let mut gid = 1;
2803+
2804+
let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) };
2805+
2806+
Errno::result(ret).map(|_| (Uid(uid), Gid(gid)))
2807+
}

test/test_unistd.rs

+39
Original file line numberDiff line numberDiff line change
@@ -1044,3 +1044,42 @@ fn test_ttyname_invalid_fd() {
10441044
fn test_ttyname_invalid_fd() {
10451045
assert_eq!(ttyname(-1), Err(Error::Sys(Errno::ENOTTY)));
10461046
}
1047+
1048+
#[test]
1049+
#[cfg(any(
1050+
target_os = "macos",
1051+
target_os = "ios",
1052+
target_os = "freebsd",
1053+
target_os = "openbsd",
1054+
target_os = "netbsd",
1055+
target_os = "dragonfly",
1056+
))]
1057+
fn test_getpeereid() {
1058+
use std::os::unix::net::UnixStream;
1059+
let (sock_a, sock_b) = UnixStream::pair().unwrap();
1060+
1061+
let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap();
1062+
let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap();
1063+
1064+
let uid = geteuid();
1065+
let gid = getegid();
1066+
1067+
assert_eq!(uid, uid_a);
1068+
assert_eq!(gid, gid_a);
1069+
assert_eq!(uid_a, uid_b);
1070+
assert_eq!(gid_a, gid_b);
1071+
}
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_invalid_fd() {
1083+
// getpeereid is not POSIX, so error codes are inconsistent between different Unices.
1084+
assert!(getpeereid(-1).is_err());
1085+
}

0 commit comments

Comments
 (0)