views:

4451

answers:

6

I'm writing a shell script to automatically add a new user and update their password. I don't know how to get passwd to read from the shell script instead of interactively prompting me for the new password. My code is below.

adduser $1
passwd $1
$2
$2
+7  A: 

from "man 1 passwd":

   --stdin
          This option is used to indicate that passwd should read the new
          password from standard input, which can be a pipe.

So in your case

adduser "$1"
echo "$2" | passwd "$1" --stdin

[Update] a few issues were brought up in the comments:

Your passwd command may not have a --stdin option: use the chpasswd utility instead, as suggested by ashawley.

If you use a shell other than bash, "echo" might not be a builtin command, and the shell will call /bin/echo. This is insecure because the password will show up in the process table and can be seen with tools like ps.

In this case, you should use another scripting language. Here is an example in Perl:

#!/usr/bin/perl -w
open my $pipe, '|chpasswd' or die "can't open pipe: $!";
print {$pipe} "$username:$password";
close $pipe
8jean
You should quote your parameter expansions. Moreover; this is in no way shape or form portable or even recommended in the slightest. See my reply for some more information on the topic.
lhunath
Please don't use echo ... | password! The password will then be visible to any other users who run ps. And the more places you pass the password through (different programs, files, pipes, etc), the higher the chances are that it will leak out somewhere.
Brian Campbell
@lhunath: you are right about the quoting, I'll fix that.@Brian: "echo" is a bash builtin, it will *not* show up in 'ps' output (at least in bash, not sure about sh)
8jean
A: 

First: Are you certain your version of adduser or useradd doesn't have an option to pass it a passwd?

Second: shell scripts don't work like that. You could (again depending on your system) have passwd read from stdin and echo the 2nd argument to it.

simon
A: 

Have you looked at the -p option of adduser (which AFAIK is just another name for useradd)? You may also want to look at the -P option of luseradd which takes a plaintext password, but I don't know if luseradd is a standard command (it may be part of SE Linux or perhaps just an oddity of Fedora).

rmeador
A: 

Tested this on a CentOS VMWare image that I keep around for this sort of thing. Note that you probably want to avoid putting passwords as command-line arguments, because anybody on the entire machine can read them out of 'ps -ef'.

That said, this will work:

user="$1"
password="$2"
adduser $user
echo $password | passwd --stdin $user
Don Werve
+5  A: 

Read the wise words from:

I quote:

Nothing you can do in bash can possibly work. passwd(1) does not read from standard input. This is intentional. It is for your protection. Passwords were never intended to be put into programs, or generated by programs. They were intended to be entered only by the fingers of an actual human being, with a functional brain, and never, ever written down anywhere.

Nonetheless, we get hordes of users asking how they can circumvent 35 years of Unix security.

It goes on to explain how you can set your shadow(5) password properly, and shows you the GNU-I-only-care-about-security-if-it-doesn't-make-me-think-too-much-way of abusing passwd(1).

Lastly, if you ARE going to use the silly GNU passwd(1) extension --stdin, do not pass the password putting it on the command line.

echo $mypassword | passwd --stdin # Eternal Sin.
echo "$mypassword" | passwd --stdin # Eternal Sin, but at least you remembered to quote your PE.
passwd --stdin <<< "$mypassword" # A little less insecure, still pretty insecure, though.
passwd --stdin < "passwordfile" # With a password file that was created with a secure `umask(1)`, a little bit secure.

The last is the best you can do with GNU passwd. Though I still wouldn't recommend it.

Putting the password on the command line means anyone with even the remotest hint of access to the box can be monitoring ps or such and steal the password. Even if you think your box is safe; it's something you should really get in the habit of avoiding at all cost (yes, even the cost of doing a bit more trouble getting the job done).

lhunath
A: 

other way is to

(sleep 3; echo "$password";sleep 3;echo "$password" )| passwd "$user" > /dev/null

but its a little tricky ;)

llazzaro