diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-05-02 18:04:25 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-02 18:04:25 +0000 |
commit | 539c5705ad6b8c372be8108ef6c6940ccfb6a417 (patch) | |
tree | e7c39dc69a2b5ddf52c88149bae3048045c4a007 /test/sys/test_socket.rs | |
parent | 3ae6b180ddba4b28582662312bfb56402fb096a0 (diff) | |
parent | b2a9c4f18c3e2314bf737ef842e5d5c7de94f33a (diff) | |
download | nix-539c5705ad6b8c372be8108ef6c6940ccfb6a417.zip |
Merge #1216
1216: Add UnixCredentials support on FreeBSD/DragonFly r=asomers a=myfreeweb
This allows working with `SCM_CREDS` messages, which are like `SCM_CREDENTIALS` on Linux, but slightly different (always overwritten by the kernel, contain a bit more info — euid and groups).
With this PR, it is possible to write portable code that would use the appropriate message for the platform, but one remaining quirk is that `PassCred` thing still has to be present and `cfg`'d to Linux.
Adding the `SCM_CREDS` constant to libc: https://github.com/rust-lang/libc/pull/1740
Co-authored-by: Greg V <greg@unrelenting.technology>
Diffstat (limited to 'test/sys/test_socket.rs')
-rw-r--r-- | test/sys/test_socket.rs | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index ae5ac66c..20ff8d78 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -752,29 +752,36 @@ pub fn test_sendmsg_empty_cmsgs() { } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "freebsd", + target_os = "dragonfly", +))] #[test] fn test_scm_credentials() { - use libc; use nix::sys::uio::IoVec; use nix::unistd::{close, getpid, getuid, getgid}; use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt, AddressFamily, SockType, SockFlag, - ControlMessage, ControlMessageOwned, MsgFlags}; + ControlMessage, ControlMessageOwned, MsgFlags, + UnixCredentials}; + #[cfg(any(target_os = "android", target_os = "linux"))] use nix::sys::socket::sockopt::PassCred; let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()) .unwrap(); + #[cfg(any(target_os = "android", target_os = "linux"))] setsockopt(recv, PassCred, &true).unwrap(); { let iov = [IoVec::from_slice(b"hello")]; - let cred = libc::ucred { - pid: getpid().as_raw(), - uid: getuid().as_raw(), - gid: getgid().as_raw(), - }.into(); + #[cfg(any(target_os = "android", target_os = "linux"))] + let cred = UnixCredentials::new(); + #[cfg(any(target_os = "android", target_os = "linux"))] let cmsg = ControlMessage::ScmCredentials(&cred); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + let cmsg = ControlMessage::ScmCreds; assert_eq!(sendmsg(send, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5); close(send).unwrap(); } @@ -782,20 +789,23 @@ fn test_scm_credentials() { { let mut buf = [0u8; 5]; let iov = [IoVec::from_mut_slice(&mut buf[..])]; - let mut cmsgspace = cmsg_space!(libc::ucred); + let mut cmsgspace = cmsg_space!(UnixCredentials); let msg = recvmsg(recv, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap(); let mut received_cred = None; for cmsg in msg.cmsgs() { - if let ControlMessageOwned::ScmCredentials(cred) = cmsg { - assert!(received_cred.is_none()); - assert_eq!(cred.pid(), getpid().as_raw()); - assert_eq!(cred.uid(), getuid().as_raw()); - assert_eq!(cred.gid(), getgid().as_raw()); - received_cred = Some(cred); - } else { - panic!("unexpected cmsg"); - } + let cred = match cmsg { + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessageOwned::ScmCredentials(cred) => cred, + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + ControlMessageOwned::ScmCreds(cred) => cred, + other => panic!("unexpected cmsg {:?}", other), + }; + assert!(received_cred.is_none()); + assert_eq!(cred.pid(), getpid().as_raw()); + assert_eq!(cred.uid(), getuid().as_raw()); + assert_eq!(cred.gid(), getgid().as_raw()); + received_cred = Some(cred); } received_cred.expect("no creds received"); assert_eq!(msg.bytes, 5); |