Add pw
module for user and group information;
which - check if our user can exec found file
This commit is contained in:
parent
cbe8b09c64
commit
d77387f963
@ -246,20 +246,7 @@ impl BootstrapCmd for dyn Cmd {
|
||||
let mut path = PathBuf::from(prefix);
|
||||
let binpath = self.path();
|
||||
match binpath {
|
||||
Some(crate::Path::Bin) => path.push("bin"),
|
||||
Some(crate::Path::Sbin) => path.push("sbin"),
|
||||
Some(crate::Path::UsrBin) => {
|
||||
if usr {
|
||||
path.push("usr");
|
||||
}
|
||||
path.push("bin");
|
||||
}
|
||||
Some(crate::Path::UsrSbin) => {
|
||||
if usr {
|
||||
path.push("usr");
|
||||
}
|
||||
path.push("sbin");
|
||||
}
|
||||
Some(p) => path.push(p.to_str(usr)),
|
||||
None => return None,
|
||||
}
|
||||
path.push(self.name());
|
||||
|
@ -62,7 +62,23 @@ fn which(command: &str, path: &[&str]) -> Option<String> {
|
||||
if let Ok(exe) = File::open(&file) {
|
||||
if let Ok(meta) = exe.metadata() {
|
||||
let mode = meta.mode();
|
||||
if mode & 0o111 != 0 {
|
||||
let myuid = unsafe {
|
||||
libc::geteuid()
|
||||
};
|
||||
let mygroups = crate::pw::get_gids();
|
||||
// we own the file and it has u+x
|
||||
if myuid == meta.uid() && mode & 0o100 != 0 {
|
||||
return Some(format!("{}", file.display()));
|
||||
// file has ug+x
|
||||
} else if mode & 0o110 != 0 {
|
||||
if let Ok(groups) = mygroups {
|
||||
// one of our groups owns the file
|
||||
if groups.contains(&meta.gid()) {
|
||||
return Some(format!("{}", file.display()));
|
||||
}
|
||||
}
|
||||
// the file has uga+x
|
||||
} else if mode & 0o111 != 0 {
|
||||
return Some(format!("{}", file.display()));
|
||||
}
|
||||
}
|
||||
|
15
src/lib.rs
15
src/lib.rs
@ -4,6 +4,8 @@ use std::{env, error::Error, path::PathBuf, process, string::ToString};
|
||||
pub mod cmd;
|
||||
pub use cmd::Cmd;
|
||||
pub mod math;
|
||||
/// User and group related functionality
|
||||
pub mod pw;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Path {
|
||||
@ -13,6 +15,19 @@ pub enum Path {
|
||||
UsrSbin,
|
||||
}
|
||||
|
||||
impl Path {
|
||||
pub fn to_str(&self, usr: bool) -> &'static str {
|
||||
match self {
|
||||
Self::Bin => "bin",
|
||||
Self::UsrBin if usr => "usr/bin",
|
||||
Self::UsrBin => "bin",
|
||||
Self::Sbin => "sbin",
|
||||
Self::UsrSbin if usr => "usr/sbin",
|
||||
Self::UsrSbin => "sbin",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn progname() -> Option<String> {
|
||||
env::args()
|
||||
|
70
src/pw/mod.rs
Normal file
70
src/pw/mod.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use std::{error::Error, ffi::CStr, num};
|
||||
|
||||
pub fn get_username<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||
let user = unsafe {
|
||||
let uid = libc::getuid();
|
||||
let pw = libc::getpwuid(uid);
|
||||
let name = (*pw).pw_name;
|
||||
CStr::from_ptr(name)
|
||||
};
|
||||
user.to_str()
|
||||
}
|
||||
|
||||
pub fn get_eusername<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||
let user = unsafe {
|
||||
let uid = libc::geteuid();
|
||||
let pw = libc::getpwuid(uid);
|
||||
let name = (*pw).pw_name;
|
||||
CStr::from_ptr(name)
|
||||
};
|
||||
user.to_str()
|
||||
}
|
||||
|
||||
pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||
let group = unsafe {
|
||||
let gid = libc::getgid();
|
||||
let gr = libc::getgrgid(gid);
|
||||
let name = (*gr).gr_name;
|
||||
CStr::from_ptr(name)
|
||||
};
|
||||
group.to_str()
|
||||
}
|
||||
|
||||
pub fn get_egrpname<'a>() -> Result<&'a str, std::str::Utf8Error> {
|
||||
let group = unsafe {
|
||||
let gid = libc::getegid();
|
||||
let gr = libc::getgrgid(gid);
|
||||
let name = (*gr).gr_name;
|
||||
CStr::from_ptr(name)
|
||||
};
|
||||
group.to_str()
|
||||
}
|
||||
|
||||
pub fn get_gids() -> Result<Vec<u32>, num::TryFromIntError> {
|
||||
let mut buf: Vec<libc::gid_t>;
|
||||
unsafe {
|
||||
buf = vec![0; 1];
|
||||
let num = libc::getgroups(0, buf.as_mut_ptr());
|
||||
buf = vec![0; num.try_into()?];
|
||||
let _num = libc::getgroups(num, buf.as_mut_ptr());
|
||||
buf.push(libc::getegid());
|
||||
};
|
||||
buf.dedup();
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
pub fn get_group_names() -> Result<Vec<String>, Box<dyn Error>> {
|
||||
let gids = get_gids()?;
|
||||
let mut names = vec![];
|
||||
for id in gids {
|
||||
let name = unsafe {
|
||||
let gr = libc::getgrgid(id);
|
||||
let name = (*gr).gr_name;
|
||||
// if we don't take ownership here the OS can (and will)
|
||||
// reuse the memory
|
||||
CStr::from_ptr(name).to_str()?.to_string()
|
||||
};
|
||||
names.push(name);
|
||||
}
|
||||
Ok(names)
|
||||
}
|
Loading…
Reference in New Issue
Block a user