If a user is added from the command line, but no password is assigned, /etc/shadow is initialized with "!!" in field 2.
When examining said user's properties from s-c-users, "Account Info" panel reports password as locked.
Novices can easily choose to "unlock" the account and exit, and the account is left with a NULL password allowing password-less entry.
Reproduced on Fedora 13 and RHEL6 beta. Probably many earlier releases as well...
This request was evaluated by Red Hat Product Management for inclusion in a Red
Hat Enterprise Linux major release. Product Management has requested further
review of this request by Red Hat Engineering, for potential inclusion in a Red
Hat Enterprise Linux Major release. This request is not yet committed for
Still reproducible with
$ rpm -q system-config-users
Hmm, I've looked into this and found that there's no straight-forward way to check "if I unlock this user, will it get an empty password?". The underlying libuser library supports a number of different backends -- local files, ldap, possibly sasl in the future (the code exists, but is not packaged ATM) -- where locking accounts is done differently. This means I can't just check whether 'pw_passwd' or 'sp_pwdp' of a user entity is '!!' since this is not the way all backends lock accounts.
The only remotely portable way I can think of right now is to unlock the user entity and then check if the entity password is empty, e.g.:
admin = libuser.ADMIN()
userEnt = admin.lookupUserByName(username)
pw_empty = False
for k in ('sp_pwdp', 'pw_passwd'):
if userEnt.get(k, [None]) == "":
pw_empty = True
# warn about empty password, focus password field, etc.
Note that this is also not really portable as it hard-codes the backend-specific password fields (probably incompatible with any future backends) and introduces a short window in which the user account is unlocked with an empty password (which we wanted to avoid in the first place).
At the moment I don't really see a safe and portable way without changes in libuser, e.g. additional userPassIsEmpty()/groupPassIsEmpty() methods which tell the application whether the password of a user is empty, independent of the backend in which the account is stored and regardless of whether the account is locked or not.
Mirek, how do you see this? Have I missed something?
which raises RuntimeError if the resulting encrypted password would be empty.
I'm afraid there is no reliable way to detect if the RuntimeError was caused by an empty password or by other causes (trying unlockUser with nonempty=False would make the account temporarily unlocked, which is not a good idea). The RuntimeError is accompanied with a (probably localized) error message, so you should be able to simply display that.
(unlock*(nonempty=True) does not try to detect a non-empty encrypted password hash of an empty string - but that is unlikely to ever happen in practice.)
Fixed in git:
Author: Nils Philippsen <firstname.lastname@example.org>
Date: Wed Jun 30 11:27:08 2010 +0200
prevent unlocking users with empty passwords
This patch excepts the RuntimeError which "admin.unlockUser(userEnt, [nonempty=]True)" raises and displays the supplied (translated) error message, then sets the password fields of the dialog sensitive and sets the "Local password is locked" checkbox.
VERIFEID as fixed in system-config-users-1.2.104-1.el6
NEW PACKAGE - system-config-users-1.2.104-1.el6:
Unlocking the user failed because:
unlocking would make the password field empty
OLD PACKAGE - system-config-users-1.2.94-1.1.el6:
/etc/shadow after reproducing the bug:
Red Hat Enterprise Linux 6.0 is now available and should resolve
the problem described in this bug report. This report is therefore being closed
with a resolution of CURRENTRELEASE. You may reopen this bug report if the
solution does not work for you.