Implemented useradd; groupadd fix

This commit is contained in:
MggMuggins
2017-11-28 21:39:20 -06:00
parent 464b5c4aa5
commit d9d3635916
7 changed files with 184 additions and 12 deletions
Generated
+3 -1
View File
@@ -104,6 +104,7 @@ dependencies = [
[[package]]
name = "redox_users"
version = "0.1.0"
source = "git+https://github.com/redox-os/users.git#50f4022e6c713a131bbbfde360cb0f369e96c672"
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)",
@@ -141,7 +142,7 @@ dependencies = [
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_users 0.1.0",
"redox_users 0.1.0 (git+https://github.com/redox-os/users.git)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -161,6 +162,7 @@ dependencies = [
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum redox_users 0.1.0 (git+https://github.com/redox-os/users.git)" = "<none>"
"checksum scoped_threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4ea459fe3ceff01e09534847c49860891d3ff1c12b4eb7731b67f2778fb60190"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
+4
View File
@@ -30,6 +30,10 @@ path = "src/bin/su.rs"
name = "sudo"
path = "src/bin/sudo.rs"
[[bin]]
name = "useradd"
path = "src/bin/useradd.rs"
[[bin]]
name = "whoami"
path = "src/bin/whoami.rs"
+5 -8
View File
@@ -1,4 +1,4 @@
#[deny(dead_code)]
#![deny(warnings)]
extern crate arg_parser;
extern crate extra;
@@ -26,7 +26,6 @@ DESCRIPTION
passed on the command line and system defaults.
OPTIONS
-f, --force
Simply forces the exit status of the program to 0
even if the group already exists. A message is still
@@ -73,14 +72,12 @@ fn main() {
match add_group(groupname, gid, &[""]) {
Ok(_) => {},
Err(ref err) if err.kind() == io::ErrorKind::AlreadyExists && parser.found("force") => {
exit(0);
},
Err(err) => {
eprintln!("groupadd: {}: group {}", err, groupname);
let msg = format!("{}", err);
if parser.found("force") && msg == "user already exists" {
exit(0);
} else {
exit(1);
}
exit(1);
}
}
}
-1
View File
@@ -114,4 +114,3 @@ pub fn main() {
}
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
#![deny(dead_code)]
#![deny(warnings)]
extern crate arg_parser;
extern crate extra;
+1 -1
View File
@@ -150,4 +150,4 @@ fn run_command_as_root(cmd: &str, args: &Vec<String>) {
exit(1);
}
}
}
}
+170
View File
@@ -0,0 +1,170 @@
#![deny(warnings)]
extern crate arg_parser;
extern crate redox_users;
use std::{env, io};
use std::io::Write;
use std::fs::DirBuilder;
use std::os::unix::fs::DirBuilderExt;
use std::process::exit;
use arg_parser::ArgParser;
use redox_users::{add_group, add_user, get_unique_group_id, get_unique_user_id};
const MAN_PAGE: &'static str = /* @MANSTART{useradd} */ r#"
NAME
useradd - add a new user
SYNOPSYS
useradd [ options ] LOGIN
useradd [ -h | --help ]
DESCRIPTION
The useradd utility creates a new user based on
system defaults and values passed on the command line.
Useradd creates a new group for the user by default and
can also be instructed to create the user's home directory.
OPTIONS
-h, --help
Display this help and exit.
-c, --comment
Any text string, usually used as the user's full name.
-d, --home-dir HOME_DIR
The new user will be created with HOME_DIR as their home
directory. The default value is LOGIN prepended with "/home".
This flag DOES NOT create the home directory. See --create-home.
-m, --create-home
Creates the user's home directory if it does not already exist.
This option is not enabled by default. This option must be specified
for a home directory to be created.
-N, --no-user-group
Do not attempt to create the user's user group.
-s, --shell SHELL
The path to the user's default login shell. If left blank, the
default shell is set as /bin/ion
AUTHORS
Written by Wesley Hershberger.
"#; /* @MANEND */
const DEFAULT_SHELL: &'static str = "/bin/ion";
const DEFAULT_HOME: &'static str = "/home";
const DEFAULT_MODE: u32 = 0o700;
fn main() {
let mut stdout = io::stdout();
let mut parser = ArgParser::new(1)
.add_flag(&["h", "help"])
.add_opt("c", "comment")
.add_opt("d", "home-dir")
.add_flag(&["m", "create-home"])
.add_flag(&["N", "no-user-group"])
.add_opt("s", "shell");
parser.parse(env::args());
if parser.found("help") {
stdout.write_all(MAN_PAGE.as_bytes()).unwrap();
stdout.flush().unwrap();
exit(0);
}
let login = if parser.args.is_empty() {
eprintln!("useradd: no login specified");
exit(1);
} else {
&parser.args[0]
};
let uid = match get_unique_user_id() {
Some(id) => id,
None => {
eprintln!("useradd: no available uid");
exit(1);
}
};
let gid = match get_unique_group_id() {
Some(id) => id,
None => {
eprintln!("useradd: no available gid");
exit(1);
}
};
let username = if parser.found("comment") {
match parser.get_opt("comment") {
Some(user) => user,
None => {
eprintln!("useradd: invalid argument: -c");
exit(1);
}
}
} else {
login.to_owned()
};
let userhome = if parser.found("home-dir") {
match parser.get_opt("home-dir") {
Some(dir) => dir,
None => {
eprintln!("useradd: invalid argument: -d");
exit(1);
}
}
} else {
format!("{}/{}", DEFAULT_HOME, login)
};
let shell = if parser.found("shell") {
match parser.get_opt("shell") {
Some(sh) => sh,
None => {
eprintln!("useradd: invalid argument: -s");
exit(1);
}
}
} else {
DEFAULT_SHELL.to_string()
};
if !parser.found("no-user-group") {
match add_group(login, gid, &[login]) {
Ok(_) => {},
Err(err) => {
eprintln!("useradd: error creating group {}: {}", login, err);
exit(1);
}
}
}
match add_user(login, uid, gid, username.as_str(), userhome.as_str(), shell.as_str()) {
Ok(_) => {},
Err(err) => {
eprintln!("useradd: {}: {}", err, login);
exit(1);
}
}
if parser.found("create-home") {
let mut builder = DirBuilder::new();
builder.mode(DEFAULT_MODE);
match builder.create(&userhome) {
Ok(_) => {},
Err(ref err) if err.kind() == io::ErrorKind::AlreadyExists => {},
Err(err) => {
eprintln!("useradd: failed to create home dir: {}", err);
exit(1);
}
};
}
}