Consolidate BSD shadow support into single module

Since OpenBSD works the same way as NetBSD, instead of writing a third
module this commit consolidates BSD shadow operations into a single
module.
This commit is contained in:
Erik Johnson 2013-06-26 16:40:38 -05:00
parent 04404e91f4
commit d3bf3f7ded
3 changed files with 82 additions and 142 deletions

View File

@ -0,0 +1,82 @@
'''
Manage the password database on BSD systems
'''
# Import python libs
try:
import pwd
except ImportError:
pass
# Import salt libs
import salt.utils
def __virtual__():
return 'shadow' if 'BSD' in __grains__.get('os', '') else False
def info(name):
'''
Return information for the specified user
CLI Example::
salt '*' shadow.info someuser
'''
try:
data = pwd.getpwnam(name)
ret = {
'name': data.pw_name,
'passwd': data.pw_passwd if data.pw_passwd.strip('*') else ''}
except KeyError:
return {
'name': '',
'passwd': ''}
# Get password aging info on FreeBSD
# TODO: Implement this for NetBSD, OpenBSD
if __salt__['cmd.has_exec']('pw'):
cmd = 'pw user show {0} | cut -f6,7 -d:'.format(name)
try:
change, expire = __salt__['cmd.run_all'](cmd)['stdout'].split(':')
except ValueError:
pass
else:
ret['change'] = change
ret['expire'] = expire
return ret
def set_password(name, password):
'''
Set the password for a named user. The password must be a properly defined
hash. The password hash can be generated with this command:
``python -c "import crypt; print crypt.crypt('password', ciphersalt)"``
``'password'`` is, of course, the password for which you want to generate
a hash.
``ciphersalt`` is a combination of a cipher identifier, an optional number
of rounds, and the cryptographic salt. The arrangement and format of these
fields depends on the cipher and which flavor of BSD you are using. For
more information on this, see the manpage for ``crpyt(3)``. On NetBSD,
additional information is available in ``passwd.conf(5)``.
Keep in mind that the $6 represents a sha512 hash, if your OS is using a
different hashing algorithm this needs to be changed accordingly
CLI Example::
salt '*' shadow.set_password someuser '$1$UYCIxa628.9qXjpQCjM4a..'
'''
if __grains__.get('os', '') == 'FreeBSD':
cmd = 'pw user mod {0} -H 0'.format(name)
stdin = password
else:
cmd = 'usermod -p \'{0}\' {1}'.format(password, name)
stdin = None
__salt__['cmd.run'](cmd, stdin=stdin)
return info(name)['passwd'] == password

View File

@ -1,74 +0,0 @@
'''
Manage the password database on FreeBSD systems
'''
# Import python libs
try:
import pwd
except ImportError:
pass
# Import salt libs
import salt.utils
def __virtual__():
return 'shadow' if __grains__.get('os', '') == 'FreeBSD' else False
def info(name):
'''
Return information for the specified user
CLI Example::
salt '*' shadow.info root
'''
try:
data = pwd.getpwnam(name)
ret = {
'name': data.pw_name,
'passwd': data.pw_passwd if data.pw_passwd != '*' else '',
'change': '',
'expire': ''}
except KeyError:
return {
'name': '',
'passwd': '',
'change': '',
'expire': ''}
# Get password aging info
cmd = 'pw user show {0} | cut -f6,7 -d:'.format(name)
try:
change, expire = __salt__['cmd.run_all'](cmd)['stdout'].split(':')
except ValueError:
pass
else:
ret['change'] = change
ret['expire'] = expire
return ret
def set_password(name, password):
'''
Set the password for a named user. The password must be a properly defined
hash. The password hash can be generated with this command:
``python -c "import crypt; print crypt.crypt('password',
'$6$SALTsalt')"``
``SALTsalt`` is the 8-character crpytographic salt. Valid characters in the
salt are ``.``, ``/``, and any alphanumeric character.
Keep in mind that the $6 represents a sha512 hash, if your OS is using a
different hashing algorithm this needs to be changed accordingly
CLI Example::
salt '*' shadow.set_password root '$1$UYCIxa628.9qXjpQCjM4a..'
'''
__salt__['cmd.run']('pw user mod {0} -H 0'.format(name), stdin=password)
uinfo = info(name)
return uinfo['passwd'] == password

View File

@ -1,68 +0,0 @@
'''
Manage the password database on NetBSD systems
'''
# Import python libs
import logging
try:
import pwd
except ImportError:
pass
# Import salt libs
import salt.utils
# Set up logging
log = logging.getLogger(__name__)
def __virtual__():
return 'shadow' if __grains__.get('os', '') == 'NetBSD' else False
def info(name):
'''
Return information for the specified user
CLI Example::
salt '*' shadow.info root
'''
try:
data = pwd.getpwnam(name)
ret = {
'name': data.pw_name,
'passwd': data.pw_passwd if data.pw_passwd != '*************'
else ''}
except KeyError:
return {
'name': '',
'passwd': ''}
return ret
def set_password(name, password):
'''
Set the password for a named user. The password must be a properly defined
hash. The password hash can be generated with this command:
``python -c "import crypt; print crypt.crypt('password',
'$sha1$numrounds$SALTsalt')"``
``numrounds`` is the number of rounds. See ``man passwd.conf`` as this
option is not used for all ciphers.
``SALTsalt`` is the 8-character crpytographic salt. Valid characters in the
salt are ``.``, ``/``, and any alphanumeric character.
CLI Example::
salt '*' shadow.set_password root
'$sha1$22295$f8s.YafO$eRQSGyI4BP98Kj/hIohuXCmatl7L'
'''
cmd = 'usermod -p \'{0}\' {1}'.format(password, name)
log.info('Setting password for user {0}'.format(name))
# Don't log this command, to keep hash out of the log
__salt__['cmd.run'](cmd, quiet=True)
uinfo = info(name)
return uinfo['passwd'] == password