File: spawn_bash.rs

package info (click to toggle)
rust-pam 0.7.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 164 kB
  • sloc: makefile: 4
file content (37 lines) | stat: -rw-r--r-- 1,628 bytes parent folder | download | duplicates (3)
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);
}