summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Hoff <maghoff@gmail.com>2015-12-15 10:03:55 +0100
committerCarl Lerche <me@carllerche.com>2015-12-22 12:55:40 -0800
commit1164ea7196994f98bc2423dd4ce73939d61ca69e (patch)
tree1a4573ec3b1c450e07a31a545959c1f2c8a53e2a
parent1ce4eeee906c69af94805bdda22e4a4579547dd2 (diff)
downloadnix-1164ea7196994f98bc2423dd4ce73939d61ca69e.zip
Implement support for getsockopt of peer credentials using the Linux specific SO_PEERCRED
-rw-r--r--src/sys/socket/mod.rs10
-rw-r--r--src/sys/socket/sockopt.rs18
2 files changed, 27 insertions, 1 deletions
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 4f6add4c..7eb1901a 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -6,7 +6,7 @@ use errno::Errno;
use features;
use fcntl::{fcntl, FD_CLOEXEC, O_NONBLOCK};
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
-use libc::{c_void, c_int, socklen_t, size_t};
+use libc::{c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
use std::{mem, ptr, slice};
use std::os::unix::io::RawFd;
use sys::uio::IoVec;
@@ -581,6 +581,14 @@ pub struct linger {
pub l_linger: c_int
}
+#[repr(C)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub struct ucred {
+ pid: pid_t,
+ uid: uid_t,
+ gid: gid_t,
+}
+
/*
*
* ===== Socket Options =====
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 2f01b91d..6ba43666 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -137,6 +137,8 @@ sockopt_impl!(Both, Broadcast, consts::SOL_SOCKET, consts::SO_BROADCAST, bool);
sockopt_impl!(Both, OobInline, consts::SOL_SOCKET, consts::SO_OOBINLINE, bool);
sockopt_impl!(GetOnly, SocketError, consts::SOL_SOCKET, consts::SO_ERROR, i32);
sockopt_impl!(Both, KeepAlive, consts::SOL_SOCKET, consts::SO_KEEPALIVE, bool);
+#[cfg(target_os = "linux")]
+sockopt_impl!(GetOnly, PeerCredentials, consts::SOL_SOCKET, consts::SO_PEERCRED, super::ucred);
#[cfg(any(target_os = "macos",
target_os = "ios"))]
sockopt_impl!(Both, TcpKeepAlive, consts::IPPROTO_TCP, consts::TCP_KEEPALIVE, u32);
@@ -300,3 +302,19 @@ impl<'a> Set<'a, u8> for SetU8 {
mem::size_of::<c_int>() as socklen_t
}
}
+
+
+#[cfg(test)]
+mod test {
+ #[cfg(target_os = "linux")]
+ #[test]
+ fn can_get_peercred_on_unix_socket() {
+ use super::super::*;
+
+ let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
+ let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
+ let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
+ assert_eq!(a_cred, b_cred);
+ assert!(a_cred.pid != 0);
+ }
+}