Commit 1d6b67cd authored by SamwiseFilmore's avatar SamwiseFilmore

Implement Unimplemented; Bugs

Fix a CLI bug with groupadd

Implement everything that involves removing user from groups, mostly
in userdel and usermod.
parent 235be05c
......@@ -182,7 +182,7 @@ dependencies = [
[[package]]
name = "redox_users"
version = "0.1.0"
source = "git+https://github.com/redox-os/users.git#0c56faee77dd86d0b48460b6e588e2c96a8a0d99"
source = "git+https://github.com/redox-os/users.git#820ab8f1ea19816175ac400ddc1d1be6c0b8d992"
dependencies = [
"argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"extra 0.1.0 (git+https://github.com/redox-os/libextra.git)",
......
......@@ -47,7 +47,7 @@ fn main() {
(about: "Add groups based on the system's redox_users backend")
(@arg GROUP: +required "Add group GROUP")
(@arg FORCE: -f --force "Force the status of the program to be 0 even if the group exists")
(@arg GID: -g --gid "Group id. Positive integer and must not be in use")
(@arg GID: -g --gid +takes_value "Group id. Positive integer and must not be in use")
).get_matches();
let mut sys_groups = AllGroups::new().unwrap_or_exit(1);
......
......@@ -8,7 +8,7 @@ extern crate redox_users;
use std::process::exit;
use extra::option::OptionalExt;
use redox_users::AllGroups;
use redox_users::{AllGroups, AllUsers};
const _MAN_PAGE: &'static str = /* @MANSTART{groupmod} */ r#"
NAME
......@@ -33,7 +33,7 @@ OPTIONS
Files with GROUP's old gid will not be updated.
User's who use the old gid as their primary gid will
also not be updated. This is a TODO and will change.
be updated.
-n, --name NAME
The name of the group will be set to NAME
......@@ -62,9 +62,16 @@ fn main() {
exit(1);
});
//TODO: Update user's primary GID, if gid is used as such
if let Some(gid) = args.value_of("GID") {
let gid = gid.parse::<usize>().unwrap_or_exit(1);
// Update users
let mut sys_users = AllUsers::new().unwrap_or_exit(1);
for user in sys_users.iter_mut() {
if user.gid == group.gid {
user.gid = gid;
}
}
sys_users.save().unwrap_or_exit(1);
group.gid = gid;
}
......
......@@ -181,6 +181,7 @@ fn main() {
.value_of("HOME_DIR")
.unwrap_or_else(|| {
if args.is_present("CREATE_HOME") {
sys_homes.push_str("/");
sys_homes.push_str(&login);
sys_homes.as_str()
} else {
......
......@@ -4,12 +4,14 @@
extern crate clap;
extern crate extra;
extern crate redox_users;
extern crate userutils;
use std::fs::remove_dir;
use std::process::exit;
use extra::option::OptionalExt;
use redox_users::AllUsers;
use redox_users::{AllGroups, AllUsers};
use userutils::AllGroupsExt;
const _MAN_PAGE: &'static str = /* @MANSTART{userdel} */ r#"
NAME
......@@ -21,12 +23,10 @@ SYNOPSYS
DESCRIPTION
userdel removes users from whatever backend is employed by
the system's redox_users.
the system's redox_users. The utility removes the user from
all groups of which they are a member.
It can also be used to manage removal of home directories.
This utility does not remove the user from any groups! This is
a planned feature and will be implemented at some point.
OPTIONS
-h, --help
......@@ -51,18 +51,21 @@ fn main() {
let login = args.value_of("LOGIN").unwrap();
let mut sys_users = AllUsers::new().unwrap_or_exit(1);
let mut sys_groups = AllGroups::new().unwrap_or_exit(1);
{
let user = sys_users.get_by_name(login).unwrap_or_else(|| {
eprintln!("userdel: user does not exist: {}", login);
exit(1);
});
sys_groups.remove_user_from_all_groups(login);
if args.is_present("REMOVE") {
let user = sys_users.get_by_name(login).unwrap_or_else(|| {
eprintln!("userdel: user does not exist: {}", login);
exit(1);
});
remove_dir(&user.home).unwrap_or_exit(1);
}
}
sys_users.remove_by_name(login.to_string()).unwrap_or_exit(1);
sys_groups.save().unwrap_or_exit(1);
sys_users.save().unwrap_or_exit(1);
}
......@@ -11,7 +11,7 @@ use std::process::exit;
use extra::option::OptionalExt;
use redox_users::{AllGroups, AllUsers};
use userutils::create_user_dir;
use userutils::{create_user_dir, AllGroupsExt};
const _MAN_PAGE: &'static str = /* @MANSTART{usermod} */ r#"
NAME
......@@ -123,24 +123,16 @@ fn main() {
let mut sys_users = AllUsers::new().unwrap_or_exit(1);
let mut sys_groups;
//Requires iteration over system groups, which requires additions to redox_users
if let Some(_new_groups) = args.value_of("SET_GROUPS") {
unimplemented!();
if let Some(new_groups) = args.value_of("SET_GROUPS") {
sys_groups = AllGroups::new().unwrap_or_exit(1);
sys_groups.remove_user_from_all_groups(login);
sys_groups.add_user_to_groups(login, new_groups.split(',').collect()).unwrap_or_exit(1);
sys_groups.save().unwrap_or_exit(1);
}
if let Some(new_groups) = args.value_of("APPEND_GROUPS") {
sys_groups = AllGroups::new().unwrap_or_exit(1);
let new_groups = new_groups.split(',');
for groupname in new_groups {
let group = sys_groups.get_mut_by_name(groupname).unwrap_or_else(|| {
eprintln!("usermod: no group found: {}", groupname);
exit(1);
});
group.users.push(login.to_string());
}
sys_groups.add_user_to_groups(login, new_groups.split(',').collect()).unwrap_or_exit(1);
sys_groups.save().unwrap_or_exit(1);
}
......
......@@ -19,15 +19,47 @@
extern crate redox_users;
extern crate syscall;
use std::io::Result;
use std::io::Result as IoResult;
use redox_users::User;
use redox_users::{AllGroups, Result, User, UsersError};
use syscall::call::{open, fchmod, fchown};
use syscall::error::Result as SysResult;
use syscall::flag::{O_CREAT, O_DIRECTORY, O_CLOEXEC};
const DEFAULT_MODE: u16 = 0o700;
// Not the prettiest thing in the world, but some functionality here makes
// some of the utils much less gross
pub trait AllGroupsExt {
fn add_user_to_groups(&mut self, login: &str, groups: Vec<&str>) -> Result<()>;
fn remove_user_from_all_groups(&mut self, login: &str);
}
impl AllGroupsExt for AllGroups {
// new_groups is a comma separated list of groupnames
fn add_user_to_groups(&mut self, login: &str, new_groups: Vec<&str>) -> Result<()> {
for groupname in new_groups {
let group = match self.get_mut_by_name(groupname) {
Some(group) => group,
None => return Err(UsersError::NotFound.into())
};
group.users.push(login.to_string());
}
Ok(())
}
/// Remove a user from all groups of which they are a member
fn remove_user_from_all_groups(&mut self, login: &str) {
for group in self.iter_mut() {
let op_pos = group.users.iter()
.position(|username| username == login );
if let Some(indx) = op_pos {
group.users.remove(indx);
}
}
}
}
/// Spawns a shell for the given `User`.
///
/// This function wraps the shell_cmd function of the User struct
......@@ -43,7 +75,7 @@ const DEFAULT_MODE: u16 = 0o700;
/// let user = sys_users.get_by_name("goyox86");
/// spawn_shell(user).unwrap();
/// ```
pub fn spawn_shell(user: &User) -> Result<i32> {
pub fn spawn_shell(user: &User) -> IoResult<i32> {
let mut command = user.shell_cmd();
let mut child = command.spawn()?;
......@@ -53,7 +85,7 @@ pub fn spawn_shell(user: &User) -> Result<i32> {
}
}
/// Creates a directory with 700 user:user permissions
pub fn create_user_dir<T>(user: &User, dir: T) -> SysResult<()>
where T: AsRef<str> + std::convert::AsRef<[u8]>
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment