Avoid false negatice permission denied error message (#9046)

The unix implementation of cd fails with a permission error when
classical unix permissions deny access to a directory, but additional mechanisms like
ACLs actually grant the user access

Fix this by miroring the windows implementation: if we can read_dir()
without error => allow the cd to proceed.

Addtionally we also handle the case where it is the other way round:
unix permissions grant access but additional security modules (SElinux,
apparmor, etc.) deny the current user/context.
This commit is contained in:
Andy Kittner 2024-04-13 20:03:10 +02:00
parent 211d9c685c
commit 768142d329
No known key found for this signature in database
GPG Key ID: 3E3299477F2851B0

View File

@ -33,6 +33,24 @@ pub fn have_permission(dir: impl AsRef<Path>) -> PermissionResult<'static> {
#[cfg(unix)] #[cfg(unix)]
pub fn have_permission(dir: impl AsRef<Path>) -> PermissionResult<'static> { pub fn have_permission(dir: impl AsRef<Path>) -> PermissionResult<'static> {
match dir.as_ref().read_dir() {
Err(_) => {
// this might produce a friendlier error message
match have_permission_by_metadata(dir) {
PermissionResult::PermissionOk => {
// handle false positive, metadata said we should be able to read but we
// actually tried to do that and failed (could be SELinux or similar in effect)
PermissionResult::PermissionDenied("Folder is unable to be read")
}
result => result,
}
}
Ok(_) => PermissionResult::PermissionOk,
}
}
#[cfg(unix)]
fn have_permission_by_metadata(dir: impl AsRef<Path>) -> PermissionResult<'static> {
match dir.as_ref().metadata() { match dir.as_ref().metadata() {
Ok(metadata) => { Ok(metadata) => {
let mode = Mode::from_bits_truncate(metadata.mode() as mode_t); let mode = Mode::from_bits_truncate(metadata.mode() as mode_t);