Cover V03, I02
Figure 1
Figure 2
Listing 1
Listing 2
Listing 3
Table 1


Heterogeneous Password Assignment

Brad Jacobs and Thomas Kraus

Congratulations! Company management just decided to consolidate the network administration for all corporate divisions, and you're the chief administrator. But overnight your previous responsibility for an homogeneous divisional network had become a nightmare where now no single UNIX vendor accounts for more than 20 percent of the hosts. To make matters worse, security across the divisions was handled in completely different manners.

Turn to the Vendor Tools

So what's an administrator to do? The first action you might take is to create a standard for user accounts and password assignments. Network Information Services (NIS) provides a centralized account database, which would make your job easier.

However, you quickly discover that NIS is not supported on all your UNIX flavors, and the pitfalls of support via the company routers creates a headache. You also find loopholes, such as local overrides in the account database that nullify the NIS entries. To top it all off, the password assignment programs across the systems don't conform to any format standard, making it virtually impossible to effectively promote a security policy.

Roll Your Own

Instead of relying solely on your users knowing proper password security techniques, why not create a password assignment program to enforce the level of security you desire? To accomplish this task, you must know how different vendors accomplish user authentication.

This article presents the account database, its fields, and the formats found on different vendor systems. It concentrates on the encrypted password field, providing code that can assist in the creation of a customized password assignment program.

The User Account Database

An account database maintains an entry for each user containing essential identifying features. These features include: the user identification number (userid); the identification number of the group to which the user belongs (groupid); and the directory into which the user is initially placed (the home directory).

To enable user authentication, the account database stores a password for each user. The login program references the database, verifies the user name and password given by the person requesting access, and, if both are legitimate, places the user in the home directory.

The database is really a flat file, historically /etc/passwd. The information within this file is crucial not only to special-purpose programs such as login, but also to general purpose programs such as ls. Without access to the /etc/passwd file, programs could not map userids to user names. The file is readable by "world," so that both developers and system programs can provide users with intelligible translations of file listings, database access names, and other important information.

To allow key information to be read, yet protect the user authentication function from prying eyes, the password for each entry is encrypted. This is typically a one-way encryption -- there is no ready method for unraveling the password with nothing more than the characters contained in the encrypted entry. An easily decrypted password would be detrimental to security.

Encrypting Your Own Passwords

The first step in creating the password assignment program is to build a function for encrypting a given password. Fortunately for this stage of the process, the vendor community decided not to alter the status quo, so they all share a common encryption method.

Listing 1 shows a low-level function to use as the basis for the program. The password string that the user entered is passed into the function. The function then places the result of the encryption in a supplied buffer, appropriate for the login program to use for its authentication process.

A random two-character "salt" is chosen from the password alphabet. The set of legal characters in this alphabet is: [a-zA-Z0-9./]. The salt is used to increase the number of possible outcomes of the encryption process. Without the salt, every identical password would always result in identical encryption output. On systems with even a relatively few users, there is a relatively high occurrence of identical passwords, since most novice users tend to choose common passwords. Using a random salt, the chance against two identical passwords resulting in an identical encryption becomes 4096:1.

Passing the salt and the password to the C library function crypt() produces a pointer to an internal 13-character buffer containing the result of the encryption, of which the first two characters are the salt characters used in the encryption. The result is then copied into the supplied buffer (make_passwd()'s second argument). Most vendors' crypt() functions consider only the first eight characters of the password to be significant.

Now Where Do You Put It?

The commonality between vendors ends with the acquisition of the encrypted password. At this point, there are no absolute standards as to format requirements of the user account database. In fact, there are only commonly used methods, and the flat file itself may even be split up, forcing a user to reference multiple files to obtain all the information necessary for a robust user administration tool. Table 1 shows which files contain which fields under various implementations.

The read permissions on /etc/passwd make it available to all users and thus vulnerable to attack by intelligent password-guessing programs. The only way around this problem is to use UNIX security to limit access to the encrypted password entry. Thus, over the years, vendors have evolved alternate strategies which complicate the /etc/passwd scheme. While /etc/passwd still exists with these strategies (in order to provide portability for products which require username/userid mapping), the password field is replaced with a placeholder. Other files contain the encrypted password and other information the vendor considers important for user account control, such as password aging, login tracking, and more. The basic strategies and their file locations are shown in Figure 1.

Because the /etc/passwd file format remains the same and thus continues to meet application developers' needs, the alternate files are not subject to any kind of standard, not even ad-hoc standards. The only requirement observed by the vendor is that its proprietary login, account control, and password change programs have access to the files. These programs are executable only through root access (possibly via setuid permission), so the non-standard files are protected from read access by the general user community and security is thereby enhanced, since a cracker program must have root access (which one would expect to be highly protected) in order gain encrypted password read access.

Selecting the Proper Files

The security implementation strategies in Figure 1 may also be used in combination, and there may even be selectable strategies available to the administrator on the same host. You must refer to the vendor's documentation (and sometimes the vendor's support line) to get an accurate list for your own network. Figure 2 contains a list of some common implementations.

