Sometimes it's useful to perform System Authentication against a Local System using the /etc/shadow or /etc/passwd password databases. This recipe provides a simple function that does exactly that.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/usr/bin/env python
from os import path
from crypt import crypt
from re import compile as compile_regex
def check_auth(user, password):
"""Perform authentication against the local systme.
This function will perform authentication against the local system's
/etc/shadow or /etc/passwd database for a given user and password.
:param user: The username to perform authentication with
:type user: str
:param password: The password (plain text) for the given user
:type password: str
:returns: True if successful, None otherwise.
:rtype: True or None
"""
salt_pattern = compile_regex(r"\$.*\$.*\$")
passwd = "/etc/shadow" if path.exists("/etc/shadow") else "/etc/passwd"
with open(passwd, "r") as f:
rows = (line.strip().split(":") for line in f)
records = [row for row in rows if row[0] == user]
hash = records and records[0][1]
salt = salt_pattern.match(hash).group()
return crypt(password, salt) == hash
|
You can use the pwd/spwd built-in modules instead of accessing /etc files directly. This will also work with LDAP authentication, for example.
No need to split the salt from the salted password - crypt is happy to accept the complete salted password as the second parameter.
@Oren: Yes you are quite right of course! I'll fork this Recipe to utilize pwd/spwg instead. I posted this based on old code I had lying around before spwd module was available in the Python std. lib (2.5). --JamesMills / prologic