Examining /etc/passwd file in Typical Unix-like OS

ABOUT /etc/passwd file

The /etc/passwd file is a text-based database of information about users that may log into the system or other operating system user identities that own running processes.

In many operating systems this file is just one of many possible back-ends for the more general passwd name service.

The file's name originates from one of its initial functions as it contained the data used to verify passwords of user accounts. However, on modern Unix systems the security-sensitive password information is instead often stored in a different file using shadow passwords, or other database implementations.

The /etc/passwd file typically has file system permissions that allow it to be readable by all users of the system (world-readable), although it may only be modified by the superuser or by using a few special purpose privileged commands.

The /etc/passwd file is a text file with one record per line, each describing a user account. Each record consists of seven fields separated by colons. The ordering of the records within the file is generally unimportant.


The fields, in order from left to right, are:

User name: the string a user would type in when logging into the operating system: the logname. Must be unique across users listed in the file.

Information used to validate a user's password; in most modern uses, this field is usually set to "x" (or "*", or some other indicator) with the actual password information being stored in a separate shadow 
password file. On Linux systems, setting this field to an asterisk ("*") is a common way to disable direct logins to an account while still preserving its name, while another possible value is "*NP*" which indicates to use an NIS server to obtain the password.[2] Without password shadowing in effect, this field would typically contain a cryptographic hash of the user's password (in combination with a salt).

user identifier number, used by the operating system for internal purposes. It need not be unique.

group identifier number, which identifies the primary group of the user; all files that are created by this user may initially be accessible to this group.

Gecos field, commentary that describes the person or account. Typically, this is a set of comma-separated values including the user's full name and contact details.

Path to the user's home directory.

Program that is started every time the user logs into the system. For an interactive user, this is usually one of the system's command line interpreters (shells).

RELATED SHELL SESSION EXPOSURE

[bash]
$cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:100534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:100534:100534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
jeffrin:x:1000:1000:Jeffrin Jose Thalakkottoor,,,:/home/jeffrin:/bin/bash
messagebus:x:101:103::/var/run/dbus:/bin/false
avahi:x:102:105:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
festival:x:103:29::/home/festival:/bin/false
usbmux:x:104:46:usbmux daemon,,,:/home/usbmux:/bin/false
saned:x:106:113::/home/saned:/bin/false
gdm:x:107:114:Gnome Display Manager:/var/lib/gdm:/bin/false
sshd:x:108:100534::/var/run/sshd:/usr/sbin/nologin
haldaemon:x:110:116:Hardware abstraction layer,,,:/var/run/hald:/bin/false
Debian-exim:x:111:118::/var/spool/exim4:/bin/false
mysql:x:112:119:MySQL Server,,,:/var/lib/mysql:/bin/false
pulse:x:109:115:PulseAudio daemon,,,:/var/run/pulse:/bin/false
rtkit:x:113:124:RealtimeKit,,,:/proc:/bin/false
jetty:x:114:125::/usr/share/jetty:/bin/false
klog:x:115:127::/home/klog:/bin/false
syslog:x:116:128::/home/syslog:/bin/false
colord:x:117:129:colord colour management daemon,,,:/var/lib/colord:/bin/false
vde2-net:x:118:132::/var/run/vde2:/bin/false
fetchmail:x:119:100534::/var/lib/fetchmail:/bin/false
libvirt-qemu:x:120:131:Libvirt Qemu,,,:/var/lib/libvirt:/bin/false
speech-dispatcher:x:121:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh
Debian-gdm:x:105:111:Gnome Display Manager:/var/lib/gdm3:/bin/false
kdm:x:122:100534::/home/kdm:/bin/false
snmp:x:123:134::/var/lib/snmp:/bin/false
$

[/bash]

RELATED SOURCE CODE EXPOSURE

 
/*
 * new_password - validate old password and replace with new (both old and
 * new in global "char crypt_passwd[128]")
 */
