mod sys;
#[cfg(test)]
mod tests;
mod utils;
pub use sys::*;
use std::ffi::OsString;
use std::fmt;
use std::io;
use std::marker::{PhantomData, PhantomPinned};
use std::ops;
use crate::private;
use crate::Error;
pub trait UseridExt: private::Sealed {
fn as_raw_psid(&self) -> sys::PSID;
fn from_raw_psid<'psid>(psid: sys::PSID) -> Option<&'psid Self>;
unsafe fn from_raw_psid_unchecked<'psid>(psid: sys::PSID) -> &'psid Self;
}
pub trait GroupidExt: private::Sealed {
fn as_raw_psid(&self) -> sys::PSID;
fn from_raw_psid<'psid>(psid: sys::PSID) -> Option<&'psid Self>;
unsafe fn from_raw_psid_unchecked<'psid>(psid: sys::PSID) -> &'psid Self;
}
pub trait GroupidBufExt: private::Sealed {
fn world() -> Result<Self, io::Error>
where
Self: Sized;
}
#[derive(Eq)]
pub(crate) struct Userid {
_data: [u8; 0],
_marker: PhantomData<(*mut u8, PhantomPinned)>,
}
impl Userid {
pub fn try_clone(&self) -> Result<UseridBuf, io::Error> {
sys::copy_sid(self.as_raw_psid()).map(UseridBuf)
}
pub fn name(&self) -> Result<OsString, Error> {
sys::lookup_account_sid(self.as_raw_psid())
}
}
impl fmt::Display for Userid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl fmt::Debug for Userid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl PartialEq for Userid {
fn eq(&self, other: &Self) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
impl PartialEq<UseridBuf> for Userid {
fn eq(&self, other: &UseridBuf) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
impl private::Sealed for Userid {}
impl UseridExt for Userid {
fn as_raw_psid(&self) -> sys::PSID {
self as *const Self as sys::PSID
}
fn from_raw_psid<'psid>(psid: sys::PSID) -> Option<&'psid Self> {
if sys::is_invalid_sid(psid) {
None
} else {
Some(unsafe { Self::from_raw_psid_unchecked(psid) })
}
}
unsafe fn from_raw_psid_unchecked<'psid>(psid: sys::PSID) -> &'psid Self {
unsafe { &*(psid as *const sys::PSID as *const Self) }
}
}
#[derive(Eq)]
pub(crate) struct UseridBuf(Vec<u8>);
impl ops::Deref for UseridBuf {
type Target = Userid;
fn deref(&self) -> &Self::Target {
unsafe { Userid::from_raw_psid_unchecked(self.0.as_ptr() as sys::PSID) }
}
}
impl fmt::Display for UseridBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl fmt::Debug for UseridBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl PartialEq for UseridBuf {
fn eq(&self, other: &Self) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
impl PartialEq<Userid> for UseridBuf {
fn eq(&self, other: &Userid) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
#[derive(Eq)]
pub(crate) struct Groupid {
_data: [u8; 0],
_marker: PhantomData<(*mut u8, PhantomPinned)>,
}
impl Groupid {
pub fn try_clone(&self) -> Result<GroupidBuf, io::Error> {
sys::copy_sid(self.as_raw_psid()).map(GroupidBuf)
}
pub fn name(&self) -> Result<OsString, Error> {
sys::lookup_account_sid(self.as_raw_psid())
}
}
impl fmt::Display for Groupid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl fmt::Debug for Groupid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl PartialEq for Groupid {
fn eq(&self, other: &Self) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
impl PartialEq<GroupidBuf> for Groupid {
fn eq(&self, other: &GroupidBuf) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
impl private::Sealed for Groupid {}
impl GroupidExt for Groupid {
fn as_raw_psid(&self) -> sys::PSID {
self as *const Self as sys::PSID
}
fn from_raw_psid<'psid>(psid: sys::PSID) -> Option<&'psid Self> {
if sys::is_invalid_sid(psid) {
None
} else {
Some(unsafe { Self::from_raw_psid_unchecked(psid) })
}
}
unsafe fn from_raw_psid_unchecked<'psid>(psid: sys::PSID) -> &'psid Self {
unsafe { &*(psid as *const sys::PSID as *const Self) }
}
}
#[derive(Eq)]
pub(crate) struct GroupidBuf(Vec<u8>);
impl fmt::Display for GroupidBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl fmt::Debug for GroupidBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
sys::fmt_sid(self.as_raw_psid(), f)
}
}
impl PartialEq for GroupidBuf {
fn eq(&self, other: &Self) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
impl PartialEq<Groupid> for GroupidBuf {
fn eq(&self, other: &Groupid) -> bool {
sys::equal_sid(self.as_raw_psid(), other.as_raw_psid())
}
}
impl ops::Deref for GroupidBuf {
type Target = Groupid;
fn deref(&self) -> &Self::Target {
unsafe { Groupid::from_raw_psid_unchecked(self.0.as_ptr() as sys::PSID) }
}
}
impl private::Sealed for GroupidBuf {}
impl GroupidBufExt for GroupidBuf {
fn world() -> Result<Self, io::Error> {
sys::create_world_sid().map(GroupidBuf)
}
}