Linux Users, Groups and Permissions
Sources:
Linux Users, Groups and Permissions
Users
Linux user is an account or an entity. Every process and file in Linux belongs to a user. Users are identified by:
- Username: Human-readable name (e.g.,
john
,alice
) - User ID (UID): Numerical identifier (e.g.,
1000
,1001
)
User Types:
- Root user: Superuser with UID 0, has complete system access
- By default, only the
root
account is an administrater. You can set other admiistraters by just settingUID=0
, but it's highly unrecommended.
- By default, only the
- System users: UIDs typically 1-999, created by the operating system or other softwares like
mysql
and that is used for operating system defined purposes. - Regular users: UIDs typically 1000+, for human users
Check information of a Linux user:
1 | id <user_name> |
Groups
Groups are collections of users that share permissions. Groups have:
- Group name: Human-readable (e.g.,
developers
,admin
) - Group ID (GID): Numerical identifier
Every user has:
- Primary group: Main group (usually same name as username)
- Secondary groups: Additional groups for extra permissions
Check group information of a Linux user:
1 | groups <user_name> |
Permissions
Unix and Unix-like systens, including macOS and Linux, use a permission system to control access to files and directories:
- Read (r): View file contents or list directory contents
- Write (w): Modify file contents or create/delete files in directory
- Execute (x): Run file as program or enter directory
Permissions are assigned to three categories:
- User (u): The file owner
- Group (g): Users in the file's group
- Others (o): All other users
1 | $ ls -al _config.yml |
- File type and permissions:
-rw-r--r--@
-
: Regular file (could be d for directory, l for linkrw-
: User (lyk) can read and write, but not executer--
: Group (staff) can only readr--
: Others can only read@
: File has extended attributes, which are additional metadata beyond standard file permissions.
- Ownership and metadata:
1
: Number of hard links to this filelyk
: File owner (user)staff
: File owner (group)5246
: File size in bytesJul 3 2024
: Last modification date_config.yml
: Filename
There’s another way to calculate the same file permissions, using numbers.
Permission (word) | Permission (number) |
---|---|
Read | 4 |
Write | 2 |
Execute | 1 |
This means, if you want to give read and write access only to the owner and group, you mention it like this 660
, where the first digit is for the owner, second digit is for the group, and the third digit is for the other users. We can use this format along with the chmod
command to change permissions of any file or directory.
Modify the user and group ID range
The default range of assigning new IDs to new users or groups are listed in /etc/login.defs
file.
The system user accounts has ids from 100 to 999.
1 | cat /etc/login.defs | grep -i SYS_UID_MIN |
The regular user accounts has ids begin from 1000 onwards.
1 | cat /etc/login.defs | grep -i UID_MIN | grep -v -E '^\#' |
To modify those ranges,change the UID_MIN
and GID_MIN
variables.
Database of users and groups
There are primarily 4 files placed under /etc
directory which manages records about users
and groups
.
/etc/passwd
-> The file containing basic information about users./etc/shadow
-> The file containing encrypted passwords./etc/group
-> The file containing basic information about groups and which users belong to them./etc/gshadow
-> The containing encrypted group passwords.
The password (/etc/passwd
) and group (/etc/group
) files doesn't contain password information for security reasons and they are plain text, but the other two files are encrypted text.
The format of files for groups (/etc/group
and /etc/gshadow
) are quite similar to that of the files for users (/etc/passwd
and /etc/shadow
).
/etc/passwd
Source: Understanding the /etc/passwd
File
1 | cat /etc/passwd # Show all users |
Entries have the format:
1 | mark:x:1001:1001:mark,,,:/home/mark:/bin/bash |
The syntax is:
1 | username:password:UID:GID:name:home directory:shell |
where
Username. the username given a the time of creation
Password. Usually, we’ll see an
x
character there. It means the password is encrypted.UID. The user identifier is a number assigned to each user. It is used by the operating system to refer to a user.
GID. The user’s group identifier number, referring to the user’s primary group. When a user creates a file , the file’s group is set to this group. Typically, the name of the group is the same as the name of the user. User’s secondary groups are listed in the
/etc/groups
file.Full name of the user. It's optional and not important. You can write anything to it.
Home directory. User’s home directory.
Login shell. User’s default shell. Note:
/sbin/nologin
or/bin/false
indicates logging in is disabled for the user.To view valid login shell please run the following command
1
cat /etc/shells
/etc/shadow
Source: Understanding the /etc/shadow
File
1 | sudo cat /etc/shadow |
Output:
1 | mark:$6$.n.:17736:0:99999:7::: |
Explanation:
Username. The string you type when you log into the system. The user account that exist on the system.
Encrypted Password. The password is using the
$type$salt$hashed
format.$type
is the method cryptographic hash algorithm and can have the following values:$1$
– MD5$2a$
– Blowfish$2y$
– Eksblowfish$5$
– SHA-256$6$
– SHA-512
If the password field contains an asterisk (
*
) or exclamation point (!
), the user will not be able to login to the system using password authentication. Other login methods like key-based authentication or switching to the user are still allowed.In older Linux systems, the user’s encrypted password was stored in the
/etc/passwd
file.Last password change. This is the date when the password was last changed. The number of days is counted since January 1, 1970 (epoch date).
Minimum password age. The number of days that must pass before the user password can be changed. Typically it is set to zero, which means that there is no minimum password age.
Maximum password age. The number of days after the user password must be changed. By default, this number is set to
99999
.Warning period. The number of days before the password expires during which the user is warned that the password must be changed.
Inactivity period. The number of days after the user password expires before the user account is disabled. Typically this field is empty.
Expiration date. The date when the account was disabled. It is represented as an epoch date.
Unused. This field is ignored. It is reserved for future use.
Let’s take a look at the following example:
1 | linuxize:$6$zHvrJMa5Y690smbQ$z5zdL...:18009:0:120:7:14:: |
The entry above contains information about the user “linuxize” password:
- The password is encrypted with SHA-512 (the password is truncated for better readability).
- The password was last changed on April 23, 2019 -
18009
. - There is no minimum password age.
- The password must be changed at least every 120 days.
- The user will receive a warning message seven days before the password expiration date.
- If the user doesn’t attempt to login to the system 14 days after the password is expired, the account will be disabled.
- There is no account expiration date.
/etc/group
1 | cat /etc/group # Show all groups |
User Management
TL;DR: On your old user account, do
1 | sudo adduser lyk |
Create a Linux User:
Method 1 (Recommended):
1 | sudo adduser <username> |
adduser
is a Perl script which uses useradd
(which is native to Linux) binary in back-end. It's more interactive and user friendly than it's back-end useradd
.
Method 2:
1 | sudo useradd <username> |
Method 3: By directly modifying /etc/passwd
file. Not a recommended way but one can create a Linux user by directly modifying /etc/passwd
file and making an entry for new user. In such cases you need to create the group
, home directory
etc. individually for that user.
Grant sudo
Permisson to a Linux User:
1 | sudo usermod -a -G adm <username> |
Alternatively, you can edit /etc/sudoers
to achieve it.
Add the write permisson to
/etc/sudoers
:1
chmod u+w /etc/sudoers
Edit
/etc/sudoers
, below the line ofroot ALL=(ALL) ALL
, add1
lyk ALL=(ALL) ALL
Finnaly, delete the write permisson to
/etc/sudoers
:1
chmod u-w /etc/sudoers
Switch user account:
1 | su - <username> |
Assign/Change password to a Linux user:
Using passwd
command we can assign passwords to Linux user.
1 | passwd <user> |
Delete a Linux user:
Using userdel
command you can delete a user from Linux operating system.
1 | userdel -r <user> |
Before this, you need to kill the systemd
process of that user, if any.
Modifying an Existing user's properties:
Change User Home Directory:
1 | usermod -d /var/www/ sample |
Group Management
There are two types of groups in Linux.
- primary group: when you create a user the primary group that the user belongs to also gets created with the same name as the user. User must be a member of a primary group and there can be only one primary group for each member.
- secondary group: It's always optional. If you have a requirement create it and add the users to it. A user can be mart of one or more secondary groups.
Create a Linux group:
1 | groupadd <new_group_name> |
Add users to a Linux group:
1 | usermod -G secondgroup sample |
Change Name of a Linux group:
1 | sudo groupmod -n new_name old_name |
Change GID of a Linux group:
1 | groupmod -g <new_gid> <groupname> |
Remove a User from a Linux group:
1 | gpasswd -d user1 lcousersecondary1 |
Delete or Remove a Linux group:
1 | groupdel secondarygroup |
Example: Create a user
Here we will use multiple useradd
command options to create the user.
Our requirement is as follows:
- Full name is
LearnCodeOnline
- username is
lcouser
- Primary group is
lcouserprimary
- Secondary groups are
lcousersecondary1
andlcousersecondary2
- Default shell is
/bin/tcsh
Run the following commands to achieve this.
1 | groupadd lcouserprimary |
Special case: Docker container example
Suppose my user information on the host system is:
1 | $ id |
By default, containers run as root (UID 0, GID 0). When container processes create files, the Linux kernel records UID 0 in the file metadata. Back on the host, these files appear owned by root, and I usually do not have root priviledge on the host machine.
There is not perfect solution for this. You may cinsider running container with host user/group IDs
1 | docker run --gpus all --rm -d -i --name <container_name> --network host \ |
and attaching to it via
1 | docker exec -it -u $(id -u):$(id -g) <image_name> bash |
But the problem is that files created during the image building process are still owned by root. Therefore, we have to always be in the container to edit files created by it.