static int new_password (const struct passwd *pw)
{
	char *clear;		/* Pointer to clear text */
	char *cipher;		/* Pointer to cipher text */
	const char *salt;	/* Pointer to new salt */
	char *cp;		/* Pointer to getpass() response */
	char orig[200];		/* Original password */
	char pass[200];		/* New password */
	int i;			/* Counter for retries */
	bool warned;
	int pass_max_len = -1;
	const char *method;

#ifdef HAVE_LIBCRACK_HIST
	int HistUpdate (const char *, const char *);
#endif				/* HAVE_LIBCRACK_HIST */

	/*
	 * Authenticate the user. The user will be prompted for their own
	 * password.
	 */

	if (!amroot && ('\0' != crypt_passwd[0])) {
		clear = getpass (_("Old password: "));
		if (NULL == clear) {
			return -1;
		}

		cipher = pw_encrypt (clear, crypt_passwd);

		if (NULL == cipher) {
			strzero (clear);
			fprintf (stderr,
			         _("%s: failed to crypt password with previous salt: %s\n"),
			         Prog, strerror (errno));
			SYSLOG ((LOG_INFO,
			         "Failed to crypt password with previous salt of user '%s'",
			         pw->pw_name));
			return -1;
		}

		if (strcmp (cipher, crypt_passwd) != 0) {
			strzero (clear);
			strzero (cipher);
			SYSLOG ((LOG_WARN, "incorrect password for %s",
			         pw->pw_name));
			(void) sleep (1);
			(void) fprintf (stderr,
			                _("Incorrect password for %s.\n"),
			                pw->pw_name);
			return -1;
		}
		STRFCPY (orig, clear);
		strzero (clear);
		strzero (cipher);
	} else {
		orig[0] = '\0';
	}

	/*
	 * Get the new password. The user is prompted for the new password
	 * and has five tries to get it right. The password will be tested
	 * for strength, unless it is the root user. This provides an escape
	 * for initial login passwords.
	 */
	method = getdef_str ("ENCRYPT_METHOD");
	if (NULL == method) {
		if (!getdef_bool ("MD5_CRYPT_ENAB")) {
			pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
		}
	} else {
		if (   (strcmp (method, "MD5")    == 0)
#ifdef USE_SHA_CRYPT
		    || (strcmp (method, "SHA256") == 0)
		    || (strcmp (method, "SHA512") == 0)
#endif				/* USE_SHA_CRYPT */
		    ) {
			pass_max_len = -1;
		} else {
			pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
		}
	}
	if (!qflg) {
		if (pass_max_len == -1) {
			(void) printf (_(
"Enter the new password (minimum of %d characters)\n"
"Please use a combination of upper and lower case letters and numbers.\n"),
				getdef_num ("PASS_MIN_LEN", 5));
		} else {
			(void) printf (_(
"Enter the new password (minimum of %d, maximum of %d characters)\n"
"Please use a combination of upper and lower case letters and numbers.\n"),
				getdef_num ("PASS_MIN_LEN", 5), pass_max_len);
		}
	}

	warned = false;
	for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) {
		cp = getpass (_("New password: "));
		if (NULL == cp) {
			memzero (orig, sizeof orig);
			return -1;
		}
		if (warned && (strcmp (pass, cp) != 0)) {
			warned = false;
		}
		STRFCPY (pass, cp);
		strzero (cp);

		if (!amroot && (!obscure (orig, pass, pw) || reuse (pass, pw))) {
			(void) puts (_("Try again."));
			continue;
		}

		/*
		 * If enabled, warn about weak passwords even if you are
		 * root (enter this password again to use it anyway). 
		 * --marekm
		 */
		if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN")
		    && (!obscure (orig, pass, pw) || reuse (pass, pw))) {
			(void) puts (_("\nWarning: weak password (enter it again to use it anyway)."));
			warned = true;
			continue;
		}
		cp = getpass (_("Re-enter new password: "));
		if (NULL == cp) {
			memzero (orig, sizeof orig);
			return -1;
		}
		if (strcmp (cp, pass) != 0) {
			(void) fputs (_("They don't match; try again.\n"), stderr);
		} else {
			strzero (cp);
			break;
		}
	}
	memzero (orig, sizeof orig);

	if (i == 0) {
		memzero (pass, sizeof pass);
		return -1;
	}

	/*
	 * Encrypt the password, then wipe the cleartext password.
	 */
	salt = crypt_make_salt (NULL, NULL);
	cp = pw_encrypt (pass, salt);
	memzero (pass, sizeof pass);

	if (NULL == cp) {
		fprintf (stderr,
		         _("%s: failed to crypt password with salt '%s': %s\n"),
		         Prog, salt, strerror (errno));
		return -1;
	}

#ifdef HAVE_LIBCRACK_HIST
	HistUpdate (pw->pw_name, crypt_passwd);
#endif				/* HAVE_LIBCRACK_HIST */
	STRFCPY (crypt_passwd, cp);
	return 0;
}

SOURCE CODE FROM DEBIAN SOURECE PACKAGE NAMED “shadow”

LINKS (SOURCE AND OTHER)

https://en.wikipedia.org/wiki/Passwd
https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.security/passwords_etc_passwd_file.htm
https://www.digitalocean.com/community/tutorials/how-to-use-passwd-and-adduser-to-manage-passwords-on-a-linux-vps

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s