37

I am trying to change a password of a user via script. I cannot use sudo as there is a feature that requires the user to change the password again if another user changes their password.

AIX is running on the system.

unfortunately, chpasswd is unavailable.

I have expected installed, but I am having trouble with that also.

here is what I thought would work

echo "oldpassword\nnewpasswd123\nnewpasswd123" | passwd user

However once run the script I am prompted with please enter user's old password shouldn't they all be echoed in?

I am a beginner with shell scripting and this has been baffled.

Craig S. Anderson
  • 6,966
  • 4
  • 33
  • 46
Grushton94
  • 603
  • 1
  • 7
  • 17

13 Answers13

76

You can try:

echo "USERNAME:NEWPASSWORD" | chpasswd

Mandar Shinde
  • 1,735
  • 4
  • 20
  • 28
  • 4
    For it to work for me I had to change it to: `echo "USERNAME:NEWPASSWORD" | sudo chpasswd` when executing through a non sudo parent script – Mattisdada Nov 12 '15 at 23:36
  • 8
    `chpasswd` to me seems like the right answer. Worked for me setting up a Docker image. I like the following (in bash) to avoid the 'echo' noise: `chpasswd <<<"$USERNAME:$PASSWORD"` – Andrew Wolfe Nov 19 '15 at 15:58
21

Use GNU passwd stdin flag.

From the man page:

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

NOTE: Only for root user.

Example

$ adduser foo 
$ echo "NewPass" |passwd foo --stdin
Changing password for user foo.
passwd: all authentication tokens updated successfully.

Alternatively you can use expect, this simple code will do the trick:

#!/usr/bin/expect
spawn passwd foo
expect "password:"
send "Xcv15kl\r"
expect "Retype new password:"
send "Xcv15kl\r"
interact

Results

$ ./passwd.xp 
spawn passwd foo
Changing password for user foo.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.
Juan Diego Godoy Robles
  • 14,447
  • 2
  • 38
  • 52
7

In addition to the other suggestions, you can also achieve this using a HEREDOC.

In your immediate case, this might look like:

$ /usr/bin/passwd root <<EOF
test
test
EOF
dho
  • 2,310
  • 18
  • 20
Andrew Yasinsky
  • 185
  • 2
  • 4
6

You need echo -e for the newline characters to take affect

you wrote

echo "oldpassword\nnewpasswd123\nnewpasswd123" | passwd user

you should try

echo -e "oldpassword\nnewpasswd123\nnewpasswd123" | passwd user

more than likely, you will not need the oldpassword\n portion of that command, you should just need the two new passwords. Don't forget to use single quotes around exclamation points!

echo -e "new"'!'"passwd123\nnew"'!'"passwd123" | passwd user
Eric Citaire
  • 4,355
  • 1
  • 29
  • 49
  • What if the password contains a "\n"? Such as `my@secret\npasword123` ? – Eduardo Baitello Nov 17 '17 at 14:27
  • Great answer! Worked fine for me on Ubuntu. I had a similar requiremnt, but for first time setting (and not changing) a user's password. The mention of \n character along with -e option to seperate out the reply to the 2 password prompts really helped me. – Binita Bharati Jan 12 '18 at 11:46
3

You can try :

echo -e "newpasswd123\nnnewpasswd123" | passwd user

TehesFR
  • 140
  • 2
  • 15
  • I have the following code in a bash script and it works fine : `useradd -s /bin/bash -g www-data -d /var/www/$vhost $Name; echo -e "$sshPasswd\n$sshPasswd" | passwd $Name; id $Name` – TehesFR Jan 08 '15 at 10:26
3

Just this

passwd <<EOF
oldpassword
newpassword
newpassword
EOF

Actual output from ubuntu machine (sorry no AIX available to me):

user@host:~$ passwd <<EOF
oldpassword
newpassword
newpassword
EOF

Changing password for user.
(current) UNIX password: Enter new UNIX password: Retype new UNIX password: 
passwd: password updated successfully
user@host:~$
2

This is from : Script to change password on linux servers over ssh

The script below will need to be saved as a file (eg ./passwdWrapper) and made executable (chmod u+x ./passwdWrapper)

