Validating A User/Password Pair + Getting Groups On Unix

Kanenas kanenas_ at t_comcast_d.t_net
Tue Mar 1 00:22:47 EST 2005


On 28 Feb 2005 20:17:58 EST, Tim Daneliuk <tundra at tundraware.com>
wrote:

[...]
>Given a username and a password (plain text):
>
>   1) Validate that the password is correct for that user *without actually logging in*.
>
The 'pwd' module probably won't be able (and won't try) to read the
shadow password file, so 'pwd' won't be of use.  There may not be a
Python module which handles your local authentication scheme (there's
a 'krb5' module for Kerberos authentication), so you may need to write
one.  The best approach may be to write an extension module in C or
C++ which wraps around whatever local authentication functions are
appropriate (e.g. a 'pam' module for PAM, an 'auth' module for BSD).
You'd only need to wrap the functions needed for simple pass/fail
authentication (e.g. auth_userokay), but the other functions could
easily be added to the extension later if needed.  

The process that calls the authentication functions will probably need
special access privileges so that the functions can succesfully accept
or reject the password.  The man pages for the authentication
functions should have details.  For example, auth_userokay calls
getpwnam, which requires the effective uid to be 0 (or, on some
systems, the user to be in the "_shadow" group) for it to include the
encrypted password in the passwd entry.

If you're not sure what authentication scheme your system uses, try
`man -s 3 authenticate` or examine "/usr/src/usr.bin/login/login.c".

extending Python:
http://www.python.org/doc/2.4/ext/ext.html

Python/C API:
http://www.python.org/doc/2.4/api/api.html

Information on Linux-PAM
http://www.kernel.org/pub/linux/libs/pam/

You could even add support for the full authentication API to your
module and contribute the extension to the Python community.
http://www.python.org/download/Contributed.html.


>   2) If the password is valid, return a list of all the groups the user belongs to.
>      Otherwise, return some error string.
>
[...]
>I can do 2) by brute force - just parse through /etc/group - but this
>misses the primary group a given user may belong to - and that requires
>also scanning /etc/passwd and then looking up the corresponding primary
>group in /etc/group.  Is there a better way?
>
Slightly better would be to use the grp and pwd modules:
http://www.python.org/doc/2.4/lib/module-grp.html
http://www.python.org/doc/2.4/lib/module-pwd.html

Even better would be to write an extension or add to the grp module to
wrap around local group database access functions (e.g. getgrouplist).
See the 'getgrouplist' man page for more information and examine the
source of the `groups` command (probably
"/usr/src/usr.bin/groups/groups.c") or `id` command (should be
"/usr/src/usr.bin/id/id.c") for other group DB access functions.

You could also call the `groups` command via 'os.popen(...)'.




More information about the Python-list mailing list