summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-22 16:49:42 +0000
committerGitHub <noreply@github.com>2020-12-22 16:49:42 +0000
commit8cff207a136258977b1d944955181fd477b11ccc (patch)
tree527ff9f58cb9fc2a12dd45b709fb7da5aad10ad0
parentd07b7f81a046ded5bd25cde744bbf47a884e3e93 (diff)
parent7c3a3535fc1502fb22867683a2ece20ff29bf314 (diff)
downloadnix-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.md4
-rw-r--r--src/unistd.rs20
-rw-r--r--test/test_unistd.rs39
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());
+}