use crate::{ERR, INFO}; use nix; /// Drop user privileges /// /// This function drop the privileges of the current user /// to another inferior privileges user. /// e.g. drop from root->maint /// /// # Arguments /// /// * `user` - system user name /// * `group` - system group name /// /// # Errors /// /// * `nix::Error` - The error from the nix package pub fn privdrop(useropt: Option<&str>, groupopt: Option<&str>) -> Result<(), nix::Error> { match groupopt { Some(group) => { INFO!("Dropping current process group to {}", group); match nix::unistd::Group::from_name(group)? { Some(group) => nix::unistd::setgid(group.gid), None => Err(nix::Error::last()), }?; } None => {} } match useropt { Some(user) => { INFO!("Dropping current process user to {}", user); match nix::unistd::User::from_name(user)? { Some(user) => nix::unistd::setuid(user.uid), None => Err(nix::Error::last()), }? } None => {} } Ok(()) } /// Check if a file descriptor is an unix socket /// /// # Arguments /// /// - `fd` (`libc::c_int`) - input file descriptor /// /// # Returns /// /// - `Result` /// pub fn is_unix_socket(fd: libc::c_int) -> Result { unsafe { let mut addr: libc::sockaddr_storage = std::mem::zeroed(); let mut addr_len: libc::socklen_t = size_of::() as libc::socklen_t; let addr_storage: *mut libc::sockaddr_storage = &mut addr; let ret = libc::getsockname(fd, addr_storage as *mut _, &mut addr_len); if ret != 0 { return Err(ERR!(format!("Unable to check socket: {}", fd))); } Ok(i32::from(addr.ss_family) == libc::AF_UNIX) } } /// Utility function to catch common signal that /// cause the program to exit /// /// Signals catched: SIGABRT, SIGINT, SIGTERM, SIGQUIT /// /// # Arguments /// /// * `f` - callback function that will be called when a signal is trapped pub fn on_exit(f: fn(n: i32) -> ()) { unsafe { let _ = libc::signal(libc::SIGPIPE, libc::SIG_IGN); let _ = libc::signal(libc::SIGABRT, (f as *const std::ffi::c_void) as usize); let _ = libc::signal(libc::SIGINT, (f as *const std::ffi::c_void) as usize); let _ = libc::signal(libc::SIGTERM, (f as *const std::ffi::c_void) as usize); let _ = libc::signal(libc::SIGQUIT, (f as *const std::ffi::c_void) as usize); }; } /// Return an Error Result object from error string /// #[macro_export] macro_rules! ERR { ($x:expr) => { std::io::Error::new( std::io::ErrorKind::Other, format!("({}:{}): {}", file!(), line!(), $x), ) }; } /// Bit value at address /// #[macro_export] macro_rules! BITV { ($v:expr,$i:expr) => { ($v & (1 << $i)) >> $i }; }