mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 17:58:06 +00:00
Merge pull request #2349 from drocco007/test-euid-egid-file-ownership
test: implement user, group ownership checks
This commit is contained in:
commit
83a8ec1a67
2 changed files with 74 additions and 10 deletions
|
@ -6,7 +6,7 @@
|
|||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (vars) FiletestOp StrlenOp
|
||||
// spell-checker:ignore (vars) egid euid FiletestOp StrlenOp
|
||||
|
||||
mod parser;
|
||||
|
||||
|
@ -96,8 +96,10 @@ fn eval(stack: &mut Vec<Symbol>) -> Result<bool, String> {
|
|||
"-e" => path(&f, PathCondition::Exists),
|
||||
"-f" => path(&f, PathCondition::Regular),
|
||||
"-g" => path(&f, PathCondition::GroupIdFlag),
|
||||
"-G" => path(&f, PathCondition::GroupOwns),
|
||||
"-h" => path(&f, PathCondition::SymLink),
|
||||
"-L" => path(&f, PathCondition::SymLink),
|
||||
"-O" => path(&f, PathCondition::UserOwns),
|
||||
"-p" => path(&f, PathCondition::Fifo),
|
||||
"-r" => path(&f, PathCondition::Readable),
|
||||
"-S" => path(&f, PathCondition::Socket),
|
||||
|
@ -166,7 +168,9 @@ enum PathCondition {
|
|||
Exists,
|
||||
Regular,
|
||||
GroupIdFlag,
|
||||
GroupOwns,
|
||||
SymLink,
|
||||
UserOwns,
|
||||
Fifo,
|
||||
Readable,
|
||||
Socket,
|
||||
|
@ -190,18 +194,28 @@ fn path(path: &OsStr, condition: PathCondition) -> bool {
|
|||
Execute = 0o1,
|
||||
}
|
||||
|
||||
let perm = |metadata: Metadata, p: Permission| {
|
||||
let geteuid = || {
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
let (uid, gid) = unsafe { (libc::getuid(), libc::getgid()) };
|
||||
let euid = unsafe { libc::geteuid() };
|
||||
#[cfg(target_os = "redox")]
|
||||
let (uid, gid) = (
|
||||
syscall::getuid().unwrap() as u32,
|
||||
syscall::getgid().unwrap() as u32,
|
||||
);
|
||||
let euid = syscall::geteuid().unwrap() as u32;
|
||||
|
||||
if uid == metadata.uid() {
|
||||
euid
|
||||
};
|
||||
|
||||
let getegid = || {
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
let egid = unsafe { libc::getegid() };
|
||||
#[cfg(target_os = "redox")]
|
||||
let egid = syscall::getegid().unwrap() as u32;
|
||||
|
||||
egid
|
||||
};
|
||||
|
||||
let perm = |metadata: Metadata, p: Permission| {
|
||||
if geteuid() == metadata.uid() {
|
||||
metadata.mode() & ((p as u32) << 6) != 0
|
||||
} else if gid == metadata.gid() {
|
||||
} else if getegid() == metadata.gid() {
|
||||
metadata.mode() & ((p as u32) << 3) != 0
|
||||
} else {
|
||||
metadata.mode() & (p as u32) != 0
|
||||
|
@ -230,7 +244,9 @@ fn path(path: &OsStr, condition: PathCondition) -> bool {
|
|||
PathCondition::Exists => true,
|
||||
PathCondition::Regular => file_type.is_file(),
|
||||
PathCondition::GroupIdFlag => metadata.mode() & S_ISGID != 0,
|
||||
PathCondition::GroupOwns => metadata.gid() == getegid(),
|
||||
PathCondition::SymLink => metadata.file_type().is_symlink(),
|
||||
PathCondition::UserOwns => metadata.uid() == geteuid(),
|
||||
PathCondition::Fifo => file_type.is_fifo(),
|
||||
PathCondition::Readable => perm(metadata, Permission::Read),
|
||||
PathCondition::Socket => file_type.is_socket(),
|
||||
|
@ -257,7 +273,9 @@ fn path(path: &OsStr, condition: PathCondition) -> bool {
|
|||
PathCondition::Exists => true,
|
||||
PathCondition::Regular => stat.is_file(),
|
||||
PathCondition::GroupIdFlag => false,
|
||||
PathCondition::GroupOwns => unimplemented!(),
|
||||
PathCondition::SymLink => false,
|
||||
PathCondition::UserOwns => unimplemented!(),
|
||||
PathCondition::Fifo => false,
|
||||
PathCondition::Readable => false, // TODO
|
||||
PathCondition::Socket => false,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// file that was distributed with this source code.
|
||||
//
|
||||
|
||||
// spell-checker:ignore (words) pseudofloat
|
||||
// spell-checker:ignore (words) egid euid pseudofloat
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
|
@ -476,6 +476,52 @@ fn test_nonexistent_file_is_not_symlink() {
|
|||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_file_owned_by_euid() {
|
||||
new_ucmd!().args(&["-O", "regular_file"]).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_nonexistent_file_not_owned_by_euid() {
|
||||
new_ucmd!()
|
||||
.args(&["-O", "nonexistent_file"])
|
||||
.run()
|
||||
.status_code(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(not(windows), not(target_os = "freebsd")))]
|
||||
fn test_file_not_owned_by_euid() {
|
||||
new_ucmd!()
|
||||
.args(&["-f", "/bin/sh", "-a", "!", "-O", "/bin/sh"])
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_file_owned_by_egid() {
|
||||
new_ucmd!().args(&["-G", "regular_file"]).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_nonexistent_file_not_owned_by_egid() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "nonexistent_file"])
|
||||
.run()
|
||||
.status_code(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(not(windows), not(target_os = "freebsd")))]
|
||||
fn test_file_not_owned_by_egid() {
|
||||
new_ucmd!()
|
||||
.args(&["-f", "/bin/sh", "-a", "!", "-G", "/bin/sh"])
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_op_precedence_and_or_1() {
|
||||
new_ucmd!().args(&[" ", "-o", "", "-a", ""]).succeeds();
|
||||
|
|
Loading…
Reference in a new issue