Порівняти коміти
3 Коміти
1c03d47dac
...
659f7bd320
Автор | SHA1 | Дата | |
---|---|---|---|
659f7bd320 | |||
bb0b2886e9 | |||
dce3d063f7 |
69
src/main.rs
69
src/main.rs
@ -5,6 +5,7 @@ use std::fs::File;
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::fs;
|
||||
|
||||
extern crate libc;
|
||||
use libc::passwd;
|
||||
@ -47,7 +48,9 @@ struct Passwd {
|
||||
|
||||
fn initgroups(user: &str, group: libc::gid_t) -> std::io::Result<()> {
|
||||
let userarg = CString::new(user);
|
||||
return errnowrapper(unsafe { libc::initgroups(userarg.unwrap().as_ptr(), group) });
|
||||
return errnowrapper(unsafe {
|
||||
libc::initgroups(userarg.unwrap().as_ptr(), group)
|
||||
});
|
||||
}
|
||||
|
||||
fn errnowrapper(ret: libc::c_int) -> std::io::Result<()> {
|
||||
@ -75,12 +78,22 @@ fn getpwnam(username: &str) -> std::io::Result<Passwd> {
|
||||
fn getstr(str: *mut libc::c_char) -> String {
|
||||
unsafe { CStr::from_ptr(str).to_string_lossy().into_owned() }
|
||||
}
|
||||
let username_c = CString::new(username).unwrap();
|
||||
let username_ptr = username_c.as_ptr();
|
||||
let pwnamresult: *mut libc::passwd = unsafe { libc::getpwnam(username_ptr) };
|
||||
if pwnamresult.is_null() {
|
||||
return Err(Error::new(Error::last_os_error().kind(),"Lookup of user failed: ".to_owned() + &Error::last_os_error().to_string()));
|
||||
let username_c = CString::new(username).unwrap();
|
||||
let username_ptr = username_c.as_ptr();
|
||||
let pwnamresult: *mut libc::passwd = unsafe { libc::getpwnam(username_ptr) };
|
||||
if pwnamresult.is_null() {
|
||||
if Error::last_os_error().raw_os_error().unwrap() == 0 {
|
||||
return Err(Error::new(
|
||||
ErrorKind::NotFound,
|
||||
format!("The username '{}' was not found", username),
|
||||
));
|
||||
}
|
||||
return Err(Error::new(
|
||||
Error::last_os_error().kind(),
|
||||
"Lookup of user failed: ".to_owned() +
|
||||
&Error::last_os_error().to_string(),
|
||||
));
|
||||
}
|
||||
unsafe {
|
||||
Ok(Passwd {
|
||||
pw_name: getstr((*pwnamresult).pw_name),
|
||||
@ -172,8 +185,7 @@ fn clearenv() -> std::io::Result<()> {
|
||||
}
|
||||
//TODO: AsRef for envs?
|
||||
fn setup_environment(passwd: &Passwd, envs: &[String]) -> std::io::Result<()> {
|
||||
let saved_envs: Vec<String> = envs
|
||||
.iter()
|
||||
let saved_envs: Vec<String> = envs.iter()
|
||||
.map(|s| std::env::var(s).expect("No such var"))
|
||||
.collect();
|
||||
clearenv()?;
|
||||
@ -201,7 +213,9 @@ fn become_user(passwd: &Passwd) -> std::io::Result<()> {
|
||||
fn drop_privs(entry: &Entry) -> std::io::Result<()> {
|
||||
if entry.no_new_privs {
|
||||
errnowrapper(unsafe { libc::prctl(libc::PR_SET_DUMPABLE, 0) })?;
|
||||
errnowrapper(unsafe { libc::prctl(libc::PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) })?;
|
||||
errnowrapper(unsafe {
|
||||
libc::prctl(libc::PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -233,9 +247,16 @@ fn create_execv_args(entry: &Entry, cmdargs: &Vec<String>) -> Vec<*const libc::c
|
||||
return args;
|
||||
}
|
||||
fn exec(entryname: &str, cmdargs: &Vec<String>) -> std::io::Result<()> {
|
||||
let mut filepath: String = String::from("/etc/raou.d/");
|
||||
filepath = filepath + entryname;
|
||||
let basedir: String = String::from("/etc/raou.d/");
|
||||
let filepath: String = basedir.to_string() + entryname;
|
||||
|
||||
let realpath = fs::canonicalize(&filepath)?;
|
||||
if !realpath.starts_with(basedir) {
|
||||
return Err(std::io::Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"Specified entry is outside base directory",
|
||||
));
|
||||
}
|
||||
if !std::path::Path::new(&filepath).exists() {
|
||||
return Err(std::io::Error::new(
|
||||
ErrorKind::NotFound,
|
||||
@ -255,12 +276,13 @@ fn exec(entryname: &str, cmdargs: &Vec<String>) -> std::io::Result<()> {
|
||||
"Failed to switch user: ".to_owned() + &e.to_string(),
|
||||
));
|
||||
})?;
|
||||
setup_environment(&destuserpasswd, &entry.inherit_envs).or_else(|e| {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"Environment setup failure: ".to_owned() + &e.to_string(),
|
||||
));
|
||||
})?;
|
||||
setup_environment(&destuserpasswd, &entry.inherit_envs)
|
||||
.or_else(|e| {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"Environment setup failure: ".to_owned() + &e.to_string(),
|
||||
));
|
||||
})?;
|
||||
|
||||
drop_privs(&entry).or_else(|e| {
|
||||
return Err(Error::new(
|
||||
@ -270,12 +292,13 @@ fn exec(entryname: &str, cmdargs: &Vec<String>) -> std::io::Result<()> {
|
||||
})?;
|
||||
|
||||
unsafe {
|
||||
errnowrapper(libc::execv(to_cstring(entry.cmd), args.as_ptr())).or_else(|e| {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"execv failed: ".to_owned() + &e.to_string(),
|
||||
));
|
||||
})?;
|
||||
errnowrapper(libc::execv(to_cstring(entry.cmd), args.as_ptr()))
|
||||
.or_else(|e| {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"execv failed: ".to_owned() + &e.to_string(),
|
||||
));
|
||||
})?;
|
||||
}
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
Завантаження…
Посилання в новій задачі
Block a user