use crate::PrivilegeInfo;
use crate::error::TokenPrivilegeError;
use crate::ffi;
pub fn is_privilege_enabled(privilege_name: &str) -> Result<bool, TokenPrivilegeError> {
let token = ffi::open_current_process_token()?;
let luid = ffi::lookup_privilege_value(privilege_name)?;
ffi::check_privilege_enabled(&token, luid)
}
pub fn has_privilege(privilege_name: &str) -> Result<bool, TokenPrivilegeError> {
let token = ffi::open_current_process_token()?;
let _luid = ffi::lookup_privilege_value(privilege_name)?;
let privileges = ffi::enumerate_token_privileges(&token)?;
Ok(privileges.iter().any(|p| p.name == privilege_name))
}
pub fn enumerate_privileges() -> Result<Vec<PrivilegeInfo>, TokenPrivilegeError> {
let token = ffi::open_current_process_token()?;
ffi::enumerate_token_privileges(&token)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn change_notify_is_enabled() {
let result = is_privilege_enabled("SeChangeNotifyPrivilege");
assert!(result.is_ok(), "should succeed");
if let Ok(is_enabled) = result {
assert!(is_enabled, "SeChangeNotifyPrivilege should be enabled");
}
}
#[test]
fn has_change_notify_privilege() {
let result = has_privilege("SeChangeNotifyPrivilege");
assert!(result.is_ok(), "should succeed");
if let Ok(has_priv) = result {
assert!(has_priv, "SeChangeNotifyPrivilege should be present");
}
}
#[test]
fn invalid_privilege_name_returns_error() {
let result = is_privilege_enabled("SeTotallyFakePrivilege");
assert!(result.is_err(), "should fail for invalid privilege");
}
#[test]
fn enumerate_privileges_non_empty() {
let result = enumerate_privileges();
assert!(result.is_ok(), "enumeration should succeed");
if let Ok(privs) = result {
assert!(!privs.is_empty(), "should have at least one privilege");
}
}
#[test]
fn enumerate_contains_change_notify() {
let result = enumerate_privileges();
assert!(result.is_ok(), "enumeration should succeed");
if let Ok(privs) = result {
let found = privs.iter().any(|p| p.name == "SeChangeNotifyPrivilege");
assert!(found, "should contain SeChangeNotifyPrivilege");
}
}
#[test]
fn change_notify_is_enabled_in_enumeration() {
let result = enumerate_privileges();
assert!(result.is_ok(), "enumeration should succeed");
if let Ok(privs) = result {
let cn = privs.iter().find(|p| p.name == "SeChangeNotifyPrivilege");
assert!(cn.is_some(), "should find SeChangeNotifyPrivilege");
if let Some(change_notify) = cn {
assert!(
change_notify.enabled,
"SeChangeNotifyPrivilege should be enabled"
);
}
}
}
}