#!/usr/bin/expect -f
#wrapper to make passwd(1) be non-interactive
#username is passed as 1st arg, passwd as 2nd

set username [lindex $argv 0]
set password [lindex $argv 1]
set serverid [lindex $argv 2]
set newpassword [lindex $argv 3]

spawn ssh $serverid passwd
expect "assword:"
send "$password\r"
expect "UNIX password:"
send "$password\r"
expect "password:"
send "$newpassword\r"
expect "password:"
send "$newpassword\r"
expect eof

Then you can run ./passwdWrapper $user $password $server $newpassword which will actually change the password.

Note: This requires that you install expect on the machine from which you will be running the command. (sudo apt-get install expect) The script works on CentOS 5/6 and Ubuntu 14.04, but if the prompts in passwd change, you may have to tweak the expect lines.

Loren
  • 9,783
  • 4
  • 39
  • 49
1
Here is the script... 

#!/bin/bash
echo "Please enter username:"
read username
echo "Please enter the new password:"
read -s password1
echo "Please repeat the new password:"
read -s password2

# Check both passwords match
if [ $password1 != $password2 ]; then
echo "Passwords do not match"
 exit    
fi

# Does User exist?
id $username &> /dev/null
if [ $? -eq 0 ]; then
echo "$username exists... changing password."
else
echo "$username does not exist - Password could not be updated for $username"; exit 
fi

# Change password
echo -e "$password1\n$password1" | passwd $username

Refer the link below as well...

http://www.putorius.net/2013/04/bash-script-to-change-users-password.html
Ikruzzz
  • 228
  • 1
  • 4
  • 15
  • thanks, but it's just this line `echo -e "$password1\n$password1" | passwd $username` that my system doesn't like – Grushton94 Jan 08 '15 at 10:46
  • Did you provided the new password here? echo -e "$password1\n$password1" | passwd $username – Ikruzzz Jan 08 '15 at 10:59
1

You can try

LINUX

echo password | passwd username --stdin

UNIX

echo username:password | chpasswd -c

If you dont use "-c" argument, you need to change password next time.

1

If you can use ansible, and set the sudo rights in it, then you can easily use this script. If you're wanting to script something like this, it means you need to do it on more than one system. Therefore, you should try to automate that as well.

itengineer
  • 36
  • 2
0

For me this worked in a vagrant VM:

sudo /usr/bin/passwd root <<EOF
12345678
12345678
EOF
-1
printf "oldpassword/nnewpassword/nnewpassword" | passwd user
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
-2
#!/usr/bin/python

import random
import string
import smtplib
import sys
import os
from subprocess import call
import socket

user = sys.argv[1]
receivers = ["%s@domain.com" %user]

'''This will generate a 30 character random password'''
def genrandpwd():
        return  ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits + string.ascii_uppercase + string.punctuation) for _ in range(30))

def change_passwd(user, password):
        p = os.popen("/usr/bin/passwd %s" %user, "w")
        p.write(password)
        p.write("\n")
        p.write(password)
    p.close()

def chage(user):
        agepasswd = call(["/usr/bin/chage", "-d", "0", "%s" %user])

def mailpwd(user, password):
        sender = "admin@%s" %socket.gethostname()
        subj = "!!!IMPORTANT!!!, Unix password changed for user %s" %user
        text = "The password for the %s user has changed, the new password is:\n\n %s \n\n Note: The system will force to change the password upon initial login. Please use the password provided in the mail as your current password and type the password of your choice as the New password" %(user, password)
        message = message = 'Subject: %s\n\n%s' % (subj, text)
        smtpObj = smtplib.SMTP('mailrelay-server.domain.com')
        smtpObj.sendmail(sender, receivers, message)
        smtpObj.quit()

def main():
        newpwd = genrandpwd()
        change_passwd(user, newpwd)
        chage(user)
        mailpwd(user, newpwd)

if __name__ == "__main__":
        main()
pythonmts
  • 9
  • 3
  • This script can be run in a linux machine. You can modify certain things according to your environment like mail relay server or change the limit in the password characters etc. – pythonmts May 12 '17 at 18:11