Recently, I found myself trying to understand what was going on in the shadow file. For one thing, the “password” field in Ubuntu Lucid Lynx is much longer than it is in Red Hat Enterprise Linux 5. Then there were the exclamation points in front of some password entries.
Originally, there was no /etc/shadow file – the passwords and salts were contained with other user information in /etc/passwd. The problem was that /etc/passwd was readable by anyone, and that attacks became more common and more powerful. It was necessary to move the password into a separate file that would only be readable by root.
Here is an example of a shadow file line:
Each field is separated by a colon (
:). There are a number of fields:
- User name. This must match up with a user name in /etc/passwd; it is the key.
- Password. This field is a hash of the password (not the actual password itself) combined with an id (specifying which form of encryption was used) and with a salt.
- Last changed date. This is the day that the password was last set (in days since January 1, 1970).
- Minimum days. This is the minimum number of days that a password must be active before a password can be changed again. A user’s password cannot be changed by them until this number of days has elapsed.
- Maximum days. This is the maximum number of days for a password to be valid. Once the maximum number of days has elapsed, the user is forced to change their password.
- Warn days. Before a password expires, warn the user this many days ahead of time.
- Inactive days. Once a password has expired, it will be disabled after this many days.
- Expire date. On this date (in days since January 1, 1970), the account is disabled and the login can no longer be used.
Rather than trying to compute the date from the number of days since 1970, use the chage command:
$ chage -l ddouthitt Last password change : May 25, 2011 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7
This also explains what each number means, and incorporates any defaults.
The password is more complicated. The actual password is not stored anywhere; the stored value in the /etc/shadow file is a hash generated from the password.
Originally, the password hash was just the hash itself; later, a two-character salt was added at the beginning.
The password hash today comes in three parts, separated by dollar signs ($):
- Id. This identifies the encryption hash method used. A value of 1 denotes MD5; 2 or 2a is Blowfish; 3 is NT Hash; 5 is SHA-256; and 6 is SHA-512.
- Salt. This is used by the encryption algorithms, and could be up to 16 characters.
- Hash. The actual “password” (or hash) is last. MD5 uses 22 characters, SHA-256 uses 43, and SHA-512 uses 86.
Picking apart the example password entry above shows this:
- Id =
- Salt =
- Hash =
Lastly, the password entry could be missing entirely (which means no password) or it could have an invalid entry (locked account).
Traditionally, locking was done with the asterisk (
*) by convention or by the word
LOCKED. However, this has been extended – by convention – to a variety of new suggestions. System logins that never had a password use a double exclamation mark (
!!) and accounts that have been locked have the valid password entry invalidated by a exclamation mark prefix. Using the prefix in this way allows the password to be reinstated as it was.
FreeBSD uses a slightly different setup, with a file called /etc/master.passwd, an extended /etc/passwd file with password aging included, and support for an extended DES format (which starts with an underline). Extended DES is more secure than the original DES, but is no longer used in favor of the new modular format described above. FreeBSD standardizes on MD5 – like Red Hat, and unlike Ubuntu.
By the way – that’s not my real password – so don’t look at it.