use std::{
fmt::{self, Display},
io,
mem::MaybeUninit,
};
#[cfg(target_os = "macos")]
use libc::dev_t;
use libc::{c_int, c_uint, pid_t, uid_t};
pub type AuditUserId = uid_t;
pub type AuditSessionId = pid_t;
pub type AuditEvent = u16;
pub type AuditEmod = u16;
pub type AuditClass = u32;
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[repr(C)]
pub struct AuditMask {
pub am_success: c_uint,
pub am_failure: c_uint,
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[repr(C)]
pub struct AuditTerminalId {
#[cfg(target_os = "freebsd")]
pub port: u32,
#[cfg(target_os = "macos")]
pub port: dev_t,
pub machine: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[repr(C)]
pub struct AuditTerminalIdAddr {
#[cfg(target_os = "freebsd")]
pub at_port: u32,
#[cfg(target_os = "macos")]
pub at_port: dev_t,
pub at_type: u32,
pub at_addr: [u32; 4],
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[repr(C)]
pub struct AuditInfo {
pub ai_auid: AuditUserId,
pub ai_mask: AuditMask,
pub ai_termid: AuditTerminalId,
pub ai_asid: AuditSessionId,
}
impl Display for AuditInfo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "auid={}", self.ai_auid)?;
writeln!(f, "mask.success={:#X}", self.ai_mask.am_success)?;
writeln!(f, "mask.failure={:#X}", self.ai_mask.am_failure)?;
writeln!(f, "asid={}", self.ai_asid)?;
writeln!(f, "termid.port={:#X}", self.ai_termid.port)?;
write!(f, "termid.machine={:#X}", self.ai_termid.machine)
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[repr(C)]
pub struct AuditInfoAddr {
pub ai_auid: AuditUserId,
pub ai_mask: AuditMask,
pub ai_termid: AuditTerminalIdAddr,
pub ai_asid: AuditSessionId,
pub ai_flags: u64,
}
impl Display for AuditInfoAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "auid={}", self.ai_auid)?;
writeln!(f, "mask.success={:#X}", self.ai_mask.am_success)?;
writeln!(f, "mask.failure={:#X}", self.ai_mask.am_failure)?;
writeln!(f, "asid={}", self.ai_asid)?;
writeln!(f, "termid.at_port={:#X}", self.ai_termid.at_port)?;
write!(f, "termid.at_type={}", self.ai_termid.at_type)
}
}
extern "C" {
pub fn getaudit(auditinfo: *mut AuditInfo) -> c_int;
pub fn getaudit_addr(auditinfo_addr: *mut AuditInfoAddr, length: c_int) -> c_int;
}
pub fn audit_info() -> io::Result<AuditInfo> {
let mut auditinfo: MaybeUninit<AuditInfo> = MaybeUninit::zeroed();
let address = auditinfo.as_mut_ptr() as *mut AuditInfo;
if unsafe { getaudit(address) } == -1 {
return Err(io::Error::last_os_error());
}
let auditinfo = unsafe { auditinfo.assume_init() };
Ok(auditinfo)
}