mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
20200216 fix gidnumber validation (#186)
* Fix an issue with gid number validation
This commit is contained in:
parent
d82b942ddc
commit
f8adfc3840
|
@ -13,7 +13,13 @@ use crate::value::{PartialValue, Value};
|
||||||
|
|
||||||
use kanidm_proto::v1::OperationError;
|
use kanidm_proto::v1::OperationError;
|
||||||
|
|
||||||
static GIDNUMBER_MIN: u32 = 2000;
|
/// Systemd dynamic units allocate between 61184–65519, most distros allocate
|
||||||
|
/// system uids from 0 - 1000, and many others give user ids between 1000 to
|
||||||
|
/// 2000. This whole numberspace is cursed, lets assume it's not ours. :(
|
||||||
|
static GID_SYSTEM_NUMBER_MIN: u32 = 65536;
|
||||||
|
|
||||||
|
/// This is the normal system range, we MUST NOT allow it to be allocated.
|
||||||
|
static GID_SAFETY_NUMBER_MIN: u32 = 1000;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CLASS_POSIXGROUP: PartialValue = PartialValue::new_iutf8s("posixgroup");
|
static ref CLASS_POSIXGROUP: PartialValue = PartialValue::new_iutf8s("posixgroup");
|
||||||
|
@ -32,11 +38,11 @@ fn apply_gidnumber<T: Copy>(
|
||||||
{
|
{
|
||||||
let u_ref = try_audit!(au, e.get_uuid().ok_or(OperationError::InvalidEntryState));
|
let u_ref = try_audit!(au, e.get_uuid().ok_or(OperationError::InvalidEntryState));
|
||||||
let gid = uuid_to_gid_u32(u_ref);
|
let gid = uuid_to_gid_u32(u_ref);
|
||||||
// assert the value is greater than 2000
|
// assert the value is greater than the system range.
|
||||||
if gid < GIDNUMBER_MIN {
|
if gid < GID_SYSTEM_NUMBER_MIN {
|
||||||
return Err(OperationError::InvalidAttribute(format!(
|
return Err(OperationError::InvalidAttribute(format!(
|
||||||
"gidnumber {} may overlap with system range {}",
|
"gidnumber {} may overlap with system range {}",
|
||||||
gid, GIDNUMBER_MIN
|
gid, GID_SYSTEM_NUMBER_MIN
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +50,16 @@ fn apply_gidnumber<T: Copy>(
|
||||||
audit_log!(au, "Generated {} for {:?}", gid, u_ref);
|
audit_log!(au, "Generated {} for {:?}", gid, u_ref);
|
||||||
e.set_avas("gidnumber", vec![gid_v]);
|
e.set_avas("gidnumber", vec![gid_v]);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else if let Some(gid) = e.get_ava_single_uint32("gidnumber") {
|
||||||
|
// If they provided us with a gid number, ensure it's in a safe range.
|
||||||
|
if gid <= GID_SAFETY_NUMBER_MIN {
|
||||||
|
Err(OperationError::InvalidAttribute(format!(
|
||||||
|
"gidnumber {} overlaps into system secure range {}",
|
||||||
|
gid, GID_SAFETY_NUMBER_MIN
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -87,6 +103,7 @@ mod tests {
|
||||||
use crate::entry::{Entry, EntryInvalid, EntryNew};
|
use crate::entry::{Entry, EntryInvalid, EntryNew};
|
||||||
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
|
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
|
||||||
use crate::value::{PartialValue, Value};
|
use crate::value::{PartialValue, Value};
|
||||||
|
use kanidm_proto::v1::OperationError;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
fn check_gid(
|
fn check_gid(
|
||||||
|
@ -146,7 +163,7 @@ mod tests {
|
||||||
"class": ["account", "posixaccount"],
|
"class": ["account", "posixaccount"],
|
||||||
"name": ["testperson"],
|
"name": ["testperson"],
|
||||||
"uuid": ["83a0927f-3de1-45ec-bea0-2f7b997ef244"],
|
"uuid": ["83a0927f-3de1-45ec-bea0-2f7b997ef244"],
|
||||||
"gidnumber": ["1000"],
|
"gidnumber": ["10001"],
|
||||||
"description": ["testperson"],
|
"description": ["testperson"],
|
||||||
"displayname": ["testperson"]
|
"displayname": ["testperson"]
|
||||||
}
|
}
|
||||||
|
@ -165,7 +182,7 @@ mod tests {
|
||||||
au,
|
au,
|
||||||
qs_write,
|
qs_write,
|
||||||
"83a0927f-3de1-45ec-bea0-2f7b997ef244",
|
"83a0927f-3de1-45ec-bea0-2f7b997ef244",
|
||||||
1000
|
10001
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -237,9 +254,9 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test NOT altered if given on mod
|
// Test NOT regenerated if given on mod
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gidnumber_modify_noaction() {
|
fn test_gidnumber_modify_noregen() {
|
||||||
let e: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str(
|
let e: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str(
|
||||||
r#"{
|
r#"{
|
||||||
"valid": null,
|
"valid": null,
|
||||||
|
@ -274,4 +291,88 @@ mod tests {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gidnumber_create_system_reject() {
|
||||||
|
let e: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str(
|
||||||
|
r#"{
|
||||||
|
"attrs": {
|
||||||
|
"class": ["account", "posixaccount"],
|
||||||
|
"name": ["testperson"],
|
||||||
|
"uuid": ["83a0927f-3de1-45ec-bea0-2f7b00000244"],
|
||||||
|
"description": ["testperson"],
|
||||||
|
"displayname": ["testperson"]
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let create = vec![e.clone()];
|
||||||
|
let preload = Vec::new();
|
||||||
|
|
||||||
|
run_create_test!(
|
||||||
|
Err(OperationError::InvalidAttribute(
|
||||||
|
"gidnumber 580 may overlap with system range 65536".to_string()
|
||||||
|
)),
|
||||||
|
preload,
|
||||||
|
create,
|
||||||
|
None,
|
||||||
|
|_, _| {}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gidnumber_create_secure_reject() {
|
||||||
|
let e: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str(
|
||||||
|
r#"{
|
||||||
|
"attrs": {
|
||||||
|
"class": ["account", "posixaccount"],
|
||||||
|
"name": ["testperson"],
|
||||||
|
"gidnumber": ["500"],
|
||||||
|
"description": ["testperson"],
|
||||||
|
"displayname": ["testperson"]
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let create = vec![e.clone()];
|
||||||
|
let preload = Vec::new();
|
||||||
|
|
||||||
|
run_create_test!(
|
||||||
|
Err(OperationError::InvalidAttribute(
|
||||||
|
"gidnumber 500 overlaps into system secure range 1000".to_string()
|
||||||
|
)),
|
||||||
|
preload,
|
||||||
|
create,
|
||||||
|
None,
|
||||||
|
|_, _| {}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gidnumber_create_secure_root_reject() {
|
||||||
|
let e: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str(
|
||||||
|
r#"{
|
||||||
|
"attrs": {
|
||||||
|
"class": ["account", "posixaccount"],
|
||||||
|
"name": ["testperson"],
|
||||||
|
"gidnumber": ["0"],
|
||||||
|
"description": ["testperson"],
|
||||||
|
"displayname": ["testperson"]
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let create = vec![e.clone()];
|
||||||
|
let preload = Vec::new();
|
||||||
|
|
||||||
|
run_create_test!(
|
||||||
|
Err(OperationError::InvalidAttribute(
|
||||||
|
"gidnumber 0 overlaps into system secure range 1000".to_string()
|
||||||
|
)),
|
||||||
|
preload,
|
||||||
|
create,
|
||||||
|
None,
|
||||||
|
|_, _| {}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue