6

I'm trying to automate the setup of SFTP access. This script is running as a user with sudo permissions and no password.

I can create a user like so:

>>> import subprocess
>>> process = subprocess.Popen(['sudo', 'useradd', 'test'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> process.communicate()
('', '')

Next I need to set the user's password, but I can't figure out how. Here's what I've tried.

>>> process = subprocess.Popen(['sudo', 'chpasswd'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> process.communicate('test:password')

In my python program it has no effect, in the interactive interpreter it locks up after the first line.

What's the best way to do this?

I'm running python 2.6 on Ubuntu lucid.

0

5 Answers 5

8

Try below code which will do as you required automation

from subprocess import Popen, PIPE, check_call  
check_call(['useradd', 'test'])   
proc=Popen(['passwd', 'test'],stdin=PIPE,stdout=PIPE,stderr=PIPE)  
proc.stdin.write('password\n')  
proc.stdin.write('password')  
proc.stdin.flush()  
stdout,stderr = proc.communicate()  
print stdout  
print stderr

print statements are optional.

Sign up to request clarification or add additional context in comments.

Comments

6

The documentation for communicate says that you'll need to add stdin=PIPE if you're sending data to standard input via the communicate parameter:

http://docs.python.org/release/2.6/library/subprocess.html#subprocess.Popen.communicate

I appreciate this is just skeleton code, but here are another couple of other small comments, in case they are of use:

  • If you're not interested in the output of the useradd command other than whether it failed or not, you might be better off using subprocess.check_call which will raise an exception if the command returns non-zero.
  • In the second case, you should check whether process.returncode is 0 after your call to communicate('test:password')

1 Comment

Thanks for the comments. The real code is in fact more thorough, but appreciated non the less.
2

On Ubuntu, use usermod

class SomeClass
    def userPasswd(self, login, password):
        encPass = crypt.crypt(password)
        command = "usermod -p '{0:s}' {1:s}".format(encPass, login)
        result = os.system(command)
        if result != 0:
            logging.error(command)
        return result

1 Comment

'crypt' is deprecated and slated for removal in Python 3.13. Do not use this method.
1

You forgot this:

stdin=subprocess.PIPE

To send data to the process, you need a stdin.

So the full statement is:

process = subprocess.Popen(['sudo', 'chpasswd'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

and then call communicate('password').

Comments

1

I guess the issue is that you forgot the -S option for sudo.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.