Javier Novoa C.
Javier Novoa C.

Reputation: 11837

is there a way to script in Python to change user passwords in Linux? if so, how?

I'm trying to write some scripts in Python and stumbled upon the need of making something to update the password of a given user in a Linux system...

UPDATE: the objective is to achieve the script to update the password automatically from a given data/algorithm. The important thing is to have no human intervention...

is there a way to achieve that? or should I search through other means?

Thanks!

Upvotes: 6

Views: 11402

Answers (4)

Juliusz Gonera
Juliusz Gonera

Reputation: 4958

You can use openssl and usermod:

#!/usr/bin/env python
import subprocess

login = 'username'
password = 'somepassword'

# OpenSSL doesn't support stronger hash functions, mkpasswd is preferred
#p = subprocess.Popen(('openssl', 'passwd', '-1', password), stdout=subprocess.PIPE)
p = subprocess.Popen(('mkpasswd', '-m', 'sha-512', password), stdout=subprocess.PIPE)
shadow_password = p.communicate()[0].strip()

if p.returncode != 0:
    print 'Error creating hash for ' + login

r = subprocess.call(('usermod', '-p', shadow_password, login))

if r != 0:
    print 'Error changing password for ' + login

Upvotes: 8

zbyszek
zbyszek

Reputation: 5305

I just needed to do this again today, and below is my solution. It is fully automatic, and also uses standard system passwd binary, so system policies are respected.

#!/usr/bin/python3    

username = 'joe'

# generate passphrase
pw_length = 6
phrase = subprocess.check_output(['pwgen', str(pw_length), '1'])
phrase = phrase.decode('utf-8').strip()

dev_null = open('/dev/null', 'w')
passwd = subprocess.Popen(['sudo', 'passwd', user], stdin=subprocess.PIPE,
                          stdout=dev_null.fileno(),
                          stderr=subprocess.STDOUT)
passwd.communicate( ((phrase + '\n')*2).encode('utf-8') )
if passwd.returncode != 0:
    raise OSError('password setting failed')

(This generated the password too. Skip the first part if not useful.)

Upvotes: 2

Filipe Pina
Filipe Pina

Reputation: 2239

You can use crypt to do the password hashing instead of using openssl passwd (where you are passing the password in plaintext in the command line)

Adapting Juliusz script:

#!/usr/bin/env python
import subprocess,crypt,random

login = 'username'
password = 'somepassword'

ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
salt = ''.join(random.choice(ALPHABET) for i in range(8))

shadow_password = crypt.crypt(password,'$1$'+salt+'$')

r = subprocess.call(('usermod', '-p', shadow_password, login))

if r != 0:
    print 'Error changing password for ' + login

This way, the password is only passed in the command line already hashed (to usermod).
I've tested this with ubuntu+python2.6.6+pycrypto2.5.

Upvotes: 5

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798516

Use subprocess to invoke passwd.

Upvotes: 0

Related Questions