Linux locked accounts and PAM

Solar Designer solar at openwall.com
Wed Oct 8 11:52:37 UTC 2008


Tomas and all,

On Wed, Oct 08, 2008 at 09:12:23AM +0200, Tomas Mraz wrote:
> I think we should do the same as sshd on Linux without PAM enabled - it
> will reject just the accounts with password hash that starts with the
> '!'. We would not reject the accounts with '*' in the password hash in
> the shadow entry.

While the above will simplify locking accounts (no need to check for
authorized_keys* files) and/or result in better security (some
meant-to-be-locked accounts will actually become locked in terms of SSH
access and maybe more), it is problematic in several ways:

1. There are plenty of systems and accounts that _intentionally_ have
their password fields locked (the string starts with "!"), but SSH keys
set up.  I am using plenty of such accounts myself.

Usually, new accounts will get "!!" for the password hash by default -
in many cases, an admin (or a script) will install SSH key(s) on those
accounts instead of setting a password.  In some other cases, an account
will be "upgraded" from password to SSH public key authentication - if
such an "upgrade" is performed by an admin, it is essential to lock the
password.

2. Allowing access for accounts with "*" in the password hash field,
while disallowing it for those with "!" as the first character, might be
wrong.

It will limit the extent of this new security measure to newly created
and locked accounts, all of which could use SSH keys on purpose.  The
new security measure will not apply to system-reserved accounts,
although there's usually no need to permit logins to those.  (Well, in
some cases it may make sense to "su" to them, and "su" may use the PAM
"account" stack too...)

Yes, a similar change that is already in OpenSSH portable has resulted
in some people using "*" in the password hash field as a workaround (I
am aware of specific occasions), and I am sure that if Linux-PAM does
the same, even more people (admins) will be "manually" changing password
hash fields to "*" (or to start with a "*") to allow access with SSH
public key authentication.  However, this results in "*" no longer
representing system-reserved accounts only, which may be unfortunate.
Also, one has to deal with the password hash string, even if via the
proper tools, to configure an account like that.  "usermod -L" and
"passwd -l" are "admin-friendly" approaches; there's no equivalent that
would be as friendly for "*-locking" (and "*-unlocking") an account.

3. Dealing with password authentication and SSH access might not be
sufficient to ensure that the account has no other "backdoors" on it.
Other ways to retain / re-gain access to an account include cron jobs,
at jobs, .forward and .procmailrc files (invoking programs).  Now, crond
does use PAM on some modern Linux distributions, and on Owl it even
invokes three PAM stacks - auth, account, and session - but I am not
sure if the same is true for other distributions with PAM-aware crond -
some might invoke the "session" stack only, yet I think that this check
belongs to the "account" stack.  I am not aware of a single distribution
that would invoke PAM for mail deliveries that involve arbitrary program
execution, although there's a long-standing to-do item for Owl to fix
that.  And it would probably make most sense to only invoke the
"session" stack on mail deliveries (such as to have rlimits set); it is
not obvious whether locking an account should disallow mail deliveries
to it or not.

Overall, checking for locked accounts is a surprisingly difficult
problem, and I am not aware of a perfect solution to it.  If pam_unix
(and/or its equivalents such as pam_tcb that we use) is enhanced to
check the password hash field in the "account" stack in some way, at the
very least this functionality should be optional - and maybe not enabled
by default (because that would break existing systems as I explained
above).

Maybe the implementation should be flexible enough to allow for
specifying just what kinds of password hash strings indicate locked or
disabled accounts - or, to not have to implement complicated parsing
(with its associated risks), maybe having several options will do for
now - e.g., deny_new or deny_passwordless (exactly "!!"), deny_locked
(starting with "!", but not exactly the string "!!"), and deny_reserved
(exactly "*").

Unfortunately, this does not address the problem of not having a
convenient way to set individual accounts to "non-password
authentication only", while allowing for use of this new functionality.
Perhaps an option would need to be added to usermod(8) for that (lock or
drop password, but don't lock account), then maybe the PAM module would
need to be further enhanced (if it's a special lock mode rather than
merely replacing the password hash with "!!").

Alternatively, the meaning of "!" can be changed to "password locked"
rather than "account locked" (in fact, this will mostly bring the
documentation in sync with today's reality, with no code changes other
than to OpenSSH portable), and a new flag introduced to indicate
"account locked".  A new option would need to be added to usermod(8).
"usermod -L" could then be documented to "lock password" or it could be
made to apply to the new flag ("lock account"), with the new option
becoming the "lock password" one.

Unfortunately, all of these approaches have their pros and cons.  There
is no single "right one".

Alexander Peslyak <solar at openwall.com>
GPG key ID: 5B341F15  fp: B3FB 63F4 D7A3 BCCC 6F6E  FC55 A2FC 027C 5B34 1F15
http://www.openwall.com - bringing security into open computing environments




More information about the Pam-list mailing list