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 mut path = PathBuf::from(prefix);
|
||||||
let binpath = self.path();
|
let binpath = self.path();
|
||||||
match binpath {
|
match binpath {
|
||||||
Some(crate::Path::Bin) => path.push("bin"),
|
Some(p) => path.push(p.to_str(usr)),
|
||||||
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");
|
|
||||||
}
|
|
||||||
None => return None,
|
None => return None,
|
||||||
}
|
}
|
||||||
path.push(self.name());
|
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(exe) = File::open(&file) {
|
||||||
if let Ok(meta) = exe.metadata() {
|
if let Ok(meta) = exe.metadata() {
|
||||||
let mode = meta.mode();
|
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()));
|
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 mod cmd;
|
||||||
pub use cmd::Cmd;
|
pub use cmd::Cmd;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
|
/// User and group related functionality
|
||||||
|
pub mod pw;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Path {
|
pub enum Path {
|
||||||
@ -13,6 +15,19 @@ pub enum Path {
|
|||||||
UsrSbin,
|
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]
|
#[must_use]
|
||||||
pub fn progname() -> Option<String> {
|
pub fn progname() -> Option<String> {
|
||||||
env::args()
|
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