102 lines
2.9 KiB
Rust
102 lines
2.9 KiB
Rust
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<bool, std::io::Error>`
|
|
///
|
|
pub fn is_unix_socket(fd: libc::c_int) -> Result<bool, std::io::Error> {
|
|
unsafe {
|
|
let mut addr: libc::sockaddr_storage = std::mem::zeroed();
|
|
let mut addr_len: libc::socklen_t = size_of::<libc::sockaddr_storage>() 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
|
|
};
|
|
}
|