3

I'm writing a cli-tool to automate the archlinux installation, that is based on toml config files.

Currently i have this problem: Once the base system is installed and configured, the next topic is creating the users and set their passwords.

Like this:

passwd $user

And this needs to get the password as prompt input

New password:

I'm trying make something like this with rust:

use std::process::Command;

struct User {
    ....
    username: String
    pwd: String
}

...

fn set_pwd(self) -> Result<()> {
    Command::new("chroot")
        .arg("/mnt")
        .arg("passwd")
        .arg(self.username)
        .spawn()
}
...

The problem is that I don't understand, how to pass the password as prompt input to the bash process.

Update:

This question https://stackoverflow.coam/questions/21615188/how-to-send-input-to-a-program-through-stdin-in-rust is something similar, but the implementation is a little different. Because it is a version of the standard library from some time ago.

robni
  • 904
  • 2
  • 6
  • 20
al3x
  • 589
  • 1
  • 4
  • 16
  • the tool initially does not interact with the user, the user write all config including users info in a toml config file... then the tool makes all works with that info – al3x Dec 27 '21 at 10:45
  • 2
    Does this answer your question? [How to send input to a program through stdin in Rust](https://stackoverflow.com/questions/21615188/how-to-send-input-to-a-program-through-stdin-in-rust) – Chayim Friedman Dec 27 '21 at 10:45
  • The Arch Linux `useradd` utiilty appears to support setting the password with the `-p` option. – tripleee Dec 27 '21 at 11:51
  • `useradd` utility works fine for my purpose, but i'm still have the problem how to set root password – al3x Dec 28 '21 at 05:29

1 Answers1

2

finally i based on this question How to send input to a program through stdin in Rust

finally the method look like this...

    fn set_pwd(self) -> Result<()> {
        match Command::new("chroot")
            .stdin(Stdio::piped())
            .arg("/mnt")
            .arg("passwd")
            .arg(self.username)
            .spawn()
        {
            Ok(mut child) => {
                let pwd = format!("{}\n{}", self.pwd, self.pwd);
                child.stdin.as_ref().unwrap().write(pwd.as_bytes()).unwrap();
                child.wait().unwrap();
                Ok(())
            }
            Err(_e) => Err(()),
        }
    }

the difference with the other question, is that instead of using a BuffWriter and the write! macro, the std::process::ChildStdin implements the std::io::Write trait and provides a write method.

Will
  • 19,789
  • 10
  • 43
  • 45
al3x
  • 589
  • 1
  • 4
  • 16