1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
use std::io::{stdin, stdout, Write};
use std::os::unix::process::CommandExt;
use std::process::Command;
use pam_auth::Authenticator;
use users::get_user_by_name;
use rpassword::read_password_from_tty;
// A simple program that requests a login and a password and then spawns /bin/bash as the
// user who logged in.
//
// Note that this proto-"sudo" is very insecure and should not be used in any production setup,
// it is just an example to show how the PAM api works.
fn main() {
// First, prompt the user for a login and a password
print!("login: ");
stdout().flush().unwrap();
let mut login = String::new();
stdin().read_line(&mut login).unwrap();
login.pop(); // remove the trailing '\n'
let password = read_password_from_tty(Some("password: ")).unwrap();
// Now, setup the authenticator, we require the basic "system-auth" service
let mut authenticator = Authenticator::with_password("system-auth").expect("Failed to init PAM client!");
authenticator.get_handler().set_credentials(login.clone(), password);
authenticator.authenticate().expect("Authentication failed!");
authenticator.open_session().expect("Failed to open a session!");
// we now try to spawn `/bin/bash` as this user
// note that setting the uid/gid is likely to fail if this program is not already run as the
// proper user or as root
let user = get_user_by_name(&login).unwrap();
let error = Command::new("/bin/bash").uid(user.uid()).gid(user.primary_group_id()).exec();
// if exec() returned, this means there was an error:
println!("Error spawning bash: {:?}", error);
}
|