The TCB Security scheme differs markedly from the other schemes. It is divided into a set of directories in much the same way as the terminfo scheme. Within the master directory are subdirectories named with the first letter of the username alphabet. Within these directories are the specific user account files containing the detailed information. For example, user "johann" will have TCB file /tcb/files/auth/j/johann. Accounts do not share TCB files, and since accounts under this scheme are not deleted but instead retired, you cannot reassign the account. The administrator can make reassignments only by bypassing the scheme and making direct alterations.

Password File Fields

For your password-assignment program, you are interested in the encrypted password field. For the normal /etc/passwd scheme, the encrypted password is located in the second field, where a colon is used as a field delimiter. When alternate security schemes are used, a place-holder is put into this field. The character used varies, but is often an asterisk.

There are no standard requirements for the password field when it's located in an alternate file. For the Shadow Password and Adjunct Password schemes, it's located in the second field, with colon delimiters.

In the TCB scheme, a security entry looks much like a termcap entry. The fields are colon delimited, but can be multiline, using the backslash character to indicate line continuation. Like termcap, the TCB fields are unordered. The password field is identified by the prefix u_pwd=. The administrator must be very careful when altering the TCB file as there are multiple field types, including string, numeric, and logical entries. The presence of special characters such as "=", "#", and "@" helps delineate the field type. For example, here is an entry for account "bin", which was located in /tcb/files/auth/b/bin:


The Security Password scheme presents its own peculiarities: the entries are multiline and context-driven. A user entry begins with <username>:. All fields applying to that user may be found on following lines, each of which is prefixed with a field name (password = for the password field). The complete entry stops with either end-of-file or a blank line.

Listing 2 shows code for obtaining an encrypted password entry using the Normal, Shadow, and Security schemes. You must set the appropriate scheme for the target system with a #define <scheme> or -D<scheme> compile option where <scheme> is one of ETCPASSWD, ETCSHADOW, or ETCSECURITY. The function takes two parameters. The first is the user name for which to search in the appropriate file. The second is a buffer in which the password, if located, is stored. The first two letters of the password represent the salt.

Putting It All Together

Your password change procedure now needs only some glue to make a complete program: Listing 3 shows the master code. The program allows a user to change his/her own password or a super-user to change any user's password. If a user name is given as an argument to the program, then that user's password will be changed. If no argument is given to the program, the logged-in user's password will be changed.

Having determined which user's password is to be changed, the program requests the user's existing password. This password is encrypted and compared to the current (encrypted) password. If they do not match, the user is rejected. This check is not done if the user is a super-user or if the user currently has no password.

If the match is successful, the program requests the new password twice, to account for typing errors. The password is then sent to the routine in Listing 1 for encryption. Once the encryption is complete, the result is then sent to a routine (not shown here) to replace the existing entry in the file appropriate to the security scheme.

The program must be owned by root and have setuid root privileges:

# chown root chngpwd
# chmod 4755 chngpwd

Always take care in applying root privileges to utility programs. As in the example program, such programs should verify the true executing user in order to restrict the use of the program to a specific task.

Password Aging

On some systems, it is possible to assign time periods to passwords. The login program will force the user to change a stale password upon the first login after a set time period. There are fields for dealing with password aging, but the differences between systems are too numerous to be addressed in this discussion. Beware of initiating password aging if you also install your own passwd program; the login program will not know the previous date of a password change if the passwd program does not also change the appropriate fields. On some systems, the aging information is tacked on to the encrypted password. On others, it's available from other fields and sometimes in other files. Once again, there is no standard for time representation.


Now that you have the tools you need to create your own password assignment program, you'll want to extend them network-wide. We suggest implementing a single-system password change program, that mimicks the vendor program (it verifies both the old and new passwords). Each target system then supports its own /etc/passwd file, according to the vendor format.

Using Remote Procedure Calls, you could even create programs for centralized management of each local /etc/password file, avoiding the pitfalls of NIS and related centralized account databases.

About the Authors

Brad Jacobs and Thomas Kraus are the principal developers for BREAKaway Software, creators of UNIX systems management software. Brad received an MSIA degree from Carnegie Mellon University; Thomas holds a BS in computer science from the University of Western Ontario. They can be contacted at BREAKaway Software at (800) 479-7236 or via e-mail at