Red Hat Bugzilla – Bug 607697
RFE: PAM support
Last modified: 2012-06-25 11:47:43 EDT
system-config-users currently enforce own rules for password "security" (sigh!) - I refer to bug #582205
please make it obey the system-wide policy, so that the behaviour is the same as with passwd
This feature request did not get resolved in time for Feature Freeze
for the current Red Hat Enterprise Linux release and has now been
denied. It has been proposed for the next Red Hat Enterprise Linux
release. If you would still like it considered for the current
release as an exception, please make that request with your support
Some things are missing for that:
- Me having more clue about PAM that I currently have (CCed Tomas Mraz, is there a way to check if a password is acceptable without actually changing it, using PAM?)
- A python wrapper for the PAM library which is actively developed. I've found "Python PAM" and "PyPam" both of which seem pretty dead.
The system-config-users would have to copy the configuration line with pam_cracklib.so from the system-auth file to a separate config file before the test of the password and then call the pam_chauthtok().
Unfortunately the above mentioned PAM python wrappers are clearly unusable.
You could write a separate one-purpose C module and call it from the python code.
(In reply to comment #4)
> The system-config-users would have to copy the configuration line with
> pam_cracklib.so from the system-auth file to a separate config file before the
> test of the password and then call the pam_chauthtok().
No deal. If we want to have this in s-c-users, I want to do it right. There needs to be something authoritative that evaluates password validity correctly, regardless of any changes a user might make in their PAM configuration files. We can't simply assume that the password stuff is configured in system-auth.
One way to achieve that would be PAM offering a "dry-run" mode where the modules don't do anything besides evaluation, where you can specify the uid under which the simulation is done.
> Unfortunately the above mentioned PAM python wrappers are clearly unusable.
> You could write a separate one-purpose C module and call it from the python
This code should be maintained along-side PAM so that any changes in PAM get into it right away.
There is simply no such thing as "dry run" for PAM password changes as far as the new password quality checks is considered. And unfortunately there is no way to add it as it would require API changes. This would however effectively make it unusable with third party modules.
(In reply to comment #8)
> There is simply no such thing as "dry run" for PAM password changes as far as
> the new password quality checks is considered. And unfortunately there is no
> way to add it as it would require API changes. This would however effectively
> make it unusable with third party modules.
As a minimum, PAM should expose API to access the parsed configuration for a specific PAM service (e.g. "passwd" -- is service the right term?), otherwise we'd end up with two separate parsers without guarantees that both understand the configuration in the same way. And if we want to implement this, I want that guarantee ;-).
For instance, this is /etc/pam.d/passwd on my system:
auth include system-auth
account include system-auth
password substack system-auth
-password optional pam_gnome_keyring.so use_authtok
The parser should read and parse that file, apply any include/substack directives and offer an API which would let an app like s-c-users read what PAM modules are applied in which order with what options. S-c-users then could parse the pam_cracklib "requisite" module options and apply these for its password checks. This wouldn't be ideal, but a great deal better than a separate parse that interprets things only similarly.
Would having the above (either in libpam or an associated helper library, but coming out of the same codebase) be acceptable? If so, we could work together to get this implemented and wrapped for python (maybe even get a proper, "authoritative" python module for PAM in the process).
I don't see any API like this implemented in PAM soon. Note that whether any of the modules in the stack are called or not heavily depends on the return values of the previous modules in the stack and of course on the configuration. So the API could not give you an answer whether this or that module will really be called or not even if it is in the configuration especially for the modules on the bottom of the stack.
The more realistic API addition would be the "dry run" call as suggested in the comment#6 but there is the obstacle in having the "dry run" added to the PAM module API meaning the modules would have to support it.
The API change in this case would be pretty minimal - I think that adding a new flag such as PAM_VALIDATE_NEW_AUTHTOK_ONLY would suffice. But modules that do not know this flag would not respect the dry run and update the password - this is not too good. There is already somehow similar flag - PAM_CHANGE_EXPIRED_AUTHTOK - this flag means that the modules should not change the password if the password is not expired. Maybe this one could be used somehow?
Hmm, I wouldn't want s-c-users checking for the validity of a password having the slightest risk of actually changing it. AIUI, the module actually setting the password is "password sufficient pam_unix.so ...", is that so? And modules checking for password strength would be "password requisite ..." (e.g. pam_cracklib.so)?
If these assumption could be made, s-c-users "only" needed a way to parse PAM configuration (for the "passwd" service), then call the "password requisite ..." modules in order (from Python) and display any errors... Can I assume this or is that to risky in yet another fashion?
Well in the standard configuration it is this way of course. However when the pam is manually configured the modules could be called in basically any way. For example the user could just put only
password requisite pam_unix.so line in the system-auth file. That would mean that no password strength checks are done but unix password changing would work.
But Nils, can you please enlighten me why the s-c-users couldn't use the full PAM password stack for setting up the user's password? I do not know the s-c-users internal design, how does it set the password currently?
(In reply to comment #12)
> Well in the standard configuration it is this way of course. However when the
> pam is manually configured the modules could be called in basically any way.
> For example the user could just put only
> password requisite pam_unix.so line in the system-auth file. That would mean
> that no password strength checks are done but unix password changing would
Well, no "password requisite ..." lines could of course be interpreted as "no password strength checking" unless pam_unix.so does some checking on its own...
> But Nils, can you please enlighten me why the s-c-users couldn't use the full
> PAM password stack for setting up the user's password? I do not know the
> s-c-users internal design, how does it set the password currently?
Currently, system-config-users uses libuser-python which wraps libuser which uses PAM (I guess). As it is, if something goes wrong in libuser I get a RuntimeError with not much machine-parseable info in it. Besides that, some part of what I called libuser for might already be done -- there are e.g. functions to create a new user with a certain home directory and password, there are a multitude of things that can go wrong -- and it would be very hard to clean up afterwards if something goes wrong.
Therefore I'd prefer checking for potential trouble spots before even calling libuser functions, so the risk of telling libuser to do something which doesn't succeed and then having to tell the user "Something went wrong, this is what libuser told me: <some string>. I can't help you now, please clean it up for me, goodbye." is as small as possible. I know that you can't 100% prevent these situations as things might change between the time s-c-users checks and libuser does its work, but if possible I'd like to able to tell the user "I won't do what you requested, because: ..." so they can e.g. use a better password or place the home directory somewhere where they can write into, etc.
Does that answer your question?
Except libuser AFAIK does not call PAM for the password setup. It sets it directly when it creates the passwd and shadow entries. So IMO the most correct way would be to create some random highly secure password and use it with the libuser call and then use direct call to PAM (temporarily switching uid to the user) for the final password. Or it could create the user with a locked password and change it through PAM as root, however the password quality checks in pam_cracklib and possibly other modules are non-fatal when root changes the user's password, so pam_cracklib would have to be changed to make them always fatal.
Hmm. Still a bit moot since there is no functional PAM wrapper for Python, or is there?
No, there isn't, but it wouldn't be hard to write one-off module for the calls s-c-users needs. As PAM API is extremely stable this would not bring any new maintenance costs to s-c-users.
Probably, but it would have to be an external package because s-c-users is noarch and I intend to leave it that way.
Please provide an update for this.
As described in comment #16 we'd first need a pam module to provide said functionality. Please feel free to open a new bug with that request against pam so we can add the support into s-c-user once the module is done.
Thanks & regards, Phil
PyPAM is in Fedora and EPEL now and should be usable for the purpose.
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated
in the current release, Red Hat is unfortunately unable to
address this request at this time. Red Hat invites you to
ask your support representative to propose this request, if
appropriate and relevant, in the next release of Red Hat
Enterprise Linux. If you would like it considered as an
exception in the current release, please ask your support