Commit 02759b4a authored by Jeremy Soller's avatar Jeremy Soller

Fix bug causing ctrl-d to log in any user with su

Document su's logic
Return error code of shell from su
parent 5765da1e
......@@ -67,22 +67,34 @@ pub fn main() {
let user = get_user_by_name(&target_user).unwrap_or_exit(1);
if uid > 0 || user.hash != "" {
// If we are root and the new user account has no password
if uid == 0 && user.hash == "" {
stdout.write(b"\n").try(&mut stderr);
stdout.flush().try(&mut stderr);
// Spawn a shell as the new user
exit(spawn_shell(user).code().unwrap_or(1));
} else {
// Ask for the new user account's password
stdout.write_all(b"password: ").try(&mut stderr);
stdout.flush().try(&mut stderr);
if let Some(password) = stdin.read_passwd(&mut stdout).try(&mut stderr) {
// Read the password, reading an empty string if CTRL-d is specified
let password = stdin.read_passwd(&mut stdout).try(&mut stderr).unwrap_or(String::new());
// Write a newline
stdout.write(b"\n").try(&mut stderr);
stdout.flush().try(&mut stderr);
if user.verify_passwd(&password) {
spawn_shell(user);
exit(0);
} else {
stdout.write(b"su: authentication failed\n").try(&mut stderr);
stdout.flush().try(&mut stderr);
exit(1);
}
// If the password is correct
if user.verify_passwd(&password) {
// Spawn a shell as the new user
exit(spawn_shell(user).code().unwrap_or(1));
}
}
spawn_shell(user);
// All other conditions will return an error
stderr.write(b"su: authentication failed\n").try(&mut stderr);
stderr.flush().try(&mut stderr);
exit(1);
}
......@@ -18,7 +18,7 @@
extern crate redox_users;
use std::process::Command;
use std::process::{Command, ExitStatus};
use std::os::unix::process::CommandExt;
use redox_users::User;
......@@ -49,7 +49,7 @@ use redox_users::User;
/// This function can panic under two scenarios. The first, when an error occurs while
/// spawning the new process containig the shell and the second, when after a succesful
/// spawn, an error happens while trying to wait for the newly created process.
pub fn spawn_shell(user: User) {
pub fn spawn_shell(user: User) -> ExitStatus {
let mut command = Command::new(&user.shell);
command.uid(user.uid);
......@@ -65,7 +65,7 @@ pub fn spawn_shell(user: User) {
match command.spawn() {
Ok(mut child) => match child.wait() {
Ok(_status) => (),
Ok(status) => status,
Err(err) => panic!("userutils: failed to wait for '{}': {}", user.shell, err)
},
Err(err) => panic!("userutils: failed to execute '{}': {}", user.shell, err)
......
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