1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
//! [`EventOdGroupSet`]
use std::ffi::OsStr;
use endpoint_sec_sys::{
es_event_od_group_set_t, es_od_member_id_array_t, es_od_member_id_array_t_anon0, es_od_member_type_t,
es_string_token_t,
};
use crate::Process;
/// Notification that a group had it's members initialised or replaced.
#[doc(alias = "es_event_od_group_set_t")]
pub struct EventOdGroupSet<'a> {
/// The raw reference.
pub(crate) raw: &'a es_event_od_group_set_t,
/// The version of the message.
pub(crate) version: u32,
}
impl<'a> EventOdGroupSet<'a> {
/// Process that instigated operation (XPC caller).
#[inline(always)]
pub fn instigator(&self) -> Process<'a> {
// Safety: 'a tied to self, object obtained through ES
Process::new(unsafe { self.raw.instigator.as_ref() }, self.version)
}
/// Result code for the operation.
#[inline(always)]
pub fn error_code(&self) -> i32 {
self.raw.error_code
}
/// The group to which members were set.
#[inline(always)]
pub fn group_name(&self) -> &'a OsStr {
// Safety: 'a tied to self, object obtained through ES
unsafe { self.raw.group_name.as_os_str() }
}
/// Array of new members.
#[inline(always)]
pub fn members(&self) -> OdMemberIdArray<'a> {
OdMemberIdArray {
// Safety: 'a tied to self, object obtained through ES
raw: unsafe { self.raw.members.as_ref() },
}
}
/// OD node being mutated.
///
/// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
#[inline(always)]
pub fn node_name(&self) -> &'a OsStr {
// Safety: 'a tied to self, object obtained through ES
unsafe { self.raw.node_name.as_os_str() }
}
/// Optional. If node_name is "/Local/Default", this is, the path of the database against which
/// OD is authenticating.
#[inline(always)]
pub fn db_path(&self) -> Option<&'a OsStr> {
if self.node_name() == OsStr::new("/Local/Default") {
// Safety: 'a tied to self, object obtained through ES
Some(unsafe { self.raw.db_path.as_os_str() })
} else {
None
}
}
}
// Safety: safe to send across threads: does not contain any interior mutability nor depend on current thread state
unsafe impl Send for EventOdGroupSet<'_> {}
impl_debug_eq_hash_with_functions!(EventOdGroupSet<'a> with version; instigator, error_code, group_name, members, node_name, db_path);
/// An array of group member identities.
#[doc(alias = "es_od_member_id_array_t")]
pub struct OdMemberIdArray<'a> {
/// The raw reference.
pub(crate) raw: &'a es_od_member_id_array_t,
}
impl<'a> OdMemberIdArray<'a> {
/// Indicates the type of the members, and how they are identified.
#[inline(always)]
pub fn member_type(&self) -> es_od_member_type_t {
self.raw.member_type
}
/// The number of elements.
#[inline(always)]
pub fn member_count(&self) -> usize {
self.raw.member_count
}
/// The members identity, as its raw value.
#[inline(always)]
pub fn raw_member_array(&self) -> &'a es_od_member_id_array_t_anon0 {
&self.raw.member_array
}
/// Iterator over the relevant union value based on the member type.
#[inline(always)]
pub fn members<'arr>(&'arr self) -> Option<OdMemberIdArrayIters<'arr, 'a>> {
let res = match self.member_type() {
es_od_member_type_t::ES_OD_MEMBER_TYPE_USER_NAME => {
OdMemberIdArrayIters::UserName(OdMemberIdArrayNames::new(self))
},
es_od_member_type_t::ES_OD_MEMBER_TYPE_USER_UUID => {
OdMemberIdArrayIters::UserUuid(OdMemberIdArrayUuids::new(self))
},
es_od_member_type_t::ES_OD_MEMBER_TYPE_GROUP_UUID => {
OdMemberIdArrayIters::GroupUuid(OdMemberIdArrayUuids::new(self))
},
_ => return None,
};
Some(res)
}
}
// Safety: safe to send across threads: does not contain any interior mutability nor depend on current thread state
unsafe impl Send for OdMemberIdArray<'_> {}
impl_debug_eq_hash_with_functions!(OdMemberIdArray<'a>; member_type, member_count);
/// One of the possible iterator for [`OdMemberIdArray`]
pub enum OdMemberIdArrayIters<'arr, 'raw> {
/// Users, designated by name
UserName(OdMemberIdArrayNames<'arr, 'raw>),
/// Users, designated by UUID
UserUuid(OdMemberIdArrayUuids<'arr, 'raw>),
/// Groups, designated by UUID
GroupUuid(OdMemberIdArrayUuids<'arr, 'raw>),
}
/// Read the `idx` name of `raw`
///
/// # Safety
///
/// Must be called with a valid member array for which `idx` is in range `0..raw.member_count` and the
/// member type is correct.
unsafe fn read_nth_name(raw: &es_od_member_id_array_t, idx: usize) -> es_string_token_t {
std::ptr::read(raw.member_array.names.as_ptr().add(idx))
}
make_event_data_iterator!(
OdMemberIdArray;
/// Iterator over the names in an [`OdMemberIdArray`]
OdMemberIdArrayNames with member_count (usize);
&'raw OsStr;
read_nth_name,
super::as_os_str,
);
/// Read the `idx` uuid of `raw`
///
/// # Safety
///
/// Must be called with a valid member array for which `idx` is in range `0..raw.member_count` and the
/// member type is correct.
unsafe fn read_nth_uuid(raw: &es_od_member_id_array_t, idx: usize) -> libc::uuid_t {
std::ptr::read(raw.member_array.uuids.as_ptr().add(idx))
}
make_event_data_iterator!(
OdMemberIdArray;
/// Iterator over the uuids in an [`OdMemberIdArray`]
OdMemberIdArrayUuids with member_count (usize);
libc::uuid_t;
read_nth_uuid,
std::convert::identity,
);