mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-31 04:57:45 +00:00
update chroot (not quite working yet)
This commit is contained in:
parent
06f1b38c91
commit
664f7d474e
2 changed files with 35 additions and 34 deletions
|
@ -1,5 +1,5 @@
|
|||
#![crate_name = "chroot"]
|
||||
#![feature(collections, core, old_io, os, old_path, rustc_private, std_misc)]
|
||||
#![feature(collections, rustc_private, path_ext)]
|
||||
|
||||
/*
|
||||
* This file is part of the uutils coreutils package.
|
||||
|
@ -15,11 +15,12 @@ extern crate libc;
|
|||
|
||||
use getopts::{optflag, optopt, getopts, usage};
|
||||
use c_types::{get_pw_from_args, get_group};
|
||||
use libc::funcs::posix88::unistd::{execvp, setuid, setgid};
|
||||
use libc::funcs::posix88::unistd::{execvp, setgid, setuid};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fs::PathExt;
|
||||
use std::io::Write;
|
||||
use std::iter::FromIterator;
|
||||
use std::path::Path;
|
||||
use std::env;
|
||||
|
||||
#[path = "../common/util.rs"] #[macro_use] mod util;
|
||||
#[path = "../common/c_types.rs"] mod c_types;
|
||||
|
@ -59,25 +60,25 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
Ok(m) => m,
|
||||
Err(f) => {
|
||||
show_error!("{}", f);
|
||||
help_menu(program.as_slice(), &options);
|
||||
help_menu(program, &options);
|
||||
return 1
|
||||
}
|
||||
};
|
||||
|
||||
if opts.opt_present("V") { version(); return 0 }
|
||||
if opts.opt_present("h") { help_menu(program.as_slice(), &options); return 0 }
|
||||
if opts.opt_present("h") { help_menu(program, &options); return 0 }
|
||||
|
||||
if opts.free.len() == 0 {
|
||||
println!("Missing operand: NEWROOT");
|
||||
println!("Try `{} --help` for more information.", program.as_slice());
|
||||
println!("Try `{} --help` for more information.", program);
|
||||
return 1
|
||||
}
|
||||
|
||||
let default_shell: &'static str = "/bin/sh";
|
||||
let default_option: &'static str = "-i";
|
||||
let user_shell = env::var("SHELL");
|
||||
let user_shell = std::env::var("SHELL");
|
||||
|
||||
let newroot = Path::new(opts.free[0].as_slice());
|
||||
let newroot = Path::new(&opts.free[0][..]);
|
||||
if !newroot.is_dir() {
|
||||
crash!(1, "cannot change root directory to `{}`: no such directory", newroot.display());
|
||||
}
|
||||
|
@ -85,12 +86,12 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
let command: Vec<&str> = match opts.free.len() {
|
||||
1 => {
|
||||
let shell: &str = match user_shell {
|
||||
None => default_shell,
|
||||
Some(ref s) => s.as_slice()
|
||||
Err(_) => default_shell,
|
||||
Ok(ref s) => &s[..],
|
||||
};
|
||||
vec!(shell, default_option)
|
||||
}
|
||||
_ => opts.free[1..opts.free.len()].iter().map(|x| x.as_slice()).collect()
|
||||
_ => opts.free[1..opts.free.len()].iter().map(|x| &x[..]).collect()
|
||||
};
|
||||
|
||||
set_context(&newroot, &opts);
|
||||
|
@ -110,32 +111,32 @@ fn set_context(root: &Path, options: &getopts::Matches) {
|
|||
let groups_str = options.opt_str("groups").unwrap_or_default();
|
||||
let userspec = match userspec_str {
|
||||
Some(ref u) => {
|
||||
let s: Vec<&str> = u.as_slice().split(':').collect();
|
||||
let s: Vec<&str> = u.split(':').collect();
|
||||
if s.len() != 2 {
|
||||
crash!(1, "invalid userspec: `{}`", u.as_slice())
|
||||
crash!(1, "invalid userspec: `{}`", u)
|
||||
};
|
||||
s
|
||||
}
|
||||
None => Vec::new()
|
||||
};
|
||||
let user = if userspec.is_empty() { user_str.as_slice() } else { userspec[0].as_slice() };
|
||||
let group = if userspec.is_empty() { group_str.as_slice() } else { userspec[1].as_slice() };
|
||||
let user = if userspec.is_empty() { &user_str[..] } else { &userspec[0][..] };
|
||||
let group = if userspec.is_empty() { &group_str[..] } else { &userspec[1][..] };
|
||||
|
||||
enter_chroot(root);
|
||||
|
||||
set_groups_from_str(groups_str.as_slice());
|
||||
set_main_group(group);
|
||||
set_user(user);
|
||||
set_groups_from_str(&groups_str[..]);
|
||||
set_main_group(&group[..]);
|
||||
set_user(&user[..]);
|
||||
}
|
||||
|
||||
fn enter_chroot(root: &Path) {
|
||||
let root_str = root.display();
|
||||
env::set_current_dir(root).unwrap();
|
||||
std::env::set_current_dir(root).unwrap();
|
||||
let err = unsafe {
|
||||
chroot(CString::new(b".").unwrap().as_bytes_with_nul().as_ptr() as *const libc::c_char)
|
||||
chroot(CString::new(".".as_bytes()).unwrap().as_bytes_with_nul().as_ptr() as *const libc::c_char)
|
||||
};
|
||||
if err != 0 {
|
||||
crash!(1, "cannot chroot to {}: {}", root_str, strerror(err).as_slice())
|
||||
crash!(1, "cannot chroot to {}: {}", root_str, strerror(err))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -147,7 +148,7 @@ fn set_main_group(group: &str) {
|
|||
};
|
||||
let err = unsafe { setgid(group_id) };
|
||||
if err != 0 {
|
||||
crash!(1, "cannot set gid to {}: {}", group_id, strerror(err).as_slice())
|
||||
crash!(1, "cannot set gid to {}: {}", group_id, strerror(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +157,7 @@ fn set_main_group(group: &str) {
|
|||
fn set_groups(groups: Vec<libc::gid_t>) -> libc::c_int {
|
||||
unsafe {
|
||||
setgroups(groups.len() as libc::c_int,
|
||||
groups.as_slice().as_ptr())
|
||||
groups.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +165,7 @@ fn set_groups(groups: Vec<libc::gid_t>) -> libc::c_int {
|
|||
fn set_groups(groups: Vec<libc::gid_t>) -> libc::c_int {
|
||||
unsafe {
|
||||
setgroups(groups.len() as libc::size_t,
|
||||
groups.as_slice().as_ptr())
|
||||
groups.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,7 +180,7 @@ fn set_groups_from_str(groups: &str) {
|
|||
);
|
||||
let err = set_groups(groups_vec);
|
||||
if err != 0 {
|
||||
crash!(1, "cannot set groups: {}", strerror(err).as_slice())
|
||||
crash!(1, "cannot set groups: {}", strerror(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ fn set_user(user: &str) {
|
|||
let user_id = get_pw_from_args(&vec!(String::from_str(user))).unwrap().pw_uid;
|
||||
let err = unsafe { setuid(user_id as libc::uid_t) };
|
||||
if err != 0 {
|
||||
crash!(1, "cannot set user to {}: {}", user, strerror(err).as_slice())
|
||||
crash!(1, "cannot set user to {}: {}", user, strerror(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@ use self::libc::int32_t;
|
|||
use self::libc::funcs::posix88::unistd::getgroups;
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::io::{Error, Write};
|
||||
use std::iter::repeat;
|
||||
use std::vec::Vec;
|
||||
|
||||
use std::os;
|
||||
use std::ptr::{null_mut, read};
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
|
@ -49,7 +49,7 @@ pub struct c_passwd {
|
|||
pub pw_shell: *const c_char,
|
||||
}
|
||||
|
||||
impl Copy for c_passwd {}
|
||||
//impl Copy for c_passwd {}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
#[repr(C)]
|
||||
|
@ -72,7 +72,7 @@ pub struct utsname {
|
|||
pub domainame: [c_char; 65]
|
||||
}
|
||||
|
||||
impl Copy for utsname {}
|
||||
//impl Copy for utsname {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct c_group {
|
||||
|
@ -82,7 +82,7 @@ pub struct c_group {
|
|||
pub gr_mem: *const *const c_char, // member list
|
||||
}
|
||||
|
||||
impl Copy for c_group {}
|
||||
//impl Copy for c_group {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct c_tm {
|
||||
|
@ -97,7 +97,7 @@ pub struct c_tm {
|
|||
pub tm_isdst: c_int /* daylight saving time */
|
||||
}
|
||||
|
||||
impl Copy for c_tm {}
|
||||
//impl Copy for c_tm {}
|
||||
|
||||
extern {
|
||||
pub fn getpwuid(uid: uid_t) -> *const c_passwd;
|
||||
|
@ -117,7 +117,7 @@ extern {
|
|||
|
||||
pub fn get_pw_from_args(free: &Vec<String>) -> Option<c_passwd> {
|
||||
if free.len() == 1 {
|
||||
let username = free[0].as_slice();
|
||||
let username = &free[0][..];
|
||||
|
||||
// Passed user as id
|
||||
if username.chars().all(|c| c.is_digit(10)) {
|
||||
|
@ -202,13 +202,13 @@ unsafe fn get_group_list_internal(name: *const c_char, gid: gid_t, groups: *mut
|
|||
pub fn get_groups() -> Result<Vec<gid_t>, i32> {
|
||||
let ngroups = unsafe { getgroups(0, null_mut()) };
|
||||
if ngroups == -1 {
|
||||
return Err(os::errno());
|
||||
return Err(Error::last_os_error().raw_os_error().unwrap())
|
||||
}
|
||||
|
||||
let mut groups : Vec<gid_t>= repeat(0).take(ngroups as usize).collect();
|
||||
let ngroups = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };
|
||||
if ngroups == -1 {
|
||||
Err(os::errno())
|
||||
Err(Error::last_os_error().raw_os_error().unwrap())
|
||||
} else {
|
||||
groups.truncate(ngroups as usize);
|
||||
Ok(groups)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue