ACL: Targets in ACL entries are NULLable
This commit is contained in:
parent
4bb0831168
commit
18979feeca
2 changed files with 46 additions and 13 deletions
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
error::{Error, ErrorCode},
|
error::{Error, ErrorCode},
|
||||||
fabric,
|
fabric,
|
||||||
interaction_model::messages::GenericPath,
|
interaction_model::messages::GenericPath,
|
||||||
tlv::{self, FromTLV, TLVElement, TLVList, TLVWriter, TagType, ToTLV},
|
tlv::{self, FromTLV, Nullable, TLVElement, TLVList, TLVWriter, TagType, ToTLV},
|
||||||
transport::session::{Session, SessionMode, MAX_CAT_IDS_PER_NOC},
|
transport::session::{Session, SessionMode, MAX_CAT_IDS_PER_NOC},
|
||||||
utils::writebuf::WriteBuf,
|
utils::writebuf::WriteBuf,
|
||||||
};
|
};
|
||||||
|
@ -282,7 +282,15 @@ impl Target {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subjects = [Option<u64>; SUBJECTS_PER_ENTRY];
|
type Subjects = [Option<u64>; SUBJECTS_PER_ENTRY];
|
||||||
type Targets = [Option<Target>; TARGETS_PER_ENTRY];
|
|
||||||
|
type Targets = Nullable<[Option<Target>; TARGETS_PER_ENTRY]>;
|
||||||
|
impl Targets {
|
||||||
|
fn init_notnull() -> Self {
|
||||||
|
const INIT_TARGETS: Option<Target> = None;
|
||||||
|
Nullable::NotNull([INIT_TARGETS; TARGETS_PER_ENTRY])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(ToTLV, FromTLV, Clone, Debug, PartialEq)]
|
#[derive(ToTLV, FromTLV, Clone, Debug, PartialEq)]
|
||||||
#[tlvargs(start = 1)]
|
#[tlvargs(start = 1)]
|
||||||
pub struct AclEntry {
|
pub struct AclEntry {
|
||||||
|
@ -298,14 +306,12 @@ pub struct AclEntry {
|
||||||
impl AclEntry {
|
impl AclEntry {
|
||||||
pub fn new(fab_idx: u8, privilege: Privilege, auth_mode: AuthMode) -> Self {
|
pub fn new(fab_idx: u8, privilege: Privilege, auth_mode: AuthMode) -> Self {
|
||||||
const INIT_SUBJECTS: Option<u64> = None;
|
const INIT_SUBJECTS: Option<u64> = None;
|
||||||
const INIT_TARGETS: Option<Target> = None;
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fab_idx: Some(fab_idx),
|
fab_idx: Some(fab_idx),
|
||||||
privilege,
|
privilege,
|
||||||
auth_mode,
|
auth_mode,
|
||||||
subjects: [INIT_SUBJECTS; SUBJECTS_PER_ENTRY],
|
subjects: [INIT_SUBJECTS; SUBJECTS_PER_ENTRY],
|
||||||
targets: [INIT_TARGETS; TARGETS_PER_ENTRY],
|
targets: Targets::init_notnull(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,12 +330,20 @@ impl AclEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_target(&mut self, target: Target) -> Result<(), Error> {
|
pub fn add_target(&mut self, target: Target) -> Result<(), Error> {
|
||||||
|
if self.targets.is_null() {
|
||||||
|
self.targets = Targets::init_notnull();
|
||||||
|
}
|
||||||
let index = self
|
let index = self
|
||||||
.targets
|
.targets
|
||||||
|
.as_ref()
|
||||||
|
.notnull()
|
||||||
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.position(|s| s.is_none())
|
.position(|s| s.is_none())
|
||||||
.ok_or(ErrorCode::NoSpace)?;
|
.ok_or(ErrorCode::NoSpace)?;
|
||||||
self.targets[index] = Some(target);
|
|
||||||
|
self.targets.as_mut().notnull().unwrap()[index] = Some(target);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +372,10 @@ impl AclEntry {
|
||||||
fn match_access_desc(&self, object: &AccessDesc) -> bool {
|
fn match_access_desc(&self, object: &AccessDesc) -> bool {
|
||||||
let mut allow = false;
|
let mut allow = false;
|
||||||
let mut entries_exist = false;
|
let mut entries_exist = false;
|
||||||
for t in self.targets.iter().flatten() {
|
match self.targets.as_ref().notnull() {
|
||||||
|
None => allow = true, // Allow if targets are NULL
|
||||||
|
Some(targets) => {
|
||||||
|
for t in targets.iter().flatten() {
|
||||||
entries_exist = true;
|
entries_exist = true;
|
||||||
if (t.endpoint.is_none() || t.endpoint == object.path.endpoint)
|
if (t.endpoint.is_none() || t.endpoint == object.path.endpoint)
|
||||||
&& (t.cluster.is_none() || t.cluster == object.path.cluster)
|
&& (t.cluster.is_none() || t.cluster == object.path.cluster)
|
||||||
|
@ -366,6 +383,8 @@ impl AclEntry {
|
||||||
allow = true
|
allow = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if !entries_exist {
|
if !entries_exist {
|
||||||
// Targets array empty implies allow for all targets
|
// Targets array empty implies allow for all targets
|
||||||
allow = true;
|
allow = true;
|
||||||
|
|
|
@ -265,6 +265,20 @@ pub enum Nullable<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Nullable<T> {
|
impl<T> Nullable<T> {
|
||||||
|
pub fn as_mut(&mut self) -> Nullable<&mut T> {
|
||||||
|
match self {
|
||||||
|
Nullable::Null => Nullable::Null,
|
||||||
|
Nullable::NotNull(t) => Nullable::NotNull(t),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_ref(&self) -> Nullable<&T> {
|
||||||
|
match self {
|
||||||
|
Nullable::Null => Nullable::Null,
|
||||||
|
Nullable::NotNull(t) => Nullable::NotNull(t),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_null(&self) -> bool {
|
pub fn is_null(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Nullable::Null => true,
|
Nullable::Null => true,
|
||||||
|
@ -272,7 +286,7 @@ impl<T> Nullable<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_notnull(self) -> Option<T> {
|
pub fn notnull(self) -> Option<T> {
|
||||||
match self {
|
match self {
|
||||||
Nullable::Null => None,
|
Nullable::Null => None,
|
||||||
Nullable::NotNull(t) => Some(t),
|
Nullable::NotNull(t) => Some(t),
|
||||||
|
|
Loading…
Add table
Reference in a new issue