User Accounts: Part 1
Contents
Introduction
How do we create new users in Linux ? Where are their passwords stored ? What are groups ? This chapter covers user management.Etc files
There are 2 important files in thfe "/etc" folder that are relevant "passwd" and "group" .
1) passwd file
Every user in the system has an entry in this file .
The entry has the following format:
uname:password:uid:gid:gecos:home:shell The "uname" refers to the user name. The "password" is a legacy field. Passwords are not stored in this field any more. Rather we are more likely to see a single letter "x" . Passwords are kept in another file "/etc/shadow". If there is no letter "x" then there might not be a password. If there is some other character than "x" then the account is disabled. The "uid" is a number denoting the user. The "gid" is a number denoting the default group the user belongs to. However a user can belong to multiple groups. The "gecos" field contains information about the user such as full name. The "home" field contains the home folder of the user who logs in. The "shell" contains the shell that is started when the user logs in. TODO Login in to the hills server and try to find your username in the passwd file. As an example: [amittal@hills /]$ whoami amittal [amittal@hills /]$ cat /etc/passwd | grep "amittal" amittal:x:2548:1258:Ajay MIttal:/users/amittal:/bin/bash2) group file
Once a user is created a default group is assigned to the user. From above we can see that this is the 4th field in the "etc/group" file. A user can be part of additional groups. Every group has an entry in the "/etc/group" file. The entry in a group file has the following format:
gname:gpass:gid:members The "gname" refers to the group name. The "gpass" is generally not used is denoted by the letter "x". It can be used to store encrypted password . The "gid" is a number denoting the group id. The "members" field is a comma seperated list of users that belong to this group. If a member's default group is this group then the member is not listed. The below commands show how we can find our entry for our group on the hills server. [amittal@hills /]$ whoami amittal [amittal@hills /]$ cat /etc/passwd | grep "amittal" amittal:x:2548:1258:Ajay MIttal:/users/amittal:/bin/bash [amittal@hills /]$ cat /etc/group | grep "1258" csdept:x:1258: No members are listed for the "csdept" group and that means all the users that belong to this group have their default group id as 1258. We can also find out our default ( primary ) group using the groups command. [amittal@hills /]$ groups csdept TODO Repeat the above commands for yourself on the hills server.
Passwords
We need to be familiar with couple of concepts before we study passwords. The concept of "hashing" refers to taking a text/string and computing a number A hash algorithm in cryptography works on a message ( message can be data of any length ) to produce a fixed size value. It is a one-way function and are the workhorses of encryption. They are used in anything involving digital signatures or certificates .It should have the following properties. 1) If it runs on the same message again it should produce the same result. 2) It should not take a long time to run. 3) We should not be able to create a message given the hash , 4) We should not be able to create 2 messages that produce the same hash. 5) A change to the message should produce a significant change in the hash. Interesting thing about the hash function is that the algorithm will be known to everyone and there is no key that is involved. Let us create our own simple hashing algorithm . If our message has characters then we use a variable storage where we will add the ascii character value and then do a modulo 15 on it. Example : " C A T" These translate to the following ascii numbers. "67 65 84" Initially "storage" has the value 0 . storage = 0 + 67 modulus 15 = 7 storage = 7 + 65 modulus 15 = = 72 modulus 15 = = 12 storage = 12 + 84 modulus 15 = 96 modulus 15 = 6 We know it satisfies 1). It will produce the same value of we run the hash algorithm on the same message. But 4) is not true. What happens if we increase one value then the modulus will carry over and then decrease the next character and the end modulus will decrease by 1 . So instead of "C A T" we use "C B S" storage = 0 + 67 modulus 15 = 7 storage = 7 + 66 modulus 15 = 73 modulus 15 = 13 storage = 13 + 83 modulus 15 = 96 modulus 15 = 6This hashing function is not going to cut it. One problem is that the hash is very small . It is less than 15 and only needs 4 bits. The other problem is the algorithm is too simple. We can easily guess how to break it.
MD4 was one of the early algorithms. It is deprecated and not secure but useful to study. It also provided the basis for other algorithms such as MD5, SHA-1 .
The hash is 128 bits. We start out with 4 integer variables initialized with specific values. The message is broken into 512 bits and operations are done with the 4 integer variables and these 512 bits. This block will change the value of the 4 integer variables. Then we fetch another block and this will change the values of the 4 integer variables also. We can use hash algorithm in passwords. Instead of storing passwords we instead store the hash of the password. When a user logs in we take the hash of the password and compare it to the stored hash. If they are equal then the password was entered correctly. This is more secure then storing the password directly. If the user forgets the password then we can reset the password. We can also add some random characers to the password and then do the hashing. This is called salting. It's possible that a person gains access to the hash and then uses a dictionary of commonly used passwords and their hashes. The user can then compare the hashes. However with salting the stored hash will be different. Of course we need to store the random characters also.
Passwords in Linux are stored in the file "/etc/shadow" file. We do not have permissions on the hills server to view this file so am using my standalone Linux machine.
root@ajkumar08-PC:/home/ajay# cat /etc/shadow | grep "ajay" ajay:$y$j9T$3fl/BTt4A0rmwME0XjaTL0$XyhUm60nGpM4fxGhFYsuz14phptjL8/.nckUBx.45UB: 19401:0:99999:7::: The first field ( as we can guess ) is the username. Second field is $y$j9T$ ... The "y" is the "yescript" algorithm and the "j9T" is the param and "3F..$" is the salt and after the last "$" we have the hash. The third field is the date of the last password change . A number of days since the epoch. Jan 1, 1970 and this comes to February 13, 2023 for 19401. The fourth field is the minimum number of days required between password changes. A 0 means there is no minimum.Password can be changed at any time. The fifth field is the maximum number of days the password is valid and after that the user is forced to change the password. For our case of "99999" that comes to 273 years. The sixth field represents the number of days before the password expiration when a warning is issued. In our case this is 7. The seventh field is the number of days after expiration that the user is allowed to login using their old password. In our case this is empty and that means it is not enforced. The eighth and last field is account expiration date. Account expiration means the user cannot login after the expired date. Password expiration means user is not allowed to login with the same password. TO DO Do a "man shadow" to see what each of the fields mean.There is a utility called "chage" that we can use to update password information for a user. Unfortunately we cannot run this from the hills server.
root@ajkumar08-PC:/home/ajay# chage -E 2023-03-01 ajay root@ajkumar08-PC:/home/ajay# cat /etc/shadow | grep "ajay" ajay:$y$j9T$3fl/BTt4A0rmwME0XjaTL0$XyhUm60nGpM4fxGhFYsuz14phpt jL8/.nckUBx.45UB:19401:0:99999:7::19417: root@ajkumar08-PC:/home/ajay# chage -l ajay Last password change : Feb 13, 2023 Password expires : never Password inactive : never Account expires : Mar 01, 2023 Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7We changed the account expiration date with the "-E" option and shadow entry changed with the addition of 19417 in the 8th field. This is the number of days since 1/1/1970. We can check the date by using an online converter such as at:
Days since Epoch
Adding "19417" to 1/1/1970 produces the data 3/1/2023. We can also use the Linux command "date" to convert the no of days to the date.
By itself date will output the current date ajay@ajkumar08-PC:~$ date Sat 25 Feb 2023 08:51:38 AM PST Shows the number of seconds elapsed since 1/1/1970 ajay@ajkumar08-PC:~$ date +%s 1677344063 ajay@ajkumar08-PC:~$ To convert the number of seconds to the date: ajay@ajkumar08-PC:~$ date --date=@1677344063 Sat 25 Feb 2023 08:54:23 AM PST To convert the number of days (19417) since Unix epoch we convert the days to seconds and then use the above command. ajay@ajkumar08-PC:~$ utime=$((19417*60*60*24)) ajay@ajkumar08-PC:~$ date --date=@$utime Tue 28 Feb 2023 04:00:00 PM PSTLet's change the maximum number of days to 60.
root@ajkumar08-PC:/home/ajay# chage -M 60 ajay root@ajkumar08-PC:/home/ajay# chage -l ajay Last password change : Feb 13, 2023 Password expires : Apr 14, 2023 Password inactive : never Account expires : Mar 01, 2023 Minimum number of days between password change : 0 Maximum number of days between password change : 60 Number of days of warning before password expires : 7The maximum number of days is 60. We add that to the date of the last password change to get "April 14th 2023". We can also get this date from the entry third field of 19401 and add 60 to it to get 19461. Converting this to a date gives us the same date of "April 14th 2023". Another utility is "passwd".
We are logged in as a normal user "ajay1" $ passwd ajay1 Changing password for ajay1. Current password: New password: Retype new password: You must choose a longer password. New password: Retype new password: passwd: password updated successfullyIn it's simpleset form we can use it to change our passwords. We normally have to do this for new accounts as we login with an assigned password; the system will ask us to change our password. As we can see in the output above the system will not allow us to set a very simple password. However this restriction does not apply to an admin user.
An admin can set a simple password. root@ajkumar08-PC:/home# passwd ajay1 New password: Retype new password: passwd: password updated successfully root@ajkumar08-PC:/home#We can use the "-d" option to delete the password for a user. This allows the user to login without a password.
The option is only available to admin user. ajay@ajkumar08-PC:~$ passwd -d ajay1 passwd: Permission denied. ajay@ajkumar08-PC:~$ su root Password: root@ajkumar08-PC:/home/ajay# passwd -d ajay1 passwd: password expiry information changed. root@ajkumar08-PC:/home/ajay# exit exit To login to the user "ajay1" no password is required. ajay@ajkumar08-PC:~$ su ajay1 $ $ exit ajay@ajkumar08-PC:~$We also have other options such as "-l" and "-u" . The "-l" will lock the password and the "-u" will unlock it. Locking the password means the user will not be able to login with the password till it is unlocked.
ajay@ajkumar08-PC:~$ su root Password: //Lock the password for ajay1 root@ajkumar08-PC:/home/ajay# passwd -l ajay1 passwd: password expiry information changed. root@ajkumar08-PC:/home/ajay# exit exit ajay@ajkumar08-PC:~$ su ajay1 Password: su: Authentication failure //unable to login to ajay1 account ajay@ajkumar08-PC:~$ su root Password: //unlock the password root@ajkumar08-PC:/home/ajay# passwd -u ajay1 passwd: password expiry information changed. root@ajkumar08-PC:/home/ajay# exit exit ajay@ajkumar08-PC:~$ su ajay1 Password: $ exit ajay@ajkumar08-PC:~$
Users
Linux is a multi-user system. That means we can have different user accounts and users can log in ("remotely") to the same system remotely. Some of the information that is relevant when creating a user is.- Login name for the user
- Default group for the user. Any additional groups the user should be part of.
- Location of the home directory for the user.
- Shell that will be started up when the user logs in. We can have different shells in Linux such as bash, csh, ksh.
- Location of the startup files that should be copied to the user's folder.
- Initial password for the user.
1) Account is created. An entry is created in "/etc/passwd" file. Home directory is created. 2)The entry in "/etc/groups" updated if user is part of supplemental groups. 3) Startup files copied to the home directory. 4) The home directory's owner and group are set. 5) Password entry created in "/etc/shadow" file.The useradd command has the following options.
These are the most important ones: useradd [ -g group ] [ -G group,group,... ] [ -N ] [ -d home ] [ -s shell ] [ -c gecos ] [ -m [ -k skeldir ] ] [ -M ] [ -r ] [ -p passwd ] username -g group use this as the default group -G g,g,... add the user to these secondary groups -N By default Linux creates a new group for each user. This option prevents that. -d home The path to the user's home directory -s shell The path to the program that will be run when the user logs in. -c gecos The initial contents of the GECOS field. Normally, the user's real name is used here. -m create the user's home directory. If -m is used, -k skeldir can be used to specify the directories to copy the user startup files from. -M do not create the user's home directory -r create a system account rather than a user account. (This determines the range that the account's uid will be in.) -p password Here, password is the encrypted password. Usually, the passwd program is run after the account is created to assign the password. username is the user's name (the login name). It must be unique.We only need to give the username as the argument. The default values are obtained from "/etc/login.defs" and "/etc/default/useradd" .
Let's look at some of the values in these 2 files. "/etc/default/useradd" # GROUP=100 If a value is not specified then a default group with the same name as the user is created and the user assigned to this group. Example for user: "ajay" on my personal Linux system. ajay@ajkumar08-PC:~$ cat /etc/passwd | grep "ajay" ajay:x:1000:1000:ajay,,,:/home/ajay:/bin/bash ajay1:x:1001:1001::/home/ajay1:/bin/sh ajay@ajkumar08-PC:~$ cat /etc/group | grep "1000" ajay:x:1000: ajay@ajkumar08-PC:~$ If we do have a value for "GROUP" in the "useradd" file then we need to specify the "-N" option in useradd to tell it not to create the group with the same name as user. # # The SKEL variable specifies the directory containing "skeletal" user # files; in other words, files such as a sample .profile that will be # copied to the new user's home directory when it is created. # SKEL=/etc/skel This folder will have the default initialization files. These are hidden files. On the hills server we have the following files for my account. [amittal@hills ~]$ ls -a | grep "^\." . .. .bash_history .bash_logout .bash_profile .bashrc .cache .config .emacs .emacs.d .history .kshrc .oracle_jre_usage .pki .python_history .sh_history .ssh .viminfo [amittal@hills ~]$ "/etc/login.defs" [amittal@hills ~]$ cat /etc/login.defs | grep "HOME" CREATE_HOME yes This variable indicates whether creating the home directory is the default. Recall that this is the same as "-m" from the command "useradd" .